From 4a73376b73216b90187906ae4d3ac12c5c026d5d Mon Sep 17 00:00:00 2001 From: ChaiNingQi <2032830459@qq.com> Date: Thu, 22 Jan 2026 16:21:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E7=AB=A0=E5=8F=91=E5=B8=83=E3=80=81?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E5=9F=B9=E8=AE=AD=EF=BC=9A=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E7=8A=B6=E6=80=81=E5=AD=97=E6=AE=B5=EF=BC=8C?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=8F=90=E4=BA=A4=E5=AE=A1=E6=A0=B8=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E4=B8=8A=E6=9E=B6=E4=B8=8B=E6=9E=B6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vet/VetKnowledgeController.java | 62 +- .../controller/vet/VetProductController.java | 2 + .../vet/VetTrainingVideoController.java | 152 +- .../com/chenhai/vet/domain/VetKnowledge.java | 94 +- .../chenhai/vet/domain/VetTrainingVideo.java | 283 ++- .../vet/mapper/VetTrainingVideoMapper.java | 23 +- .../vet/service/IVetKnowledgeService.java | 48 +- .../vet/service/IVetProductService.java | 1 + .../vet/service/IVetTrainingVideoService.java | 44 +- .../service/impl/VetKnowledgeServiceImpl.java | 257 +- .../service/impl/VetProductServiceImpl.java | 4 + .../impl/VetTrainingVideoServiceImpl.java | 223 +- .../mapper/vet/VetKnowledgeMapper.xml | 43 +- .../resources/mapper/vet/VetProductMapper.xml | 2 +- .../mapper/vet/VetTrainingVideoMapper.xml | 88 +- chenhai-ui/src/api/vet/knowledge.js | 39 +- chenhai-ui/src/api/vet/training.js | 101 +- chenhai-ui/src/views/vet/knowledge/index.vue | 585 ++++- chenhai-ui/src/views/vet/product/index.vue | 1851 +++++++++++--- .../src/views/vet/training/TrainingHome.vue | 2208 +++++++++-------- 20 files changed, 4471 insertions(+), 1639 deletions(-) diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java index b40b221..4236d92 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.chenhai.common.annotation.Log; import com.chenhai.common.core.controller.BaseController; @@ -23,7 +24,7 @@ import com.chenhai.common.core.page.TableDataInfo; /** * 兽医文章Controller - * + * * @author ruoyi * @date 2026-01-08 */ @@ -77,7 +78,8 @@ public class VetKnowledgeController extends BaseController @PostMapping public AjaxResult add(@RequestBody VetKnowledge vetKnowledge) { - vetKnowledge.setStatus("0"); + vetKnowledge.setArticleStatus("0"); // 草稿 + vetKnowledge.setAuditStatus("0"); // 待审核 return toAjax(vetKnowledgeService.insertVetKnowledge(vetKnowledge)); } @@ -97,24 +99,39 @@ public class VetKnowledgeController extends BaseController */ @PreAuthorize("@ss.hasPermi('vet:knowledge:remove')") @Log(title = "兽医文章", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") + @DeleteMapping("/{ids}") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(vetKnowledgeService.deleteVetKnowledgeByIds(ids)); } /** - * 上传文章(待审核) + * 提交审核 */ - @PreAuthorize("@ss.hasPermi('vet:knowledge:upload')") - @Log(title = "兽医文章", businessType = BusinessType.INSERT) - @PostMapping("/upload") - public AjaxResult upload(@RequestBody VetKnowledge vetKnowledge) { - return vetKnowledgeService.uploadVetKnowledge(vetKnowledge); + @PreAuthorize("@ss.hasPermi('vet:knowledge:submit')") + @Log(title = "兽医文章", businessType = BusinessType.UPDATE) + @PutMapping("/submit/{id}") + public AjaxResult submitForAudit(@PathVariable Long id) { + return vetKnowledgeService.submitForAudit(id); } /** - * 发布文章(更新状态) + * 审核文章 + */ + @PreAuthorize("@ss.hasPermi('vet:knowledge:audit')") + @Log(title = "兽医文章", businessType = BusinessType.UPDATE) + @PutMapping("/audit/{id}") + public AjaxResult audit(@PathVariable Long id, + @RequestParam String auditStatus, // 注意参数名改为auditStatus + @RequestParam(required = false) String auditComment) { + // 验证状态值是否合法 + if (!"2".equals(auditStatus) && !"3".equals(auditStatus)) { + return AjaxResult.error("无效的审核状态值"); + } + return vetKnowledgeService.auditVetKnowledge(id, auditStatus, auditComment); + } + /** + * 发布文章 */ @PreAuthorize("@ss.hasPermi('vet:knowledge:publish')") @Log(title = "兽医文章", businessType = BusinessType.UPDATE) @@ -122,4 +139,27 @@ public class VetKnowledgeController extends BaseController public AjaxResult publish(@PathVariable Long id) { return vetKnowledgeService.publishVetKnowledge(id); } -} + + /** + * 上架文章 + */ + @PreAuthorize("@ss.hasPermi('vet:knowledge:publish')") + @Log(title = "兽医文章", businessType = BusinessType.UPDATE) + @PutMapping("/online/{id}") + public AjaxResult online(@PathVariable Long id) { + return vetKnowledgeService.onlineVetKnowledge(id); + } + + /** + * 下架文章 + */ + @PreAuthorize("@ss.hasPermi('vet:knowledge:publish')") + @Log(title = "兽医文章", businessType = BusinessType.UPDATE) + @PutMapping("/offline/{id}") + public AjaxResult offline(@PathVariable Long id, @RequestParam(required = false) String auditComment) { + if (auditComment == null || auditComment.trim().isEmpty()) { + return AjaxResult.error("请输入下架原因"); + } + return vetKnowledgeService.offlineVetKnowledge(id, auditComment); + } +} \ No newline at end of file diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java index 55f0732..65010a8 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetProductController.java @@ -101,4 +101,6 @@ public class VetProductController extends BaseController { return toAjax(vetProductService.deleteVetProductByIds(ids)); } + + } diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java index 8621498..539c8a7 100644 --- a/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetTrainingVideoController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; +import java.util.Map; @RestController @RequestMapping("/vet/training") @@ -31,11 +32,11 @@ public class VetTrainingVideoController extends BaseController { */ @PostMapping("/upload") public AjaxResult uploadVideo( - @RequestParam("title") String title, // 改为 @RequestParam - @RequestParam("videoFile") MultipartFile videoFile, // 文件字段保持 @RequestPart 或改为 @RequestParam + @RequestParam("title") String title, + @RequestParam("videoFile") MultipartFile videoFile, @RequestParam(value = "description", required = false) String description, @RequestParam(value = "category", required = false) String category, - @RequestParam(value = "status", required = false, defaultValue = "1") String status) { + @RequestParam(value = "coverImage", required = false) MultipartFile coverImage) { Long userId = getCurrentUserId(); @@ -45,9 +46,8 @@ public class VetTrainingVideoController extends BaseController { video.setTitle(title); video.setDescription(description); video.setCategory(category); - video.setStatus(status); - String result = trainingVideoService.uploadAndSave(video, videoFile, null); + String result = trainingVideoService.uploadAndSave(video, videoFile, coverImage); return success(result); } catch (Exception e) { e.printStackTrace(); @@ -55,37 +55,6 @@ public class VetTrainingVideoController extends BaseController { } } - /** - * 批量上传视频(可选功能) - */ - @PostMapping("/upload/batch") - public AjaxResult uploadBatch( - @RequestParam String[] titles, - @RequestParam MultipartFile[] videoFiles, - @RequestParam(required = false) String[] categories) { - - Long userId = getCurrentUserId(); - - try { - int successCount = 0; - for (int i = 0; i < videoFiles.length; i++) { - if (i < titles.length) { - VetTrainingVideo video = new VetTrainingVideo(); - video.setUserId(userId); // 修正变量名 - video.setTitle(titles[i]); - video.setCategory(categories != null && i < categories.length ? categories[i] : null); - video.setStatus("1"); - - trainingVideoService.uploadAndSave(video, videoFiles[i], null); - successCount++; - } - } - return success("成功上传 " + successCount + " 个视频"); - } catch (Exception e) { - return error("批量上传失败:" + e.getMessage()); - } - } - /** * 查看我上传的视频 */ @@ -93,11 +62,12 @@ public class VetTrainingVideoController extends BaseController { public TableDataInfo getMyVideos( @RequestParam(required = false) String title, @RequestParam(required = false) String category, - @RequestParam(required = false) String status) { + @RequestParam(required = false) String status, + @RequestParam(required = false) String auditStatus) { startPage(); - Long userId = getCurrentUserId(); // 修正变量名 - List list = trainingVideoService.getMyVideos(userId, title, category, status); + Long userId = getCurrentUserId(); + List list = trainingVideoService.getMyVideos(userId, title, category, status, auditStatus); return getDataTable(list); } @@ -108,7 +78,7 @@ public class VetTrainingVideoController extends BaseController { public TableDataInfo getPublicVideos( @RequestParam(required = false) String title, @RequestParam(required = false) String category, - @RequestParam(required = false) String userName) { // 参数名改为userName + @RequestParam(required = false) String userName) { startPage(); List list = trainingVideoService.getPublicVideos(title, category, userName); @@ -120,15 +90,16 @@ public class VetTrainingVideoController extends BaseController { */ @GetMapping("/video/{videoId}") public AjaxResult getVideoDetail(@PathVariable Long videoId) { - Long userId = getCurrentUserId(); // 修正变量名 + Long userId = getCurrentUserId(); VetTrainingVideo video = trainingVideoService.getVideoDetail(videoId, userId); if (video == null) { return error("视频不存在或无权限查看"); } - // 如果是公开视频或自己的视频,增加观看次数 - if ("1".equals(video.getStatus()) || userId.equals(video.getUserId())) { + // 如果是审核通过且公开的视频,增加观看次数 + if ("1".equals(video.getAuditStatus()) && // 1-审核通过 + "1".equals(video.getStatus())) { // 1-已上架/公开 trainingVideoService.incrementViewCount(videoId); video.setViewCount(video.getViewCount() + 1); } @@ -137,45 +108,104 @@ public class VetTrainingVideoController extends BaseController { } /** - * 获取视频播放地址(带权限校验)- 可选功能 + * 提交审核(手动提交) + */ + @PostMapping("/submit-audit/{videoId}") + public AjaxResult submitForAudit(@PathVariable Long videoId) { + Long userId = getCurrentUserId(); + boolean success = trainingVideoService.submitForAudit(videoId, userId); + return success ? success("提交审核成功") : error("提交审核失败"); + } + + /** + * 取消审核 + */ + @PostMapping("/cancel-audit/{videoId}") + public AjaxResult cancelAudit(@PathVariable Long videoId) { + Long userId = getCurrentUserId(); + boolean success = trainingVideoService.cancelAudit(videoId, userId); + return success ? success("取消审核成功") : error("取消审核失败"); + } + + /** + * 重新提交审核 + */ + @PostMapping("/resubmit-audit/{videoId}") + public AjaxResult resubmitForAudit(@PathVariable Long videoId) { + Long userId = getCurrentUserId(); + boolean success = trainingVideoService.resubmitForAudit(videoId, userId); + return success ? success("重新提交审核成功") : error("重新提交审核失败"); + } + + /** + * 审核视频(管理员接口)- 使用JSON接收 */ - @GetMapping("/video/play/{videoId}") - public AjaxResult getPlayUrl(@PathVariable Long videoId) { - Long userId = getCurrentUserId(); // 修正变量名 - String playUrl = trainingVideoService.getVideoPlayUrl(videoId, userId); + @PostMapping("/audit/{videoId}") + public AjaxResult auditVideo(@PathVariable Long videoId, + @RequestBody Map auditData) { - if (playUrl == null) { - return error("无权限播放此视频"); + String auditStatus = auditData.get("auditStatus"); + String auditOpinion = auditData.get("auditOpinion"); + + if (auditStatus == null || auditStatus.trim().isEmpty()) { + return error("审核状态不能为空"); } - return success(playUrl); + Long auditUserId = getCurrentUserId(); + boolean success = trainingVideoService.auditVideo(videoId, auditStatus, auditOpinion, auditUserId); + return success ? success("审核操作成功") : error("审核操作失败"); } /** - * 获取热门视频(按观看次数排序) + * 上架视频(审核通过后才能上架) */ - @GetMapping("/hot-videos") - public AjaxResult getHotVideos(@RequestParam(defaultValue = "10") Integer limit) { - List list = trainingVideoService.getHotVideos(limit); - return success(list); + @PostMapping("/publish/{videoId}") + public AjaxResult publishVideo(@PathVariable Long videoId) { + Long userId = getCurrentUserId(); + boolean success = trainingVideoService.publishVideo(videoId, userId); + return success ? success("视频已上架") : error("上架失败,请确保视频已通过审核"); } /** - * 搜索视频 + * 下架视频 */ - @GetMapping("/search") - public TableDataInfo searchVideos(@RequestParam String keyword) { + @PostMapping("/offline/{videoId}") + public AjaxResult offlineVideo(@PathVariable Long videoId) { + Long userId = getCurrentUserId(); + boolean success = trainingVideoService.offlineVideo(videoId, userId); + return success ? success("视频已下架") : error("下架失败"); + } + + /** + * 获取待审核视频列表(管理员接口) + */ + @GetMapping("/pending-audit") + public TableDataInfo getPendingAuditVideos( + @RequestParam(required = false) String title, + @RequestParam(required = false) String userName) { + startPage(); - List list = trainingVideoService.searchVideos(keyword); + List list = trainingVideoService.getPendingAuditVideos(title, userName); return getDataTable(list); } + /** + * 编辑视频信息 + */ + @PutMapping("/update/{videoId}") + public AjaxResult updateVideoInfo(@PathVariable Long videoId, + @RequestBody VetTrainingVideo video) { + Long userId = getCurrentUserId(); + boolean success = trainingVideoService.updateVideoInfo(videoId, video, userId); + return success ? success("更新成功") : error("更新失败"); + } + /** * 删除我的视频 */ @DeleteMapping("/{videoId}") public AjaxResult deleteVideo(@PathVariable Long videoId) { - Long userId = getCurrentUserId(); // 修正变量名 + Long userId = getCurrentUserId(); VetTrainingVideo video = trainingVideoService.getVideoDetail(videoId, userId); if (video == null) { diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetKnowledge.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetKnowledge.java index 33cb0bf..20570cc 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetKnowledge.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetKnowledge.java @@ -7,7 +7,7 @@ import com.chenhai.common.core.domain.BaseEntity; /** * 兽医文章对象 vet_knowledge - * + * * @author ruoyi * @date 2026-01-08 */ @@ -27,91 +27,115 @@ public class VetKnowledge extends BaseEntity private String content; /** 文章分类(治疗防治/饲养管理/其他) */ - @Excel(name = "文章分类", readConverterExp = "治=疗防治/饲养管理/其他") + @Excel(name = "文章分类", dictType = "article_category") private String category; /** 检测出的敏感词 */ @Excel(name = "检测出的敏感词") private String sensitiveWords; - /** 状态(0-待审核 1-已发布 2-敏感内容驳回) */ - @Excel(name = "状态", readConverterExp = "0=-待审核,1=-已发布,2=-敏感内容驳回") - private String status; + /** 文章状态(0-草稿 1-已发布 2-已下架) */ + @Excel(name = "文章状态", dictType = "article_status") + private String articleStatus; - public void setId(Long id) + /** 审核状态(0-待审核 1-审核中 2-审核通过 3-审核驳回 4-敏感内容驳回) */ + @Excel(name = "审核状态", dictType = "vet_audit_status") + private String auditStatus; + + /** 审核意见 */ + @Excel(name = "审核意见") + private String auditComment; + + public void setId(Long id) { this.id = id; } - public Long getId() + public Long getId() { return id; } - public void setTitle(String title) + public void setTitle(String title) { this.title = title; } - public String getTitle() + public String getTitle() { return title; } - public void setContent(String content) + public void setContent(String content) { this.content = content; } - public String getContent() + public String getContent() { return content; } - public void setCategory(String category) + public void setCategory(String category) { this.category = category; } - public String getCategory() + public String getCategory() { return category; } - public void setSensitiveWords(String sensitiveWords) + public void setSensitiveWords(String sensitiveWords) { this.sensitiveWords = sensitiveWords; } - public String getSensitiveWords() + public String getSensitiveWords() { return sensitiveWords; } - public void setStatus(String status) - { - this.status = status; + public String getArticleStatus() { + return articleStatus; } - public String getStatus() - { - return status; + public void setArticleStatus(String articleStatus) { + this.articleStatus = articleStatus; + } + + public String getAuditStatus() { + return auditStatus; + } + + public void setAuditStatus(String auditStatus) { + this.auditStatus = auditStatus; + } + + public String getAuditComment() { + return auditComment; + } + + public void setAuditComment(String auditComment) { + this.auditComment = auditComment; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("title", getTitle()) - .append("content", getContent()) - .append("category", getCategory()) - .append("sensitiveWords", getSensitiveWords()) - .append("status", getStatus()) - .append("createBy", getCreateBy()) - .append("createTime", getCreateTime()) - .append("updateBy", getUpdateBy()) - .append("updateTime", getUpdateTime()) - .append("remark", getRemark()) - .toString(); - } -} + .append("id", getId()) + .append("title", getTitle()) + .append("content", getContent()) + .append("category", getCategory()) + .append("sensitiveWords", getSensitiveWords()) + .append("articleStatus", getArticleStatus()) + .append("auditStatus", getAuditStatus()) + .append("auditComment", getAuditComment()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetTrainingVideo.java b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetTrainingVideo.java index a7aaf47..e53e46c 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/domain/VetTrainingVideo.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/domain/VetTrainingVideo.java @@ -1,26 +1,287 @@ package com.chenhai.vet.domain; -import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.chenhai.common.annotation.Excel; +import com.chenhai.common.core.domain.BaseEntity; + import java.util.Date; -@Data -public class VetTrainingVideo { +/** + * 兽医培训视频对象 vet_training_video + * + * @author ruoyi + * @date 2026-01-08 + */ +public class VetTrainingVideo extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ private Long id; + + /** 用户ID */ private Long userId; + + /** 视频标题 */ + @Excel(name = "视频标题") private String title; + + /** 视频描述 */ + @Excel(name = "视频描述") private String description; + + /** 视频URL */ + @Excel(name = "视频URL") private String videoUrl; + + /** 封面图片 */ + @Excel(name = "封面图片") private String coverImage; + + /** 视频分类(手术技巧/疾病诊断/药物使用/其他) */ + @Excel(name = "视频分类", dictType = "video_category") private String category; + + /** 视频标签 */ + @Excel(name = "视频标签") private String tags; - private Integer duration; // 视频时长(秒) - private Long fileSize; // 文件大小(字节) + + /** 视频时长(秒) */ + @Excel(name = "视频时长") + private Integer duration; + + /** 文件大小(字节) */ + @Excel(name = "文件大小") + private Long fileSize; + + /** 观看次数 */ + @Excel(name = "观看次数") private Integer viewCount; - private String status; // 0-私有 1-公开 - private Date createTime; - private Date updateTime; - // 非数据库字段 - private String userName; // 兽医姓名 - private String durationStr; // 格式化后的时长(如:12:30) + /** 上架状态(0-私有 1-公开) */ + @Excel(name = "上架状态", dictType = "video_status") + private String status; + + /** 审核状态(0-待审核 1-审核通过 2-审核拒绝 3-无需审核) */ + @Excel(name = "审核状态", dictType = "video_audit_status") + private String auditStatus; + + /** 审核意见 */ + @Excel(name = "审核意见") + private String auditOpinion; + + /** 审核人ID */ + private Long auditUserId; + + /** 审核时间 */ + private Date auditTime; + + /** 格式化后的时长(如:12:30) */ + private String durationStr; + + /** 用户名称(非数据库字段) */ + private String userName; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getTitle() + { + return title; + } + + public void setDescription(String description) + { + this.description = description; + } + + public String getDescription() + { + return description; + } + + public void setVideoUrl(String videoUrl) + { + this.videoUrl = videoUrl; + } + + public String getVideoUrl() + { + return videoUrl; + } + + public void setCoverImage(String coverImage) + { + this.coverImage = coverImage; + } + + public String getCoverImage() + { + return coverImage; + } + + public void setCategory(String category) + { + this.category = category; + } + + public String getCategory() + { + return category; + } + + public void setTags(String tags) + { + this.tags = tags; + } + + public String getTags() + { + return tags; + } + + public void setDuration(Integer duration) + { + this.duration = duration; + } + + public Integer getDuration() + { + return duration; + } + + public void setFileSize(Long fileSize) + { + this.fileSize = fileSize; + } + + public Long getFileSize() + { + return fileSize; + } + + public void setViewCount(Integer viewCount) + { + this.viewCount = viewCount; + } + + public Integer getViewCount() + { + return viewCount; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + public void setAuditStatus(String auditStatus) + { + this.auditStatus = auditStatus; + } + + public String getAuditStatus() + { + return auditStatus; + } + + public void setAuditOpinion(String auditOpinion) + { + this.auditOpinion = auditOpinion; + } + + public String getAuditOpinion() + { + return auditOpinion; + } + + public void setAuditUserId(Long auditUserId) + { + this.auditUserId = auditUserId; + } + + public Long getAuditUserId() + { + return auditUserId; + } + + public void setAuditTime(Date auditTime) + { + this.auditTime = auditTime; + } + + public Date getAuditTime() + { + return auditTime; + } + + public String getDurationStr() { + return durationStr; + } + + public void setDurationStr(String durationStr) { + this.durationStr = durationStr; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("userId", getUserId()) + .append("title", getTitle()) + .append("description", getDescription()) + .append("videoUrl", getVideoUrl()) + .append("coverImage", getCoverImage()) + .append("category", getCategory()) + .append("tags", getTags()) + .append("duration", getDuration()) + .append("fileSize", getFileSize()) + .append("viewCount", getViewCount()) + .append("status", getStatus()) + .append("auditStatus", getAuditStatus()) + .append("auditOpinion", getAuditOpinion()) + .append("auditUserId", getAuditUserId()) + .append("auditTime", getAuditTime()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .toString(); + } } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetTrainingVideoMapper.java b/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetTrainingVideoMapper.java index 4171069..2b814fb 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetTrainingVideoMapper.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/mapper/VetTrainingVideoMapper.java @@ -2,6 +2,7 @@ package com.chenhai.vet.mapper; import com.chenhai.vet.domain.VetTrainingVideo; import org.apache.ibatis.annotations.Param; +import java.util.Date; import java.util.List; public interface VetTrainingVideoMapper { @@ -11,7 +12,8 @@ public interface VetTrainingVideoMapper { List selectMyVideos(@Param("userId") Long userId, @Param("title") String title, @Param("category") String category, - @Param("status") String status); + @Param("status") String status, + @Param("auditStatus") String auditStatus); List selectPublicVideos(@Param("title") String title, @Param("category") String category, @@ -24,5 +26,24 @@ public interface VetTrainingVideoMapper { List selectHotVideos(@Param("limit") Integer limit); List searchVideos(@Param("keyword") String keyword); + int deleteVideoById(@Param("id") Long id); + + // 更新审核状态 + int updateAuditStatus(@Param("id") Long id, + @Param("auditStatus") String auditStatus, + @Param("auditOpinion") String auditOpinion, + @Param("auditUserId") Long auditUserId, + @Param("auditTime") Date auditTime); + + // 更新视频状态(公开/私有) + int updateStatus(@Param("id") Long id, + @Param("status") String status); + + // 获取待审核视频列表 + List selectPendingAuditVideos(@Param("title") String title, + @Param("userName") String userName); + + // 更新视频信息 + int updateVideoInfo(VetTrainingVideo video); } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java index 4997780..c73be4e 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java @@ -7,15 +7,15 @@ import com.chenhai.vet.domain.VetKnowledge; /** * 兽医文章Service接口 - * + * * @author ruoyi * @date 2026-01-08 */ -public interface IVetKnowledgeService +public interface IVetKnowledgeService { /** * 查询兽医文章 - * + * * @param id 兽医文章主键 * @return 兽医文章 */ @@ -23,7 +23,7 @@ public interface IVetKnowledgeService /** * 查询兽医文章列表 - * + * * @param vetKnowledge 兽医文章 * @return 兽医文章集合 */ @@ -31,7 +31,7 @@ public interface IVetKnowledgeService /** * 新增兽医文章 - * + * * @param vetKnowledge 兽医文章 * @return 结果 */ @@ -39,7 +39,7 @@ public interface IVetKnowledgeService /** * 修改兽医文章 - * + * * @param vetKnowledge 兽医文章 * @return 结果 */ @@ -47,7 +47,7 @@ public interface IVetKnowledgeService /** * 批量删除兽医文章 - * + * * @param ids 需要删除的兽医文章主键集合 * @return 结果 */ @@ -55,20 +55,44 @@ public interface IVetKnowledgeService /** * 删除兽医文章信息 - * + * * @param id 兽医文章主键 * @return 结果 */ public int deleteVetKnowledgeById(Long id); /** - * 上传文章(待审核) + * 提交审核 + * @param id 文章ID + * @return 结果 + */ + AjaxResult submitForAudit(Long id); + + /** + * 审核文章 + * @param id 文章ID + * @param auditStatus 审核状态(2-审核通过 3-审核驳回) + * @param auditComment 审核意见 + * @return 结果 */ - AjaxResult uploadVetKnowledge(VetKnowledge vetKnowledge); + AjaxResult auditVetKnowledge(Long id, String auditStatus, String auditComment); /** - * 发布文章(更新状态为已发布) + * 发布文章(更新文章状态为已发布) */ AjaxResult publishVetKnowledge(Long id); -} + /** + * 上架文章 + * @param id 文章ID + * @return 结果 + */ + AjaxResult onlineVetKnowledge(Long id); + + /** + * 下架文章 + * @param id 文章ID + * @return 结果 + */ + AjaxResult offlineVetKnowledge(Long id, String auditComment); +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java index 50e2331..33f98ae 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetProductService.java @@ -58,4 +58,5 @@ public interface IVetProductService * @return 结果 */ public int deleteVetProductById(Long id); + } diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java index f40b611..62f3c2f 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java @@ -8,14 +8,14 @@ import java.util.List; public interface IVetTrainingVideoService { /** - * 上传并保存视频 + * 上传并保存视频(自动设为待审核) */ String uploadAndSave(VetTrainingVideo video, MultipartFile videoFile, MultipartFile coverImage); /** * 获取我的视频列表 */ - List getMyVideos(Long userId, String title, String category, String status); + List getMyVideos(Long userId, String title, String category, String status, String auditStatus); /** * 获取公开视频列表 @@ -48,4 +48,44 @@ public interface IVetTrainingVideoService { List searchVideos(String keyword); int deleteVideoById(Long videoId); + + /** + * 提交审核(用户手动提交) + */ + boolean submitForAudit(Long videoId, Long userId); + + /** + * 取消审核(用户主动取消) + */ + boolean cancelAudit(Long videoId, Long userId); + + /** + * 重新提交审核(审核拒绝后) + */ + boolean resubmitForAudit(Long videoId, Long userId); + + /** + * 审核视频(管理员) + */ + boolean auditVideo(Long videoId, String auditStatus, String auditOpinion, Long auditUserId); + + /** + * 上架视频(审核通过后) + */ + boolean publishVideo(Long videoId, Long userId); + + /** + * 下架视频 + */ + boolean offlineVideo(Long videoId, Long userId); + + /** + * 获取待审核视频列表(管理员) + */ + List getPendingAuditVideos(String title, String userName); + + /** + * 编辑视频信息 + */ + boolean updateVideoInfo(Long videoId, VetTrainingVideo video, Long userId); } \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java index 83e285c..353693e 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java @@ -13,21 +13,18 @@ import com.chenhai.vet.service.IVetKnowledgeService; /** * 兽医文章Service业务层处理 - * + * * @author ruoyi * @date 2026-01-08 */ @Service -public class VetKnowledgeServiceImpl implements IVetKnowledgeService +public class VetKnowledgeServiceImpl implements IVetKnowledgeService { @Autowired private VetKnowledgeMapper vetKnowledgeMapper; /** * 查询兽医文章 - * - * @param id 兽医文章主键 - * @return 兽医文章 */ @Override public VetKnowledge selectVetKnowledgeById(Long id) @@ -37,9 +34,6 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService /** * 查询兽医文章列表 - * - * @param vetKnowledge 兽医文章 - * @return 兽医文章 */ @Override public List selectVetKnowledgeList(VetKnowledge vetKnowledge) @@ -49,22 +43,23 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService /** * 新增兽医文章 - * - * @param vetKnowledge 兽医文章 - * @return 结果 */ @Override public int insertVetKnowledge(VetKnowledge vetKnowledge) { vetKnowledge.setCreateTime(DateUtils.getNowDate()); + // 新增文章时,默认状态为草稿,审核状态为待审核 + if (vetKnowledge.getArticleStatus() == null) { + vetKnowledge.setArticleStatus("0"); // 草稿 + } + if (vetKnowledge.getAuditStatus() == null) { + vetKnowledge.setAuditStatus("0"); // 待审核 + } return vetKnowledgeMapper.insertVetKnowledge(vetKnowledge); } /** * 修改兽医文章 - * - * @param vetKnowledge 兽医文章 - * @return 结果 */ @Override public int updateVetKnowledge(VetKnowledge vetKnowledge) @@ -75,9 +70,6 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService /** * 批量删除兽医文章 - * - * @param ids 需要删除的兽医文章主键 - * @return 结果 */ @Override public int deleteVetKnowledgeByIds(Long[] ids) @@ -87,9 +79,6 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService /** * 删除兽医文章信息 - * - * @param id 兽医文章主键 - * @return 结果 */ @Override public int deleteVetKnowledgeById(Long id) @@ -98,37 +87,223 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService } /** - * 上传文章:默认状态为0-待审核 + * 提交审核:将审核状态改为审核中 */ @Override - public AjaxResult uploadVetKnowledge(VetKnowledge vetKnowledge) { - // 填充基础信息 - vetKnowledge.setCreateBy(SecurityUtils.getUsername()); - vetKnowledge.setCreateTime(DateUtils.getNowDate()); - vetKnowledge.setStatus("0"); // 固定为待审核 + public AjaxResult submitForAudit(Long id) { + + try { + VetKnowledge current = vetKnowledgeMapper.selectVetKnowledgeById(id); + + if (current == null) { + return AjaxResult.error("文章不存在"); + } + // 只有草稿状态(0)且待审核状态(0)的文章才能提交审核 + if (!"0".equals(current.getArticleStatus())) { + return AjaxResult.error("只有草稿状态的文章可以提交审核"); + } + if (!"0".equals(current.getAuditStatus())) { + return AjaxResult.error("文章当前状态不能提交审核"); + } + + String username = SecurityUtils.getUsername(); + if (username == null || username.trim().isEmpty()) { + username = "system"; + } + System.out.println("当前用户: " + username); + + VetKnowledge vetKnowledge = new VetKnowledge(); + vetKnowledge.setId(id); + vetKnowledge.setAuditStatus("1"); // 审核中 + vetKnowledge.setUpdateBy(username); + vetKnowledge.setUpdateTime(DateUtils.getNowDate()); + int result = vetKnowledgeMapper.updateVetKnowledge(vetKnowledge); - int result = vetKnowledgeMapper.insertVetKnowledge(vetKnowledge); - if (result > 0) { - return AjaxResult.success("文章上传成功,等待审核"); + // 验证更新是否真的成功 + if (result > 0) { + // 重新查询验证 + VetKnowledge updated = vetKnowledgeMapper.selectVetKnowledgeById(id); + return AjaxResult.success("文章已提交审核,等待审核"); + } else { + return AjaxResult.error("提交审核失败"); + } + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error("提交审核失败: " + e.getMessage()); } - return AjaxResult.error("文章上传失败"); } /** - * 发布文章:更新状态为1-已发布 + * 审核文章 + */ + @Override + public AjaxResult auditVetKnowledge(Long id, String auditStatus, String auditComment) { + try { + VetKnowledge current = vetKnowledgeMapper.selectVetKnowledgeById(id); + if (current == null) { + return AjaxResult.error("文章不存在"); + } + + + // 只有审核中状态(1)才能进行审核 + if (!"1".equals(current.getAuditStatus())) { + return AjaxResult.error("只有审核中状态的文章可以审核"); + } + + VetKnowledge vetKnowledge = new VetKnowledge(); + vetKnowledge.setId(id); + vetKnowledge.setAuditStatus(auditStatus); // 审核状态 + vetKnowledge.setAuditComment(auditComment); // 审核意见 + + String username = SecurityUtils.getUsername(); + if (username == null || username.trim().isEmpty()) { + username = "system"; + } + vetKnowledge.setUpdateBy(username); + vetKnowledge.setUpdateTime(DateUtils.getNowDate()); + + int result = vetKnowledgeMapper.updateVetKnowledge(vetKnowledge); + + if (result > 0) { + String message = "2".equals(auditStatus) ? "文章审核通过" : "文章审核驳回"; + return AjaxResult.success(message); + } + return AjaxResult.error("审核操作失败"); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error("审核操作失败: " + e.getMessage()); + } + } + + /** + * 发布文章:审核通过的文章才能发布 */ @Override public AjaxResult publishVetKnowledge(Long id) { - VetKnowledge vetKnowledge = new VetKnowledge(); - vetKnowledge.setId(id); - vetKnowledge.setStatus("1"); // 已发布 - vetKnowledge.setUpdateBy(SecurityUtils.getUsername()); - vetKnowledge.setUpdateTime(DateUtils.getNowDate()); - int result = vetKnowledgeMapper.updateVetKnowledge(vetKnowledge); - if (result > 0) { - return AjaxResult.success("文章发布成功"); + try { + VetKnowledge current = vetKnowledgeMapper.selectVetKnowledgeById(id); + if (current == null) { + return AjaxResult.error("文章不存在"); + } + + // 只有审核通过(2)且为草稿状态(0)的文章才能发布 + if (!"2".equals(current.getAuditStatus())) { + return AjaxResult.error("只有审核通过的文章可以发布"); + } + if (!"0".equals(current.getArticleStatus())) { + return AjaxResult.error("文章当前状态不能发布"); + } + + VetKnowledge vetKnowledge = new VetKnowledge(); + vetKnowledge.setId(id); + vetKnowledge.setArticleStatus("1"); // 已发布 + String username = SecurityUtils.getUsername(); + if (username == null || username.trim().isEmpty()) { + username = "system"; + } + vetKnowledge.setUpdateBy(username); + vetKnowledge.setUpdateTime(DateUtils.getNowDate()); + + + int result = vetKnowledgeMapper.updateVetKnowledge(vetKnowledge); + + if (result > 0) { + return AjaxResult.success("文章发布成功"); + } + return AjaxResult.error("文章发布失败"); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error("文章发布失败: " + e.getMessage()); + } + } + + /** + * 上架文章:将已下架的文章重新上架 + */ + @Override + public AjaxResult onlineVetKnowledge(Long id) { + try { + VetKnowledge current = vetKnowledgeMapper.selectVetKnowledgeById(id); + if (current == null) { + return AjaxResult.error("文章不存在"); + } + + + // 只有已下架状态(2)的文章才能上架 + if (!"2".equals(current.getArticleStatus())) { + return AjaxResult.error("只有已下架的文章可以上架"); + } + + VetKnowledge vetKnowledge = new VetKnowledge(); + vetKnowledge.setId(id); + vetKnowledge.setArticleStatus("1"); // 上架后变为已发布 + + String username = SecurityUtils.getUsername(); + if (username == null || username.trim().isEmpty()) { + username = "system"; + } + vetKnowledge.setUpdateBy(username); + vetKnowledge.setUpdateTime(DateUtils.getNowDate()); + + + int result = vetKnowledgeMapper.updateVetKnowledge(vetKnowledge); + + if (result > 0) { + return AjaxResult.success("文章上架成功"); + } + return AjaxResult.error("文章上架失败"); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error("文章上架失败: " + e.getMessage()); + } + } + + /** + * 下架文章:将已发布的文章下架(增加下架原因参数) + */ + @Override + public AjaxResult offlineVetKnowledge(Long id, String auditComment) { + try { + VetKnowledge current = vetKnowledgeMapper.selectVetKnowledgeById(id); + if (current == null) { + return AjaxResult.error("文章不存在"); + } + + // 只有已发布状态(1)的文章才能下架 + if (!"1".equals(current.getArticleStatus())) { + return AjaxResult.error("只有已发布的文章可以下架"); + } + + // 验证下架原因(前端已经验证,这里再次确认) + if (auditComment == null || auditComment.trim().length() < 2) { + return AjaxResult.error("下架原因不能少于2个字"); + } + if (auditComment.trim().length() > 200) { + return AjaxResult.error("下架原因不能超过200字"); + } + + VetKnowledge vetKnowledge = new VetKnowledge(); + vetKnowledge.setId(id); + vetKnowledge.setArticleStatus("2"); // 已下架 + vetKnowledge.setAuditComment(auditComment.trim()); // 存储下架原因到审核意见字段 + + String username = SecurityUtils.getUsername(); + if (username == null || username.trim().isEmpty()) { + username = "system"; + } + vetKnowledge.setUpdateBy(username); + vetKnowledge.setUpdateTime(DateUtils.getNowDate()); + + int result = vetKnowledgeMapper.updateVetKnowledge(vetKnowledge); + + if (result > 0) { + return AjaxResult.success("文章下架成功"); + } + return AjaxResult.error("文章下架失败"); + } catch (Exception e) { + e.printStackTrace(); + return AjaxResult.error("文章下架失败: " + e.getMessage()); } - return AjaxResult.error("文章发布失败"); } -} +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java index 38b9dd6..b4f9df1 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java @@ -1,11 +1,15 @@ package com.chenhai.vet.service.impl; +import java.util.Date; import java.util.List; + +import com.chenhai.vet.domain.VetTrainingVideo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.chenhai.vet.mapper.VetProductMapper; import com.chenhai.vet.domain.VetProduct; import com.chenhai.vet.service.IVetProductService; +import org.springframework.transaction.annotation.Transactional; /** * 兽医产品信息Service业务层处理 diff --git a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java index ab531d4..6dfcc3e 100644 --- a/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java +++ b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetTrainingVideoServiceImpl.java @@ -6,6 +6,7 @@ import com.chenhai.vet.service.IVetTrainingVideoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.File; @@ -27,6 +28,7 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { private String uploadPath; @Override + @Transactional public String uploadAndSave(VetTrainingVideo video, MultipartFile videoFile, MultipartFile coverImage) { try { // 1. 创建上传目录 @@ -55,10 +57,12 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { } // 5. 计算视频时长和大小 - int duration = getVideoDuration(videoFile); // 需要实现这个方法 + int duration = getVideoDuration(videoFile); long fileSize = videoFile.getSize(); - // 6. 保存到数据库 + // 6. 设置初始状态:私有 + 待审核 + video.setStatus("0"); // 0-未上架/私有 + video.setAuditStatus("0"); // 0-待审核 video.setVideoUrl("/uploads/" + uniqueFileName); video.setCoverImage(coverImageUrl); video.setDuration(duration); @@ -69,7 +73,7 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { videoMapper.insertVideo(video); - return "上传成功!视频ID:" + video.getId(); + return "上传成功!视频已自动提交审核,请耐心等待管理员审核。"; } catch (IOException e) { throw new RuntimeException("文件保存失败", e); @@ -77,12 +81,13 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { } @Override - public List getMyVideos(Long userId, String title, String category, String status) { - return videoMapper.selectMyVideos(userId, title, category, status); + public List getMyVideos(Long userId, String title, String category, String status, String auditStatus) { + return videoMapper.selectMyVideos(userId, title, category, status, auditStatus); } @Override public List getPublicVideos(String title, String category, String vetName) { + // 只显示审核通过且公开的视频 return videoMapper.selectPublicVideos(title, category, vetName); } @@ -94,8 +99,10 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { return null; } - // 权限校验:只能查看公开视频或自己的视频 - boolean canView = "1".equals(video.getStatus()) || currentVetId.equals(video.getUserId()); + // 权限校验:只能查看自己的视频或审核通过公开的视频 + boolean canView = "1".equals(video.getAuditStatus()) && // 1-审核通过 + "1".equals(video.getStatus()) || // 1-已上架/公开 + currentVetId.equals(video.getUserId()); return canView ? video : null; } @@ -107,8 +114,10 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { return null; } - // 权限校验 - boolean canPlay = "1".equals(video.getStatus()) || currentVetId.equals(video.getUserId()); + // 权限校验:只能播放自己的视频或审核通过公开的视频 + boolean canPlay = "1".equals(video.getAuditStatus()) && // 1-审核通过 + "1".equals(video.getStatus()) || // 1-已上架/公开 + currentVetId.equals(video.getUserId()); return canPlay ? video.getVideoUrl() : null; } @@ -127,20 +136,200 @@ public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { return videoMapper.searchVideos(keyword); } + @Override + @Transactional + public int deleteVideoById(Long videoId) { + return videoMapper.deleteVideoById(videoId); + } + + @Override + @Transactional + public boolean submitForAudit(Long videoId, Long userId) { + VetTrainingVideo video = videoMapper.selectVideoById(videoId); + + if (video == null || !userId.equals(video.getUserId())) { + return false; + } + + // 只能提交无需审核或审核拒绝的视频 + if (!"3".equals(video.getAuditStatus()) && // 3-无需审核 + !"2".equals(video.getAuditStatus())) { // 2-审核拒绝 + return false; + } + + // 更新为待审核状态 + int result = videoMapper.updateAuditStatus(videoId, + "0", // 0-待审核 + "已提交审核", + null, + new Date()); + return result > 0; + } + + @Override + @Transactional + public boolean cancelAudit(Long videoId, Long userId) { + VetTrainingVideo video = videoMapper.selectVideoById(videoId); + + if (video == null || !userId.equals(video.getUserId())) { + return false; + } + + // 只能取消待审核状态的视频 + if (!"0".equals(video.getAuditStatus())) { // 0-待审核 + return false; + } + + // 更新为无需审核状态 + int result = videoMapper.updateAuditStatus(videoId, + "3", // 3-无需审核 + "用户取消审核", + null, + new Date()); + return result > 0; + } + + @Override + @Transactional + public boolean resubmitForAudit(Long videoId, Long userId) { + VetTrainingVideo video = videoMapper.selectVideoById(videoId); + + if (video == null || !userId.equals(video.getUserId())) { + return false; + } + + // 只能重新提交审核拒绝状态的视频 + if (!"2".equals(video.getAuditStatus())) { // 2-审核拒绝 + return false; + } + + // 更新为待审核状态 + int result = videoMapper.updateAuditStatus(videoId, + "0", // 0-待审核 + "重新提交审核", + null, + new Date()); + return result > 0; + } + + @Override + @Transactional + public boolean auditVideo(Long videoId, String auditStatus, String auditOpinion, Long auditUserId) { + // 验证审核状态 + if (!"1".equals(auditStatus) && // 1-审核通过 + !"2".equals(auditStatus)) { // 2-审核拒绝 + return false; + } + + VetTrainingVideo video = videoMapper.selectVideoById(videoId); + if (video == null) { + return false; + } + + // 只能审核待审核状态的视频 + if (!"0".equals(video.getAuditStatus())) { // 0-待审核 + return false; + } + + int result = videoMapper.updateAuditStatus(videoId, + auditStatus, + auditOpinion, + auditUserId, + new Date()); + + // 如果审核通过,自动设置为私有状态,等待用户上架 + if (result > 0 && "1".equals(auditStatus)) { // 1-审核通过 + videoMapper.updateStatus(videoId, "0"); // 0-未上架/私有 + } + + return result > 0; + } + + @Override + @Transactional + public boolean publishVideo(Long videoId, Long userId) { + VetTrainingVideo video = videoMapper.selectVideoById(videoId); + + if (video == null) { + return false; + } + + // 权限校验:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + return false; + } + + // 只能上架审核通过的视频 + if (!"1".equals(video.getAuditStatus())) { // 1-审核通过 + return false; + } + + return videoMapper.updateStatus(videoId, "1") > 0; // 1-已上架/公开 + } + + @Override + @Transactional + public boolean offlineVideo(Long videoId, Long userId) { + VetTrainingVideo video = videoMapper.selectVideoById(videoId); + + if (video == null) { + return false; + } + + // 权限校验:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + return false; + } + + // 只能下架已上架的视频 + if (!"1".equals(video.getStatus())) { // 1-已上架/公开 + return false; + } + + return videoMapper.updateStatus(videoId, "0") > 0; // 0-未上架/私有 + } + + @Override + public List getPendingAuditVideos(String title, String userName) { + return videoMapper.selectPendingAuditVideos(title, userName); + } + + @Override + @Transactional + public boolean updateVideoInfo(Long videoId, VetTrainingVideo video, Long userId) { + VetTrainingVideo existingVideo = videoMapper.selectVideoById(videoId); + + if (existingVideo == null || !userId.equals(existingVideo.getUserId())) { + return false; + } + + // 只能编辑无需审核、审核拒绝或私有状态的视频 + boolean canEdit = "3".equals(existingVideo.getAuditStatus()) || // 3-无需审核 + "2".equals(existingVideo.getAuditStatus()) || // 2-审核拒绝 + "0".equals(existingVideo.getStatus()); // 0-未上架/私有 + + if (!canEdit) { + return false; + } + + // 更新视频信息 + existingVideo.setTitle(video.getTitle()); + existingVideo.setDescription(video.getDescription()); + existingVideo.setCategory(video.getCategory()); + existingVideo.setUpdateTime(new Date()); + + return videoMapper.updateVideoInfo(existingVideo) > 0; + } + private String getFileExtension(String fileName) { + if (fileName == null || fileName.lastIndexOf(".") == -1) { + return "mp4"; + } return fileName.substring(fileName.lastIndexOf(".") + 1); } private int getVideoDuration(MultipartFile videoFile) { // 这里需要实现获取视频时长的方法 - // 可以使用 FFmpeg 或 Java 的库来获取 - // 暂时返回一个默认值 return 60; // 默认60秒 } - - @Override - public int deleteVideoById(Long videoId) { - // 逻辑删除,设置 del_flag = '1' - return videoMapper.deleteVideoById(videoId); - } } \ No newline at end of file diff --git a/chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml index bbfaef6..a58cd31 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml @@ -1,16 +1,18 @@ + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + - + + + @@ -19,20 +21,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, title, content, category, sensitive_words, status, create_by, create_time, update_by, update_time, remark from vet_knowledge + select id, title, content, category, sensitive_words, article_status, audit_status, audit_comment, create_by, create_time, update_by, update_time, remark from vet_knowledge - + diff --git a/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml index 6bc522a..2807fa0 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml @@ -1,7 +1,5 @@ - - + + @@ -17,21 +15,27 @@ + + + + INSERT INTO vet_training_video ( - user_id, title, description, video_url, cover_image, - category, tags, duration, file_size, view_count, - status, create_time, update_time + user_id, title, description, video_url, cover_image, + category, tags, duration, file_size, view_count, + status, audit_status, audit_opinion, + create_time, update_time ) VALUES ( - #{userId}, #{title}, #{description}, #{videoUrl}, #{coverImage}, - #{category}, #{tags}, #{duration}, #{fileSize}, #{viewCount}, - #{status}, #{createTime}, #{updateTime} - ) + #{userId}, #{title}, #{description}, #{videoUrl}, #{coverImage}, + #{category}, #{tags}, #{duration}, #{fileSize}, #{viewCount}, + #{status}, #{auditStatus}, #{auditOpinion}, + #{createTime}, #{updateTime} + ) @@ -56,6 +63,7 @@ FROM vet_training_video v LEFT JOIN sys_user u ON v.user_id = u.user_id WHERE v.status = '1' + AND v.audit_status = '1' AND v.title LIKE CONCAT('%', #{title}, '%') @@ -71,7 +79,7 @@ @@ -84,21 +92,23 @@ @@ -106,4 +116,44 @@ DELETE FROM vet_training_video WHERE id = #{id} + + + UPDATE vet_training_video + SET audit_status = #{auditStatus}, + audit_opinion = #{auditOpinion}, + audit_user_id = #{auditUserId}, + audit_time = #{auditTime}, + update_time = NOW() + WHERE id = #{id} + + + + UPDATE vet_training_video + SET status = #{status}, + update_time = NOW() + WHERE id = #{id} + + + + + + UPDATE vet_training_video + SET title = #{title}, + description = #{description}, + category = #{category}, + update_time = NOW() + WHERE id = #{id} + \ No newline at end of file diff --git a/chenhai-ui/src/api/vet/knowledge.js b/chenhai-ui/src/api/vet/knowledge.js index f85a202..01198c5 100644 --- a/chenhai-ui/src/api/vet/knowledge.js +++ b/chenhai-ui/src/api/vet/knowledge.js @@ -42,12 +42,22 @@ export function delKnowledge(id) { method: 'delete' }) } -// 上传文章(待审核) -export function uploadKnowledge(data) { + +// 提交审核 +export function submitForAudit(id) { return request({ - url: '/vet/knowledge/upload', - method: 'post', - data: data + url: '/vet/knowledge/submit/' + id, + method: 'put' + }) +} +export function auditVetKnowledge(id, auditStatus, auditComment) { + return request({ + url: '/vet/knowledge/audit/' + id, + method: 'put', + params: { // 使用params传递查询参数 + auditStatus: auditStatus, // 参数名改为auditStatus + auditComment: auditComment + } }) } @@ -58,3 +68,22 @@ export function publishKnowledge(id) { method: 'put' }) } + +// 上架文章 +export function onlineVetKnowledge(id) { + return request({ + url: '/vet/knowledge/online/' + id, + method: 'put' + }) +} + +// 下架文章 +export function offlineVetKnowledge(id, auditComment) { + return request({ + url: '/vet/knowledge/offline/' + id, + method: 'put', + params: { + auditComment: auditComment // 使用 auditComment 作为参数名,后端会存储到 audit_comment 字段 + } + }) +} diff --git a/chenhai-ui/src/api/vet/training.js b/chenhai-ui/src/api/vet/training.js index 320adec..3b25112 100644 --- a/chenhai-ui/src/api/vet/training.js +++ b/chenhai-ui/src/api/vet/training.js @@ -1,21 +1,18 @@ -// src/api/vet/training.js +// trainingApi.js - 完整修正版 import request from '@/utils/request' -// 兽医培训视频相关接口 export default { // 上传视频 uploadVideo(data) { - // 注意:这里直接返回请求,不要重新创建 FormData return request({ url: '/vet/training/upload', method: 'post', - data: data, // data 已经是 FormData 对象 + data: data, headers: { 'Content-Type': 'multipart/form-data' }, timeout: 300000 }) - }, // 获取公开视频列表 @@ -23,22 +20,16 @@ export default { return request({ url: '/vet/training/public-videos', method: 'get', - params + params: params }) }, // 获取我的视频 - getMyVideos(params = {}) { + getMyVideos(params) { return request({ url: '/vet/training/my-videos', method: 'get', - params: { - pageNum: params.pageNum || 1, - pageSize: params.pageSize || 10, - title: params.title || '', - category: params.category || '', - status: params.status || '' - } + params: params }) }, @@ -50,37 +41,85 @@ export default { }) }, - // 获取播放地址(可选) - getPlayUrl(id) { + // 提交审核(用户提交给管理员) + submitForAudit(videoId) { return request({ - url: `/vet/training/video/play/${id}`, - method: 'get' + url: `/vet/training/submit-audit/${videoId}`, + method: 'post' }) }, - // 删除视频 - deleteVideo(id) { + // 取消审核 + cancelAudit(videoId) { return request({ - url: `/vet/training/${id}`, - method: 'delete' + url: `/vet/training/cancel-audit/${videoId}`, + method: 'post' }) }, - // 搜索视频 - searchVideos(keyword) { + // 重新提交审核 + resubmitAudit(videoId) { return request({ - url: '/vet/training/search', - method: 'get', - params: { keyword } + url: `/vet/training/resubmit-audit/${videoId}`, + method: 'post' + }) + }, + // 审核视频(管理员审核) + auditVideo(videoId, auditStatus, auditOpinion = '') { + // 改用JSON方式传递参数 + const data = { + auditStatus: auditStatus, + auditOpinion: auditOpinion || '' + } + + return request({ + url: `/vet/training/audit/${videoId}`, + method: 'post', + data: data, + headers: { + 'Content-Type': 'application/json' + } + }) + }, + // 上架视频 + publishVideo(videoId) { + return request({ + url: `/vet/training/publish/${videoId}`, + method: 'post' + }) + }, + + // 下架视频 + offlineVideo(videoId) { + return request({ + url: `/vet/training/offline/${videoId}`, + method: 'post' }) }, - // 获取热门视频 - getHotVideos(limit = 10) { + // 获取待审核视频列表 + getPendingAuditVideos(params) { return request({ - url: '/vet/training/hot-videos', + url: '/vet/training/pending-audit', method: 'get', - params: { limit } + params: params + }) + }, + + // 更新视频信息 + updateVideoInfo(videoId, data) { + return request({ + url: `/vet/training/update/${videoId}`, + method: 'put', + data: data + }) + }, + + // 删除视频 + deleteVideo(videoId) { + return request({ + url: `/vet/training/${videoId}`, + method: 'delete' }) } } diff --git a/chenhai-ui/src/views/vet/knowledge/index.vue b/chenhai-ui/src/views/vet/knowledge/index.vue index a924fa5..04e0ff8 100644 --- a/chenhai-ui/src/views/vet/knowledge/index.vue +++ b/chenhai-ui/src/views/vet/knowledge/index.vue @@ -10,27 +10,45 @@ /> - - - - + - + + + + + + - - + @@ -44,33 +62,44 @@ 上传文章 + @click="handleAdd" + v-hasPermi="['vet:knowledge:add']" + >新增文章 发布文章 + @click="handleSubmitAudit" + v-hasPermi="['vet:knowledge:submit']" + >提交审核 修改 + @click="handleAuditDialog" + v-hasPermi="['vet:knowledge:audit']" + >审核 + + + 发布文章 - - - - - + + + + + + + + + + + + + + + + + + - + @@ -146,21 +244,23 @@ @pagination="getList" /> - - + + - + - - - - + @@ -172,12 +272,81 @@ 取 消 + + + + + + + 审核通过 + 审核驳回 + + + + + + + + + + + + + {{ viewData.title }} + + + {{ viewData.category }} + + + + + {{ getArticleStatusLabel(viewData.articleStatus) }} + + + + + {{ getAuditStatusLabel(viewData.auditStatus) }} + + + + {{ viewData.auditComment || '无' }} + + {{ viewData.createBy }} + {{ viewData.createTime }} + + 文章内容 +
+ +
+ + diff --git a/chenhai-ui/src/views/vet/product/index.vue b/chenhai-ui/src/views/vet/product/index.vue index 2d6b071..d26e3af 100644 --- a/chenhai-ui/src/views/vet/product/index.vue +++ b/chenhai-ui/src/views/vet/product/index.vue @@ -1,6 +1,13 @@