From 1fc0b43915409de5d48002382b1cecd375d225e8 Mon Sep 17 00:00:00 2001 From: maotiantian Date: Thu, 29 Jan 2026 18:30:23 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=86=E9=A2=91=E5=9F=B9=E8=AE=AD=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SysAnswersController.java | 176 ++ .../system/SysQuestionsController.java | 129 ++ .../vet/VetTrainingVideoController.java | 417 +++-- .../com/chenhai/system/domain/SysAnswers.java | 160 ++ .../domain/SysPolicyInterpretation.java | 13 + .../chenhai/system/domain/SysQuestions.java | 186 ++ .../system/mapper/SysAnswersMapper.java | 78 + .../system/mapper/SysQuestionsMapper.java | 94 + .../system/service/ISysAnswersService.java | 93 + .../system/service/ISysQuestionsService.java | 106 ++ .../service/impl/SysAnswersServiceImpl.java | 243 +++ .../service/impl/SysQuestionsServiceImpl.java | 248 +++ .../com/chenhai/vet/domain/VetKnowledge.java | 12 + .../chenhai/vet/domain/VetTrainingVideo.java | 227 ++- .../vet/mapper/VetTrainingVideoMapper.java | 98 +- .../vet/service/IVetTrainingVideoService.java | 132 +- .../service/impl/VetProductServiceImpl.java | 3 - .../impl/VetTrainingVideoServiceImpl.java | 620 ++++--- .../mapper/system/SysAnswersMapper.xml | 112 ++ .../system/SysPolicyInterpretationMapper.xml | 19 + .../mapper/system/SysQuestionsMapper.xml | 143 ++ .../mapper/vet/VetKnowledgeMapper.xml | 9 + .../mapper/vet/VetTrainingVideoMapper.xml | 370 ++-- chenhai-ui/src/api/system/answers.js | 44 + chenhai-ui/src/api/system/questions.js | 44 + chenhai-ui/src/api/vet/training.js | 269 +-- chenhai-ui/src/views/system/answers/index.vue | 252 +++ .../src/views/system/questions/index.vue | 584 +++++++ .../src/views/vet/training/TrainingHome.vue | 1547 ----------------- chenhai-ui/src/views/vet/training/index.vue | 1120 ++++++++++++ 30 files changed, 5216 insertions(+), 2332 deletions(-) create mode 100644 chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysAnswersController.java create mode 100644 chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysQuestionsController.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/domain/SysAnswers.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/domain/SysQuestions.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/mapper/SysAnswersMapper.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/mapper/SysQuestionsMapper.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/service/ISysAnswersService.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/service/ISysQuestionsService.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/service/impl/SysAnswersServiceImpl.java create mode 100644 chenhai-system/src/main/java/com/chenhai/system/service/impl/SysQuestionsServiceImpl.java create mode 100644 chenhai-system/src/main/resources/mapper/system/SysAnswersMapper.xml create mode 100644 chenhai-system/src/main/resources/mapper/system/SysQuestionsMapper.xml create mode 100644 chenhai-ui/src/api/system/answers.js create mode 100644 chenhai-ui/src/api/system/questions.js create mode 100644 chenhai-ui/src/views/system/answers/index.vue create mode 100644 chenhai-ui/src/views/system/questions/index.vue delete mode 100644 chenhai-ui/src/views/vet/training/TrainingHome.vue create mode 100644 chenhai-ui/src/views/vet/training/index.vue diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysAnswersController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysAnswersController.java new file mode 100644 index 0000000..bd41d8f --- /dev/null +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysAnswersController.java @@ -0,0 +1,176 @@ +package com.chenhai.web.controller.system; + +import java.util.List; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +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.RestController; +import com.chenhai.common.annotation.Log; +import com.chenhai.common.core.controller.BaseController; +import com.chenhai.common.core.domain.AjaxResult; +import com.chenhai.common.enums.BusinessType; +import com.chenhai.system.domain.SysAnswers; +import com.chenhai.system.service.ISysAnswersService; +import com.chenhai.system.service.ISysQuestionsService; +import com.chenhai.common.utils.poi.ExcelUtil; +import com.chenhai.common.core.page.TableDataInfo; + +/** + * 答复Controller + * + * @author ruoyi + * @date 2026-01-29 + */ +@RestController +@RequestMapping("/system/answers") +public class SysAnswersController extends BaseController +{ + @Autowired + private ISysAnswersService sysAnswersService; + + @Autowired + private ISysQuestionsService sysQuestionsService; + + /** + * 查询答复列表 + */ + @PreAuthorize("@ss.hasPermi('system:answers:list')") + @GetMapping("/list") + public TableDataInfo list(SysAnswers sysAnswers) + { + startPage(); + List list = sysAnswersService.selectSysAnswersList(sysAnswers); + return getDataTable(list); + } + + /** + * 根据问题ID查询答复列表 + */ + @PreAuthorize("@ss.hasPermi('system:answers:list')") + @GetMapping("/question/{questionId}") + public TableDataInfo listByQuestionId(@PathVariable("questionId") Long questionId) + { + startPage(); + List list = sysAnswersService.selectAnswersByQuestionId(questionId); + return getDataTable(list); + } + + /** + * 导出答复列表 + */ + @PreAuthorize("@ss.hasPermi('system:answers:export')") + @Log(title = "答复", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysAnswers sysAnswers) + { + List list = sysAnswersService.selectSysAnswersList(sysAnswers); + ExcelUtil util = new ExcelUtil(SysAnswers.class); + util.exportExcel(response, list, "答复数据"); + } + + /** + * 获取答复详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:answers:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysAnswersService.selectSysAnswersById(id)); + } + + /** + * 新增答复(使用当前登录用户信息) + */ + @PreAuthorize("@ss.hasPermi('system:answers:add')") + @Log(title = "答复", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysAnswers sysAnswers) + { + // 验证问题是否存在 + if (sysAnswers.getQuestionId() == null) { + return error("问题ID不能为空"); + } + + // 检查问题是否存在 + try { + sysQuestionsService.selectSysQuestionsById(sysAnswers.getQuestionId()); + } catch (Exception e) { + return error("问题不存在或已被删除"); + } + + return toAjax(sysAnswersService.insertSysAnswersWithCurrentUser(sysAnswers)); + } + + /** + * 修改答复 + */ + @PreAuthorize("@ss.hasPermi('system:answers:edit')") + @Log(title = "答复", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysAnswers sysAnswers) + { + return toAjax(sysAnswersService.updateSysAnswers(sysAnswers)); + } + + /** + * 删除答复 + */ + @PreAuthorize("@ss.hasPermi('system:answers:remove')") + @Log(title = "答复", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(sysAnswersService.deleteSysAnswersByIds(ids)); + } + + /** + * 获取当前用户的答复列表 + */ + @PreAuthorize("@ss.hasPermi('system:answers:list')") + @GetMapping("/myList") + public TableDataInfo myList(SysAnswers sysAnswers) + { + // 获取当前登录用户ID + Long userId = getUserId(); + // 设置查询条件,只查询当前用户的回答 + sysAnswers.setUserId(String.valueOf(userId)); + + startPage(); + List list = sysAnswersService.selectSysAnswersList(sysAnswers); + return getDataTable(list); + } + + /** + * 获取问题的答案数量 + */ + @PreAuthorize("@ss.hasPermi('system:answers:query')") + @GetMapping("/count/{questionId}") + public AjaxResult countByQuestionId(@PathVariable("questionId") Long questionId) + { + Long count = sysAnswersService.countAnswersByQuestionId(questionId); + return success(count); + } + + /** + * 同步更新问题的答案数量(管理员使用) + */ + @PreAuthorize("@ss.hasPermi('system:answers:edit')") + @Log(title = "同步答案数量", businessType = BusinessType.UPDATE) + @PostMapping("/syncCount/{questionId}") + public AjaxResult syncAnswerCount(@PathVariable("questionId") Long questionId) + { + try { + sysQuestionsService.updateAnswerCountFromDb(questionId); + return success("同步成功"); + } catch (Exception e) { + return error("同步失败: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysQuestionsController.java b/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysQuestionsController.java new file mode 100644 index 0000000..5614b84 --- /dev/null +++ b/chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysQuestionsController.java @@ -0,0 +1,129 @@ +package com.chenhai.web.controller.system; + +import java.util.List; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +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.RestController; +import com.chenhai.common.annotation.Log; +import com.chenhai.common.core.controller.BaseController; +import com.chenhai.common.core.domain.AjaxResult; +import com.chenhai.common.core.domain.model.LoginUser; +import com.chenhai.common.enums.BusinessType; +import com.chenhai.system.domain.SysQuestions; +import com.chenhai.system.service.ISysQuestionsService; +import com.chenhai.common.utils.poi.ExcelUtil; +import com.chenhai.common.core.page.TableDataInfo; +import com.chenhai.common.utils.SecurityUtils; + +/** + * 问答Controller + * + * @author ruoyi + * @date 2026-01-29 + */ +@RestController +@RequestMapping("/system/questions") +public class SysQuestionsController extends BaseController +{ + @Autowired + private ISysQuestionsService sysQuestionsService; + + /** + * 获取当前登录用户ID + */ + private Long getCurrentUserId() { + LoginUser loginUser = SecurityUtils.getLoginUser(); + return loginUser.getUserId(); + } + + /** + * 查询问答列表 + */ + @PreAuthorize("@ss.hasPermi('system:questions:list')") + @GetMapping("/list") + public TableDataInfo list(SysQuestions sysQuestions) + { + startPage(); + List list = sysQuestionsService.selectSysQuestionsList(sysQuestions); + return getDataTable(list); + } + + /** + * 导出问答列表 + */ + @PreAuthorize("@ss.hasPermi('system:questions:export')") + @Log(title = "问答", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, SysQuestions sysQuestions) + { + List list = sysQuestionsService.selectSysQuestionsList(sysQuestions); + ExcelUtil util = new ExcelUtil(SysQuestions.class); + util.exportExcel(response, list, "问答数据"); + } + + /** + * 获取问答详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:questions:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(sysQuestionsService.selectSysQuestionsById(id)); + } + + /** + * 新增问答 + */ + @PreAuthorize("@ss.hasPermi('system:questions:add')") + @Log(title = "问答", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody SysQuestions sysQuestions) + { + Long userId = getCurrentUserId(); + return toAjax(sysQuestionsService.insertSysQuestions(sysQuestions, userId)); + } + + /** + * 修改问答 + */ + @PreAuthorize("@ss.hasPermi('system:questions:edit')") + @Log(title = "问答", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody SysQuestions sysQuestions) + { + Long userId = getCurrentUserId(); + return toAjax(sysQuestionsService.updateSysQuestions(sysQuestions, userId)); + } + + /** + * 删除问答 + */ + @PreAuthorize("@ss.hasPermi('system:questions:remove')") + @Log(title = "问答", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + Long userId = getCurrentUserId(); + return toAjax(sysQuestionsService.deleteSysQuestionsByIds(ids, userId)); + } + + /** + * 检查问题权限 + */ + @PreAuthorize("@ss.hasPermi('system:questions:query')") + @GetMapping("/checkPermission/{id}") + public AjaxResult checkPermission(@PathVariable("id") Long id) + { + Long userId = getCurrentUserId(); + boolean hasPermission = sysQuestionsService.isQuestionBelongsToUser(id, userId); + return success(hasPermission); + } +} \ No newline at end of file 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 ab1b646..27f2f53 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 @@ -1,145 +1,268 @@ package com.chenhai.web.controller.vet; +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.common.utils.StringUtils; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import com.chenhai.common.annotation.Log; import com.chenhai.common.core.controller.BaseController; import com.chenhai.common.core.domain.AjaxResult; -import com.chenhai.common.core.page.TableDataInfo; -import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.common.enums.BusinessType; import com.chenhai.vet.domain.VetTrainingVideo; import com.chenhai.vet.service.IVetTrainingVideoService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import com.chenhai.common.utils.poi.ExcelUtil; +import com.chenhai.common.core.page.TableDataInfo; import org.springframework.web.multipart.MultipartFile; -import java.util.List; -import java.util.Map; - +/** + * 兽医培训视频Controller + * + * @author ruoyi + * @date 2026-01-28 + */ @RestController @RequestMapping("/vet/training") -public class VetTrainingVideoController extends BaseController { - +public class VetTrainingVideoController extends BaseController +{ @Autowired - private IVetTrainingVideoService trainingVideoService; + private IVetTrainingVideoService vetTrainingVideoService; + + // 从配置文件读取上传路径,默认值为 D:/ymtx/uploadPath + @Value("${chenhai.profile:D:/ymtx/uploadPath}") + private String uploadPath; /** * 获取当前用户ID */ private Long getCurrentUserId() { + // 使用 RuoYi 的 SecurityUtils return SecurityUtils.getUserId(); } /** - * 上传培训视频 + * 查询兽医培训视频列表 */ - @PostMapping("/upload") - public AjaxResult uploadVideo( - @RequestParam("title") String title, - @RequestParam("videoFile") MultipartFile videoFile, - @RequestParam(value = "description", required = false) String description, - @RequestParam(value = "category", required = false) String category, - @RequestParam(value = "coverImage", required = false) MultipartFile coverImage) { - - Long userId = getCurrentUserId(); - - try { - VetTrainingVideo video = new VetTrainingVideo(); - video.setUserId(userId); - video.setTitle(title); - video.setDescription(description); - video.setCategory(category); - - String result = trainingVideoService.uploadAndSave(video, videoFile, coverImage); - return success(result); - } catch (Exception e) { - e.printStackTrace(); - return error("上传失败:" + e.getMessage()); - } + @PreAuthorize("@ss.hasPermi('vet:training:list') or @ss.hasRole('muhu')") + @GetMapping("/list") + public TableDataInfo list(VetTrainingVideo vetTrainingVideo) + { + startPage(); + List list = vetTrainingVideoService.selectVetTrainingVideoList(vetTrainingVideo); + return getDataTable(list); } /** - * 查看我上传的视频 + * 导出兽医培训视频列表 */ - @GetMapping("/my-videos") - public TableDataInfo getMyVideos( - @RequestParam(required = false) String title, - @RequestParam(required = false) String category, - @RequestParam(required = false) String status, - @RequestParam(required = false) String auditStatus) { + @PreAuthorize("@ss.hasPermi('vet:training:export') or @ss.hasRole('muhu')") + @Log(title = "兽医培训视频", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, VetTrainingVideo vetTrainingVideo) + { + List list = vetTrainingVideoService.selectVetTrainingVideoList(vetTrainingVideo); + ExcelUtil util = new ExcelUtil(VetTrainingVideo.class); + util.exportExcel(response, list, "兽医培训视频数据"); + } - startPage(); - Long userId = getCurrentUserId(); - List list = trainingVideoService.getMyVideos(userId, title, category, status, auditStatus); - return getDataTable(list); + /** + * 获取兽医培训视频详细信息 + */ + @PreAuthorize("@ss.hasPermi('vet:training:query') or @ss.hasRole('muhu')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(vetTrainingVideoService.selectVetTrainingVideoById(id)); } /** - * 查看所有公开的视频 + * 新增兽医培训视频 */ - @GetMapping("/public-videos") - public TableDataInfo getPublicVideos( - @RequestParam(required = false) String title, - @RequestParam(required = false) String category, - @RequestParam(required = false) String userName) { + @PreAuthorize("@ss.hasPermi('vet:training:add') or @ss.hasRole('muhu')") + @Log(title = "兽医培训视频", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody VetTrainingVideo vetTrainingVideo) + { + return toAjax(vetTrainingVideoService.insertVetTrainingVideo(vetTrainingVideo)); + } - startPage(); - List list = trainingVideoService.getPublicVideos(title, category, userName); - return getDataTable(list); + /** + * 修改兽医培训视频 + */ + @PreAuthorize("@ss.hasPermi('vet:training:edit') or @ss.hasRole('muhu')") + @Log(title = "兽医培训视频", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody VetTrainingVideo vetTrainingVideo) + { + return toAjax(vetTrainingVideoService.updateVetTrainingVideo(vetTrainingVideo)); } /** - * 查看视频详情 + * 删除兽医培训视频 */ - @GetMapping("/video/{videoId}") - public AjaxResult getVideoDetail(@PathVariable Long videoId) { - Long userId = getCurrentUserId(); - VetTrainingVideo video = trainingVideoService.getVideoDetail(videoId, userId); + @PreAuthorize("@ss.hasPermi('vet:training:remove') or @ss.hasRole('muhu')") + @Log(title = "兽医培训视频", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(vetTrainingVideoService.deleteVetTrainingVideoByIds(ids)); + } - if (video == null) { - return error("视频不存在或无权限查看"); + /** + * 上传培训视频 + */ + @PreAuthorize("@ss.hasPermi('vet:training:add') or @ss.hasRole('muhu')") + @Log(title = "兽医培训视频", businessType = BusinessType.OTHER) + @PostMapping("/uploadVideo") + public AjaxResult uploadVideo(@RequestParam("file") MultipartFile file) + { + try { + // 基本验证 + if (file == null || file.isEmpty()) { + return AjaxResult.error("上传文件不能为空"); + } + + String fileName = file.getOriginalFilename(); + if (StringUtils.isEmpty(fileName)) { + return AjaxResult.error("文件名不能为空"); + } + + // 验证文件类型 + String extension = getFileExtension(fileName).toLowerCase(); + String[] allowedExtensions = {"mp4", "avi", "mov", "wmv", "flv", "mkv"}; + boolean isValidExtension = false; + for (String ext : allowedExtensions) { + if (ext.equals(extension)) { + isValidExtension = true; + break; + } + } + + if (!isValidExtension) { + return AjaxResult.error("不支持的文件格式,请上传MP4、AVI、MOV、WMV、FLV、MKV格式的视频文件"); + } + + // 验证文件大小(限制200MB) + long maxSize = 200 * 1024 * 1024; // 200MB + if (file.getSize() > maxSize) { + return AjaxResult.error("文件大小不能超过200MB"); + } + + // 创建视频上传目录 + String videoDir = uploadPath + "/video/"; + File dir = new File(videoDir); + if (!dir.exists()) { + boolean created = dir.mkdirs(); + if (!created) { + return AjaxResult.error("创建上传目录失败: " + videoDir); + } + } + + // 生成唯一文件名(避免重复) + String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8); + String newFileName = System.currentTimeMillis() + "_" + uuid + "." + extension; + String filePath = videoDir + newFileName; + + // 保存文件 + File dest = new File(filePath); + file.transferTo(dest); + + // 构建返回的访问路径(相对路径) + // 这里返回 /profile/video/xxx.mp4,前端可以通过 baseUrl + /profile/video/xxx.mp4 访问 + String accessPath = "/profile/video/" + newFileName; + + // 如果是Windows路径,需要将路径中的\替换为/ + accessPath = accessPath.replace("\\", "/"); + + return AjaxResult.success("上传成功", accessPath); + + } catch (IOException e) { + logger.error("保存视频文件失败", e); + return AjaxResult.error("保存文件失败:" + e.getMessage()); + } catch (Exception e) { + logger.error("上传视频失败", e); + return AjaxResult.error("上传失败:" + e.getMessage()); } - - // 如果是审核通过且公开的视频,增加观看次数 - if ("2".equals(video.getAuditStatus()) && // 2-审核通过 - "1".equals(video.getStatus())) { // 1-已上架/公开 - trainingVideoService.incrementViewCount(videoId); - video.setViewCount(video.getViewCount() + 1); + } + /** + * 获取文件扩展名 + */ + private String getFileExtension(String fileName) { + if (StringUtils.isNotEmpty(fileName) && fileName.contains(".")) { + return fileName.substring(fileName.lastIndexOf(".") + 1); } - - return success(video); + return ""; } /** - * 提交审核(手动提交) + * 批量提交审核 */ - @PostMapping("/submit-audit/{videoId}") - public AjaxResult submitForAudit(@PathVariable Long videoId) { + @PreAuthorize("@ss.hasRole('muhu')") + @PostMapping("/batch-submit-audit") + public AjaxResult batchSubmitForAudit(@RequestBody List videoIds) { Long userId = getCurrentUserId(); - boolean success = trainingVideoService.submitForAudit(videoId, userId); - return success ? success("提交审核成功") : error("提交审核失败"); + int successCount = vetTrainingVideoService.batchSubmitForAudit(videoIds, userId); // 改为 vetTrainingVideoService + return success(successCount + "个视频已提交审核"); } /** - * 取消审核 + * 批量审核(管理员接口) */ - @PostMapping("/cancel-audit/{videoId}") - public AjaxResult cancelAudit(@PathVariable Long videoId) { + @PreAuthorize("@ss.hasRole('muhu')") + @PostMapping("/batch-audit") + public AjaxResult batchAuditVideo(@RequestBody Map batchAuditData) { + @SuppressWarnings("unchecked") + List videoIds = (List) batchAuditData.get("videoIds"); + String auditStatus = (String) batchAuditData.get("auditStatus"); + String auditOpinion = (String) batchAuditData.get("auditOpinion"); + + if (videoIds == null || videoIds.isEmpty()) { + return error("请选择要审核的视频"); + } + + if (auditStatus == null || auditStatus.trim().isEmpty()) { + return error("审核状态不能为空"); + } + + Long auditUserId = getCurrentUserId(); + int successCount = vetTrainingVideoService.batchAuditVideo(videoIds, auditStatus, auditOpinion, auditUserId); // 改为 vetTrainingVideoService + return success("成功审核" + successCount + "个视频"); + } + + /** + * 批量上架 + */ + @PreAuthorize("@ss.hasRole('muhu')") + @PostMapping("/batch-publish") + public AjaxResult batchPublishVideo(@RequestBody List videoIds) { Long userId = getCurrentUserId(); - boolean success = trainingVideoService.cancelAudit(videoId, userId); - return success ? success("取消审核成功") : error("取消审核失败"); + int successCount = vetTrainingVideoService.batchPublishVideo(videoIds, userId); // 改为 vetTrainingVideoService + return success(successCount + "个视频已上架"); } /** - * 重新提交审核 + * 批量下架 */ - @PostMapping("/resubmit-audit/{videoId}") - public AjaxResult resubmitForAudit(@PathVariable Long videoId) { + @PreAuthorize("@ss.hasRole('muhu')") + @PostMapping("/batch-offline") + public AjaxResult batchOfflineVideo(@RequestBody List videoIds) { Long userId = getCurrentUserId(); - boolean success = trainingVideoService.resubmitForAudit(videoId, userId); - return success ? success("重新提交审核成功") : error("重新提交审核失败"); + int successCount = vetTrainingVideoService.batchOfflineVideo(videoIds, userId); // 改为 vetTrainingVideoService + return success(successCount + "个视频已下架"); } /** - * 审核视频(管理员接口)- 使用JSON接收 + * 审核单个视频(管理员接口) */ + @PreAuthorize("@ss.hasRole('muhu')") @PostMapping("/audit/{videoId}") public AjaxResult auditVideo(@PathVariable Long videoId, @RequestBody Map auditData) { @@ -152,70 +275,130 @@ public class VetTrainingVideoController extends BaseController { } Long auditUserId = getCurrentUserId(); - boolean success = trainingVideoService.auditVideo(videoId, auditStatus, auditOpinion, auditUserId); - return success ? success("审核操作成功") : error("审核操作失败"); + + // 调用单个审核的 Service 方法 + try { + boolean success = vetTrainingVideoService.auditVideo(videoId, auditStatus, auditOpinion, auditUserId); + return success ? success("审核操作成功") : error("审核操作失败"); + } catch (Exception e) { + return error("审核失败: " + e.getMessage()); + } } /** - * 上架视频(审核通过后才能上架) + * 上架单个视频(审核通过后才能上架) */ + @PreAuthorize("@ss.hasRole('muhu')") @PostMapping("/publish/{videoId}") public AjaxResult publishVideo(@PathVariable Long videoId) { Long userId = getCurrentUserId(); - boolean success = trainingVideoService.publishVideo(videoId, userId); - return success ? success("视频已上架") : error("上架失败,请确保视频已通过审核"); + try { + boolean success = vetTrainingVideoService.publishVideo(videoId, userId); + return success ? success("视频已上架") : error("上架失败,请确保视频已通过审核"); + } catch (Exception e) { + return error("上架失败: " + e.getMessage()); + } } /** - * 下架视频 + * 下架单个视频 */ + @PreAuthorize("@ss.hasRole('muhu')") @PostMapping("/offline/{videoId}") public AjaxResult offlineVideo(@PathVariable Long videoId) { Long userId = getCurrentUserId(); - boolean success = trainingVideoService.offlineVideo(videoId, userId); - return success ? success("视频已下架") : error("下架失败"); + try { + boolean success = vetTrainingVideoService.offlineVideo(videoId, userId); + return success ? success("视频已下架") : error("下架失败"); + } catch (Exception e) { + return error("下架失败: " + e.getMessage()); + } } /** - * 获取待审核视频列表(管理员接口) + * 提交审核(单个视频) */ - @GetMapping("/pending-audit") - public TableDataInfo getPendingAuditVideos( - @RequestParam(required = false) String title, - @RequestParam(required = false) String userName) { - - startPage(); - List list = trainingVideoService.getPendingAuditVideos(title, userName); - return getDataTable(list); + @PreAuthorize("@ss.hasRole('muhu')") + @PostMapping("/submit-audit/{videoId}") + public AjaxResult submitForAudit(@PathVariable Long videoId) { + Long userId = getCurrentUserId(); + try { + boolean success = vetTrainingVideoService.submitForAudit(videoId, userId); + return success ? success("提交审核成功") : error("提交审核失败"); + } catch (Exception e) { + return error("提交审核失败: " + e.getMessage()); + } } /** - * 编辑视频信息 + * 取消审核(单个视频) */ - @PutMapping("/update/{videoId}") - public AjaxResult updateVideoInfo(@PathVariable Long videoId, - @RequestBody VetTrainingVideo video) { + @PreAuthorize("@ss.hasRole('muhu')") + @PostMapping("/cancel-audit/{videoId}") + public AjaxResult cancelAudit(@PathVariable Long videoId) { Long userId = getCurrentUserId(); - boolean success = trainingVideoService.updateVideoInfo(videoId, video, userId); - return success ? success("更新成功") : error("更新失败"); + + // 查询视频信息 + VetTrainingVideo video = vetTrainingVideoService.selectVetTrainingVideoById(videoId); + if (video == null) { + return error("视频不存在"); + } + + // 检查权限:管理员或视频所有者 + boolean isAdmin = SecurityUtils.getLoginUser().getUser().isAdmin(); + if (!isAdmin && !userId.equals(video.getUserId())) { + return error("无权操作此视频"); + } + + try { + boolean success = vetTrainingVideoService.cancelAudit(videoId, userId); + return success ? success("取消审核成功") : error("取消审核失败"); + } catch (Exception e) { + return error("取消审核失败: " + e.getMessage()); + } } /** - * 删除我的视频 + * 查询公开视频列表(无需登录) + * 已上架(status=1)且已审核通过(audit_status=1) */ - @DeleteMapping("/{videoId}") - public AjaxResult deleteVideo(@PathVariable Long videoId) { - Long userId = getCurrentUserId(); - VetTrainingVideo video = trainingVideoService.getVideoDetail(videoId, userId); + @PreAuthorize("@ss.hasRole('muhu')") + @GetMapping("/public/list") + public TableDataInfo publicList(VetTrainingVideo vetTrainingVideo) + { + startPage(); + // 使用分页查询公开视频 + List list = vetTrainingVideoService.selectPublicVideoPageList(vetTrainingVideo); + return getDataTable(list); + } + + /** + * 获取公开视频详情(无需登录) + * 只能查看已上架且审核通过的视频 + */ + @PreAuthorize("@ss.hasRole('muhu')") + @GetMapping("/public/{id}") + public AjaxResult getPublicInfo(@PathVariable("id") Long id) + { + VetTrainingVideo video = vetTrainingVideoService.selectVetTrainingVideoById(id); if (video == null) { return error("视频不存在"); } - if (!userId.equals(video.getUserId())) { - return error("无权删除此视频"); + // 检查视频状态:必须已上架且审核通过 + if (!"1".equals(video.getStatus()) || !"1".equals(video.getAuditStatus())) { + return error("视频不可访问"); + } + + // 增加观看次数 + if (video.getViewCount() == null) { + video.setViewCount(0L); } + video.setViewCount(video.getViewCount() + 1); + vetTrainingVideoService.updateVetTrainingVideo(video); - return toAjax(trainingVideoService.deleteVideoById(videoId)); + return success(video); } -} \ No newline at end of file + +} diff --git a/chenhai-system/src/main/java/com/chenhai/system/domain/SysAnswers.java b/chenhai-system/src/main/java/com/chenhai/system/domain/SysAnswers.java new file mode 100644 index 0000000..b072c5b --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/domain/SysAnswers.java @@ -0,0 +1,160 @@ +package com.chenhai.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +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; + +/** + * 答复对象 sys_answers + * + * @author ruoyi + * @date 2026-01-29 + */ +public class SysAnswers extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** $column.columnComment */ + private Long id; + + /** 对应的问题ID */ + @Excel(name = "对应的问题ID") + private Long questionId; + + /** 用户ID */ + @Excel(name = "用户ID") + private String userId; + + /** 用户名 */ + @Excel(name = "用户名") + private String username; + + /** 用户昵称 */ + @Excel(name = "用户昵称") + private String nickName; + + /** 用户头像 */ + private String avatar; + + /** 回答内容 */ + @Excel(name = "回答内容") + private String content; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date createdAt; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date updatedAt; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public void setQuestionId(Long questionId) + { + this.questionId = questionId; + } + + public Long getQuestionId() + { + return questionId; + } + + public void setUserId(String userId) + { + this.userId = userId; + } + + public String getUserId() + { + return userId; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getUsername() + { + return username; + } + + public void setNickName(String nickName) + { + this.nickName = nickName; + } + + public String getNickName() + { + return nickName; + } + + public void setAvatar(String avatar) + { + this.avatar = avatar; + } + + public String getAvatar() + { + return avatar; + } + + public void setContent(String content) + { + this.content = content; + } + + public String getContent() + { + return content; + } + + public void setCreatedAt(Date createdAt) + { + this.createdAt = createdAt; + } + + public Date getCreatedAt() + { + return createdAt; + } + + public void setUpdatedAt(Date updatedAt) + { + this.updatedAt = updatedAt; + } + + public Date getUpdatedAt() + { + return updatedAt; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("questionId", getQuestionId()) + .append("userId", getUserId()) + .append("username", getUsername()) + .append("nickName", getNickName()) + .append("avatar", getAvatar()) + .append("content", getContent()) + .append("createdAt", getCreatedAt()) + .append("updatedAt", getUpdatedAt()) + .toString(); + } +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/system/domain/SysPolicyInterpretation.java b/chenhai-system/src/main/java/com/chenhai/system/domain/SysPolicyInterpretation.java index 9645c1e..2017b23 100644 --- a/chenhai-system/src/main/java/com/chenhai/system/domain/SysPolicyInterpretation.java +++ b/chenhai-system/src/main/java/com/chenhai/system/domain/SysPolicyInterpretation.java @@ -53,6 +53,9 @@ public class SysPolicyInterpretation extends BaseEntity @Excel(name = "政策分类") // 添加dictType用于字典转换 private String policyCategory; + /** 搜索关键词(非数据库字段) */ + private String searchKey; + /** 删除标志(0代表存在 2代表删除) */ private String delFlag; @@ -156,6 +159,15 @@ public class SysPolicyInterpretation extends BaseEntity return policyCategory; } + public String getSearchKey() { + return searchKey; + } + + public void setSearchKey(String searchKey) { + this.searchKey = searchKey; + } + + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -174,6 +186,7 @@ public class SysPolicyInterpretation extends BaseEntity .append("updateTime", getUpdateTime()) .append("remark", getRemark()) .append("policyCategory", getPolicyCategory()) + .append("searchKey", getSearchKey()) .toString(); } } diff --git a/chenhai-system/src/main/java/com/chenhai/system/domain/SysQuestions.java b/chenhai-system/src/main/java/com/chenhai/system/domain/SysQuestions.java new file mode 100644 index 0000000..718ba90 --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/domain/SysQuestions.java @@ -0,0 +1,186 @@ +package com.chenhai.system.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +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; + +/** + * 问答对象 sys_questions + * + * @author ruoyi + * @date 2026-01-29 + */ +public class SysQuestions extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** $column.columnComment */ + private Long id; + + /** 用户ID */ + @Excel(name = "用户ID") + private Long userId; + + /** 用户名 */ + @Excel(name = "用户名") + private String username; + + /** 问题标题 */ + @Excel(name = "问题标题") + private String title; + + /** 问题内容 */ + @Excel(name = "问题内容") + private String content; + + /** 标签 */ + @Excel(name = "标签") + private String tags; + + /** 回答数 */ + @Excel(name = "回答数") + private Long answerCount; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date createdAt; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date updatedAt; + + /** 用户昵称 */ + @Excel(name = "用户昵称") + private String nickName; + + /** 用户头像 */ + private String avatar; + + 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 setUsername(String username) + { + this.username = username; + } + + public String getUsername() + { + return username; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getTitle() + { + return title; + } + + public void setContent(String content) + { + this.content = content; + } + + public String getContent() + { + return content; + } + + public void setTags(String tags) + { + this.tags = tags; + } + + public String getTags() + { + return tags; + } + + public void setAnswerCount(Long answerCount) + { + this.answerCount = answerCount; + } + + public Long getAnswerCount() + { + return answerCount; + } + + public void setCreatedAt(Date createdAt) + { + this.createdAt = createdAt; + } + + public Date getCreatedAt() + { + return createdAt; + } + + public void setUpdatedAt(Date updatedAt) + { + this.updatedAt = updatedAt; + } + + public Date getUpdatedAt() + { + return updatedAt; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("userId", getUserId()) + .append("username", getUsername()) + .append("title", getTitle()) + .append("content", getContent()) + .append("tags", getTags()) + .append("answerCount", getAnswerCount()) + .append("createdAt", getCreatedAt()) + .append("updatedAt", getUpdatedAt()) + .append("nickName", getNickName()) + .append("avatar", getAvatar()) + .toString(); + } +} diff --git a/chenhai-system/src/main/java/com/chenhai/system/mapper/SysAnswersMapper.java b/chenhai-system/src/main/java/com/chenhai/system/mapper/SysAnswersMapper.java new file mode 100644 index 0000000..9837686 --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/mapper/SysAnswersMapper.java @@ -0,0 +1,78 @@ +package com.chenhai.system.mapper; + +import java.util.List; +import com.chenhai.system.domain.SysAnswers; +import org.apache.ibatis.annotations.Param; + +/** + * 答复Mapper接口 + * + * @author ruoyi + * @date 2026-01-29 + */ +public interface SysAnswersMapper +{ + /** + * 查询答复 + * + * @param id 答复主键 + * @return 答复 + */ + public SysAnswers selectSysAnswersById(Long id); + + /** + * 查询答复列表 + * + * @param sysAnswers 答复 + * @return 答复集合 + */ + public List selectSysAnswersList(SysAnswers sysAnswers); + + /** + * 新增答复 + * + * @param sysAnswers 答复 + * @return 结果 + */ + public int insertSysAnswers(SysAnswers sysAnswers); + + /** + * 修改答复 + * + * @param sysAnswers 答复 + * @return 结果 + */ + public int updateSysAnswers(SysAnswers sysAnswers); + + /** + * 删除答复 + * + * @param id 答复主键 + * @return 结果 + */ + public int deleteSysAnswersById(Long id); + + /** + * 批量删除答复 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysAnswersByIds(Long[] ids); + + /** + * 根据问题ID删除答复 + * + * @param questionId 问题ID + * @return 结果 + */ + public int deleteAnswersByQuestionId(Long questionId); + + /** + * 获取问题的答案数量 + * + * @param questionId 问题ID + * @return 答案数量 + */ + public Long countAnswersByQuestionId(Long questionId); +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/system/mapper/SysQuestionsMapper.java b/chenhai-system/src/main/java/com/chenhai/system/mapper/SysQuestionsMapper.java new file mode 100644 index 0000000..e049646 --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/mapper/SysQuestionsMapper.java @@ -0,0 +1,94 @@ +package com.chenhai.system.mapper; + +import java.util.List; +import com.chenhai.system.domain.SysQuestions; +import org.apache.ibatis.annotations.Param; + +/** + * 问答Mapper接口 + * + * @author ruoyi + * @date 2026-01-29 + */ +public interface SysQuestionsMapper +{ + /** + * 查询问答 + * + * @param id 问答主键 + * @return 问答 + */ + public SysQuestions selectSysQuestionsById(Long id); + + /** + * 查询问答列表 + * + * @param sysQuestions 问答 + * @return 问答集合 + */ + public List selectSysQuestionsList(SysQuestions sysQuestions); + + /** + * 新增问答 + * + * @param sysQuestions 问答 + * @return 结果 + */ + public int insertSysQuestions(SysQuestions sysQuestions); + + /** + * 修改问答 + * + * @param sysQuestions 问答 + * @return 结果 + */ + public int updateSysQuestions(SysQuestions sysQuestions); + + /** + * 删除问答 + * + * @param id 问答主键 + * @return 结果 + */ + public int deleteSysQuestionsById(Long id); + + /** + * 批量删除问答 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteSysQuestionsByIds(Long[] ids); + + /** + * 增加问题的答案数量 + * + * @param questionId 问题ID + * @return 结果 + */ + public int increaseAnswerCount(Long questionId); + + /** + * 减少问题的答案数量 + * + * @param questionId 问题ID + * @return 结果 + */ + public int decreaseAnswerCount(Long questionId); + + /** + * 更新问题的答案数量(从数据库实时统计) + * + * @param questionId 问题ID + * @return 结果 + */ + public int updateAnswerCountFromDb(Long questionId); + + /** + * 获取问题的答案数量 + * + * @param questionId 问题ID + * @return 答案数量 + */ + public Long getAnswerCount(Long questionId); +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/system/service/ISysAnswersService.java b/chenhai-system/src/main/java/com/chenhai/system/service/ISysAnswersService.java new file mode 100644 index 0000000..ed0aaf1 --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/service/ISysAnswersService.java @@ -0,0 +1,93 @@ +package com.chenhai.system.service; + +import java.util.List; +import com.chenhai.system.domain.SysAnswers; + +/** + * 答复Service接口 + * + * @author ruoyi + * @date 2026-01-29 + */ +public interface ISysAnswersService +{ + /** + * 查询答复 + * + * @param id 答复主键 + * @return 答复 + */ + public SysAnswers selectSysAnswersById(Long id); + + /** + * 查询答复列表 + * + * @param sysAnswers 答复 + * @return 答复集合 + */ + public List selectSysAnswersList(SysAnswers sysAnswers); + + /** + * 新增答复 + * + * @param sysAnswers 答复 + * @return 结果 + */ + public int insertSysAnswers(SysAnswers sysAnswers); + + /** + * 新增答复(自动设置当前用户信息) + * + * @param sysAnswers 答复 + * @return 结果 + */ + public int insertSysAnswersWithCurrentUser(SysAnswers sysAnswers); + + /** + * 修改答复 + * + * @param sysAnswers 答复 + * @return 结果 + */ + public int updateSysAnswers(SysAnswers sysAnswers); + + /** + * 批量删除答复 + * + * @param ids 需要删除的答复主键集合 + * @return 结果 + */ + public int deleteSysAnswersByIds(Long[] ids); + + /** + * 删除答复信息 + * + * @param id 答复主键 + * @return 结果 + */ + public int deleteSysAnswersById(Long id); + + /** + * 根据问题ID删除答复 + * + * @param questionId 问题ID + * @return 结果 + */ + public int deleteSysAnswersByQuestionId(Long questionId); + + /** + * 获取问题的答案列表 + * + * @param questionId 问题ID + * @return 答案集合 + */ + public List selectAnswersByQuestionId(Long questionId); + + /** + * 获取问题的答案数量 + * + * @param questionId 问题ID + * @return 答案数量 + */ + public Long countAnswersByQuestionId(Long questionId); +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/system/service/ISysQuestionsService.java b/chenhai-system/src/main/java/com/chenhai/system/service/ISysQuestionsService.java new file mode 100644 index 0000000..bcd0bca --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/service/ISysQuestionsService.java @@ -0,0 +1,106 @@ +package com.chenhai.system.service; + +import java.util.List; +import com.chenhai.system.domain.SysQuestions; + +/** + * 问答Service接口 + * + * @author ruoyi + * @date 2026-01-29 + */ +public interface ISysQuestionsService +{ + /** + * 查询问答 + * + * @param id 问答主键 + * @return 问答 + */ + public SysQuestions selectSysQuestionsById(Long id); + + /** + * 查询问答列表 + * + * @param sysQuestions 问答 + * @return 问答集合 + */ + public List selectSysQuestionsList(SysQuestions sysQuestions); + + /** + * 新增问答(自动关联当前用户) + * + * @param sysQuestions 问答 + * @param userId 当前用户ID + * @return 结果 + */ + public int insertSysQuestions(SysQuestions sysQuestions, Long userId); + + /** + * 修改问答(权限验证) + * + * @param sysQuestions 问答 + * @param userId 当前用户ID + * @return 结果 + */ + public int updateSysQuestions(SysQuestions sysQuestions, Long userId); + + /** + * 批量删除问答(权限验证) + * + * @param ids 需要删除的问答主键集合 + * @param userId 当前用户ID + * @return 结果 + */ + public int deleteSysQuestionsByIds(Long[] ids, Long userId); + + /** + * 删除问答信息(权限验证) + * + * @param id 问答主键 + * @param userId 当前用户ID + * @return 结果 + */ + public int deleteSysQuestionsById(Long id, Long userId); + + /** + * 检查问题是否属于当前用户 + * + * @param questionId 问题ID + * @param userId 用户ID + * @return 结果 + */ + public boolean isQuestionBelongsToUser(Long questionId, Long userId); + + /** + * 增加问题的答案数量 + * + * @param questionId 问题ID + * @return 结果 + */ + public int increaseAnswerCount(Long questionId); + + /** + * 减少问题的答案数量 + * + * @param questionId 问题ID + * @return 结果 + */ + public int decreaseAnswerCount(Long questionId); + + /** + * 更新问题的答案数量(从数据库实时统计) + * + * @param questionId 问题ID + * @return 结果 + */ + public int updateAnswerCountFromDb(Long questionId); + + /** + * 获取问题的答案数量 + * + * @param questionId 问题ID + * @return 答案数量 + */ + public Long getAnswerCount(Long questionId); +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/system/service/impl/SysAnswersServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/system/service/impl/SysAnswersServiceImpl.java new file mode 100644 index 0000000..55c9fc5 --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/service/impl/SysAnswersServiceImpl.java @@ -0,0 +1,243 @@ +package com.chenhai.system.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.chenhai.common.core.domain.entity.SysUser; +import com.chenhai.common.utils.SecurityUtils; +import com.chenhai.common.utils.StringUtils; +import com.chenhai.system.mapper.SysAnswersMapper; +import com.chenhai.system.domain.SysAnswers; +import com.chenhai.system.service.ISysAnswersService; +import com.chenhai.system.service.ISysQuestionsService; +import com.chenhai.common.exception.ServiceException; + +/** + * 答复Service业务层处理 + * + * @author ruoyi + * @date 2026-01-29 + */ +@Service +public class SysAnswersServiceImpl implements ISysAnswersService +{ + @Autowired + private SysAnswersMapper sysAnswersMapper; + + @Autowired + private ISysQuestionsService sysQuestionsService; + + /** + * 查询答复 + * + * @param id 答复主键 + * @return 答复 + */ + @Override + public SysAnswers selectSysAnswersById(Long id) + { + return sysAnswersMapper.selectSysAnswersById(id); + } + + /** + * 查询答复列表 + * + * @param sysAnswers 答复 + * @return 答复 + */ + @Override + public List selectSysAnswersList(SysAnswers sysAnswers) + { + return sysAnswersMapper.selectSysAnswersList(sysAnswers); + } + + /** + * 新增答复 + * + * @param sysAnswers 答复 + * @return 结果 + */ + @Override + @Transactional + public int insertSysAnswers(SysAnswers sysAnswers) + { + // 验证问题ID是否存在 + if (sysAnswers.getQuestionId() == null) { + throw new ServiceException("问题ID不能为空"); + } + + int result = sysAnswersMapper.insertSysAnswers(sysAnswers); + + if (result > 0) { + // 增加问题的答案数量 + sysQuestionsService.increaseAnswerCount(sysAnswers.getQuestionId()); + } + + return result; + } + + /** + * 新增答复(自动设置当前用户信息) + * + * @param sysAnswers 答复 + * @return 结果 + */ + @Override + @Transactional + public int insertSysAnswersWithCurrentUser(SysAnswers sysAnswers) + { + // 验证问题ID是否存在 + if (sysAnswers.getQuestionId() == null) { + throw new ServiceException("问题ID不能为空"); + } + + // 获取当前登录用户信息 + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + + // 设置用户信息 + sysAnswers.setUserId(String.valueOf(currentUser.getUserId())); + sysAnswers.setUsername(currentUser.getUserName()); + // 如果前端没有传递昵称,使用系统昵称 + if (StringUtils.isEmpty(sysAnswers.getNickName())) { + sysAnswers.setNickName(currentUser.getNickName()); + } + // 设置头像 + sysAnswers.setAvatar(currentUser.getAvatar()); + + int result = sysAnswersMapper.insertSysAnswers(sysAnswers); + + if (result > 0) { + // 增加问题的答案数量 + sysQuestionsService.increaseAnswerCount(sysAnswers.getQuestionId()); + } + + return result; + } + + /** + * 修改答复 + * + * @param sysAnswers 答复 + * @return 结果 + */ + @Override + @Transactional + public int updateSysAnswers(SysAnswers sysAnswers) + { + return sysAnswersMapper.updateSysAnswers(sysAnswers); + } + + /** + * 批量删除答复 + * + * @param ids 需要删除的答复主键 + * @return 结果 + */ + @Override + @Transactional + public int deleteSysAnswersByIds(Long[] ids) + { + // 先获取所有要删除的答案,记录对应的问题ID + for (Long id : ids) { + SysAnswers answer = sysAnswersMapper.selectSysAnswersById(id); + if (answer != null) { + // 减少问题的答案数量 + sysQuestionsService.decreaseAnswerCount(answer.getQuestionId()); + } + } + + return sysAnswersMapper.deleteSysAnswersByIds(ids); + } + + /** + * 删除答复信息 + * + * @param id 答复主键 + * @return 结果 + */ + @Override + @Transactional + public int deleteSysAnswersById(Long id) + { + SysAnswers answer = sysAnswersMapper.selectSysAnswersById(id); + if (answer == null) { + throw new ServiceException("答复不存在"); + } + + Long questionId = answer.getQuestionId(); + int result = sysAnswersMapper.deleteSysAnswersById(id); + + if (result > 0) { + // 减少问题的答案数量 + sysQuestionsService.decreaseAnswerCount(questionId); + } + + return result; + } + + /** + * 根据问题ID删除答复 + * + * @param questionId 问题ID + * @return 结果 + */ + @Override + @Transactional + public int deleteSysAnswersByQuestionId(Long questionId) + { + // 获取该问题的所有答案 + List answers = selectAnswersByQuestionId(questionId); + + // 删除所有答案 + int result = sysAnswersMapper.deleteAnswersByQuestionId(questionId); + + if (result > 0) { + // 重置问题的答案数量为0 + updateAnswerCountToZero(questionId); + } + + return result; + } + + /** + * 获取问题的答案列表 + * + * @param questionId 问题ID + * @return 答案集合 + */ + @Override + public List selectAnswersByQuestionId(Long questionId) + { + SysAnswers query = new SysAnswers(); + query.setQuestionId(questionId); + return sysAnswersMapper.selectSysAnswersList(query); + } + + /** + * 获取问题的答案数量 + * + * @param questionId 问题ID + * @return 答案数量 + */ + @Override + public Long countAnswersByQuestionId(Long questionId) + { + SysAnswers query = new SysAnswers(); + query.setQuestionId(questionId); + List answers = sysAnswersMapper.selectSysAnswersList(query); + return (long) answers.size(); + } + + /** + * 重置问题的答案数量为0(私有方法) + * + * @param questionId 问题ID + */ + private void updateAnswerCountToZero(Long questionId) + { + // 这里需要调用Questions的更新方法 + // 由于service间循环依赖问题,这里直接更新数据库 + // 或者可以在QuestionsService中添加一个重置方法 + } +} \ No newline at end of file diff --git a/chenhai-system/src/main/java/com/chenhai/system/service/impl/SysQuestionsServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/system/service/impl/SysQuestionsServiceImpl.java new file mode 100644 index 0000000..18b609c --- /dev/null +++ b/chenhai-system/src/main/java/com/chenhai/system/service/impl/SysQuestionsServiceImpl.java @@ -0,0 +1,248 @@ +package com.chenhai.system.service.impl; + +import java.util.Date; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.chenhai.system.mapper.SysQuestionsMapper; +import com.chenhai.system.domain.SysQuestions; +import com.chenhai.system.service.ISysQuestionsService; +import com.chenhai.common.exception.ServiceException; +import com.chenhai.common.utils.MessageUtils; + +/** + * 问答Service业务层处理 + * + * @author ruoyi + * @date 2026-01-29 + */ +@Service +public class SysQuestionsServiceImpl implements ISysQuestionsService +{ + @Autowired + private SysQuestionsMapper sysQuestionsMapper; + + /** + * 查询问答 + * + * @param id 问答主键 + * @return 问答 + */ + @Override + public SysQuestions selectSysQuestionsById(Long id) + { + return sysQuestionsMapper.selectSysQuestionsById(id); + } + + /** + * 查询问答列表 + * + * @param sysQuestions 问答 + * @return 问答 + */ + @Override + public List selectSysQuestionsList(SysQuestions sysQuestions) + { + return sysQuestionsMapper.selectSysQuestionsList(sysQuestions); + } + + /** + * 新增问答(自动关联当前用户) + * + * @param sysQuestions 问答 + * @param userId 当前用户ID + * @return 结果 + */ + @Override + @Transactional + public int insertSysQuestions(SysQuestions sysQuestions, Long userId) + { + // 设置当前用户ID + sysQuestions.setUserId(userId); + + // 设置默认值 + if (sysQuestions.getAnswerCount() == null) { + sysQuestions.setAnswerCount(0L); + } + + Date now = new Date(); + if (sysQuestions.getCreatedAt() == null) { + sysQuestions.setCreatedAt(now); + } + if (sysQuestions.getUpdatedAt() == null) { + sysQuestions.setUpdatedAt(now); + } + + return sysQuestionsMapper.insertSysQuestions(sysQuestions); + } + + /** + * 修改问答(权限验证) + * + * @param sysQuestions 问答 + * @param userId 当前用户ID + * @return 结果 + */ + @Override + @Transactional + public int updateSysQuestions(SysQuestions sysQuestions, Long userId) + { + // 检查问题是否存在 + SysQuestions existingQuestion = sysQuestionsMapper.selectSysQuestionsById(sysQuestions.getId()); + if (existingQuestion == null) { + throw new ServiceException("问题不存在"); + } + + // 检查权限:只能修改自己的问题 + if (!existingQuestion.getUserId().equals(userId)) { + throw new ServiceException("没有权限修改此问题"); + } + + // 设置更新时间 + sysQuestions.setUpdatedAt(new Date()); + + return sysQuestionsMapper.updateSysQuestions(sysQuestions); + } + + /** + * 批量删除问答(权限验证) + * + * @param ids 需要删除的问答主键 + * @param userId 当前用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteSysQuestionsByIds(Long[] ids, Long userId) + { + // 检查权限:只能删除自己的问题 + for (Long id : ids) { + SysQuestions question = sysQuestionsMapper.selectSysQuestionsById(id); + if (question == null) { + throw new ServiceException("问题不存在,ID: " + id); + } + if (!question.getUserId().equals(userId)) { + throw new ServiceException("没有权限删除此问题,ID: " + id); + } + } + + return sysQuestionsMapper.deleteSysQuestionsByIds(ids); + } + + /** + * 删除问答信息(权限验证) + * + * @param id 问答主键 + * @param userId 当前用户ID + * @return 结果 + */ + @Override + @Transactional + public int deleteSysQuestionsById(Long id, Long userId) + { + // 检查问题是否存在 + SysQuestions question = sysQuestionsMapper.selectSysQuestionsById(id); + if (question == null) { + throw new ServiceException("问题不存在"); + } + + // 检查权限:只能删除自己的问题 + if (!question.getUserId().equals(userId)) { + throw new ServiceException("没有权限删除此问题"); + } + + return sysQuestionsMapper.deleteSysQuestionsById(id); + } + + /** + * 检查问题是否属于当前用户 + * + * @param questionId 问题ID + * @param userId 用户ID + * @return 结果 + */ + @Override + public boolean isQuestionBelongsToUser(Long questionId, Long userId) + { + SysQuestions question = sysQuestionsMapper.selectSysQuestionsById(questionId); + if (question == null) { + return false; + } + return question.getUserId().equals(userId); + } + + /** + * 增加问题的答案数量 + * + * @param questionId 问题ID + * @return 结果 + */ + @Override + @Transactional + public int increaseAnswerCount(Long questionId) + { + // 检查问题是否存在 + SysQuestions question = sysQuestionsMapper.selectSysQuestionsById(questionId); + if (question == null) { + throw new ServiceException("问题不存在,ID: " + questionId); + } + + return sysQuestionsMapper.increaseAnswerCount(questionId); + } + + /** + * 减少问题的答案数量 + * + * @param questionId 问题ID + * @return 结果 + */ + @Override + @Transactional + public int decreaseAnswerCount(Long questionId) + { + // 检查问题是否存在 + SysQuestions question = sysQuestionsMapper.selectSysQuestionsById(questionId); + if (question == null) { + throw new ServiceException("问题不存在,ID: " + questionId); + } + + return sysQuestionsMapper.decreaseAnswerCount(questionId); + } + + /** + * 更新问题的答案数量(从数据库实时统计) + * + * @param questionId 问题ID + * @return 结果 + */ + @Override + @Transactional + public int updateAnswerCountFromDb(Long questionId) + { + // 检查问题是否存在 + SysQuestions question = sysQuestionsMapper.selectSysQuestionsById(questionId); + if (question == null) { + throw new ServiceException("问题不存在,ID: " + questionId); + } + + return sysQuestionsMapper.updateAnswerCountFromDb(questionId); + } + + /** + * 获取问题的答案数量 + * + * @param questionId 问题ID + * @return 答案数量 + */ + @Override + public Long getAnswerCount(Long questionId) + { + SysQuestions question = sysQuestionsMapper.selectSysQuestionsById(questionId); + if (question == null) { + throw new ServiceException("问题不存在,ID: " + questionId); + } + + return question.getAnswerCount(); + } +} \ No newline at end of file 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 ad1fb98..7dff647 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 @@ -66,6 +66,9 @@ public class VetKnowledge extends BaseEntity @Excel(name = "副标题") private String subtitle; + /** 搜索关键词(非数据库字段,用于搜索) */ + private String searchKey; + /** 专家ID */ @Excel(name = "专家ID") private Long expertId; @@ -206,6 +209,14 @@ public class VetKnowledge extends BaseEntity this.subtitle = subtitle; } + public String getSearchKey() { + return searchKey; + } + + public void setSearchKey(String searchKey) { + this.searchKey = searchKey; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @@ -227,6 +238,7 @@ public class VetKnowledge extends BaseEntity .append("expertId", getExpertId()) .append("coverImage", getCoverImage()) .append("subtitle", getSubtitle()) + .append("searchKey", getSearchKey()) .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 9a76591..efb449d 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,28 @@ package com.chenhai.vet.domain; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; 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; - /** * 兽医培训视频对象 vet_training_video - * + * * @author ruoyi - * @date 2026-01-08 + * @date 2026-01-28 */ public class VetTrainingVideo extends BaseEntity { private static final long serialVersionUID = 1L; - /** 主键 */ + /** 主键ID */ private Long id; - /** 用户ID */ + /** 兽医ID */ + @Excel(name = "兽医ID") private Long userId; /** 视频标题 */ @@ -31,40 +33,43 @@ public class VetTrainingVideo extends BaseEntity @Excel(name = "视频描述") private String description; - /** 视频URL */ - @Excel(name = "视频URL") + /** 视频地址 */ + @Excel(name = "视频地址") private String videoUrl; /** 封面图片 */ @Excel(name = "封面图片") private String coverImage; - /** 视频分类(手术技巧/疾病诊断/药物使用/其他) */ - @Excel(name = "视频分类", dictType = "video_category") + /** 分类 */ + @Excel(name = "分类") private String category; - /** 视频标签 */ - @Excel(name = "视频标签") + /** 标签(逗号分隔) */ + @Excel(name = "标签", readConverterExp = "逗=号分隔") private String tags; /** 视频时长(秒) */ - @Excel(name = "视频时长") - private Integer duration; + @Excel(name = "视频时长", readConverterExp = "秒=") + private Long duration; /** 文件大小(字节) */ - @Excel(name = "文件大小") + @Excel(name = "文件大小", readConverterExp = "字=节") private Long fileSize; /** 观看次数 */ @Excel(name = "观看次数") - private Integer viewCount; + private Long viewCount; - /** 上架状态(0-私有 1-公开) */ - @Excel(name = "上架状态", dictType = "sys_publish_status") + /** 状态(0-私有 1-公开) */ + @Excel(name = "状态", readConverterExp = "0=-私有,1=-公开") private String status; - /** 审核状态(0-待审核 1-审核通过 2-审核拒绝 3-无需审核) */ - @Excel(name = "审核状态", dictType = "audit_status") + /** 删除标志(0=正常,1=删除) */ + private String delFlag; + + /** 审核状态:0-待审核 1-审核通过 2-审核拒绝 3-无需审核 */ + @Excel(name = "审核状态:0-待审核 1-审核通过 2-审核拒绝 3-无需审核") private String auditStatus; /** 审核意见 */ @@ -72,225 +77,261 @@ public class VetTrainingVideo extends BaseEntity private String auditOpinion; /** 审核人ID */ + @Excel(name = "审核人ID") private Long auditUserId; /** 审核时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "审核时间", width = 30, dateFormat = "yyyy-MM-dd") private Date auditTime; - /** 格式化后的时长(如:12:30) */ - private String durationStr; + /** 发布者姓名(非数据库字段) */ + @JsonProperty("publisherName") + @Excel(name = "发布者") + private String publisherName; + + /** 发布者头像(非数据库字段) */ + @JsonProperty("publisherAvatar") + private String publisherAvatar; - /** 用户名称(非数据库字段) */ - private String userName; - private String userAvatar; + /** 搜索关键词(非数据库字段,用于多字段模糊搜索) */ + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private String searchKey; - public void setId(Long id) + /** 发布时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "发布时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date publishTime; + + public void setId(Long id) { this.id = id; } - public Long getId() + public Long getId() { return id; } - public void setUserId(Long userId) + public void setUserId(Long userId) { this.userId = userId; } - public Long getUserId() + public Long getUserId() { return userId; } - public void setTitle(String title) + public void setTitle(String title) { this.title = title; } - public String getTitle() + public String getTitle() { return title; } - public void setDescription(String description) + public void setDescription(String description) { this.description = description; } - public String getDescription() + public String getDescription() { return description; } - public void setVideoUrl(String videoUrl) + public void setVideoUrl(String videoUrl) { this.videoUrl = videoUrl; } - public String getVideoUrl() + public String getVideoUrl() { return videoUrl; } - public void setCoverImage(String coverImage) + public void setCoverImage(String coverImage) { this.coverImage = coverImage; } - public String getCoverImage() + public String getCoverImage() { return coverImage; } - public void setCategory(String category) + public void setCategory(String category) { this.category = category; } - public String getCategory() + public String getCategory() { return category; } - public void setTags(String tags) + public void setTags(String tags) { this.tags = tags; } - public String getTags() + public String getTags() { return tags; } - public void setDuration(Integer duration) + public void setDuration(Long duration) { this.duration = duration; } - public Integer getDuration() + public Long getDuration() { return duration; } - public void setFileSize(Long fileSize) + public void setFileSize(Long fileSize) { this.fileSize = fileSize; } - public Long getFileSize() + public Long getFileSize() { return fileSize; } - public void setViewCount(Integer viewCount) + public void setViewCount(Long viewCount) { this.viewCount = viewCount; } - public Integer getViewCount() + public Long getViewCount() { return viewCount; } - public void setStatus(String status) + public void setStatus(String status) { this.status = status; } - public String getStatus() + public String getStatus() { return status; } - public void setAuditStatus(String auditStatus) + public void setDelFlag(String delFlag) + { + this.delFlag = delFlag; + } + + public String getDelFlag() + { + return delFlag; + } + + public void setAuditStatus(String auditStatus) { this.auditStatus = auditStatus; } - public String getAuditStatus() + public String getAuditStatus() { return auditStatus; } - public void setAuditOpinion(String auditOpinion) + public void setAuditOpinion(String auditOpinion) { this.auditOpinion = auditOpinion; } - public String getAuditOpinion() + public String getAuditOpinion() { return auditOpinion; } - public void setAuditUserId(Long auditUserId) + public void setAuditUserId(Long auditUserId) { this.auditUserId = auditUserId; } - public Long getAuditUserId() + public Long getAuditUserId() { return auditUserId; } - public void setAuditTime(Date auditTime) + public void setAuditTime(Date auditTime) { this.auditTime = auditTime; } - public Date getAuditTime() + public Date getAuditTime() { return auditTime; } - public String getDurationStr() { - return durationStr; + public String getPublisherName() { + return publisherName; + } + + public void setPublisherName(String publisherName) { + this.publisherName = publisherName; } - public void setDurationStr(String durationStr) { - this.durationStr = durationStr; + public String getPublisherAvatar() { + return publisherAvatar; } - public String getUserName() { - return userName; + public void setPublisherAvatar(String publisherAvatar) { + this.publisherAvatar = publisherAvatar; } - public void setUserName(String userName) { - this.userName = userName; + public String getSearchKey() { + return searchKey; } - public String getUserAvatar() { - return userAvatar; + public void setSearchKey(String searchKey) { + this.searchKey = searchKey; } - public void setUserAvatar(String userAvatar) { - this.userAvatar = userAvatar; + public void setPublishTime(Date publishTime) + { + this.publishTime = publishTime; + } + + public Date getPublishTime() + { + return publishTime; } @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 + 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("createTime", getCreateTime()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("auditStatus", getAuditStatus()) + .append("auditOpinion", getAuditOpinion()) + .append("auditUserId", getAuditUserId()) + .append("auditTime", getAuditTime()) + .append("publisherName", getPublisherName()) + .append("publisherAvatar", getPublisherAvatar()) + .append("publishTime", getPublishTime()) + .toString(); + } +} 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 2b814fb..484c043 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 @@ -1,49 +1,69 @@ 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; +import com.chenhai.vet.domain.VetTrainingVideo; -public interface VetTrainingVideoMapper { - - int insertVideo(VetTrainingVideo video); - - List selectMyVideos(@Param("userId") Long userId, - @Param("title") String title, - @Param("category") String category, - @Param("status") String status, - @Param("auditStatus") String auditStatus); - - List selectPublicVideos(@Param("title") String title, - @Param("category") String category, - @Param("userName") String userName); - - VetTrainingVideo selectVideoById(Long id); - - void incrementViewCount(Long id); - - List selectHotVideos(@Param("limit") Integer limit); +/** + * 兽医培训视频Mapper接口 + * + * @author ruoyi + * @date 2026-01-28 + */ +public interface VetTrainingVideoMapper +{ + /** + * 查询兽医培训视频 + * + * @param id 兽医培训视频主键 + * @return 兽医培训视频 + */ + public VetTrainingVideo selectVetTrainingVideoById(Long id); - List searchVideos(@Param("keyword") String keyword); + /** + * 查询兽医培训视频列表 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 兽医培训视频集合 + */ + public List selectVetTrainingVideoList(VetTrainingVideo vetTrainingVideo); - int deleteVideoById(@Param("id") Long id); + /** + * 新增兽医培训视频 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 结果 + */ + public int insertVetTrainingVideo(VetTrainingVideo vetTrainingVideo); - // 更新审核状态 - int updateAuditStatus(@Param("id") Long id, - @Param("auditStatus") String auditStatus, - @Param("auditOpinion") String auditOpinion, - @Param("auditUserId") Long auditUserId, - @Param("auditTime") Date auditTime); + /** + * 修改兽医培训视频 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 结果 + */ + public int updateVetTrainingVideo(VetTrainingVideo vetTrainingVideo); - // 更新视频状态(公开/私有) - int updateStatus(@Param("id") Long id, - @Param("status") String status); + /** + * 删除兽医培训视频 + * + * @param id 兽医培训视频主键 + * @return 结果 + */ + public int deleteVetTrainingVideoById(Long id); - // 获取待审核视频列表 - List selectPendingAuditVideos(@Param("title") String title, - @Param("userName") String userName); + /** + * 批量删除兽医培训视频 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteVetTrainingVideoByIds(Long[] ids); - // 更新视频信息 - int updateVideoInfo(VetTrainingVideo video); -} \ No newline at end of file + /** + * 查询公开视频列表(已上架且已审核通过) + * + * @param vetTrainingVideo 兽医培训视频 + * @return 兽医培训视频集合 + */ + public List selectPublicVideoList(VetTrainingVideo vetTrainingVideo); +} 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 21743a3..88969bf 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 @@ -1,92 +1,140 @@ package com.chenhai.vet.service; -import com.chenhai.vet.domain.VetTrainingVideo; -import org.springframework.web.multipart.MultipartFile; - import java.util.List; +import com.chenhai.vet.domain.VetTrainingVideo; -public interface IVetTrainingVideoService { - +/** + * 兽医培训视频Service接口 + * + * @author ruoyi + * @date 2026-01-28 + */ +public interface IVetTrainingVideoService +{ /** - * 上传并保存视频(自动设为待审核) + * 查询兽医培训视频 + * + * @param id 兽医培训视频主键 + * @return 兽医培训视频 */ - String uploadAndSave(VetTrainingVideo video, MultipartFile videoFile, MultipartFile coverImage); - + public VetTrainingVideo selectVetTrainingVideoById(Long id); /** - * 获取我的视频列表 + * 查询兽医培训视频列表 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 兽医培训视频集合 */ - List getMyVideos(Long userId, String title, String category, String status, String auditStatus); + public List selectVetTrainingVideoList(VetTrainingVideo vetTrainingVideo); /** - * 获取公开视频列表 + * 新增兽医培训视频 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 结果 */ - List getPublicVideos(String title, String category, String vetName); + public int insertVetTrainingVideo(VetTrainingVideo vetTrainingVideo); /** - * 获取视频详情(带权限校验) + * 修改兽医培训视频 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 结果 */ - VetTrainingVideo getVideoDetail(Long videoId, Long currentVetId); + public int updateVetTrainingVideo(VetTrainingVideo vetTrainingVideo); /** - * 获取视频播放地址(带权限校验) + * 批量删除兽医培训视频 + * + * @param ids 需要删除的兽医培训视频主键集合 + * @return 结果 */ - String getVideoPlayUrl(Long videoId, Long currentVetId); + public int deleteVetTrainingVideoByIds(Long[] ids); /** - * 增加观看次数 + * 删除兽医培训视频信息 + * + * @param id 兽医培训视频主键 + * @return 结果 */ - void incrementViewCount(Long videoId); + public int deleteVetTrainingVideoById(Long id); + + // 批量操作 + int batchSubmitForAudit(List videoIds, Long userId); + int batchAuditVideo(List videoIds, String auditStatus, String auditOpinion, Long auditUserId); + int batchPublishVideo(List videoIds, Long userId); + int batchOfflineVideo(List videoIds, Long userId); /** - * 获取热门视频 + * 审核单个视频 + * @param videoId 视频ID + * @param auditStatus 审核状态 + * @param auditOpinion 审核意见 + * @param auditUserId 审核用户ID + * @return 是否成功 */ - List getHotVideos(Integer limit); + boolean auditVideo(Long videoId, String auditStatus, String auditOpinion, Long auditUserId); /** - * 搜索视频 + * 上架单个视频 + * @param videoId 视频ID + * @param userId 用户ID + * @return 是否成功 */ - List searchVideos(String keyword); + boolean publishVideo(Long videoId, Long userId); - int deleteVideoById(Long videoId); + /** + * 下架单个视频 + * @param videoId 视频ID + * @param userId 用户ID + * @return 是否成功 + */ + boolean offlineVideo(Long videoId, Long userId); /** - * 提交审核(用户手动提交) + * 提交审核(单个视频) + * @param videoId 视频ID + * @param userId 用户ID + * @return 是否成功 */ boolean submitForAudit(Long videoId, Long userId); /** - * 取消审核(用户主动取消) + * 取消审核(单个视频) + * @param videoId 视频ID + * @param userId 用户ID + * @return 是否成功 */ boolean cancelAudit(Long videoId, Long userId); /** - * 重新提交审核(审核拒绝后) + * 重新提交审核(单个视频) + * @param videoId 视频ID + * @param userId 用户ID + * @return 是否成功 */ boolean resubmitForAudit(Long videoId, Long userId); /** - * 审核视频(管理员) + * 修复缺少用户ID的视频记录 + * @return 修复的记录数 */ - boolean auditVideo(Long videoId, String auditStatus, String auditOpinion, Long auditUserId); + int fixMissingUserIds(); /** - * 上架视频(审核通过后) + * 查询公开视频列表(已上架且已审核通过) + * + * @param vetTrainingVideo 查询条件 + * @return 公开视频集合 */ - boolean publishVideo(Long videoId, Long userId); + public List selectPublicVideoList(VetTrainingVideo vetTrainingVideo); /** - * 下架视频 + * 分页查询公开视频列表(已上架且已审核通过) + * + * @param vetTrainingVideo 查询条件 + * @return 公开视频集合 */ - boolean offlineVideo(Long videoId, Long userId); + public List selectPublicVideoPageList(VetTrainingVideo vetTrainingVideo); - /** - * 获取待审核视频列表(管理员) - */ - 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/VetProductServiceImpl.java b/chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetProductServiceImpl.java index b4f9df1..4d0ff2c 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,15 +1,12 @@ 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 73e1a3b..3ad392e 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 @@ -1,335 +1,499 @@ package com.chenhai.vet.service.impl; -import com.chenhai.vet.domain.VetTrainingVideo; -import com.chenhai.vet.mapper.VetTrainingVideoMapper; -import com.chenhai.vet.service.IVetTrainingVideoService; +import java.util.List; + +import com.chenhai.common.utils.SecurityUtils; +import org.slf4j.Logger; + +import com.chenhai.common.utils.DateUtils; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import com.chenhai.vet.mapper.VetTrainingVideoMapper; +import com.chenhai.vet.domain.VetTrainingVideo; +import com.chenhai.vet.service.IVetTrainingVideoService; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Date; -import java.util.List; -import java.util.UUID; +/** + * 兽医培训视频Service业务层处理 + * + * @author ruoyi + * @date 2026-01-28 + */ @Service -public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService { +public class VetTrainingVideoServiceImpl implements IVetTrainingVideoService +{ + // 添加 logger + private static final Logger logger = LoggerFactory.getLogger(VetTrainingVideoServiceImpl.class); @Autowired - private VetTrainingVideoMapper videoMapper; - - @Value("${file.upload.path:/uploads}") - private String uploadPath; - + private VetTrainingVideoMapper vetTrainingVideoMapper; + + /** + * 查询兽医培训视频 + * + * @param id 兽医培训视频主键 + * @return 兽医培训视频 + */ @Override - @Transactional - public String uploadAndSave(VetTrainingVideo video, MultipartFile videoFile, MultipartFile coverImage) { - try { - // 1. 创建上传目录 - File uploadDir = new File(uploadPath); - if (!uploadDir.exists()) { - uploadDir.mkdirs(); - } - - // 2. 生成唯一文件名 - String originalFileName = videoFile.getOriginalFilename(); - String fileExtension = getFileExtension(originalFileName); - String uniqueFileName = UUID.randomUUID().toString() + "." + fileExtension; - - // 3. 保存视频文件 - Path videoPath = Paths.get(uploadPath, uniqueFileName); - Files.write(videoPath, videoFile.getBytes()); - - // 4. 保存封面图(如果有) - String coverImageUrl = null; - if (coverImage != null && !coverImage.isEmpty()) { - String coverExtension = getFileExtension(coverImage.getOriginalFilename()); - String coverFileName = "cover_" + UUID.randomUUID().toString() + "." + coverExtension; - Path coverPath = Paths.get(uploadPath, coverFileName); - Files.write(coverPath, coverImage.getBytes()); - coverImageUrl = "/uploads/" + coverFileName; - } - - // 5. 计算视频时长和大小 - int duration = getVideoDuration(videoFile); - long fileSize = videoFile.getSize(); - - // 6. 设置初始状态:私有 + 待审核 - video.setStatus("0"); // 0-未上架/私有 - video.setAuditStatus("0"); // 0-待审核 - video.setVideoUrl("/uploads/" + uniqueFileName); - video.setCoverImage(coverImageUrl); - video.setDuration(duration); - video.setFileSize(fileSize); - video.setViewCount(0); - video.setCreateTime(new Date()); - video.setUpdateTime(new Date()); - - videoMapper.insertVideo(video); - - return "上传成功!视频已自动提交审核,请耐心等待管理员审核。"; - - } catch (IOException e) { - throw new RuntimeException("文件保存失败", e); - } + public VetTrainingVideo selectVetTrainingVideoById(Long id) + { + return vetTrainingVideoMapper.selectVetTrainingVideoById(id); } + /** + * 查询兽医培训视频列表 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 兽医培训视频 + */ @Override - public List getMyVideos(Long userId, String title, String category, String status, String auditStatus) { - return videoMapper.selectMyVideos(userId, title, category, status, auditStatus); + public List selectVetTrainingVideoList(VetTrainingVideo vetTrainingVideo) + { + return vetTrainingVideoMapper.selectVetTrainingVideoList(vetTrainingVideo); } + /** + * 新增兽医培训视频 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 结果 + */ @Override - public List getPublicVideos(String title, String category, String vetName) { - // 只显示审核通过且公开的视频 - return videoMapper.selectPublicVideos(title, category, vetName); - } - - @Override - public VetTrainingVideo getVideoDetail(Long videoId, Long currentVetId) { - VetTrainingVideo video = videoMapper.selectVideoById(videoId); - - if (video == null) { - return null; + public int insertVetTrainingVideo(VetTrainingVideo vetTrainingVideo) + { + // 强制设置当前用户ID(确保不为空) + Long userId = SecurityUtils.getUserId(); + if (userId == null) { + throw new RuntimeException("用户未登录"); } - // 权限校验:只能查看自己的视频或审核通过公开的视频 - boolean canView = ("2".equals(video.getAuditStatus()) && // 2-审核通过(新编码) - "1".equals(video.getStatus())) || // 1-已上架/公开 - currentVetId.equals(video.getUserId()); - return canView ? video : null; + vetTrainingVideo.setUserId(userId); // 确保设置用户ID + vetTrainingVideo.setStatus("0"); // 私有 + vetTrainingVideo.setAuditStatus("0"); // 待审核 + vetTrainingVideo.setDelFlag("0"); // 正常 + + vetTrainingVideo.setCreateTime(DateUtils.getNowDate()); + return vetTrainingVideoMapper.insertVetTrainingVideo(vetTrainingVideo); } + // 添加一个修复历史数据的方法 @Override - public String getVideoPlayUrl(Long videoId, Long currentVetId) { - VetTrainingVideo video = videoMapper.selectVideoById(videoId); - - if (video == null) { - return null; + @Transactional(rollbackFor = Exception.class) + public int fixMissingUserIds() { + // 查找 user_id 为 null 的视频记录 + VetTrainingVideo query = new VetTrainingVideo(); + query.setUserId(null); // 查找用户ID为空的记录 + + List videos = vetTrainingVideoMapper.selectVetTrainingVideoList(query); + int fixedCount = 0; + + for (VetTrainingVideo video : videos) { + if (video.getUserId() == null) { + // 这里可以根据实际情况设置一个默认用户ID + // 例如:设置为系统管理员ID或第一个用户 + video.setUserId(1L); // 假设1是系统管理员 + video.setUpdateTime(DateUtils.getNowDate()); + vetTrainingVideoMapper.updateVetTrainingVideo(video); + fixedCount++; + } } - // 权限校验:只能播放自己的视频或审核通过公开的视频 - boolean canPlay = ("2".equals(video.getAuditStatus()) && // 2-审核通过(新编码) - "1".equals(video.getStatus())) || // 1-已上架/公开 - currentVetId.equals(video.getUserId()); - return canPlay ? video.getVideoUrl() : null; + return fixedCount; } - @Override - public void incrementViewCount(Long videoId) { - videoMapper.incrementViewCount(videoId); - } + /** + * 修改兽医培训视频 + * + * @param vetTrainingVideo 兽医培训视频 + * @return 结果 + */ @Override - public List getHotVideos(Integer limit) { - return videoMapper.selectHotVideos(limit); + public int updateVetTrainingVideo(VetTrainingVideo vetTrainingVideo) + { + vetTrainingVideo.setUpdateTime(DateUtils.getNowDate()); + return vetTrainingVideoMapper.updateVetTrainingVideo(vetTrainingVideo); } + /** + * 批量删除兽医培训视频 + * + * @param ids 需要删除的兽医培训视频主键 + * @return 结果 + */ @Override - public List searchVideos(String keyword) { - return videoMapper.searchVideos(keyword); + public int deleteVetTrainingVideoByIds(Long[] ids) + { + return vetTrainingVideoMapper.deleteVetTrainingVideoByIds(ids); } + /** + * 删除兽医培训视频信息 + * + * @param id 兽医培训视频主键 + * @return 结果 + */ @Override - @Transactional - public int deleteVideoById(Long videoId) { - return videoMapper.deleteVideoById(videoId); + public int deleteVetTrainingVideoById(Long id) + { + return vetTrainingVideoMapper.deleteVetTrainingVideoById(id); } @Override - @Transactional - public boolean submitForAudit(Long videoId, Long userId) { - VetTrainingVideo video = videoMapper.selectVideoById(videoId); - - if (video == null || !userId.equals(video.getUserId())) { - return false; - } - - // 只能提交无需审核或审核拒绝的视频 - if (!"4".equals(video.getAuditStatus()) && // 3-无需审核 - !"3".equals(video.getAuditStatus())) { // 2-审核拒绝 - return false; + @Transactional(rollbackFor = Exception.class) + public int batchSubmitForAudit(List videoIds, Long userId) { + int successCount = 0; + + for (Long videoId : videoIds) { + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + + if (video == null) { + logger.warn("视频不存在,ID: {}", videoId); + continue; + } + + // 验证权限:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + logger.warn("用户 {} 无权限操作视频 {}", userId, videoId); + continue; + } + + // 状态验证:只有审核拒绝或无需审核状态才能重新提交审核 + String auditStatus = video.getAuditStatus(); + if (!"2".equals(auditStatus) && !"3".equals(auditStatus)) { + logger.warn("视频 {} 当前状态 {} 不能提交审核", videoId, auditStatus); + continue; + } + + // 更新为待审核状态 + video.setAuditStatus("0"); // 待审核 + video.setUpdateTime(DateUtils.getNowDate()); + + int result = vetTrainingVideoMapper.updateVetTrainingVideo(video); + if (result > 0) { + successCount++; + } + + } catch (Exception e) { + logger.error("批量提交审核失败,视频ID: {}", videoId, e); + // 继续处理下一个,不中断批量操作 + } } - // 更新为待审核状态 - int result = videoMapper.updateAuditStatus(videoId, - "1", // 1-审核中 - "已提交审核", - null, - new Date()); - return result > 0; + return successCount; } @Override - @Transactional - public boolean cancelAudit(Long videoId, Long userId) { - VetTrainingVideo video = videoMapper.selectVideoById(videoId); + @Transactional(rollbackFor = Exception.class) + public int batchAuditVideo(List videoIds, String auditStatus, String auditOpinion, Long auditUserId) { + int successCount = 0; - if (video == null || !userId.equals(video.getUserId())) { - return false; + // 如果是拒绝审核,必须填写意见 + if ("2".equals(auditStatus) && (auditOpinion == null || auditOpinion.trim().isEmpty())) { + throw new RuntimeException("审核拒绝时必须填写审核意见"); } - if (!"1".equals(video.getAuditStatus())) { // 1-审核中 - return false; + for (Long videoId : videoIds) { + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + + if (video == null) { + logger.warn("视频不存在,ID: {}", videoId); + continue; + } + + // 状态验证:只有待审核状态才能审核 + if (!"0".equals(video.getAuditStatus())) { + logger.warn("视频 {} 当前状态 {} 不能审核", videoId, video.getAuditStatus()); + continue; + } + + // 更新审核信息 + video.setAuditStatus(auditStatus); + video.setAuditOpinion(auditOpinion); + video.setAuditUserId(auditUserId); + video.setAuditTime(DateUtils.getNowDate()); + video.setUpdateTime(DateUtils.getNowDate()); + + int result = vetTrainingVideoMapper.updateVetTrainingVideo(video); + if (result > 0) { + successCount++; + } + + } catch (Exception e) { + logger.error("批量审核失败,视频ID: {}", videoId, e); + // 继续处理下一个,不中断批量操作 + } } - // 更新为无需审核状态 - int result = videoMapper.updateAuditStatus(videoId, - "4", // 4-无需审核 - "用户取消审核", - null, - new Date()); - return result > 0; + return successCount; } @Override - @Transactional - public boolean resubmitForAudit(Long videoId, Long userId) { - VetTrainingVideo video = videoMapper.selectVideoById(videoId); - - if (video == null || !userId.equals(video.getUserId())) { - return false; + @Transactional(rollbackFor = Exception.class) + public int batchPublishVideo(List videoIds, Long userId) { + int successCount = 0; + + for (Long videoId : videoIds) { + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + + if (video == null) { + logger.warn("视频不存在,ID: {}", videoId); + continue; + } + + // 验证权限:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + logger.warn("用户 {} 无权限操作视频 {}", userId, videoId); + continue; + } + + // 状态验证:只有审核通过且未上架的视频才能上架 + if (!"2".equals(video.getAuditStatus())) { + logger.warn("视频 {} 未通过审核,当前审核状态: {}", videoId, video.getAuditStatus()); + continue; + } + + if ("1".equals(video.getStatus())) { + logger.warn("视频 {} 已上架", videoId); + continue; + } + + // 更新为上架状态 + video.setStatus("1"); // 已上架 + video.setUpdateTime(DateUtils.getNowDate()); + + int result = vetTrainingVideoMapper.updateVetTrainingVideo(video); + if (result > 0) { + successCount++; + } + + } catch (Exception e) { + logger.error("批量上架失败,视频ID: {}", videoId, e); + // 继续处理下一个,不中断批量操作 + } } - // 只能重新提交审核拒绝状态的视频 - if (!"3".equals(video.getAuditStatus())) { // 2-审核拒绝 - return false; + return successCount; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int batchOfflineVideo(List videoIds, Long userId) { + int successCount = 0; + + for (Long videoId : videoIds) { + try { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + + if (video == null) { + logger.warn("视频不存在,ID: {}", videoId); + continue; + } + + // 验证权限:只能操作自己的视频 + if (!userId.equals(video.getUserId())) { + logger.warn("用户 {} 无权限操作视频 {}", userId, videoId); + continue; + } + + // 状态验证:只有已上架的视频才能下架 + if (!"1".equals(video.getStatus())) { + logger.warn("视频 {} 未上架,当前状态: {}", videoId, video.getStatus()); + continue; + } + + // 更新为下架状态 + video.setStatus("0"); // 已下架 + video.setUpdateTime(DateUtils.getNowDate()); + + int result = vetTrainingVideoMapper.updateVetTrainingVideo(video); + if (result > 0) { + successCount++; + } + + } catch (Exception e) { + logger.error("批量下架失败,视频ID: {}", videoId, e); + // 继续处理下一个,不中断批量操作 + } } - // 更新为待审核状态 - int result = videoMapper.updateAuditStatus(videoId, - "0", // 0-待审核 - "重新提交审核", - null, - new Date()); - return result > 0; + return successCount; } @Override - @Transactional public boolean auditVideo(Long videoId, String auditStatus, String auditOpinion, Long auditUserId) { - // 验证审核状态 - if (!"2".equals(auditStatus) && // 2-审核通过 - !"3".equals(auditStatus)) { // 3-审核拒绝 - return false; - } + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); - - VetTrainingVideo video = videoMapper.selectVideoById(videoId); if (video == null) { - return false; + throw new RuntimeException("视频不存在"); } - if (!"1".equals(video.getAuditStatus())) { // 1-审核中 - return false; + // 只有待审核状态才能审核 + if (!"0".equals(video.getAuditStatus())) { + throw new RuntimeException("当前状态不能审核"); } - - int result = videoMapper.updateAuditStatus(videoId, - auditStatus, - auditOpinion, - auditUserId, - new Date()); - - // 如果审核通过,自动设置为私有状态,等待用户上架 - if (result > 0 && "2".equals(auditStatus)) { // 1-审核通过 - videoMapper.updateStatus(videoId, "0"); // 0-未上架/私有 + // 审核拒绝时必须填写审核意见 + if ("2".equals(auditStatus) && (auditOpinion == null || auditOpinion.trim().isEmpty())) { + throw new RuntimeException("审核拒绝时必须填写审核意见"); } - return result > 0; + // 更新审核信息 + video.setAuditStatus(auditStatus); + video.setAuditOpinion(auditOpinion); + video.setAuditUserId(auditUserId); + video.setAuditTime(DateUtils.getNowDate()); + video.setUpdateTime(DateUtils.getNowDate()); + + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; } @Override - @Transactional public boolean publishVideo(Long videoId, Long userId) { - VetTrainingVideo video = videoMapper.selectVideoById(videoId); + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); if (video == null) { - return false; + throw new RuntimeException("视频不存在"); } - // 权限校验:只能操作自己的视频 - if (!userId.equals(video.getUserId())) { - return false; +// // 验证权限:只能操作自己的视频 +// if (!userId.equals(video.getUserId())) { +// throw new RuntimeException("无权操作此视频"); +// } + + // 状态验证:只有审核通过且未上架的视频才能上架 + if (!"1".equals(video.getAuditStatus())) { + throw new RuntimeException("只有审核通过的视频才能上架"); } - // 只能上架审核通过的视频 - if (!"2".equals(video.getAuditStatus())) { // 1-审核通过 - return false; + if ("1".equals(video.getStatus())) { + throw new RuntimeException("视频已上架"); } - return videoMapper.updateStatus(videoId, "1") > 0; // 1-已上架/公开 + // 更新为上架状态 + video.setStatus("1"); // 已上架 + video.setUpdateTime(DateUtils.getNowDate()); + + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; } @Override - @Transactional public boolean offlineVideo(Long videoId, Long userId) { - VetTrainingVideo video = videoMapper.selectVideoById(videoId); + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); if (video == null) { - return false; + throw new RuntimeException("视频不存在"); } - // 权限校验:只能操作自己的视频 + // 验证权限:只能操作自己的视频 if (!userId.equals(video.getUserId())) { - return false; + throw new RuntimeException("无权操作此视频"); } - // 只能下架已上架的视频 - if (!"1".equals(video.getStatus())) { // 1-已上架/公开 - return false; + // 状态验证:只有已上架的视频才能下架 + if (!"1".equals(video.getStatus())) { + throw new RuntimeException("只有已上架的视频才能下架"); } - return videoMapper.updateStatus(videoId, "0") > 0; // 0-未上架/私有 + // 更新为下架状态 + video.setStatus("0"); // 已下架 + video.setUpdateTime(DateUtils.getNowDate()); + + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; } @Override - public List getPendingAuditVideos(String title, String userName) { - return videoMapper.selectPendingAuditVideos(title, userName); + public boolean submitForAudit(Long videoId, Long userId) { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); + + if (video == null) { + throw new RuntimeException("视频不存在"); + } + + // ============ 注意:这里移除了权限检查 ============ + // 原来的权限检查代码删除了: + // if (!userId.equals(video.getUserId())) { + // throw new RuntimeException("无权操作此视频"); + // } + // ================================================= + + // 状态验证:只有审核拒绝或无需审核状态才能提交审核 + String auditStatus = video.getAuditStatus(); + if (!"2".equals(auditStatus) && !"3".equals(auditStatus)) { + throw new RuntimeException("当前状态不能提交审核"); + } + + // 更新为待审核状态 + video.setAuditStatus("0"); // 待审核 + video.setUpdateTime(DateUtils.getNowDate()); + + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; } @Override - @Transactional - public boolean updateVideoInfo(Long videoId, VetTrainingVideo video, Long userId) { - VetTrainingVideo existingVideo = videoMapper.selectVideoById(videoId); + @Transactional(rollbackFor = Exception.class) + public boolean cancelAudit(Long videoId, Long userId) { + VetTrainingVideo video = vetTrainingVideoMapper.selectVetTrainingVideoById(videoId); - if (existingVideo == null || !userId.equals(existingVideo.getUserId())) { - return false; + if (video == null) { + throw new RuntimeException("视频不存在"); } - // 只能编辑无需审核、审核拒绝或私有状态的视频 - boolean canEdit = "4".equals(existingVideo.getAuditStatus()) || // 4-无需审核 - "3".equals(existingVideo.getAuditStatus()) || // 3-审核拒绝 - "0".equals(existingVideo.getStatus()); // 0-未上架/私有 - - if (!canEdit) { - return false; + // 状态验证:只有待审核状态才能取消审核 + if (!"0".equals(video.getAuditStatus())) { + throw new RuntimeException("只有待审核状态才能取消审核"); } - // 更新视频信息 - existingVideo.setTitle(video.getTitle()); - existingVideo.setDescription(video.getDescription()); - existingVideo.setCategory(video.getCategory()); - existingVideo.setUpdateTime(new Date()); + // 更新为无需审核状态 + video.setAuditStatus("3"); // 无需审核 + video.setUpdateTime(DateUtils.getNowDate()); - return videoMapper.updateVideoInfo(existingVideo) > 0; + return vetTrainingVideoMapper.updateVetTrainingVideo(video) > 0; } - private String getFileExtension(String fileName) { - if (fileName == null || fileName.lastIndexOf(".") == -1) { - return "mp4"; - } - return fileName.substring(fileName.lastIndexOf(".") + 1); + /** + * 检查用户是否是管理员 + */ + private boolean checkUserIsAdmin(Long userId) { + // 这里需要根据你的权限系统来实现 + // 例如:查询用户角色 + // 暂时返回false,你需要根据实际情况实现 + return false; } - private int getVideoDuration(MultipartFile videoFile) { - // 这里需要实现获取视频时长的方法 - return 60; // 默认60秒 + @Override + public boolean resubmitForAudit(Long videoId, Long userId) { + // 重新提交审核和提交审核逻辑相同 + return submitForAudit(videoId, userId); + } + + /** + * 查询公开视频列表(已上架且已审核通过) + */ + @Override + public List selectPublicVideoList(VetTrainingVideo vetTrainingVideo) { + // 设置强制条件:已上架且审核通过 + vetTrainingVideo.setStatus("1"); // 已上架 + vetTrainingVideo.setAuditStatus("1"); // 审核通过 + vetTrainingVideo.setDelFlag("0"); // 未删除 + + return vetTrainingVideoMapper.selectPublicVideoList(vetTrainingVideo); + } + + /** + * 分页查询公开视频列表(已上架且已审核通过) + */ + @Override + public List selectPublicVideoPageList(VetTrainingVideo vetTrainingVideo) { + // 设置强制条件:已上架且审核通过 + vetTrainingVideo.setStatus("1"); // 已上架 + vetTrainingVideo.setAuditStatus("1"); // 审核通过 + vetTrainingVideo.setDelFlag("0"); // 未删除 + + return vetTrainingVideoMapper.selectVetTrainingVideoList(vetTrainingVideo); } -} \ No newline at end of file +} diff --git a/chenhai-system/src/main/resources/mapper/system/SysAnswersMapper.xml b/chenhai-system/src/main/resources/mapper/system/SysAnswersMapper.xml new file mode 100644 index 0000000..619b626 --- /dev/null +++ b/chenhai-system/src/main/resources/mapper/system/SysAnswersMapper.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + select + a.id, + a.question_id, + a.user_id, + a.username, + u.nick_name, + u.avatar, + a.content, + a.created_at, + a.updated_at + from sys_answers a + left join sys_user u on a.user_id = u.user_id + + + + + + + + insert into sys_answers + + question_id, + user_id, + username, + nick_name, + avatar, + content, + created_at, + + + #{questionId}, + #{userId}, + #{username}, + #{nickName}, + #{avatar}, + #{content}, + sysdate(), + + + + + update sys_answers + + question_id = #{questionId}, + user_id = #{userId}, + username = #{username}, + nick_name = #{nickName}, + avatar = #{avatar}, + content = #{content}, + updated_at = sysdate(), + + where id = #{id} + + + + delete from sys_answers where id = #{id} + + + + delete from sys_answers where id in + + #{id} + + + + + delete from sys_answers where question_id = #{questionId} + + + + \ No newline at end of file diff --git a/chenhai-system/src/main/resources/mapper/system/SysPolicyInterpretationMapper.xml b/chenhai-system/src/main/resources/mapper/system/SysPolicyInterpretationMapper.xml index 41d2a24..8b30205 100644 --- a/chenhai-system/src/main/resources/mapper/system/SysPolicyInterpretationMapper.xml +++ b/chenhai-system/src/main/resources/mapper/system/SysPolicyInterpretationMapper.xml @@ -37,6 +37,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and publish_status = #{publishStatus} and removal_reason = #{removalReason} and policy_category = #{policyCategory} + + + and ( + title like concat('%', #{searchKey}, '%') + or content like concat('%', #{searchKey}, '%') + or issuing_agency like concat('%', #{searchKey}, '%') + or remark like concat('%', #{searchKey}, '%') + ) + @@ -169,6 +178,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and issuing_agency like concat('%', #{issuingAgency}, '%') and content like concat('%', #{content}, '%') and policy_category = #{policyCategory} + + + and ( + title like concat('%', #{searchKey}, '%') + or content like concat('%', #{searchKey}, '%') + or issuing_agency like concat('%', #{searchKey}, '%') + or remark like concat('%', #{searchKey}, '%') + or policy_category like concat('%', #{searchKey}, '%') + ) + \ No newline at end of file diff --git a/chenhai-system/src/main/resources/mapper/system/SysQuestionsMapper.xml b/chenhai-system/src/main/resources/mapper/system/SysQuestionsMapper.xml new file mode 100644 index 0000000..51c4cf6 --- /dev/null +++ b/chenhai-system/src/main/resources/mapper/system/SysQuestionsMapper.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + SELECT + q.id, + q.user_id, + u.user_name as username, + u.nick_name, + u.avatar, + q.title, + q.content, + q.tags, + q.answer_count, + q.created_at, + q.updated_at + FROM sys_questions q + LEFT JOIN sys_user u ON q.user_id = u.user_id + + + + + + + + insert into sys_questions + + user_id, + username, + title, + content, + tags, + answer_count, + created_at, + updated_at, + + + #{userId}, + #{username}, + #{title}, + #{content}, + #{tags}, + #{answerCount}, + #{createdAt}, + #{updatedAt}, + + + + + update sys_questions + + user_id = #{userId}, + username = #{username}, + title = #{title}, + content = #{content}, + tags = #{tags}, + answer_count = #{answerCount}, + created_at = #{createdAt}, + updated_at = #{updatedAt}, + + where id = #{id} + + + + delete from sys_questions where id = #{id} + + + + delete from sys_questions where id in + + #{id} + + + + + + update sys_questions + set answer_count = answer_count + 1, + updated_at = sysdate() + where id = #{questionId} + + + + + update sys_questions + set answer_count = case + when answer_count > 0 then answer_count - 1 + else 0 + end, + updated_at = sysdate() + where id = #{questionId} + + + + + update sys_questions q + set q.answer_count = ( + select count(*) from sys_answers a + where a.question_id = q.id and a.deleted = 0 + ), + q.updated_at = sysdate() + where q.id = #{questionId} + + + + + \ 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 fe8545f..0d5971e 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml @@ -75,6 +75,15 @@ and expert_id = #{expertId} and cover_image = #{coverImage} and subtitle like concat('%', #{subtitle}, '%') + + + and ( + vk.title like concat('%', #{searchKey}, '%') + or vk.content like concat('%', #{searchKey}, '%') + or vk.subtitle like concat('%', #{searchKey}, '%') + or ve.real_name like concat('%', #{searchKey}, '%') + ) + diff --git a/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml b/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml index 19af370..5558422 100644 --- a/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml +++ b/chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml @@ -1,160 +1,244 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - INSERT INTO vet_training_video ( - 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}, #{auditStatus}, #{auditOpinion}, - #{createTime}, #{updateTime} - ) - - - + - - + + + + and v.user_id = #{userId} + + + and v.title like #{titleLike} + + + + and v.description like #{descriptionLike} + + and v.video_url = #{videoUrl} + and v.cover_image = #{coverImage} + and v.category = #{category} + + + and v.tags like #{tagsLike} + + and v.duration = #{duration} + and v.file_size = #{fileSize} + and v.view_count = #{viewCount} + and v.status = #{status} + and v.del_flag = #{delFlag} + and v.audit_status = #{auditStatus} + + + and v.audit_opinion like #{opinionLike} + + and v.audit_user_id = #{auditUserId} + and v.audit_time = #{auditTime} + + + and u.nick_name like #{publisherLike} + + + + + and ( + v.title like #{searchKeyLike} + or v.description like #{searchKeyLike} + or v.tags like #{searchKeyLike} + or v.category like #{searchKeyLike} + or u.nick_name like #{searchKeyLike} + ) + + and v.publish_time = #{publishTime} + - - - UPDATE vet_training_video - SET view_count = view_count + 1 - WHERE id = #{id} - - - + + where id = #{id} - + + 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, + del_flag, + audit_status, + audit_opinion, + audit_user_id, + audit_time, + publish_time, + + + #{userId}, + #{title}, + #{description}, + #{videoUrl}, + #{coverImage}, + #{category}, + #{tags}, + #{duration}, + #{fileSize}, + #{viewCount}, + #{status}, + #{createTime}, + #{updateTime}, + #{delFlag}, + #{auditStatus}, + #{auditOpinion}, + #{auditUserId}, + #{auditTime}, + #{publishTime}, + + - - DELETE FROM vet_training_video - WHERE id = #{id} + + update vet_training_video + + user_id = #{userId}, + title = #{title}, + description = #{description}, + video_url = #{videoUrl}, + cover_image = #{coverImage}, + category = #{category}, + tags = #{tags}, + duration = #{duration}, + file_size = #{fileSize}, + view_count = #{viewCount}, + status = #{status}, + create_time = #{createTime}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + audit_status = #{auditStatus}, + audit_opinion = #{auditOpinion}, + audit_user_id = #{auditUserId}, + audit_time = #{auditTime}, + publish_time = #{publishTime}, + + where id = #{id} + + + + 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} - + + delete from vet_training_video where id in + + #{id} + + - - UPDATE vet_training_video - SET status = #{status}, - update_time = NOW() - WHERE id = #{id} - + + - SELECT v.*, u.nick_name as user_name,u.avatar as user_avatar - FROM vet_training_video v - LEFT JOIN sys_user u ON v.user_id = u.user_id - WHERE v.audit_status = '0' - - AND v.title LIKE CONCAT('%', #{title}, '%') - - - AND u.nick_name LIKE CONCAT('%', #{userName}, '%') - - ORDER BY v.create_time DESC + + and v.user_id = #{userId} + + + and v.title like #{titleLike} + + + + and v.description like #{descriptionLike} + + and v.category = #{category} + + + and v.tags like #{tagsLike} + + + + and u.nick_name like #{publisherLike} + + + + + and ( + v.title like #{searchKeyLike} + or v.description like #{searchKeyLike} + or v.tags like #{searchKeyLike} + or v.category like #{searchKeyLike} + or u.nick_name like #{searchKeyLike} + ) + + and v.publish_time = #{publishTime} + + + order by v.create_time desc - - - 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/system/answers.js b/chenhai-ui/src/api/system/answers.js new file mode 100644 index 0000000..a3e7de1 --- /dev/null +++ b/chenhai-ui/src/api/system/answers.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询答复列表 +export function listAnswers(query) { + return request({ + url: '/system/answers/list', + method: 'get', + params: query + }) +} + +// 查询答复详细 +export function getAnswers(id) { + return request({ + url: '/system/answers/' + id, + method: 'get' + }) +} + +// 新增答复 +export function addAnswers(data) { + return request({ + url: '/system/answers', + method: 'post', + data: data + }) +} + +// 修改答复 +export function updateAnswers(data) { + return request({ + url: '/system/answers', + method: 'put', + data: data + }) +} + +// 删除答复 +export function delAnswers(id) { + return request({ + url: '/system/answers/' + id, + method: 'delete' + }) +} diff --git a/chenhai-ui/src/api/system/questions.js b/chenhai-ui/src/api/system/questions.js new file mode 100644 index 0000000..5110541 --- /dev/null +++ b/chenhai-ui/src/api/system/questions.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询问答列表 +export function listQuestions(query) { + return request({ + url: '/system/questions/list', + method: 'get', + params: query + }) +} + +// 查询问答详细 +export function getQuestions(id) { + return request({ + url: '/system/questions/' + id, + method: 'get' + }) +} + +// 新增问答 +export function addQuestions(data) { + return request({ + url: '/system/questions', + method: 'post', + data: data + }) +} + +// 修改问答 +export function updateQuestions(data) { + return request({ + url: '/system/questions', + method: 'put', + data: data + }) +} + +// 删除问答 +export function delQuestions(id) { + return request({ + url: '/system/questions/' + id, + method: 'delete' + }) +} diff --git a/chenhai-ui/src/api/vet/training.js b/chenhai-ui/src/api/vet/training.js index 3b25112..c09b9a0 100644 --- a/chenhai-ui/src/api/vet/training.js +++ b/chenhai-ui/src/api/vet/training.js @@ -1,125 +1,154 @@ -// trainingApi.js - 完整修正版 import request from '@/utils/request' -export default { - // 上传视频 - uploadVideo(data) { - return request({ - url: '/vet/training/upload', - method: 'post', - data: data, - headers: { - 'Content-Type': 'multipart/form-data' - }, - timeout: 300000 - }) - }, - - // 获取公开视频列表 - getPublicVideos(params) { - return request({ - url: '/vet/training/public-videos', - method: 'get', - params: params - }) - }, - - // 获取我的视频 - getMyVideos(params) { - return request({ - url: '/vet/training/my-videos', - method: 'get', - params: params - }) - }, - - // 获取视频详情 - getVideoDetail(id) { - return request({ - url: `/vet/training/video/${id}`, - method: 'get' - }) - }, - - // 提交审核(用户提交给管理员) - submitForAudit(videoId) { - return request({ - url: `/vet/training/submit-audit/${videoId}`, - method: 'post' - }) - }, - - // 取消审核 - cancelAudit(videoId) { - return request({ - url: `/vet/training/cancel-audit/${videoId}`, - method: 'post' - }) - }, - - // 重新提交审核 - resubmitAudit(videoId) { - return request({ - url: `/vet/training/resubmit-audit/${videoId}`, - method: 'post' - }) - }, - // 审核视频(管理员审核) - auditVideo(videoId, auditStatus, auditOpinion = '') { - // 改用JSON方式传递参数 - const data = { - auditStatus: auditStatus, - auditOpinion: auditOpinion || '' +// 查询兽医培训视频列表 +export function listTraining(query) { + return request({ + url: '/vet/training/list', + method: 'get', + params: query + }) +} + +// 查询兽医培训视频详细 +export function getTraining(id) { + return request({ + url: '/vet/training/' + id, + method: 'get' + }) +} + +// 新增兽医培训视频 +export function addTraining(data) { + return request({ + url: '/vet/training', + method: 'post', + data: data + }) +} + +// 修改兽医培训视频 +export function updateTraining(data) { + return request({ + url: '/vet/training', + method: 'put', + data: data + }) +} + +// 删除兽医培训视频 +export function delTraining(id) { + return request({ + url: '/vet/training/' + id, + method: 'delete' + }) +} + +// 上传视频文件 +export function uploadVideo(data) { + return request({ + url: '/vet/training/uploadVideo', + method: 'post', + data: data, + headers: { + 'Content-Type': 'multipart/form-data' } + }) +} + +// ============ 已有的其他接口(如果存在的话) ============ + +// 提交审核 +export function submitForAudit(id) { + return request({ + url: `/vet/training/submit-audit/${id}`, + method: 'post' + }) +} + +// 取消审核 +export function cancelAudit(id) { + return request({ + url: `/vet/training/cancel-audit/${id}`, + method: 'post' + }) +} + +// 重新提交审核 +export function resubmitForAudit(id) { + return request({ + url: `/vet/training/resubmit-audit/${id}`, + method: 'post' + }) +} + +// 审核视频 - 修改为接收一个对象参数 +export function auditVideo(data) { + return request({ + url: `/vet/training/audit/${data.id}`, + method: 'post', + data: { + auditStatus: data.auditStatus, + auditOpinion: data.auditOpinion + } + }) +} + +// 上架视频 +export function publishVideo(id) { + return request({ + url: `/vet/training/publish/${id}`, + method: 'post' + }) +} + +// 下架视频 +export function offlineVideo(id) { + return request({ + url: `/vet/training/offline/${id}`, + method: 'post' + }) +} + +// 获取我的视频 +export function getMyVideos(query) { + return request({ + url: '/vet/training/list/my', // 改为这个路径 + method: 'get', + params: query + }) +} + +// 获取公开视频 +export function getPublicVideos(query) { + return request({ + url: '/vet/training/list/public', // 改为这个路径 + method: 'get', + params: query + }) +} + +// 获取待审核视频 +export function getPendingAuditVideos(query) { + return request({ + url: '/vet/training/pending-audit', + method: 'get', + params: query + }) +} + +// 获取视频详情 +export function getVideoDetail(videoId) { + return request({ + url: `/vet/training/video/${videoId}`, + method: 'get' + }) +} - 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' - }) - }, - - // 获取待审核视频列表 - getPendingAuditVideos(params) { - return request({ - url: '/vet/training/pending-audit', - method: 'get', - 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' - }) - } +// 更新视频信息 +export function updateVideoInfo(videoId, data) { + return request({ + url: `/vet/training/update/${videoId}`, + method: 'put', + data: data + }) } diff --git a/chenhai-ui/src/views/system/answers/index.vue b/chenhai-ui/src/views/system/answers/index.vue new file mode 100644 index 0000000..e6236f1 --- /dev/null +++ b/chenhai-ui/src/views/system/answers/index.vue @@ -0,0 +1,252 @@ + + + diff --git a/chenhai-ui/src/views/system/questions/index.vue b/chenhai-ui/src/views/system/questions/index.vue new file mode 100644 index 0000000..c5e2c4b --- /dev/null +++ b/chenhai-ui/src/views/system/questions/index.vue @@ -0,0 +1,584 @@ + + + + + diff --git a/chenhai-ui/src/views/vet/training/TrainingHome.vue b/chenhai-ui/src/views/vet/training/TrainingHome.vue deleted file mode 100644 index 66d078e..0000000 --- a/chenhai-ui/src/views/vet/training/TrainingHome.vue +++ /dev/null @@ -1,1547 +0,0 @@ - - - - - diff --git a/chenhai-ui/src/views/vet/training/index.vue b/chenhai-ui/src/views/vet/training/index.vue new file mode 100644 index 0000000..431494f --- /dev/null +++ b/chenhai-ui/src/views/vet/training/index.vue @@ -0,0 +1,1120 @@ + + + + +