Browse Source

知识学习功能

master
maotiantian 3 months ago
parent
commit
904a00d420
  1. 657
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/ChatController.java
  2. 275
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysChatMessageController.java
  3. 215
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysChatSessionController.java
  4. 12
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysDictDataController.java
  5. 104
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysExpertConsultationController.java
  6. 104
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysKnowledgeQueryController.java
  7. 4
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysLoginController.java
  8. 104
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysMedicineRecommendationController.java
  9. 27
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysPolicyInterpretationController.java
  10. 104
      chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysQueryTipController.java
  11. 21
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExpertsController.java
  12. 55
      chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java
  13. 163
      chenhai-system/src/main/java/com/chenhai/system/domain/SysChatMessage.java
  14. 194
      chenhai-system/src/main/java/com/chenhai/system/domain/SysChatSession.java
  15. 299
      chenhai-system/src/main/java/com/chenhai/system/domain/SysExpertConsultation.java
  16. 130
      chenhai-system/src/main/java/com/chenhai/system/domain/SysKnowledgeQuery.java
  17. 531
      chenhai-system/src/main/java/com/chenhai/system/domain/SysMedicineRecommendation.java
  18. 15
      chenhai-system/src/main/java/com/chenhai/system/domain/SysPolicyInterpretation.java
  19. 67
      chenhai-system/src/main/java/com/chenhai/system/domain/SysQueryTip.java
  20. 61
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysChatMessageMapper.java
  21. 61
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysChatSessionMapper.java
  22. 61
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysExpertConsultationMapper.java
  23. 61
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysKnowledgeQueryMapper.java
  24. 72
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysMedicineRecommendationMapper.java
  25. 8
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysPolicyInterpretationMapper.java
  26. 61
      chenhai-system/src/main/java/com/chenhai/system/mapper/SysQueryTipMapper.java
  27. 87
      chenhai-system/src/main/java/com/chenhai/system/service/ISysChatMessageService.java
  28. 102
      chenhai-system/src/main/java/com/chenhai/system/service/ISysChatSessionService.java
  29. 61
      chenhai-system/src/main/java/com/chenhai/system/service/ISysExpertConsultationService.java
  30. 61
      chenhai-system/src/main/java/com/chenhai/system/service/ISysKnowledgeQueryService.java
  31. 61
      chenhai-system/src/main/java/com/chenhai/system/service/ISysMedicineRecommendationService.java
  32. 8
      chenhai-system/src/main/java/com/chenhai/system/service/ISysPolicyInterpretationService.java
  33. 61
      chenhai-system/src/main/java/com/chenhai/system/service/ISysQueryTipService.java
  34. 207
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysChatMessageServiceImpl.java
  35. 207
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysChatSessionServiceImpl.java
  36. 93
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysExpertConsultationServiceImpl.java
  37. 93
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysKnowledgeQueryServiceImpl.java
  38. 93
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysMedicineRecommendationServiceImpl.java
  39. 16
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysPolicyInterpretationServiceImpl.java
  40. 93
      chenhai-system/src/main/java/com/chenhai/system/service/impl/SysQueryTipServiceImpl.java
  41. 15
      chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperts.java
  42. 91
      chenhai-system/src/main/java/com/chenhai/vet/domain/VetKnowledge.java
  43. 9
      chenhai-system/src/main/java/com/chenhai/vet/domain/VetTrainingVideo.java
  44. 13
      chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExpertsMapper.java
  45. 17
      chenhai-system/src/main/java/com/chenhai/vet/mapper/VetKnowledgeMapper.java
  46. 8
      chenhai-system/src/main/java/com/chenhai/vet/service/IVetExpertsService.java
  47. 17
      chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java
  48. 1
      chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java
  49. 158
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExpertsServiceImpl.java
  50. 37
      chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java
  51. 106
      chenhai-system/src/main/resources/mapper/system/SysChatMessageMapper.xml
  52. 122
      chenhai-system/src/main/resources/mapper/system/SysChatSessionMapper.xml
  53. 136
      chenhai-system/src/main/resources/mapper/system/SysExpertConsultationMapper.xml
  54. 85
      chenhai-system/src/main/resources/mapper/system/SysKnowledgeQueryMapper.xml
  55. 277
      chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml
  56. 22
      chenhai-system/src/main/resources/mapper/system/SysPolicyInterpretationMapper.xml
  57. 63
      chenhai-system/src/main/resources/mapper/system/SysQueryTipMapper.xml
  58. 34
      chenhai-system/src/main/resources/mapper/vet/VetExpertsMapper.xml
  59. 59
      chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml
  60. 13
      chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml
  61. 72
      chenhai-ui/src/api/system/chat.js
  62. 44
      chenhai-ui/src/api/system/consultation.js
  63. 44
      chenhai-ui/src/api/system/message.js
  64. 44
      chenhai-ui/src/api/system/query.js
  65. 44
      chenhai-ui/src/api/system/recommendation.js
  66. 44
      chenhai-ui/src/api/system/session.js
  67. 44
      chenhai-ui/src/api/system/tip.js
  68. 68
      chenhai-ui/src/router/index.js
  69. 1178
      chenhai-ui/src/views/chat/expert.vue
  70. 1353
      chenhai-ui/src/views/chat/index.vue
  71. 460
      chenhai-ui/src/views/system/consultation/index.vue
  72. 20
      chenhai-ui/src/views/system/interpretation/index.vue
  73. 328
      chenhai-ui/src/views/system/message/index.vue
  74. 286
      chenhai-ui/src/views/system/query/index.vue
  75. 1012
      chenhai-ui/src/views/system/recommendation/index.vue
  76. 347
      chenhai-ui/src/views/system/session/index.vue
  77. 246
      chenhai-ui/src/views/system/tip/index.vue
  78. 124
      chenhai-ui/src/views/vet/experts/index.vue
  79. 79
      chenhai-ui/src/views/vet/knowledge/index.vue
  80. 147
      chenhai-ui/src/views/vet/training/TrainingHome.vue

657
chenhai-admin/src/main/java/com/chenhai/web/controller/system/ChatController.java

@ -0,0 +1,657 @@
//package com.chenhai.system.controller;
//
//import java.util.*;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//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.utils.SecurityUtils;
//import com.chenhai.system.domain.SysChatMessage;
//import com.chenhai.system.domain.SysChatSession;
//import com.chenhai.system.service.ISysChatMessageService;
//import com.chenhai.system.service.ISysChatSessionService;
//import com.chenhai.vet.domain.VetExperts;
//import com.chenhai.vet.service.IVetExpertsService;
//
//@RestController
//@RequestMapping("/system/chat")
//public class ChatController extends BaseController {
//
// @Autowired
// private IVetExpertsService expertsService;
//
// @Autowired
// private ISysChatSessionService sessionService;
//
// @Autowired
// private ISysChatMessageService messageService;
//
// /**
// * 获取当前用户身份基于权限判断
// */
// @GetMapping("/identity")
// public AjaxResult getIdentity() {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// Map<String, Object> result = new HashMap<>();
//
// // 检查用户权限
// boolean isExpertRole = SecurityUtils.hasPermi("vet:experts:list");
// boolean isMuhuRole = SecurityUtils.hasPermi("system:notice:list"); // 假设牧户有这个权限
//
// // 或者使用角色检查如果您的系统使用角色
// // boolean isExpertRole = SecurityUtils.hasRole("vetnotshenhe");
// // boolean isMuhuRole = SecurityUtils.hasRole("muhu");
//
// // 判断是否是专家
// List<VetExperts> experts = expertsService.selectVetExpertsList(null);
// VetExperts currentExpert = null;
// for (VetExperts expert : experts) {
// if (expert.getUserId() != null && expert.getUserId().equals(loginUser.getUserId())) {
// currentExpert = expert;
// break;
// }
// }
//
// if (currentExpert != null) {
// // 是专家
// result.put("userType", "expert");
// result.put("expertId", currentExpert.getExpertId());
// result.put("expertName", currentExpert.getRealName());
// result.put("expertAvatar", currentExpert.getAvatar());
// result.put("isOnline", currentExpert.getIsOnline());
// } else if (isMuhuRole) {
// // 是牧户
// result.put("userType", "user");
// result.put("userId", loginUser.getUserId());
// result.put("userName", loginUser.getUsername());
// } else {
// // 其他用户
// result.put("userType", "unknown");
// }
//
// return AjaxResult.success(result);
//
// } catch (Exception e) {
// logger.error("获取用户身份失败", e);
// return AjaxResult.error("获取失败");
// }
// }
//
// /**
// * 获取在线专家列表牧户端使用
// */
// @GetMapping("/experts")
// public AjaxResult getOnlineExperts() {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// // 查询所有在线专家
// VetExperts query = new VetExperts();
// query.setStatus("0"); // 只查询状态正常的专家
// List<VetExperts> allExperts = expertsService.selectVetExpertsList(query);
//
// List<Map<String, Object>> result = new ArrayList<>();
//
// for (VetExperts expert : allExperts) {
// Map<String, Object> expertMap = new HashMap<>();
// expertMap.put("expertId", expert.getExpertId());
// expertMap.put("realName", expert.getRealName());
// expertMap.put("title", expert.getTitle());
// expertMap.put("avatar", expert.getAvatar());
// expertMap.put("expertiseArea", expert.getExpertiseArea());
// expertMap.put("isOnline", "1".equals(expert.getIsOnline()) ? "在线" : "离线");
// expertMap.put("introduction", expert.getIntroduction());
// expertMap.put("workExperience", expert.getWorkExperience());
//
// // 获取未读数牧户视角
// SysChatSession querySession = new SysChatSession();
// querySession.setUserId(loginUser.getUserId());
// querySession.setExpertId(expert.getExpertId());
// querySession.setDelFlag("0");
// List<SysChatSession> sessions = sessionService.selectSysChatSessionList(querySession);
// long unreadCount = 0;
// if (!sessions.isEmpty()) {
// unreadCount = sessions.get(0).getUnreadUser() != null ? sessions.get(0).getUnreadUser() : 0;
// }
// expertMap.put("unreadCount", unreadCount);
//
// result.add(expertMap);
// }
//
// return AjaxResult.success(result);
//
// } catch (Exception e) {
// logger.error("获取专家列表失败", e);
// return AjaxResult.error("获取失败");
// }
// }
//
// /**
// * 获取用户会话列表牧户端使用
// */
// @GetMapping("/sessions")
// public AjaxResult getUserSessions() {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// // 查询用户的所有会话
// SysChatSession query = new SysChatSession();
// query.setUserId(loginUser.getUserId());
// query.setDelFlag("0");
// query.setSessionStatus("0"); // 只查询进行中的会话
// List<SysChatSession> sessions = sessionService.selectSysChatSessionList(query);
//
// List<Map<String, Object>> result = new ArrayList<>();
// for (SysChatSession session : sessions) {
// Map<String, Object> sessionMap = new HashMap<>();
// sessionMap.put("sessionId", session.getSessionId());
// sessionMap.put("expertId", session.getExpertId());
// sessionMap.put("animalType", session.getAnimalType());
// sessionMap.put("symptomSummary", session.getSymptomSummary());
// sessionMap.put("lastMessage", session.getLastMessage());
// sessionMap.put("lastMessageTime", session.getLastMessageTime());
// sessionMap.put("createTime", session.getCreateTime());
// sessionMap.put("unreadCount", session.getUnreadUser() != null ? session.getUnreadUser() : 0);
// sessionMap.put("sessionStatus", session.getSessionStatus());
//
// // 获取专家信息
// VetExperts expert = expertsService.selectVetExpertsByExpertId(session.getExpertId());
// if (expert != null) {
// sessionMap.put("expertName", expert.getRealName());
// sessionMap.put("expertTitle", expert.getTitle());
// sessionMap.put("expertAvatar", expert.getAvatar());
// sessionMap.put("expertIsOnline", expert.getIsOnline());
// }
//
// result.add(sessionMap);
// }
//
// // 按最后消息时间排序
// result.sort((a, b) -> {
// Date timeA = (Date) a.get("lastMessageTime");
// Date timeB = (Date) b.get("lastMessageTime");
// if (timeA == null && timeB == null) return 0;
// if (timeA == null) return 1;
// if (timeB == null) return -1;
// return timeB.compareTo(timeA);
// });
//
// return AjaxResult.success(result);
//
// } catch (Exception e) {
// logger.error("获取用户会话列表失败", e);
// return AjaxResult.error("获取失败");
// }
// }
//
// /**
// * 专家端获取等待回复的会话列表
// */
// @GetMapping("/expert/sessions")
// public AjaxResult getExpertSessions() {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// // 检查是否是专家
// List<VetExperts> experts = expertsService.selectVetExpertsList(null);
// VetExperts currentExpert = null;
// for (VetExperts expert : experts) {
// if (expert.getUserId() != null && expert.getUserId().equals(loginUser.getUserId())) {
// currentExpert = expert;
// break;
// }
// }
//
// if (currentExpert == null) {
// return AjaxResult.error("您不是专家或专家信息未配置");
// }
//
// // 查询该专家的所有会话
// SysChatSession query = new SysChatSession();
// query.setExpertId(currentExpert.getExpertId());
// query.setDelFlag("0");
// query.setSessionStatus("0"); // 只查询进行中的
// List<SysChatSession> sessions = sessionService.selectSysChatSessionList(query);
//
// List<Map<String, Object>> result = new ArrayList<>();
// for (SysChatSession session : sessions) {
// Map<String, Object> sessionMap = new HashMap<>();
// sessionMap.put("sessionId", session.getSessionId());
// sessionMap.put("userId", session.getUserId());
// sessionMap.put("animalType", session.getAnimalType());
// sessionMap.put("symptomSummary", session.getSymptomSummary());
// sessionMap.put("lastMessage", session.getLastMessage());
// sessionMap.put("lastMessageTime", session.getLastMessageTime());
// sessionMap.put("createTime", session.getCreateTime());
// sessionMap.put("unreadCount", session.getUnreadExpert() != null ? session.getUnreadExpert() : 0);
// sessionMap.put("sessionStatus", session.getSessionStatus());
//
// result.add(sessionMap);
// }
//
// // 按最后消息时间排序
// result.sort((a, b) -> {
// Date timeA = (Date) a.get("lastMessageTime");
// Date timeB = (Date) b.get("lastMessageTime");
// if (timeA == null && timeB == null) return 0;
// if (timeA == null) return 1;
// if (timeB == null) return -1;
// return timeB.compareTo(timeA);
// });
//
// return AjaxResult.success(result);
//
// } catch (Exception e) {
// logger.error("获取专家会话列表失败", e);
// return AjaxResult.error("获取失败");
// }
// }
//
// /**
// * 开始咨询创建会话
// */
// @PostMapping("/start")
// public AjaxResult startConsultation(@RequestBody Map<String, Object> params) {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// Long expertId = Long.valueOf(params.get("expertId").toString());
// String animalType = params.get("animalType") != null ? params.get("animalType").toString() : "牛";
// String symptom = params.get("symptom") != null ? params.get("symptom").toString() : "";
//
// // 检查专家是否存在
// VetExperts expert = expertsService.selectVetExpertsByExpertId(expertId);
// if (expert == null) {
// return AjaxResult.error("专家不存在");
// }
//
// // 创建会话
// String sessionId = sessionService.createOrGetSession(loginUser.getUserId(), expertId, animalType, symptom);
//
// // 发送欢迎消息
// String welcomeMessage = "您好,我是" + expert.getRealName() + "专家,有什么可以帮您?";
// messageService.sendTextMessage(sessionId, "1", expertId, welcomeMessage);
//
// Map<String, Object> result = new HashMap<>();
// result.put("sessionId", sessionId);
// result.put("expert", expert);
// result.put("message", welcomeMessage);
//
// return AjaxResult.success("咨询开始", result);
//
// } catch (Exception e) {
// logger.error("开始咨询失败", e);
// return AjaxResult.error("开始咨询失败");
// }
// }
//
// /**
// * 发送消息通用根据身份自动判断
// */
// @PostMapping("/send")
// public AjaxResult sendMessage(@RequestBody Map<String, Object> params) {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// String sessionId = params.get("sessionId").toString();
// String content = params.get("content").toString();
// String msgType = params.get("msgType") != null ? params.get("msgType").toString() : "text";
//
// // 获取会话
// SysChatSession session = sessionService.selectSysChatSessionBySessionId(sessionId);
// if (session == null) {
// return AjaxResult.error("会话不存在");
// }
//
// // 判断发送者身份
// String senderType;
// Long senderId;
//
// // 检查是否是专家
// List<VetExperts> experts = expertsService.selectVetExpertsList(null);
// VetExperts currentExpert = null;
// for (VetExperts expert : experts) {
// if (expert.getUserId() != null && expert.getUserId().equals(loginUser.getUserId())) {
// currentExpert = expert;
// break;
// }
// }
//
// if (currentExpert != null && currentExpert.getExpertId().equals(session.getExpertId())) {
// // 专家回复
// senderType = "1";
// senderId = currentExpert.getExpertId();
// } else if (session.getUserId().equals(loginUser.getUserId())) {
// // 用户发送
// senderType = "0";
// senderId = loginUser.getUserId();
// } else {
// return AjaxResult.error("无权发送消息");
// }
//
// // 发送消息
// if ("image".equals(msgType)) {
// messageService.sendImageMessage(sessionId, senderType, senderId, content);
// } else {
// messageService.sendTextMessage(sessionId, senderType, senderId, content);
// }
//
// return AjaxResult.success("发送成功");
//
// } catch (Exception e) {
// logger.error("发送消息失败", e);
// return AjaxResult.error("发送失败");
// }
// }
//
// /**
// * 结束咨询用户端和专家端通用
// */
// @PostMapping("/end")
// public AjaxResult endConsultation(@RequestBody Map<String, Object> params) {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// String sessionId = params.get("sessionId").toString();
// String reason = params.get("reason") != null ? params.get("reason").toString() : "咨询结束";
//
// // 获取会话
// SysChatSession session = sessionService.selectSysChatSessionBySessionId(sessionId);
// if (session == null) {
// return AjaxResult.error("会话不存在");
// }
//
// // 验证权限
// boolean hasPermission = false;
// String endBy = "";
//
// // 检查是否是专家
// List<VetExperts> experts = expertsService.selectVetExpertsList(null);
// VetExperts currentExpert = null;
// for (VetExperts expert : experts) {
// if (expert.getUserId() != null && expert.getUserId().equals(loginUser.getUserId())) {
// currentExpert = expert;
// break;
// }
// }
//
// if (currentExpert != null && currentExpert.getExpertId().equals(session.getExpertId())) {
// // 专家可以结束会话
// hasPermission = true;
// endBy = "expert";
// } else if (session.getUserId().equals(loginUser.getUserId())) {
// // 用户可以结束自己的会话
// hasPermission = true;
// endBy = "user";
// }
//
// if (!hasPermission) {
// return AjaxResult.error("无权结束会话");
// }
//
// // 结束会话
// sessionService.endSession(sessionId, endBy, reason);
//
// // 发送结束消息
// String endMessage = "";
// if ("expert".equals(endBy)) {
// endMessage = "专家已结束本次咨询,感谢您的信任。";
// } else {
// endMessage = "您已结束本次咨询,感谢专家的帮助。";
// }
//
// if (currentExpert != null) {
// messageService.sendSystemMessage(sessionId, "系统通知:" + endMessage);
// }
//
// return AjaxResult.success("咨询已结束");
//
// } catch (Exception e) {
// logger.error("结束咨询失败", e);
// return AjaxResult.error("结束咨询失败");
// }
// }
//
// /**
// * 获取聊天历史通用
// */
// @GetMapping("/history")
// public AjaxResult getChatHistory(@RequestParam String sessionId) {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// // 获取会话
// SysChatSession session = sessionService.selectSysChatSessionBySessionId(sessionId);
// if (session == null) {
// return AjaxResult.error("会话不存在");
// }
//
// // 验证权限用户或专家都可以查看
// boolean hasPermission = false;
//
// // 检查是否是专家
// List<VetExperts> experts = expertsService.selectVetExpertsList(null);
// VetExperts currentExpert = null;
// for (VetExperts expert : experts) {
// if (expert.getUserId() != null && expert.getUserId().equals(loginUser.getUserId())) {
// currentExpert = expert;
// break;
// }
// }
//
// if (currentExpert != null && currentExpert.getExpertId().equals(session.getExpertId())) {
// // 专家可以查看
// hasPermission = true;
// // 标记专家已读
// sessionService.markMessagesAsReadByExpert(sessionId);
// } else if (session.getUserId().equals(loginUser.getUserId())) {
// // 用户可以查看
// hasPermission = true;
// // 标记用户已读
// sessionService.markMessagesAsReadByUser(sessionId);
// }
//
// if (!hasPermission) {
// return AjaxResult.error("无权查看");
// }
//
// // 获取消息
// List<SysChatMessage> messages = messageService.selectMessagesBySessionId(sessionId);
//
// // 格式化消息
// List<Map<String, Object>> formattedMessages = new ArrayList<>();
// for (SysChatMessage msg : messages) {
// Map<String, Object> msgMap = new HashMap<>();
// msgMap.put("id", msg.getMessageId());
// msgMap.put("messageId", msg.getMessageId());
// msgMap.put("senderType", msg.getSenderType());
// msgMap.put("content", msg.getContent());
// msgMap.put("msgType", msg.getMsgType());
// msgMap.put("time", msg.getCreateTime());
// msgMap.put("createTime", msg.getCreateTime());
// msgMap.put("isRead", msg.getIsRead());
// formattedMessages.add(msgMap);
// }
//
// // 获取相关用户信息
// Map<String, Object> userInfo = new HashMap<>();
// if (currentExpert != null && currentExpert.getExpertId().equals(session.getExpertId())) {
// // 专家端获取用户信息
// userInfo.put("type", "user");
// userInfo.put("userId", session.getUserId());
// userInfo.put("userName", session.getUserName());
// } else {
// // 用户端获取专家信息
// VetExperts expert = expertsService.selectVetExpertsByExpertId(session.getExpertId());
// if (expert != null) {
// userInfo.put("type", "expert");
// userInfo.put("expertId", expert.getExpertId());
// userInfo.put("realName", expert.getRealName());
// userInfo.put("title", expert.getTitle());
// userInfo.put("avatar", expert.getAvatar());
// userInfo.put("isOnline", expert.getIsOnline());
// }
// }
//
// Map<String, Object> result = new HashMap<>();
// result.put("session", session);
// result.put("userInfo", userInfo);
// result.put("messages", formattedMessages);
//
// return AjaxResult.success(result);
//
// } catch (Exception e) {
// logger.error("获取聊天历史失败", e);
// return AjaxResult.error("获取失败");
// }
// }
//
// /**
// * 标记消息为已读
// */
// @PostMapping("/read")
// public AjaxResult markAsRead(@RequestBody Map<String, Object> params) {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// String sessionId = params.get("sessionId").toString();
// String messageIds = params.get("messageIds") != null ? params.get("messageIds").toString() : "";
//
// // 获取会话
// SysChatSession session = sessionService.selectSysChatSessionBySessionId(sessionId);
// if (session == null) {
// return AjaxResult.error("会话不存在");
// }
//
// // 验证权限
// boolean hasPermission = false;
// String readerType = "";
//
// // 检查是否是专家
// List<VetExperts> experts = expertsService.selectVetExpertsList(null);
// VetExperts currentExpert = null;
// for (VetExperts expert : experts) {
// if (expert.getUserId() != null && expert.getUserId().equals(loginUser.getUserId())) {
// currentExpert = expert;
// break;
// }
// }
//
// if (currentExpert != null && currentExpert.getExpertId().equals(session.getExpertId())) {
// // 专家标记已读
// hasPermission = true;
// readerType = "expert";
// } else if (session.getUserId().equals(loginUser.getUserId())) {
// // 用户标记已读
// hasPermission = true;
// readerType = "user";
// }
//
// if (!hasPermission) {
// return AjaxResult.error("无权操作");
// }
//
// // 标记已读
// if ("expert".equals(readerType)) {
// messageService.markMessagesAsReadByExpert(sessionId, messageIds);
// } else {
// messageService.markMessagesAsReadByUser(sessionId, messageIds);
// }
//
// return AjaxResult.success("标记已读成功");
//
// } catch (Exception e) {
// logger.error("标记已读失败", e);
// return AjaxResult.error("标记已读失败");
// }
// }
//
// /**
// * 获取未读消息数量
// */
// @GetMapping("/unread/count")
// public AjaxResult getUnreadCount() {
// try {
// LoginUser loginUser = SecurityUtils.getLoginUser();
// if (loginUser == null) {
// return AjaxResult.error("用户未登录");
// }
//
// Map<String, Object> result = new HashMap<>();
//
// // 检查是否是专家
// List<VetExperts> experts = expertsService.selectVetExpertsList(null);
// VetExperts currentExpert = null;
// for (VetExperts expert : experts) {
// if (expert.getUserId() != null && expert.getUserId().equals(loginUser.getUserId())) {
// currentExpert = expert;
// break;
// }
// }
//
// long totalUnread = 0;
// if (currentExpert != null) {
// // 专家获取未读消息数
// SysChatSession query = new SysChatSession();
// query.setExpertId(currentExpert.getExpertId());
// query.setDelFlag("0");
// query.setSessionStatus("0");
// List<SysChatSession> sessions = sessionService.selectSysChatSessionList(query);
//
// for (SysChatSession session : sessions) {
// totalUnread += session.getUnreadExpert() != null ? session.getUnreadExpert() : 0;
// }
// result.put("userType", "expert");
// } else {
// // 用户获取未读消息数
// SysChatSession query = new SysChatSession();
// query.setUserId(loginUser.getUserId());
// query.setDelFlag("0");
// query.setSessionStatus("0");
// List<SysChatSession> sessions = sessionService.selectSysChatSessionList(query);
//
// for (SysChatSession session : sessions) {
// totalUnread += session.getUnreadUser() != null ? session.getUnreadUser() : 0;
// }
// result.put("userType", "user");
// }
//
// result.put("totalUnread", totalUnread);
// return AjaxResult.success(result);
//
// } catch (Exception e) {
// logger.error("获取未读消息数失败", e);
// return AjaxResult.error("获取失败");
// }
// }
//}

275
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysChatMessageController.java

@ -0,0 +1,275 @@
package com.chenhai.web.controller.system;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import com.chenhai.common.utils.SecurityUtils;
import com.chenhai.common.utils.file.FileUploadUtils;
import com.chenhai.system.domain.SysChatSession;
import com.chenhai.system.service.ISysChatSessionService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
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.enums.BusinessType;
import com.chenhai.system.domain.SysChatMessage;
import com.chenhai.system.service.ISysChatMessageService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* 兽医咨询聊天消息Controller
*
* @author ruoyi
* @date 2026-01-19
*/
@RestController
@RequestMapping("/system/message")
public class SysChatMessageController extends BaseController
{
@Autowired
private ISysChatMessageService sysChatMessageService;
@Autowired // 添加这个注入
private ISysChatSessionService sysChatSessionService;
/**
* 查询兽医咨询聊天消息列表
*/
@PreAuthorize("@ss.hasPermi('system:message:list')")
@GetMapping("/list")
public TableDataInfo list(SysChatMessage sysChatMessage)
{
startPage();
List<SysChatMessage> list = sysChatMessageService.selectSysChatMessageList(sysChatMessage);
return getDataTable(list);
}
/**
* 导出兽医咨询聊天消息列表
*/
@PreAuthorize("@ss.hasPermi('system:message:export')")
@Log(title = "兽医咨询聊天消息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysChatMessage sysChatMessage)
{
List<SysChatMessage> list = sysChatMessageService.selectSysChatMessageList(sysChatMessage);
ExcelUtil<SysChatMessage> util = new ExcelUtil<SysChatMessage>(SysChatMessage.class);
util.exportExcel(response, list, "兽医咨询聊天消息数据");
}
/**
* 获取兽医咨询聊天消息详细信息
*/
@PreAuthorize("@ss.hasPermi('system:message:query')")
@GetMapping(value = "/{messageId}")
public AjaxResult getInfo(@PathVariable("messageId") Long messageId)
{
return success(sysChatMessageService.selectSysChatMessageByMessageId(messageId));
}
/**
* 新增兽医咨询聊天消息
*/
@PreAuthorize("@ss.hasPermi('system:message:add')")
@Log(title = "兽医咨询聊天消息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysChatMessage sysChatMessage)
{
return toAjax(sysChatMessageService.insertSysChatMessage(sysChatMessage));
}
/**
* 修改兽医咨询聊天消息
*/
@PreAuthorize("@ss.hasPermi('system:message:edit')")
@Log(title = "兽医咨询聊天消息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysChatMessage sysChatMessage)
{
return toAjax(sysChatMessageService.updateSysChatMessage(sysChatMessage));
}
/**
* 删除兽医咨询聊天消息
*/
@PreAuthorize("@ss.hasPermi('system:message:remove')")
@Log(title = "兽医咨询聊天消息", businessType = BusinessType.DELETE)
@DeleteMapping("/{messageIds}")
public AjaxResult remove(@PathVariable Long[] messageIds)
{
return toAjax(sysChatMessageService.deleteSysChatMessageByMessageIds(messageIds));
}
/**
* 发送文本消息新增
*/
@PostMapping("/send")
public AjaxResult sendMessage(@RequestBody MessageSendRequest request) {
try {
// 验证用户
Long currentUserId = SecurityUtils.getUserId();
// 如果是用户发送验证senderId
if ("0".equals(request.getSenderType()) && !currentUserId.equals(request.getSenderId())) {
return error("用户ID不匹配");
}
// 发送消息
int result = sysChatMessageService.sendTextMessage(
request.getSessionId(),
request.getSenderType(),
request.getSenderId(),
request.getContent()
);
if (result > 0) {
return success("消息发送成功");
} else {
return error("消息发送失败");
}
} catch (Exception e) {
return error("发送消息失败:" + e.getMessage());
}
}
/**
* 获取会话消息新增
*/
@GetMapping("/session/{sessionId}")
public AjaxResult getSessionMessages(@PathVariable String sessionId) {
try {
// 验证权限用户必须是会话的参与者
Long currentUserId = SecurityUtils.getUserId();
List<SysChatMessage> messages = sysChatMessageService.selectMessagesBySessionId(sessionId);
// 过滤返回的消息确保安全性
if (!messages.isEmpty()) {
SysChatMessage firstMessage = messages.get(0);
// 这里应该查询会话信息来验证权限简化处理
}
return success(messages);
} catch (Exception e) {
return error("获取消息失败:" + e.getMessage());
}
}
/**
* 标记所有消息为已读新增
*/
@PostMapping("/markAllRead")
public AjaxResult markAllMessagesAsRead(@RequestBody MarkReadRequest request) {
try {
int count = sysChatMessageService.markAllMessagesAsRead(
request.getSessionId(),
request.getSenderType()
);
return success("已标记" + count + "条消息为已读");
} catch (Exception e) {
return error("标记已读失败:" + e.getMessage());
}
}
/**
* 获取用户未读消息数量新增
*/
@GetMapping("/unreadCount/{userId}")
public AjaxResult getUnreadCount(@PathVariable Long userId) {
try {
// 验证当前用户
Long currentUserId = SecurityUtils.getUserId();
if (!currentUserId.equals(userId)) {
return error("无权限查看");
}
// 通过会话服务获取未读数
SysChatSession query = new SysChatSession();
query.setUserId(userId);
query.setDelFlag("0");
List<SysChatSession> sessions = sysChatSessionService.selectSysChatSessionList(query);
int totalUnread = sessions.stream()
.mapToInt(session -> session.getUnreadUser() != null ?
session.getUnreadUser().intValue() : 0)
.sum();
return success(totalUnread);
} catch (Exception e) {
return error("获取未读数失败:" + e.getMessage());
}
}
/**
* 上传聊天图片新增
*/
@PostMapping("/uploadImage")
public AjaxResult uploadImage(@RequestParam("file") MultipartFile file,
@RequestParam("sessionId") String sessionId) {
try {
if (file.isEmpty()) {
return error("请选择文件");
}
// 验证文件类型
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
if (!Arrays.asList(".jpg", ".jpeg", ".png", ".gif").contains(suffix.toLowerCase())) {
return error("只支持jpg、jpeg、png、gif格式的图片");
}
// 验证文件大小5MB以内
if (file.getSize() > 5 * 1024 * 1024) {
return error("图片大小不能超过5MB");
}
// 上传文件到服务器
String filePath = FileUploadUtils.upload(file);
// 发送图片消息
Long currentUserId = SecurityUtils.getUserId();
String imageUrl = "/profile/upload/" + filePath;
SysChatMessage message = new SysChatMessage();
message.setSessionId(sessionId);
message.setSenderType("0"); // 用户发送
message.setSenderId(currentUserId);
message.setContent("[图片]" + imageUrl);
message.setMsgType("image");
message.setIsRead("0");
message.setDelFlag("0");
message.setCreateTime(new Date());
int result = sysChatMessageService.insertSysChatMessage(message);
if (result > 0) {
return success(imageUrl);
} else {
return error("发送图片失败");
}
} catch (Exception e) {
return error("上传失败:" + e.getMessage());
}
}
// 请求参数类
@Data
public static class MessageSendRequest {
private String sessionId;
private String senderType; // 0-用户1-专家
private Long senderId;
private String content;
}
@Data
public static class MarkReadRequest {
private String sessionId;
private String senderType; // 标记谁的消息为已读
}
}

215
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysChatSessionController.java

@ -0,0 +1,215 @@
package com.chenhai.web.controller.system;
import java.util.Date;
import java.util.List;
import com.chenhai.common.utils.SecurityUtils;
import com.chenhai.system.service.ISysChatMessageService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
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.SysChatSession;
import com.chenhai.system.service.ISysChatSessionService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
/**
* 兽医咨询聊天会话Controller
*
* @author ruoyi
* @date 2026-01-19
*/
@RestController
@RequestMapping("/system/session")
public class SysChatSessionController extends BaseController
{
@Autowired
private ISysChatSessionService sysChatSessionService;
@Autowired
private ISysChatMessageService sysChatMessageService;
/**
* 查询兽医咨询聊天会话列表
*/
@PreAuthorize("@ss.hasPermi('system:session:list')")
@GetMapping("/list")
public TableDataInfo list(SysChatSession sysChatSession)
{
startPage();
List<SysChatSession> list = sysChatSessionService.selectSysChatSessionList(sysChatSession);
return getDataTable(list);
}
/**
* 导出兽医咨询聊天会话列表
*/
@PreAuthorize("@ss.hasPermi('system:session:export')")
@Log(title = "兽医咨询聊天会话", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysChatSession sysChatSession)
{
List<SysChatSession> list = sysChatSessionService.selectSysChatSessionList(sysChatSession);
ExcelUtil<SysChatSession> util = new ExcelUtil<SysChatSession>(SysChatSession.class);
util.exportExcel(response, list, "兽医咨询聊天会话数据");
}
/**
* 获取兽医咨询聊天会话详细信息
*/
@PreAuthorize("@ss.hasPermi('system:session:query')")
@GetMapping(value = "/{sessionId}")
public AjaxResult getInfo(@PathVariable("sessionId") String sessionId)
{
return success(sysChatSessionService.selectSysChatSessionBySessionId(sessionId));
}
/**
* 新增兽医咨询聊天会话
*/
@PreAuthorize("@ss.hasPermi('system:session:add')")
@Log(title = "兽医咨询聊天会话", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysChatSession sysChatSession)
{
return toAjax(sysChatSessionService.insertSysChatSession(sysChatSession));
}
/**
* 修改兽医咨询聊天会话
*/
@PreAuthorize("@ss.hasPermi('system:session:edit')")
@Log(title = "兽医咨询聊天会话", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysChatSession sysChatSession)
{
return toAjax(sysChatSessionService.updateSysChatSession(sysChatSession));
}
/**
* 删除兽医咨询聊天会话
*/
@PreAuthorize("@ss.hasPermi('system:session:remove')")
@Log(title = "兽医咨询聊天会话", businessType = BusinessType.DELETE)
@DeleteMapping("/{sessionIds}")
public AjaxResult remove(@PathVariable String[] sessionIds)
{
return toAjax(sysChatSessionService.deleteSysChatSessionBySessionIds(sessionIds));
}
/**
* 创建或获取会话新增
*/
@PostMapping("/createOrGetSession")
public AjaxResult createOrGetSession(@RequestBody SessionCreateRequest request) {
try {
Long currentUserId = SecurityUtils.getUserId();
String sessionId = sysChatSessionService.createOrGetSession(
currentUserId, // 使用当前登录用户
request.getExpertId(),
request.getAnimalType(),
request.getSymptomSummary()
);
// 发送欢迎消息
if (sessionId != null) {
sysChatMessageService.sendSystemMessage(sessionId,
"欢迎咨询,请描述您的问题。专家会尽快回复您。");
}
return success(sessionId);
} catch (Exception e) {
return error("创建会话失败:" + e.getMessage());
}
}
/**
* 获取用户会话列表新增
*/
@GetMapping("/user/list")
public AjaxResult getUserSessionList() {
Long userId = SecurityUtils.getUserId();
List<SysChatSession> sessions = sysChatSessionService.selectSessionsByUserId(userId);
return success(sessions);
}
/**
* 获取专家会话列表新增
*/
@GetMapping("/expert/list")
public AjaxResult getExpertSessionList() {
Long expertId = SecurityUtils.getUserId(); // 假设专家也是用userId
List<SysChatSession> sessions = sysChatSessionService.selectSessionsByExpertId(expertId);
return success(sessions);
}
/**
* 结束会话新增
*/
@PostMapping("/end")
public AjaxResult endSession(@RequestBody EndSessionRequest request) {
try {
SysChatSession session = sysChatSessionService.selectSysChatSessionBySessionId(
request.getSessionId()
);
if (session == null) {
return error("会话不存在");
}
// 验证权限
Long currentUserId = SecurityUtils.getUserId();
if (!currentUserId.equals(session.getUserId()) &&
!currentUserId.equals(session.getExpertId())) {
return error("无权限结束此会话");
}
// 更新会话状态
session.setSessionStatus("1");
session.setRemark("结束原因:" + request.getReason());
session.setUpdateTime(new Date());
int result = sysChatSessionService.updateSysChatSession(session);
if (result > 0) {
// 发送结束消息
sysChatMessageService.sendSystemMessage(
request.getSessionId(),
"本次咨询已结束:" + request.getReason()
);
return success("会话已结束");
} else {
return error("结束会话失败");
}
} catch (Exception e) {
return error("操作失败:" + e.getMessage());
}
}
// 请求参数类
@Data
public static class SessionCreateRequest {
private Long expertId;
private String animalType;
private String symptomSummary;
}
@Data
public static class EndSessionRequest {
private String sessionId;
private String reason;
}
}

12
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysDictDataController.java

@ -40,7 +40,7 @@ public class SysDictDataController extends BaseController
@Autowired @Autowired
private ISysDictTypeService dictTypeService; private ISysDictTypeService dictTypeService;
@PreAuthorize("@ss.hasPermi('system:dict:list')")
@PreAuthorize("@ss.hasPermi('system:dict:list') or @ss.hasRole('muhu')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysDictData dictData) public TableDataInfo list(SysDictData dictData)
{ {
@ -50,7 +50,7 @@ public class SysDictDataController extends BaseController
} }
@Log(title = "字典数据", businessType = BusinessType.EXPORT) @Log(title = "字典数据", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PreAuthorize("@ss.hasPermi('system:dict:export') or @ss.hasRole('muhu')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysDictData dictData) public void export(HttpServletResponse response, SysDictData dictData)
{ {
@ -62,7 +62,7 @@ public class SysDictDataController extends BaseController
/** /**
* 查询字典数据详细 * 查询字典数据详细
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:query')")
@PreAuthorize("@ss.hasPermi('system:dict:query') or @ss.hasRole('muhu')")
@GetMapping(value = "/{dictCode}") @GetMapping(value = "/{dictCode}")
public AjaxResult getInfo(@PathVariable Long dictCode) public AjaxResult getInfo(@PathVariable Long dictCode)
{ {
@ -86,7 +86,7 @@ public class SysDictDataController extends BaseController
/** /**
* 新增字典类型 * 新增字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:add')")
@PreAuthorize("@ss.hasPermi('system:dict:add') or @ss.hasRole('muhu')")
@Log(title = "字典数据", businessType = BusinessType.INSERT) @Log(title = "字典数据", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysDictData dict) public AjaxResult add(@Validated @RequestBody SysDictData dict)
@ -98,7 +98,7 @@ public class SysDictDataController extends BaseController
/** /**
* 修改保存字典类型 * 修改保存字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
@PreAuthorize("@ss.hasPermi('system:dict:edit') or @ss.hasRole('muhu')")
@Log(title = "字典数据", businessType = BusinessType.UPDATE) @Log(title = "字典数据", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictData dict) public AjaxResult edit(@Validated @RequestBody SysDictData dict)
@ -110,7 +110,7 @@ public class SysDictDataController extends BaseController
/** /**
* 删除字典类型 * 删除字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@PreAuthorize("@ss.hasPermi('system:dict:remove') or @ss.hasRole('muhu')")
@Log(title = "字典类型", businessType = BusinessType.DELETE) @Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}") @DeleteMapping("/{dictCodes}")
public AjaxResult remove(@PathVariable Long[] dictCodes) public AjaxResult remove(@PathVariable Long[] dictCodes)

104
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysExpertConsultationController.java

@ -1,104 +0,0 @@
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.SysExpertConsultation;
import com.chenhai.system.service.ISysExpertConsultationService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
/**
* 专家咨询Controller
*
* @author ruoyi
* @date 2026-01-12
*/
@RestController
@RequestMapping("/system/consultation")
public class SysExpertConsultationController extends BaseController
{
@Autowired
private ISysExpertConsultationService sysExpertConsultationService;
/**
* 查询专家咨询列表
*/
@PreAuthorize("@ss.hasPermi('system:consultation:list')")
@GetMapping("/list")
public TableDataInfo list(SysExpertConsultation sysExpertConsultation)
{
startPage();
List<SysExpertConsultation> list = sysExpertConsultationService.selectSysExpertConsultationList(sysExpertConsultation);
return getDataTable(list);
}
/**
* 导出专家咨询列表
*/
@PreAuthorize("@ss.hasPermi('system:consultation:export')")
@Log(title = "专家咨询", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysExpertConsultation sysExpertConsultation)
{
List<SysExpertConsultation> list = sysExpertConsultationService.selectSysExpertConsultationList(sysExpertConsultation);
ExcelUtil<SysExpertConsultation> util = new ExcelUtil<SysExpertConsultation>(SysExpertConsultation.class);
util.exportExcel(response, list, "专家咨询数据");
}
/**
* 获取专家咨询详细信息
*/
@PreAuthorize("@ss.hasPermi('system:consultation:query')")
@GetMapping(value = "/{consultationId}")
public AjaxResult getInfo(@PathVariable("consultationId") Long consultationId)
{
return success(sysExpertConsultationService.selectSysExpertConsultationByConsultationId(consultationId));
}
/**
* 新增专家咨询
*/
@PreAuthorize("@ss.hasPermi('system:consultation:add')")
@Log(title = "专家咨询", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysExpertConsultation sysExpertConsultation)
{
return toAjax(sysExpertConsultationService.insertSysExpertConsultation(sysExpertConsultation));
}
/**
* 修改专家咨询
*/
@PreAuthorize("@ss.hasPermi('system:consultation:edit')")
@Log(title = "专家咨询", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysExpertConsultation sysExpertConsultation)
{
return toAjax(sysExpertConsultationService.updateSysExpertConsultation(sysExpertConsultation));
}
/**
* 删除专家咨询
*/
@PreAuthorize("@ss.hasPermi('system:consultation:remove')")
@Log(title = "专家咨询", businessType = BusinessType.DELETE)
@DeleteMapping("/{consultationIds}")
public AjaxResult remove(@PathVariable Long[] consultationIds)
{
return toAjax(sysExpertConsultationService.deleteSysExpertConsultationByConsultationIds(consultationIds));
}
}

104
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysKnowledgeQueryController.java

@ -0,0 +1,104 @@
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.SysKnowledgeQuery;
import com.chenhai.system.service.ISysKnowledgeQueryService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
/**
* 知识库查询Controller
*
* @author ruoyi
* @date 2026-01-21
*/
@RestController
@RequestMapping("/system/query")
public class SysKnowledgeQueryController extends BaseController
{
@Autowired
private ISysKnowledgeQueryService sysKnowledgeQueryService;
/**
* 查询知识库查询列表
*/
@PreAuthorize("@ss.hasPermi('system:query:list') or @ss.hasRole('muhu')")
@GetMapping("/list")
public TableDataInfo list(SysKnowledgeQuery sysKnowledgeQuery)
{
startPage();
List<SysKnowledgeQuery> list = sysKnowledgeQueryService.selectSysKnowledgeQueryList(sysKnowledgeQuery);
return getDataTable(list);
}
/**
* 导出知识库查询列表
*/
@PreAuthorize("@ss.hasPermi('system:query:export') or @ss.hasRole('muhu')")
@Log(title = "知识库查询", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysKnowledgeQuery sysKnowledgeQuery)
{
List<SysKnowledgeQuery> list = sysKnowledgeQueryService.selectSysKnowledgeQueryList(sysKnowledgeQuery);
ExcelUtil<SysKnowledgeQuery> util = new ExcelUtil<SysKnowledgeQuery>(SysKnowledgeQuery.class);
util.exportExcel(response, list, "知识库查询数据");
}
/**
* 获取知识库查询详细信息
*/
@PreAuthorize("@ss.hasPermi('system:query:query') or @ss.hasRole('muhu')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(sysKnowledgeQueryService.selectSysKnowledgeQueryById(id));
}
/**
* 新增知识库查询
*/
@PreAuthorize("@ss.hasPermi('system:query:add') or @ss.hasRole('muhu')")
@Log(title = "知识库查询", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysKnowledgeQuery sysKnowledgeQuery)
{
return toAjax(sysKnowledgeQueryService.insertSysKnowledgeQuery(sysKnowledgeQuery));
}
/**
* 修改知识库查询
*/
@PreAuthorize("@ss.hasPermi('system:query:edit') or @ss.hasRole('muhu')")
@Log(title = "知识库查询", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysKnowledgeQuery sysKnowledgeQuery)
{
return toAjax(sysKnowledgeQueryService.updateSysKnowledgeQuery(sysKnowledgeQuery));
}
/**
* 删除知识库查询
*/
@PreAuthorize("@ss.hasPermi('system:query:remove')")
@Log(title = "知识库查询", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(sysKnowledgeQueryService.deleteSysKnowledgeQueryByIds(ids));
}
}

4
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysLoginController.java

@ -23,6 +23,7 @@ import com.chenhai.framework.web.service.SysPermissionService;
import com.chenhai.framework.web.service.TokenService; import com.chenhai.framework.web.service.TokenService;
import com.chenhai.system.service.ISysConfigService; import com.chenhai.system.service.ISysConfigService;
import com.chenhai.system.service.ISysMenuService; import com.chenhai.system.service.ISysMenuService;
import com.chenhai.vet.service.IVetExpertsService;
/** /**
* 登录验证 * 登录验证
@ -47,6 +48,9 @@ public class SysLoginController
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@Autowired // 添加这行
private IVetExpertsService vetExpertsService;
/** /**
* 登录方法 * 登录方法
* *

104
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysMedicineRecommendationController.java

@ -0,0 +1,104 @@
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.SysMedicineRecommendation;
import com.chenhai.system.service.ISysMedicineRecommendationService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
/**
* 药品推荐Controller
*
* @author ruoyi
* @date 2026-01-20
*/
@RestController
@RequestMapping("/system/recommendation")
public class SysMedicineRecommendationController extends BaseController
{
@Autowired
private ISysMedicineRecommendationService sysMedicineRecommendationService;
/**
* 查询药品推荐列表
*/
@PreAuthorize("@ss.hasPermi('system:recommendation:list') or @ss.hasRole('muhu')")
@GetMapping("/list")
public TableDataInfo list(SysMedicineRecommendation sysMedicineRecommendation)
{
startPage();
List<SysMedicineRecommendation> list = sysMedicineRecommendationService.selectSysMedicineRecommendationList(sysMedicineRecommendation);
return getDataTable(list);
}
/**
* 导出药品推荐列表
*/
@PreAuthorize("@ss.hasPermi('system:recommendation:export') or @ss.hasRole('muhu')")
@Log(title = "药品推荐", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysMedicineRecommendation sysMedicineRecommendation)
{
List<SysMedicineRecommendation> list = sysMedicineRecommendationService.selectSysMedicineRecommendationList(sysMedicineRecommendation);
ExcelUtil<SysMedicineRecommendation> util = new ExcelUtil<SysMedicineRecommendation>(SysMedicineRecommendation.class);
util.exportExcel(response, list, "药品推荐数据");
}
/**
* 获取药品推荐详细信息
*/
@PreAuthorize("@ss.hasPermi('system:recommendation:query') or @ss.hasRole('muhu')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(sysMedicineRecommendationService.selectSysMedicineRecommendationById(id));
}
/**
* 新增药品推荐
*/
@PreAuthorize("@ss.hasPermi('system:recommendation:add') or @ss.hasRole('muhu')")
@Log(title = "药品推荐", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysMedicineRecommendation sysMedicineRecommendation)
{
return toAjax(sysMedicineRecommendationService.insertSysMedicineRecommendation(sysMedicineRecommendation));
}
/**
* 修改药品推荐
*/
@PreAuthorize("@ss.hasPermi('system:recommendation:edit') or @ss.hasRole('muhu')")
@Log(title = "药品推荐", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysMedicineRecommendation sysMedicineRecommendation)
{
return toAjax(sysMedicineRecommendationService.updateSysMedicineRecommendation(sysMedicineRecommendation));
}
/**
* 删除药品推荐
*/
@PreAuthorize("@ss.hasPermi('system:recommendation:remove') or @ss.hasRole('muhu')")
@Log(title = "药品推荐", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(sysMedicineRecommendationService.deleteSysMedicineRecommendationByIds(ids));
}
}

27
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysPolicyInterpretationController.java

@ -159,4 +159,31 @@ public class SysPolicyInterpretationController extends BaseController
String removalReason = (String) requestBody.get("removalReason"); String removalReason = (String) requestBody.get("removalReason");
return toAjax(sysPolicyInterpretationService.unpublishSysPolicyInterpretationByIds(ids, removalReason)); return toAjax(sysPolicyInterpretationService.unpublishSysPolicyInterpretationByIds(ids, removalReason));
} }
/**
* 查询已上架政策解读列表公共接口无需权限
*/
@PreAuthorize("@ss.hasRole('muhu')")
@GetMapping("/published/list")
public TableDataInfo publishedList(SysPolicyInterpretation sysPolicyInterpretation)
{
startPage();
List<SysPolicyInterpretation> list = sysPolicyInterpretationService.selectPublishedSysPolicyInterpretationList(sysPolicyInterpretation);
return getDataTable(list);
}
/**
* 获取已上架政策解读详情公共接口无需权限
*/
@PreAuthorize("@ss.hasRole('muhu')")
@GetMapping("/published/{id}")
public AjaxResult getPublishedInfo(@PathVariable("id") Long id)
{
SysPolicyInterpretation policy = sysPolicyInterpretationService.selectSysPolicyInterpretationById(id);
// 检查是否已上架
if (policy == null || !"1".equals(policy.getPublishStatus())) {
return error("政策解读不存在或未上架");
}
return success(policy);
}
} }

104
chenhai-admin/src/main/java/com/chenhai/web/controller/system/SysQueryTipController.java

@ -0,0 +1,104 @@
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.SysQueryTip;
import com.chenhai.system.service.ISysQueryTipService;
import com.chenhai.common.utils.poi.ExcelUtil;
import com.chenhai.common.core.page.TableDataInfo;
/**
* 知识库查询提示Controller
*
* @author ruoyi
* @date 2026-01-22
*/
@RestController
@RequestMapping("/system/tip")
public class SysQueryTipController extends BaseController
{
@Autowired
private ISysQueryTipService sysQueryTipService;
/**
* 查询知识库查询提示列表
*/
@PreAuthorize("@ss.hasPermi('system:tip:list') or @ss.hasRole('muhu')")
@GetMapping("/list")
public TableDataInfo list(SysQueryTip sysQueryTip)
{
startPage();
List<SysQueryTip> list = sysQueryTipService.selectSysQueryTipList(sysQueryTip);
return getDataTable(list);
}
/**
* 导出知识库查询提示列表
*/
@PreAuthorize("@ss.hasPermi('system:tip:export') or @ss.hasRole('muhu')")
@Log(title = "知识库查询提示", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysQueryTip sysQueryTip)
{
List<SysQueryTip> list = sysQueryTipService.selectSysQueryTipList(sysQueryTip);
ExcelUtil<SysQueryTip> util = new ExcelUtil<SysQueryTip>(SysQueryTip.class);
util.exportExcel(response, list, "知识库查询提示数据");
}
/**
* 获取知识库查询提示详细信息
*/
@PreAuthorize("@ss.hasPermi('system:tip:query') or @ss.hasRole('muhu')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(sysQueryTipService.selectSysQueryTipById(id));
}
/**
* 新增知识库查询提示
*/
@PreAuthorize("@ss.hasPermi('system:tip:add') or @ss.hasRole('muhu')")
@Log(title = "知识库查询提示", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysQueryTip sysQueryTip)
{
return toAjax(sysQueryTipService.insertSysQueryTip(sysQueryTip));
}
/**
* 修改知识库查询提示
*/
@PreAuthorize("@ss.hasPermi('system:tip:edit') or @ss.hasRole('muhu')")
@Log(title = "知识库查询提示", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysQueryTip sysQueryTip)
{
return toAjax(sysQueryTipService.updateSysQueryTip(sysQueryTip));
}
/**
* 删除知识库查询提示
*/
@PreAuthorize("@ss.hasPermi('system:tip:remove') or @ss.hasRole('muhu')")
@Log(title = "知识库查询提示", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(sysQueryTipService.deleteSysQueryTipByIds(ids));
}
}

21
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetExpertsController.java

@ -4,14 +4,7 @@ import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; 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 org.springframework.web.bind.annotation.*;
import com.chenhai.common.annotation.Log; import com.chenhai.common.annotation.Log;
import com.chenhai.common.core.controller.BaseController; import com.chenhai.common.core.controller.BaseController;
import com.chenhai.common.core.domain.AjaxResult; import com.chenhai.common.core.domain.AjaxResult;
@ -101,4 +94,16 @@ public class VetExpertsController extends BaseController
{ {
return toAjax(vetExpertsService.deleteVetExpertsByExpertIds(expertIds)); return toAjax(vetExpertsService.deleteVetExpertsByExpertIds(expertIds));
} }
/**
* 搜索专家信息按真实姓名和擅长领域
*/
@PreAuthorize("@ss.hasPermi('vet:experts:list') or @ss.hasRole('muhu')")
@GetMapping("/search")
public TableDataInfo search(@RequestParam(value = "keyword", required = false) String keyword)
{
startPage();
List<VetExperts> list = vetExpertsService.searchVetExperts(keyword);
return getDataTable(list);
}
} }

55
chenhai-admin/src/main/java/com/chenhai/web/controller/vet/VetKnowledgeController.java

@ -38,7 +38,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 查询兽医文章列表 * 查询兽医文章列表
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:list')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:list') or @ss.hasRole('muhu')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(VetKnowledge vetKnowledge) public TableDataInfo list(VetKnowledge vetKnowledge)
{ {
@ -50,7 +50,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 导出兽医文章列表 * 导出兽医文章列表
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:export')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:export') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.EXPORT) @Log(title = "兽医文章", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, VetKnowledge vetKnowledge) public void export(HttpServletResponse response, VetKnowledge vetKnowledge)
@ -63,7 +63,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 获取兽医文章详细信息 * 获取兽医文章详细信息
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:query')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:query') or @ss.hasRole('muhu')")
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) public AjaxResult getInfo(@PathVariable("id") Long id)
{ {
@ -73,7 +73,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 新增兽医文章 * 新增兽医文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:add')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:add') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.INSERT) @Log(title = "兽医文章", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@RequestBody VetKnowledge vetKnowledge) public AjaxResult add(@RequestBody VetKnowledge vetKnowledge)
@ -86,7 +86,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 修改兽医文章 * 修改兽医文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:edit')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:edit') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@RequestBody VetKnowledge vetKnowledge) public AjaxResult edit(@RequestBody VetKnowledge vetKnowledge)
@ -97,7 +97,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 删除兽医文章 * 删除兽医文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:remove')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:remove') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.DELETE) @Log(title = "兽医文章", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) public AjaxResult remove(@PathVariable Long[] ids)
@ -108,7 +108,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 提交审核 * 提交审核
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:submit')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:submit') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/submit/{id}") @PutMapping("/submit/{id}")
public AjaxResult submitForAudit(@PathVariable Long id) { public AjaxResult submitForAudit(@PathVariable Long id) {
@ -118,7 +118,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 审核文章 * 审核文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:audit')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:audit') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/audit/{id}") @PutMapping("/audit/{id}")
public AjaxResult audit(@PathVariable Long id, public AjaxResult audit(@PathVariable Long id,
@ -133,7 +133,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 发布文章 * 发布文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/publish/{id}") @PutMapping("/publish/{id}")
public AjaxResult publish(@PathVariable Long id) { public AjaxResult publish(@PathVariable Long id) {
@ -143,7 +143,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 上架文章 * 上架文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/online/{id}") @PutMapping("/online/{id}")
public AjaxResult online(@PathVariable Long id) { public AjaxResult online(@PathVariable Long id) {
@ -153,7 +153,7 @@ public class VetKnowledgeController extends BaseController
/** /**
* 下架文章 * 下架文章
*/ */
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish')")
@PreAuthorize("@ss.hasPermi('vet:knowledge:publish') or @ss.hasRole('muhu')")
@Log(title = "兽医文章", businessType = BusinessType.UPDATE) @Log(title = "兽医文章", businessType = BusinessType.UPDATE)
@PutMapping("/offline/{id}") @PutMapping("/offline/{id}")
public AjaxResult offline(@PathVariable Long id, @RequestParam(required = false) String auditComment) { public AjaxResult offline(@PathVariable Long id, @RequestParam(required = false) String auditComment) {
@ -162,4 +162,37 @@ public class VetKnowledgeController extends BaseController
} }
return vetKnowledgeService.offlineVetKnowledge(id, auditComment); return vetKnowledgeService.offlineVetKnowledge(id, auditComment);
} }
/**
* 查询已发布且审核通过的兽医文章列表公开接口无需权限
* 用于前端展示给用户只显示可公开的文章
*/
@PreAuthorize("@ss.hasRole('muhu')")
@GetMapping("/published/list")
public TableDataInfo publishedList(VetKnowledge vetKnowledge)
{
startPage();
List<VetKnowledge> list = vetKnowledgeService.selectPublishedKnowledgeList(vetKnowledge);
return getDataTable(list);
}
/**
* 获取已发布文章的详细信息公开接口
*/
@PreAuthorize("@ss.hasRole('muhu')")
@GetMapping("/published/{id}")
public AjaxResult getPublishedInfo(@PathVariable("id") Long id)
{
VetKnowledge knowledge = vetKnowledgeService.selectVetKnowledgeById(id);
// 检查文章是否是已发布且审核通过状态
if (knowledge != null && "1".equals(knowledge.getArticleStatus()) && "2".equals(knowledge.getAuditStatus())) {
// 增加查看次数
vetKnowledgeService.addViewCount(id);
// 重新查询以获取更新后的查看次数
knowledge = vetKnowledgeService.selectVetKnowledgeById(id);
return success(knowledge);
}
return error("文章不存在或未发布");
}
} }

163
chenhai-system/src/main/java/com/chenhai/system/domain/SysChatMessage.java

@ -0,0 +1,163 @@
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_chat_message
*
* @author ruoyi
* @date 2026-01-19
*/
public class SysChatMessage extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 消息ID */
private Long messageId;
/** 会话ID */
@Excel(name = "会话ID")
private String sessionId;
/** 发送者类型:0-用户,1-专家 */
@Excel(name = "发送者类型:0-用户,1-专家")
private String senderType;
/** 发送者ID */
@Excel(name = "发送者ID")
private Long senderId;
/** 消息内容 */
@Excel(name = "消息内容")
private String content;
/** 消息类型:text-文本,image-图片 */
@Excel(name = "消息类型:text-文本,image-图片")
private String msgType;
/** 是否已读:0-未读,1-已读 */
@Excel(name = "是否已读:0-未读,1-已读")
private String isRead;
/** 阅读时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "阅读时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date readTime;
/** 删除标志(0-存在 2-删除) */
private String delFlag;
public void setMessageId(Long messageId)
{
this.messageId = messageId;
}
public Long getMessageId()
{
return messageId;
}
public void setSessionId(String sessionId)
{
this.sessionId = sessionId;
}
public String getSessionId()
{
return sessionId;
}
public void setSenderType(String senderType)
{
this.senderType = senderType;
}
public String getSenderType()
{
return senderType;
}
public void setSenderId(Long senderId)
{
this.senderId = senderId;
}
public Long getSenderId()
{
return senderId;
}
public void setContent(String content)
{
this.content = content;
}
public String getContent()
{
return content;
}
public void setMsgType(String msgType)
{
this.msgType = msgType;
}
public String getMsgType()
{
return msgType;
}
public void setIsRead(String isRead)
{
this.isRead = isRead;
}
public String getIsRead()
{
return isRead;
}
public void setReadTime(Date readTime)
{
this.readTime = readTime;
}
public Date getReadTime()
{
return readTime;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("messageId", getMessageId())
.append("sessionId", getSessionId())
.append("senderType", getSenderType())
.append("senderId", getSenderId())
.append("content", getContent())
.append("msgType", getMsgType())
.append("isRead", getIsRead())
.append("readTime", getReadTime())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

194
chenhai-system/src/main/java/com/chenhai/system/domain/SysChatSession.java

@ -0,0 +1,194 @@
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_chat_session
*
* @author ruoyi
* @date 2026-01-19
*/
public class SysChatSession extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 会话ID,格式:user_{uid}_expert_{eid} */
private String sessionId;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** 专家ID */
@Excel(name = "专家ID")
private Long expertId;
/** 动物类型 */
@Excel(name = "动物类型")
private String animalType;
/** 症状摘要 */
@Excel(name = "症状摘要")
private String symptomSummary;
/** 最后一条消息 */
@Excel(name = "最后一条消息")
private String lastMessage;
/** 最后消息时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "最后消息时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date lastMessageTime;
/** 用户未读数 */
@Excel(name = "用户未读数")
private Long unreadUser;
/** 专家未读数 */
@Excel(name = "专家未读数")
private Long unreadExpert;
/** 0-进行中 1-已结束 */
@Excel(name = "0-进行中 1-已结束")
private String sessionStatus;
/** 删除标志(0-存在 2-删除) */
private String delFlag;
public void setSessionId(String sessionId)
{
this.sessionId = sessionId;
}
public String getSessionId()
{
return sessionId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setExpertId(Long expertId)
{
this.expertId = expertId;
}
public Long getExpertId()
{
return expertId;
}
public void setAnimalType(String animalType)
{
this.animalType = animalType;
}
public String getAnimalType()
{
return animalType;
}
public void setSymptomSummary(String symptomSummary)
{
this.symptomSummary = symptomSummary;
}
public String getSymptomSummary()
{
return symptomSummary;
}
public void setLastMessage(String lastMessage)
{
this.lastMessage = lastMessage;
}
public String getLastMessage()
{
return lastMessage;
}
public void setLastMessageTime(Date lastMessageTime)
{
this.lastMessageTime = lastMessageTime;
}
public Date getLastMessageTime()
{
return lastMessageTime;
}
public void setUnreadUser(Long unreadUser)
{
this.unreadUser = unreadUser;
}
public Long getUnreadUser()
{
return unreadUser;
}
public void setUnreadExpert(Long unreadExpert)
{
this.unreadExpert = unreadExpert;
}
public Long getUnreadExpert()
{
return unreadExpert;
}
public void setSessionStatus(String sessionStatus)
{
this.sessionStatus = sessionStatus;
}
public String getSessionStatus()
{
return sessionStatus;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("sessionId", getSessionId())
.append("userId", getUserId())
.append("expertId", getExpertId())
.append("animalType", getAnimalType())
.append("symptomSummary", getSymptomSummary())
.append("lastMessage", getLastMessage())
.append("lastMessageTime", getLastMessageTime())
.append("unreadUser", getUnreadUser())
.append("unreadExpert", getUnreadExpert())
.append("sessionStatus", getSessionStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

299
chenhai-system/src/main/java/com/chenhai/system/domain/SysExpertConsultation.java

@ -1,299 +0,0 @@
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_expert_consultation
*
* @author ruoyi
* @date 2026-01-12
*/
public class SysExpertConsultation extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 咨询ID */
private Long consultationId;
/** 用户ID */
@Excel(name = "用户ID")
private Long userId;
/** 专家ID */
@Excel(name = "专家ID")
private Long expertId;
/** 关联问诊单ID */
@Excel(name = "关联问诊单ID")
private Long formId;
/** 咨询类型: 1-图文咨询, 2-电话咨询, 3-视频咨询 */
@Excel(name = "咨询类型: 1-图文咨询, 2-电话咨询, 3-视频咨询")
private String consultationType;
/** 咨询状态: 0-待接诊, 1-进行中, 2-已完成, 3-已取消 */
@Excel(name = "咨询状态: 0-待接诊, 1-进行中, 2-已完成, 3-已取消")
private String consultationStatus;
/** 咨询标题 */
@Excel(name = "咨询标题")
private String consultationTitle;
/** 用户初始咨询内容 */
@Excel(name = "用户初始咨询内容")
private String initialContent;
/** 用户初始附件(JSON数组) */
@Excel(name = "用户初始附件(JSON数组)")
private String initialAttachments;
/** 对话消息(JSON格式) */
@Excel(name = "对话消息(JSON格式)")
private String messages;
/** 用户评分(1-5分) */
@Excel(name = "用户评分(1-5分)")
private Integer rating;
/** 用户评价内容 */
@Excel(name = "用户评价内容")
private String evaluation;
/** 评价标签(JSON数组) */
@Excel(name = "评价标签(JSON数组)")
private String evaluationTags;
/** 评价时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "评价时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date evaluationTime;
/** 咨询开始时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "咨询开始时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date startTime;
/** 咨询结束时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "咨询结束时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date endTime;
/** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date createdTime;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date updatedTime;
public void setConsultationId(Long consultationId)
{
this.consultationId = consultationId;
}
public Long getConsultationId()
{
return consultationId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setExpertId(Long expertId)
{
this.expertId = expertId;
}
public Long getExpertId()
{
return expertId;
}
public void setFormId(Long formId)
{
this.formId = formId;
}
public Long getFormId()
{
return formId;
}
public void setConsultationType(String consultationType)
{
this.consultationType = consultationType;
}
public String getConsultationType()
{
return consultationType;
}
public void setConsultationStatus(String consultationStatus)
{
this.consultationStatus = consultationStatus;
}
public String getConsultationStatus()
{
return consultationStatus;
}
public void setConsultationTitle(String consultationTitle)
{
this.consultationTitle = consultationTitle;
}
public String getConsultationTitle()
{
return consultationTitle;
}
public void setInitialContent(String initialContent)
{
this.initialContent = initialContent;
}
public String getInitialContent()
{
return initialContent;
}
public void setInitialAttachments(String initialAttachments)
{
this.initialAttachments = initialAttachments;
}
public String getInitialAttachments()
{
return initialAttachments;
}
public void setMessages(String messages)
{
this.messages = messages;
}
public String getMessages()
{
return messages;
}
public void setRating(Integer rating)
{
this.rating = rating;
}
public Integer getRating()
{
return rating;
}
public void setEvaluation(String evaluation)
{
this.evaluation = evaluation;
}
public String getEvaluation()
{
return evaluation;
}
public void setEvaluationTags(String evaluationTags)
{
this.evaluationTags = evaluationTags;
}
public String getEvaluationTags()
{
return evaluationTags;
}
public void setEvaluationTime(Date evaluationTime)
{
this.evaluationTime = evaluationTime;
}
public Date getEvaluationTime()
{
return evaluationTime;
}
public void setStartTime(Date startTime)
{
this.startTime = startTime;
}
public Date getStartTime()
{
return startTime;
}
public void setEndTime(Date endTime)
{
this.endTime = endTime;
}
public Date getEndTime()
{
return endTime;
}
public void setCreatedTime(Date createdTime)
{
this.createdTime = createdTime;
}
public Date getCreatedTime()
{
return createdTime;
}
public void setUpdatedTime(Date updatedTime)
{
this.updatedTime = updatedTime;
}
public Date getUpdatedTime()
{
return updatedTime;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("consultationId", getConsultationId())
.append("userId", getUserId())
.append("expertId", getExpertId())
.append("formId", getFormId())
.append("consultationType", getConsultationType())
.append("consultationStatus", getConsultationStatus())
.append("consultationTitle", getConsultationTitle())
.append("initialContent", getInitialContent())
.append("initialAttachments", getInitialAttachments())
.append("messages", getMessages())
.append("rating", getRating())
.append("evaluation", getEvaluation())
.append("evaluationTags", getEvaluationTags())
.append("evaluationTime", getEvaluationTime())
.append("startTime", getStartTime())
.append("endTime", getEndTime())
.append("createdTime", getCreatedTime())
.append("updatedTime", getUpdatedTime())
.toString();
}
}

130
chenhai-system/src/main/java/com/chenhai/system/domain/SysKnowledgeQuery.java

@ -0,0 +1,130 @@
package com.chenhai.system.domain;
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;
import java.util.Date;
/**
* 知识库查询对象 sys_knowledge_query
*
* @author ruoyi
* @date 2026-01-21
*/
public class SysKnowledgeQuery extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 标题,如“猪瘟防治” */
@Excel(name = "标题,如“猪瘟防治”")
private String title;
/** 具体内容,如防治措施、饲养方法等 */
@Excel(name = "具体内容,如防治措施、饲养方法等")
private String content;
/** 分类,如“疾病防治”、“饲养管理” */
@Excel(name = "分类,如“疾病防治”、“饲养管理”")
private String categoryType;
/** 关键词 */
@Excel(name = "关键词")
private String keywords;
/** 发布时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "发布时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date publishTime;
/** 搜索关键字(非数据库字段) */
private String searchKey;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
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 setCategoryType(String categoryType)
{
this.categoryType = categoryType;
}
public String getCategoryType()
{
return categoryType;
}
public void setKeywords(String keywords)
{
this.keywords = keywords;
}
public String getKeywords()
{
return keywords;
}
public Date getPublishTime()
{
return publishTime;
}
public void setPublishTime(Date publishTime)
{
this.publishTime = publishTime;
}
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)
.append("id", getId())
.append("title", getTitle())
.append("content", getContent())
.append("categoryType", getCategoryType())
.append("keywords", getKeywords())
.append("publishTime", getPublishTime())
.append("searchKey", getSearchKey())
.toString();
}
}

531
chenhai-system/src/main/java/com/chenhai/system/domain/SysMedicineRecommendation.java

@ -0,0 +1,531 @@
package com.chenhai.system.domain;
import java.math.BigDecimal;
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_medicine_recommendation
*
* @author ruoyi
* @date 2026-01-20
*/
public class SysMedicineRecommendation extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 药品名称 */
@Excel(name = "药品名称")
private String medicineName;
/** 药品类型(处方药、非处方药、中成药、保健品等) */
@Excel(name = "药品类型", readConverterExp = "处=方药、非处方药、中成药、保健品等")
private String medicineType;
/** 规格(如:0.25g*24粒/盒) */
@Excel(name = "规格", readConverterExp = "如=:0.25g*24粒/盒")
private String specification;
/** 当前价格 */
@Excel(name = "当前价格")
private BigDecimal price;
/** 原价 */
@Excel(name = "原价")
private BigDecimal originalPrice;
/** 已售数量 */
@Excel(name = "已售数量")
private Long soldQuantity;
/** 适用症状 */
@Excel(name = "适用症状")
private String indications;
/** 用法用量 */
@Excel(name = "用法用量")
private String usageDosage;
/** 注意事项 */
@Excel(name = "注意事项")
private String precautions;
/** 贮藏方式 */
@Excel(name = "贮藏方式")
private String storageMethod;
/** 有效期 */
@Excel(name = "有效期")
private String expiryDate;
/** 生产厂家 */
@Excel(name = "生产厂家")
private String manufacturer;
/** 销售类型(hot:热销, new:新品, recommend:推荐, normal:普通) */
@Excel(name = "销售类型")
private String salesType;
/** 专家ID */
@Excel(name = "专家ID")
private Long expertId;
/** 推荐理由 */
@Excel(name = "推荐理由")
private String recommendReason;
/** 药品图片(多张图片用逗号分隔) */
@Excel(name = "药品图片")
private String images;
/** 轮播图片URL */
@Excel(name = "轮播图片URL")
private String imageUrl;
/** 搜索关键词(用于快速搜索,包含药品名称、症状、厂家等信息) */
@Excel(name = "搜索关键词")
private String searchKeywords;
/** 推荐时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "推荐时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date recommendTime;
/** 创建时间 */
@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;
// 专家信息不持久化到数据库仅用于展示
private String expertAvatar;
private String expertName;
private String expertExpert;
private String expertIntroduction;
private String expertAddress;
private String expertExpertiseArea;
private String expertWorkExperience;
// 推荐店铺信息
/** 店铺名称 */
@Excel(name = "店铺名称")
private String storeName;
/** 店铺地址 */
@Excel(name = "店铺地址")
private String storeAddress;
/** 店铺电话 */
@Excel(name = "店铺电话")
private String storePhone;
/** 营业时间 */
@Excel(name = "营业时间")
private String businessHours;
/** 备注 */
@Excel(name = "备注")
private String storeRemark;
/** 经度 */
@Excel(name = "经度")
private BigDecimal longitude;
/** 纬度 */
@Excel(name = "纬度")
private BigDecimal latitude;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setMedicineName(String medicineName)
{
this.medicineName = medicineName;
}
public String getMedicineName()
{
return medicineName;
}
public void setMedicineType(String medicineType)
{
this.medicineType = medicineType;
}
public String getMedicineType()
{
return medicineType;
}
public void setSpecification(String specification)
{
this.specification = specification;
}
public String getSpecification()
{
return specification;
}
public void setPrice(BigDecimal price)
{
this.price = price;
}
public BigDecimal getPrice()
{
return price;
}
public void setOriginalPrice(BigDecimal originalPrice)
{
this.originalPrice = originalPrice;
}
public BigDecimal getOriginalPrice()
{
return originalPrice;
}
public void setSoldQuantity(Long soldQuantity)
{
this.soldQuantity = soldQuantity;
}
public Long getSoldQuantity()
{
return soldQuantity;
}
public void setIndications(String indications)
{
this.indications = indications;
}
public String getIndications()
{
return indications;
}
public void setUsageDosage(String usageDosage)
{
this.usageDosage = usageDosage;
}
public String getUsageDosage()
{
return usageDosage;
}
public void setPrecautions(String precautions)
{
this.precautions = precautions;
}
public String getPrecautions()
{
return precautions;
}
public void setStorageMethod(String storageMethod)
{
this.storageMethod = storageMethod;
}
public String getStorageMethod()
{
return storageMethod;
}
public void setExpiryDate(String expiryDate)
{
this.expiryDate = expiryDate;
}
public String getExpiryDate()
{
return expiryDate;
}
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 void setManufacturer(String manufacturer)
{
this.manufacturer = manufacturer;
}
public String getManufacturer()
{
return manufacturer;
}
public void setSalesType(String salesType)
{
this.salesType = salesType;
}
public String getSalesType()
{
return salesType;
}
public void setExpertId(Long expertId)
{
this.expertId = expertId;
}
public Long getExpertId()
{
return expertId;
}
public void setRecommendReason(String recommendReason)
{
this.recommendReason = recommendReason;
}
public String getRecommendReason()
{
return recommendReason;
}
public void setRecommendTime(Date recommendTime)
{
this.recommendTime = recommendTime;
}
public Date getRecommendTime()
{
return recommendTime;
}
public void setExpertAvatar(String expertAvatar)
{
this.expertAvatar = expertAvatar;
}
public String getExpertAvatar()
{
return expertAvatar;
}
public void setExpertName(String expertName)
{
this.expertName = expertName;
}
public String getExpertName()
{
return expertName;
}
public void setExpertExpert(String expertExpert)
{
this.expertExpert = expertExpert;
}
public String getExpertExpert()
{
return expertExpert;
}
public void setExpertIntroduction(String expertIntroduction)
{
this.expertIntroduction = expertIntroduction;
}
public String getExpertIntroduction()
{
return expertIntroduction;
}
public void setExpertAddress(String expertAddress)
{
this.expertAddress = expertAddress;
}
public String getExpertAddress()
{
return expertAddress;
}
public void setExpertExpertiseArea(String expertExpertiseArea)
{
this.expertExpertiseArea = expertExpertiseArea;
}
public String getExpertExpertiseArea()
{
return expertExpertiseArea;
}
public void setExpertWorkExperience(String expertWorkExperience)
{
this.expertWorkExperience = expertWorkExperience;
}
public String getExpertWorkExperience()
{
return expertWorkExperience;
}
// 店铺相关getter/setter
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
public String getStoreAddress() {
return storeAddress;
}
public void setStoreAddress(String storeAddress) {
this.storeAddress = storeAddress;
}
public String getStorePhone() {
return storePhone;
}
public void setStorePhone(String storePhone) {
this.storePhone = storePhone;
}
public String getBusinessHours() {
return businessHours;
}
public void setBusinessHours(String businessHours) {
this.businessHours = businessHours;
}
public String getStoreRemark() {
return storeRemark;
}
public void setStoreRemark(String storeRemark) {
this.storeRemark = storeRemark;
}
public BigDecimal getLongitude() {
return longitude;
}
public void setLongitude(BigDecimal longitude) {
this.longitude = longitude;
}
public BigDecimal getLatitude() {
return latitude;
}
public void setLatitude(BigDecimal latitude) {
this.latitude = latitude;
}
public void setImages(String images)
{
this.images = images;
}
public String getImages()
{
return images;
}
public void setImageUrl(String imageUrl)
{
this.imageUrl = imageUrl;
}
public String getImageUrl()
{
return imageUrl;
}
public void setSearchKeywords(String searchKeywords)
{
this.searchKeywords = searchKeywords;
}
public String getSearchKeywords()
{
return searchKeywords;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("medicineName", getMedicineName())
.append("medicineType", getMedicineType())
.append("specification", getSpecification())
.append("price", getPrice())
.append("originalPrice", getOriginalPrice())
.append("soldQuantity", getSoldQuantity())
.append("indications", getIndications())
.append("usageDosage", getUsageDosage())
.append("precautions", getPrecautions())
.append("storageMethod", getStorageMethod())
.append("expiryDate", getExpiryDate())
.append("createdAt", getCreatedAt())
.append("updatedAt", getUpdatedAt())
.append("manufacturer", getManufacturer())
.append("salesType", getSalesType())
.append("expertId", getExpertId())
.append("recommendReason", getRecommendReason())
.append("recommendTime", getRecommendTime())
.append("storeName", getStoreName())
.append("storeAddress", getStoreAddress())
.append("storePhone", getStorePhone())
.append("businessHours", getBusinessHours())
.append("storeRemark", getStoreRemark())
.append("longitude", getLongitude())
.append("latitude", getLatitude())
.append("images", getImages())
.append("imageUrl", getImageUrl())
.append("searchKeywords", getSearchKeywords())
.toString();
}
}

15
chenhai-system/src/main/java/com/chenhai/system/domain/SysPolicyInterpretation.java

@ -49,6 +49,10 @@ public class SysPolicyInterpretation extends BaseEntity
@Excel(name = "下架原因") @Excel(name = "下架原因")
private String removalReason; private String removalReason;
/** 政策分类 */
@Excel(name = "政策分类") // 添加dictType用于字典转换
private String policyCategory;
/** 删除标志(0代表存在 2代表删除) */ /** 删除标志(0代表存在 2代表删除) */
private String delFlag; private String delFlag;
@ -142,6 +146,16 @@ public class SysPolicyInterpretation extends BaseEntity
return delFlag; return delFlag;
} }
public void setPolicyCategory(String policyCategory)
{
this.policyCategory = policyCategory;
}
public String getPolicyCategory()
{
return policyCategory;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -159,6 +173,7 @@ public class SysPolicyInterpretation extends BaseEntity
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.append("policyCategory", getPolicyCategory())
.toString(); .toString();
} }
} }

67
chenhai-system/src/main/java/com/chenhai/system/domain/SysQueryTip.java

@ -0,0 +1,67 @@
package com.chenhai.system.domain;
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_query_tip
*
* @author ruoyi
* @date 2026-01-22
*/
public class SysQueryTip extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键id */
private Long id;
/** 关联知识库查询id */
@Excel(name = "关联知识库查询id")
private Long queryId;
/** 提示 */
@Excel(name = "提示")
private String tips;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setQueryId(Long queryId)
{
this.queryId = queryId;
}
public Long getQueryId()
{
return queryId;
}
public void setTips(String tips)
{
this.tips = tips;
}
public String getTips()
{
return tips;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("queryId", getQueryId())
.append("tips", getTips())
.toString();
}
}

61
chenhai-system/src/main/java/com/chenhai/system/mapper/SysChatMessageMapper.java

@ -0,0 +1,61 @@
package com.chenhai.system.mapper;
import java.util.List;
import com.chenhai.system.domain.SysChatMessage;
/**
* 兽医咨询聊天消息Mapper接口
*
* @author ruoyi
* @date 2026-01-19
*/
public interface SysChatMessageMapper
{
/**
* 查询兽医咨询聊天消息
*
* @param messageId 兽医咨询聊天消息主键
* @return 兽医咨询聊天消息
*/
public SysChatMessage selectSysChatMessageByMessageId(Long messageId);
/**
* 查询兽医咨询聊天消息列表
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 兽医咨询聊天消息集合
*/
public List<SysChatMessage> selectSysChatMessageList(SysChatMessage sysChatMessage);
/**
* 新增兽医咨询聊天消息
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 结果
*/
public int insertSysChatMessage(SysChatMessage sysChatMessage);
/**
* 修改兽医咨询聊天消息
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 结果
*/
public int updateSysChatMessage(SysChatMessage sysChatMessage);
/**
* 删除兽医咨询聊天消息
*
* @param messageId 兽医咨询聊天消息主键
* @return 结果
*/
public int deleteSysChatMessageByMessageId(Long messageId);
/**
* 批量删除兽医咨询聊天消息
*
* @param messageIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteSysChatMessageByMessageIds(Long[] messageIds);
}

61
chenhai-system/src/main/java/com/chenhai/system/mapper/SysChatSessionMapper.java

@ -0,0 +1,61 @@
package com.chenhai.system.mapper;
import java.util.List;
import com.chenhai.system.domain.SysChatSession;
/**
* 兽医咨询聊天会话Mapper接口
*
* @author ruoyi
* @date 2026-01-19
*/
public interface SysChatSessionMapper
{
/**
* 查询兽医咨询聊天会话
*
* @param sessionId 兽医咨询聊天会话主键
* @return 兽医咨询聊天会话
*/
public SysChatSession selectSysChatSessionBySessionId(String sessionId);
/**
* 查询兽医咨询聊天会话列表
*
* @param sysChatSession 兽医咨询聊天会话
* @return 兽医咨询聊天会话集合
*/
public List<SysChatSession> selectSysChatSessionList(SysChatSession sysChatSession);
/**
* 新增兽医咨询聊天会话
*
* @param sysChatSession 兽医咨询聊天会话
* @return 结果
*/
public int insertSysChatSession(SysChatSession sysChatSession);
/**
* 修改兽医咨询聊天会话
*
* @param sysChatSession 兽医咨询聊天会话
* @return 结果
*/
public int updateSysChatSession(SysChatSession sysChatSession);
/**
* 删除兽医咨询聊天会话
*
* @param sessionId 兽医咨询聊天会话主键
* @return 结果
*/
public int deleteSysChatSessionBySessionId(String sessionId);
/**
* 批量删除兽医咨询聊天会话
*
* @param sessionIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteSysChatSessionBySessionIds(String[] sessionIds);
}

61
chenhai-system/src/main/java/com/chenhai/system/mapper/SysExpertConsultationMapper.java

@ -1,61 +0,0 @@
package com.chenhai.system.mapper;
import java.util.List;
import com.chenhai.system.domain.SysExpertConsultation;
/**
* 专家咨询Mapper接口
*
* @author ruoyi
* @date 2026-01-12
*/
public interface SysExpertConsultationMapper
{
/**
* 查询专家咨询
*
* @param consultationId 专家咨询主键
* @return 专家咨询
*/
public SysExpertConsultation selectSysExpertConsultationByConsultationId(Long consultationId);
/**
* 查询专家咨询列表
*
* @param sysExpertConsultation 专家咨询
* @return 专家咨询集合
*/
public List<SysExpertConsultation> selectSysExpertConsultationList(SysExpertConsultation sysExpertConsultation);
/**
* 新增专家咨询
*
* @param sysExpertConsultation 专家咨询
* @return 结果
*/
public int insertSysExpertConsultation(SysExpertConsultation sysExpertConsultation);
/**
* 修改专家咨询
*
* @param sysExpertConsultation 专家咨询
* @return 结果
*/
public int updateSysExpertConsultation(SysExpertConsultation sysExpertConsultation);
/**
* 删除专家咨询
*
* @param consultationId 专家咨询主键
* @return 结果
*/
public int deleteSysExpertConsultationByConsultationId(Long consultationId);
/**
* 批量删除专家咨询
*
* @param consultationIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteSysExpertConsultationByConsultationIds(Long[] consultationIds);
}

61
chenhai-system/src/main/java/com/chenhai/system/mapper/SysKnowledgeQueryMapper.java

@ -0,0 +1,61 @@
package com.chenhai.system.mapper;
import java.util.List;
import com.chenhai.system.domain.SysKnowledgeQuery;
/**
* 知识库查询Mapper接口
*
* @author ruoyi
* @date 2026-01-21
*/
public interface SysKnowledgeQueryMapper
{
/**
* 查询知识库查询
*
* @param id 知识库查询主键
* @return 知识库查询
*/
public SysKnowledgeQuery selectSysKnowledgeQueryById(Long id);
/**
* 查询知识库查询列表
*
* @param sysKnowledgeQuery 知识库查询
* @return 知识库查询集合
*/
public List<SysKnowledgeQuery> selectSysKnowledgeQueryList(SysKnowledgeQuery sysKnowledgeQuery);
/**
* 新增知识库查询
*
* @param sysKnowledgeQuery 知识库查询
* @return 结果
*/
public int insertSysKnowledgeQuery(SysKnowledgeQuery sysKnowledgeQuery);
/**
* 修改知识库查询
*
* @param sysKnowledgeQuery 知识库查询
* @return 结果
*/
public int updateSysKnowledgeQuery(SysKnowledgeQuery sysKnowledgeQuery);
/**
* 删除知识库查询
*
* @param id 知识库查询主键
* @return 结果
*/
public int deleteSysKnowledgeQueryById(Long id);
/**
* 批量删除知识库查询
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteSysKnowledgeQueryByIds(Long[] ids);
}

72
chenhai-system/src/main/java/com/chenhai/system/mapper/SysMedicineRecommendationMapper.java

@ -0,0 +1,72 @@
package com.chenhai.system.mapper;
import java.util.List;
import com.chenhai.system.domain.SysMedicineRecommendation;
/**
* 药品推荐Mapper接口
*
* @author ruoyi
* @date 2026-01-20
*/
public interface SysMedicineRecommendationMapper
{
/**
* 查询药品推荐
*
* @param id 药品推荐主键
* @return 药品推荐
*/
public SysMedicineRecommendation selectSysMedicineRecommendationById(Long id);
/**
* 查询药品推荐列表
*
* @param sysMedicineRecommendation 药品推荐
* @return 药品推荐集合
*/
public List<SysMedicineRecommendation> selectSysMedicineRecommendationList(SysMedicineRecommendation sysMedicineRecommendation);
/**
* 新增药品推荐
*
* @param sysMedicineRecommendation 药品推荐
* @return 结果
*/
public int insertSysMedicineRecommendation(SysMedicineRecommendation sysMedicineRecommendation);
/**
* 修改药品推荐
*
* @param sysMedicineRecommendation 药品推荐
* @return 结果
*/
public int updateSysMedicineRecommendation(SysMedicineRecommendation sysMedicineRecommendation);
/**
* 删除药品推荐
*
* @param id 药品推荐主键
* @return 结果
*/
public int deleteSysMedicineRecommendationById(Long id);
/**
* 批量删除药品推荐
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteSysMedicineRecommendationByIds(Long[] ids);
// 添加专家查询方法声明
String getExpertNameById(Long expertId);
String getExpertExpertById(Long expertId);
String getExpertIntroductionById(Long expertId);
String getExpertAddressById(Long expertId);
String getExpertExpertiseAreaById(Long expertId);
String getExpertWorkExperienceById(Long expertId);
}

8
chenhai-system/src/main/java/com/chenhai/system/mapper/SysPolicyInterpretationMapper.java

@ -92,4 +92,12 @@ public interface SysPolicyInterpretationMapper
* @return 结果 * @return 结果
*/ */
public int unpublishSysPolicyInterpretationByIds(Long[] ids, String removalReason); public int unpublishSysPolicyInterpretationByIds(Long[] ids, String removalReason);
/**
* 查询已上架政策解读列表
*
* @param sysPolicyInterpretation 政策解读查询条件会忽略publish_status条件
* @return 政策解读集合
*/
public List<SysPolicyInterpretation> selectPublishedSysPolicyInterpretationList(SysPolicyInterpretation sysPolicyInterpretation);
} }

61
chenhai-system/src/main/java/com/chenhai/system/mapper/SysQueryTipMapper.java

@ -0,0 +1,61 @@
package com.chenhai.system.mapper;
import java.util.List;
import com.chenhai.system.domain.SysQueryTip;
/**
* 知识库查询提示Mapper接口
*
* @author ruoyi
* @date 2026-01-22
*/
public interface SysQueryTipMapper
{
/**
* 查询知识库查询提示
*
* @param id 知识库查询提示主键
* @return 知识库查询提示
*/
public SysQueryTip selectSysQueryTipById(Long id);
/**
* 查询知识库查询提示列表
*
* @param sysQueryTip 知识库查询提示
* @return 知识库查询提示集合
*/
public List<SysQueryTip> selectSysQueryTipList(SysQueryTip sysQueryTip);
/**
* 新增知识库查询提示
*
* @param sysQueryTip 知识库查询提示
* @return 结果
*/
public int insertSysQueryTip(SysQueryTip sysQueryTip);
/**
* 修改知识库查询提示
*
* @param sysQueryTip 知识库查询提示
* @return 结果
*/
public int updateSysQueryTip(SysQueryTip sysQueryTip);
/**
* 删除知识库查询提示
*
* @param id 知识库查询提示主键
* @return 结果
*/
public int deleteSysQueryTipById(Long id);
/**
* 批量删除知识库查询提示
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteSysQueryTipByIds(Long[] ids);
}

87
chenhai-system/src/main/java/com/chenhai/system/service/ISysChatMessageService.java

@ -0,0 +1,87 @@
package com.chenhai.system.service;
import java.util.List;
import com.chenhai.system.domain.SysChatMessage;
/**
* 兽医咨询聊天消息Service接口
*
* @author ruoyi
* @date 2026-01-19
*/
public interface ISysChatMessageService
{
/**
* 查询兽医咨询聊天消息
*
* @param messageId 兽医咨询聊天消息主键
* @return 兽医咨询聊天消息
*/
public SysChatMessage selectSysChatMessageByMessageId(Long messageId);
/**
* 查询兽医咨询聊天消息列表
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 兽医咨询聊天消息集合
*/
public List<SysChatMessage> selectSysChatMessageList(SysChatMessage sysChatMessage);
/**
* 新增兽医咨询聊天消息
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 结果
*/
public int insertSysChatMessage(SysChatMessage sysChatMessage);
/**
* 修改兽医咨询聊天消息
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 结果
*/
public int updateSysChatMessage(SysChatMessage sysChatMessage);
/**
* 批量删除兽医咨询聊天消息
*
* @param messageIds 需要删除的兽医咨询聊天消息主键集合
* @return 结果
*/
public int deleteSysChatMessageByMessageIds(Long[] messageIds);
/**
* 删除兽医咨询聊天消息信息
*
* @param messageId 兽医咨询聊天消息主键
* @return 结果
*/
public int deleteSysChatMessageByMessageId(Long messageId);
// 新增方法复制以下代码到现有接口中
/**
* 根据会话ID查询消息列表
*/
List<SysChatMessage> selectMessagesBySessionId(String sessionId);
/**
* 发送文本消息
*/
int sendTextMessage(String sessionId, String senderType, Long senderId, String content);
/**
* 发送系统消息
*/
int sendSystemMessage(String sessionId, String content);
/**
* 标记消息为已读
*/
int markMessageAsRead(Long messageId);
/**
* 标记会话中所有消息为已读
*/
int markAllMessagesAsRead(String sessionId, String senderType);
}

102
chenhai-system/src/main/java/com/chenhai/system/service/ISysChatSessionService.java

@ -0,0 +1,102 @@
package com.chenhai.system.service;
import java.util.List;
import com.chenhai.system.domain.SysChatSession;
/**
* 兽医咨询聊天会话Service接口
*
* @author ruoyi
* @date 2026-01-19
*/
public interface ISysChatSessionService
{
/**
* 查询兽医咨询聊天会话
*
* @param sessionId 兽医咨询聊天会话主键
* @return 兽医咨询聊天会话
*/
public SysChatSession selectSysChatSessionBySessionId(String sessionId);
/**
* 查询兽医咨询聊天会话列表
*
* @param sysChatSession 兽医咨询聊天会话
* @return 兽医咨询聊天会话集合
*/
public List<SysChatSession> selectSysChatSessionList(SysChatSession sysChatSession);
/**
* 新增兽医咨询聊天会话
*
* @param sysChatSession 兽医咨询聊天会话
* @return 结果
*/
public int insertSysChatSession(SysChatSession sysChatSession);
/**
* 修改兽医咨询聊天会话
*
* @param sysChatSession 兽医咨询聊天会话
* @return 结果
*/
public int updateSysChatSession(SysChatSession sysChatSession);
/**
* 批量删除兽医咨询聊天会话
*
* @param sessionIds 需要删除的兽医咨询聊天会话主键集合
* @return 结果
*/
public int deleteSysChatSessionBySessionIds(String[] sessionIds);
/**
* 删除兽医咨询聊天会话信息
*
* @param sessionId 兽医咨询聊天会话主键
* @return 结果
*/
public int deleteSysChatSessionBySessionId(String sessionId);
// 新增的方法复制以下代码到现有接口中
/**
* 根据用户ID查询会话列表
*/
List<SysChatSession> selectSessionsByUserId(Long userId);
/**
* 根据专家ID查询会话列表
*/
List<SysChatSession> selectSessionsByExpertId(Long expertId);
/**
* 创建或获取会话
*/
String createOrGetSession(Long userId, Long expertId, String animalType, String symptomSummary);
/**
* 更新最后一条消息
*/
int updateLastMessage(String sessionId, String lastMessage);
/**
* 增加用户未读数
*/
int incrementUnreadUser(String sessionId);
/**
* 增加专家未读数
*/
int incrementUnreadExpert(String sessionId);
/**
* 标记用户已读
*/
int markUserRead(String sessionId);
/**
* 标记专家已读
*/
int markExpertRead(String sessionId);
}

61
chenhai-system/src/main/java/com/chenhai/system/service/ISysExpertConsultationService.java

@ -1,61 +0,0 @@
package com.chenhai.system.service;
import java.util.List;
import com.chenhai.system.domain.SysExpertConsultation;
/**
* 专家咨询Service接口
*
* @author ruoyi
* @date 2026-01-12
*/
public interface ISysExpertConsultationService
{
/**
* 查询专家咨询
*
* @param consultationId 专家咨询主键
* @return 专家咨询
*/
public SysExpertConsultation selectSysExpertConsultationByConsultationId(Long consultationId);
/**
* 查询专家咨询列表
*
* @param sysExpertConsultation 专家咨询
* @return 专家咨询集合
*/
public List<SysExpertConsultation> selectSysExpertConsultationList(SysExpertConsultation sysExpertConsultation);
/**
* 新增专家咨询
*
* @param sysExpertConsultation 专家咨询
* @return 结果
*/
public int insertSysExpertConsultation(SysExpertConsultation sysExpertConsultation);
/**
* 修改专家咨询
*
* @param sysExpertConsultation 专家咨询
* @return 结果
*/
public int updateSysExpertConsultation(SysExpertConsultation sysExpertConsultation);
/**
* 批量删除专家咨询
*
* @param consultationIds 需要删除的专家咨询主键集合
* @return 结果
*/
public int deleteSysExpertConsultationByConsultationIds(Long[] consultationIds);
/**
* 删除专家咨询信息
*
* @param consultationId 专家咨询主键
* @return 结果
*/
public int deleteSysExpertConsultationByConsultationId(Long consultationId);
}

61
chenhai-system/src/main/java/com/chenhai/system/service/ISysKnowledgeQueryService.java

@ -0,0 +1,61 @@
package com.chenhai.system.service;
import java.util.List;
import com.chenhai.system.domain.SysKnowledgeQuery;
/**
* 知识库查询Service接口
*
* @author ruoyi
* @date 2026-01-21
*/
public interface ISysKnowledgeQueryService
{
/**
* 查询知识库查询
*
* @param id 知识库查询主键
* @return 知识库查询
*/
public SysKnowledgeQuery selectSysKnowledgeQueryById(Long id);
/**
* 查询知识库查询列表
*
* @param sysKnowledgeQuery 知识库查询
* @return 知识库查询集合
*/
public List<SysKnowledgeQuery> selectSysKnowledgeQueryList(SysKnowledgeQuery sysKnowledgeQuery);
/**
* 新增知识库查询
*
* @param sysKnowledgeQuery 知识库查询
* @return 结果
*/
public int insertSysKnowledgeQuery(SysKnowledgeQuery sysKnowledgeQuery);
/**
* 修改知识库查询
*
* @param sysKnowledgeQuery 知识库查询
* @return 结果
*/
public int updateSysKnowledgeQuery(SysKnowledgeQuery sysKnowledgeQuery);
/**
* 批量删除知识库查询
*
* @param ids 需要删除的知识库查询主键集合
* @return 结果
*/
public int deleteSysKnowledgeQueryByIds(Long[] ids);
/**
* 删除知识库查询信息
*
* @param id 知识库查询主键
* @return 结果
*/
public int deleteSysKnowledgeQueryById(Long id);
}

61
chenhai-system/src/main/java/com/chenhai/system/service/ISysMedicineRecommendationService.java

@ -0,0 +1,61 @@
package com.chenhai.system.service;
import java.util.List;
import com.chenhai.system.domain.SysMedicineRecommendation;
/**
* 药品推荐Service接口
*
* @author ruoyi
* @date 2026-01-20
*/
public interface ISysMedicineRecommendationService
{
/**
* 查询药品推荐
*
* @param id 药品推荐主键
* @return 药品推荐
*/
public SysMedicineRecommendation selectSysMedicineRecommendationById(Long id);
/**
* 查询药品推荐列表
*
* @param sysMedicineRecommendation 药品推荐
* @return 药品推荐集合
*/
public List<SysMedicineRecommendation> selectSysMedicineRecommendationList(SysMedicineRecommendation sysMedicineRecommendation);
/**
* 新增药品推荐
*
* @param sysMedicineRecommendation 药品推荐
* @return 结果
*/
public int insertSysMedicineRecommendation(SysMedicineRecommendation sysMedicineRecommendation);
/**
* 修改药品推荐
*
* @param sysMedicineRecommendation 药品推荐
* @return 结果
*/
public int updateSysMedicineRecommendation(SysMedicineRecommendation sysMedicineRecommendation);
/**
* 批量删除药品推荐
*
* @param ids 需要删除的药品推荐主键集合
* @return 结果
*/
public int deleteSysMedicineRecommendationByIds(Long[] ids);
/**
* 删除药品推荐信息
*
* @param id 药品推荐主键
* @return 结果
*/
public int deleteSysMedicineRecommendationById(Long id);
}

8
chenhai-system/src/main/java/com/chenhai/system/service/ISysPolicyInterpretationService.java

@ -92,4 +92,12 @@ public interface ISysPolicyInterpretationService
* @return 结果 * @return 结果
*/ */
public int unpublishSysPolicyInterpretationByIds(Long[] ids, String removalReason); public int unpublishSysPolicyInterpretationByIds(Long[] ids, String removalReason);
/**
* 查询已上架政策解读列表
*
* @param sysPolicyInterpretation 政策解读查询条件
* @return 政策解读集合
*/
public List<SysPolicyInterpretation> selectPublishedSysPolicyInterpretationList(SysPolicyInterpretation sysPolicyInterpretation);
} }

61
chenhai-system/src/main/java/com/chenhai/system/service/ISysQueryTipService.java

@ -0,0 +1,61 @@
package com.chenhai.system.service;
import java.util.List;
import com.chenhai.system.domain.SysQueryTip;
/**
* 知识库查询提示Service接口
*
* @author ruoyi
* @date 2026-01-22
*/
public interface ISysQueryTipService
{
/**
* 查询知识库查询提示
*
* @param id 知识库查询提示主键
* @return 知识库查询提示
*/
public SysQueryTip selectSysQueryTipById(Long id);
/**
* 查询知识库查询提示列表
*
* @param sysQueryTip 知识库查询提示
* @return 知识库查询提示集合
*/
public List<SysQueryTip> selectSysQueryTipList(SysQueryTip sysQueryTip);
/**
* 新增知识库查询提示
*
* @param sysQueryTip 知识库查询提示
* @return 结果
*/
public int insertSysQueryTip(SysQueryTip sysQueryTip);
/**
* 修改知识库查询提示
*
* @param sysQueryTip 知识库查询提示
* @return 结果
*/
public int updateSysQueryTip(SysQueryTip sysQueryTip);
/**
* 批量删除知识库查询提示
*
* @param ids 需要删除的知识库查询提示主键集合
* @return 结果
*/
public int deleteSysQueryTipByIds(Long[] ids);
/**
* 删除知识库查询提示信息
*
* @param id 知识库查询提示主键
* @return 结果
*/
public int deleteSysQueryTipById(Long id);
}

207
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysChatMessageServiceImpl.java

@ -0,0 +1,207 @@
package com.chenhai.system.service.impl;
import java.util.List;
import com.chenhai.common.utils.DateUtils;
import com.chenhai.system.service.ISysChatSessionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.system.mapper.SysChatMessageMapper;
import com.chenhai.system.domain.SysChatMessage;
import com.chenhai.system.service.ISysChatMessageService;
import org.springframework.transaction.annotation.Transactional;
/**
* 兽医咨询聊天消息Service业务层处理
*
* @author ruoyi
* @date 2026-01-19
*/
@Service
public class SysChatMessageServiceImpl implements ISysChatMessageService
{
@Autowired
private SysChatMessageMapper sysChatMessageMapper;
@Autowired
private ISysChatSessionService sessionService; // 添加这行
/**
* 查询兽医咨询聊天消息
*
* @param messageId 兽医咨询聊天消息主键
* @return 兽医咨询聊天消息
*/
@Override
public SysChatMessage selectSysChatMessageByMessageId(Long messageId)
{
return sysChatMessageMapper.selectSysChatMessageByMessageId(messageId);
}
/**
* 查询兽医咨询聊天消息列表
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 兽医咨询聊天消息
*/
@Override
public List<SysChatMessage> selectSysChatMessageList(SysChatMessage sysChatMessage)
{
return sysChatMessageMapper.selectSysChatMessageList(sysChatMessage);
}
/**
* 新增兽医咨询聊天消息
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 结果
*/
@Override
public int insertSysChatMessage(SysChatMessage sysChatMessage)
{
sysChatMessage.setCreateTime(DateUtils.getNowDate());
return sysChatMessageMapper.insertSysChatMessage(sysChatMessage);
}
/**
* 修改兽医咨询聊天消息
*
* @param sysChatMessage 兽医咨询聊天消息
* @return 结果
*/
@Override
public int updateSysChatMessage(SysChatMessage sysChatMessage)
{
sysChatMessage.setUpdateTime(DateUtils.getNowDate());
return sysChatMessageMapper.updateSysChatMessage(sysChatMessage);
}
/**
* 批量删除兽医咨询聊天消息
*
* @param messageIds 需要删除的兽医咨询聊天消息主键
* @return 结果
*/
@Override
public int deleteSysChatMessageByMessageIds(Long[] messageIds)
{
return sysChatMessageMapper.deleteSysChatMessageByMessageIds(messageIds);
}
/**
* 删除兽医咨询聊天消息信息
*
* @param messageId 兽医咨询聊天消息主键
* @return 结果
*/
@Override
public int deleteSysChatMessageByMessageId(Long messageId)
{
return sysChatMessageMapper.deleteSysChatMessageByMessageId(messageId);
}
// ============ 新增的方法 ============
@Override
public List<SysChatMessage> selectMessagesBySessionId(String sessionId) {
SysChatMessage query = new SysChatMessage();
query.setSessionId(sessionId);
query.setDelFlag("0");
return sysChatMessageMapper.selectSysChatMessageList(query);
}
@Override
@Transactional
public int sendTextMessage(String sessionId, String senderType, Long senderId, String content) {
SysChatMessage message = new SysChatMessage();
message.setSessionId(sessionId);
message.setSenderType(senderType);
message.setSenderId(senderId);
message.setContent(content);
message.setMsgType("text");
message.setIsRead("0");
message.setDelFlag("0");
message.setCreateTime(DateUtils.getNowDate());
int result = sysChatMessageMapper.insertSysChatMessage(message);
if (result > 0) {
// 更新会话的最后一条消息截取前50个字符
String lastMessage = content.length() > 50 ? content.substring(0, 50) + "..." : content;
sessionService.updateLastMessage(sessionId, lastMessage);
// 更新未读数
if ("0".equals(senderType)) {
// 用户发送的消息增加专家未读数
sessionService.incrementUnreadExpert(sessionId);
} else {
// 专家发送的消息增加用户未读数
sessionService.incrementUnreadUser(sessionId);
}
}
return result;
}
@Override
@Transactional
public int sendSystemMessage(String sessionId, String content) {
SysChatMessage message = new SysChatMessage();
message.setSessionId(sessionId);
message.setSenderType("2"); // 系统消息
message.setSenderId(0L);
message.setContent("[系统]" + content);
message.setMsgType("text");
message.setIsRead("1"); // 系统消息默认已读
message.setDelFlag("0");
message.setCreateTime(DateUtils.getNowDate());
int result = sysChatMessageMapper.insertSysChatMessage(message);
if (result > 0) {
sessionService.updateLastMessage(sessionId, content);
}
return result;
}
@Override
@Transactional
public int markMessageAsRead(Long messageId) {
SysChatMessage message = new SysChatMessage();
message.setMessageId(messageId);
message.setIsRead("1");
message.setReadTime(DateUtils.getNowDate());
message.setUpdateTime(DateUtils.getNowDate());
return sysChatMessageMapper.updateSysChatMessage(message);
}
@Override
@Transactional
public int markAllMessagesAsRead(String sessionId, String senderType) {
// 查询所有未读消息
SysChatMessage query = new SysChatMessage();
query.setSessionId(sessionId);
query.setIsRead("0");
query.setSenderType(senderType);
query.setDelFlag("0");
List<SysChatMessage> unreadMessages = sysChatMessageMapper.selectSysChatMessageList(query);
int count = 0;
for (SysChatMessage message : unreadMessages) {
count += markMessageAsRead(message.getMessageId());
}
// 更新会话未读数
if ("0".equals(senderType)) {
// 用户标记专家消息为已读
sessionService.markExpertRead(sessionId);
} else {
// 专家标记用户消息为已读
sessionService.markUserRead(sessionId);
}
return count;
}
}

207
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysChatSessionServiceImpl.java

@ -0,0 +1,207 @@
package com.chenhai.system.service.impl;
import java.util.List;
import com.chenhai.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.system.mapper.SysChatSessionMapper;
import com.chenhai.system.domain.SysChatSession;
import com.chenhai.system.service.ISysChatSessionService;
import org.springframework.transaction.annotation.Transactional;
/**
* 兽医咨询聊天会话Service业务层处理
*
* @author ruoyi
* @date 2026-01-19
*/
@Service
public class SysChatSessionServiceImpl implements ISysChatSessionService
{
@Autowired
private SysChatSessionMapper sysChatSessionMapper;
/**
* 查询兽医咨询聊天会话
*
* @param sessionId 兽医咨询聊天会话主键
* @return 兽医咨询聊天会话
*/
@Override
public SysChatSession selectSysChatSessionBySessionId(String sessionId)
{
return sysChatSessionMapper.selectSysChatSessionBySessionId(sessionId);
}
/**
* 查询兽医咨询聊天会话列表
*
* @param sysChatSession 兽医咨询聊天会话
* @return 兽医咨询聊天会话
*/
@Override
public List<SysChatSession> selectSysChatSessionList(SysChatSession sysChatSession)
{
return sysChatSessionMapper.selectSysChatSessionList(sysChatSession);
}
/**
* 新增兽医咨询聊天会话
*
* @param sysChatSession 兽医咨询聊天会话
* @return 结果
*/
@Override
public int insertSysChatSession(SysChatSession sysChatSession)
{
sysChatSession.setCreateTime(DateUtils.getNowDate());
return sysChatSessionMapper.insertSysChatSession(sysChatSession);
}
/**
* 修改兽医咨询聊天会话
*
* @param sysChatSession 兽医咨询聊天会话
* @return 结果
*/
@Override
public int updateSysChatSession(SysChatSession sysChatSession)
{
sysChatSession.setUpdateTime(DateUtils.getNowDate());
return sysChatSessionMapper.updateSysChatSession(sysChatSession);
}
/**
* 批量删除兽医咨询聊天会话
*
* @param sessionIds 需要删除的兽医咨询聊天会话主键
* @return 结果
*/
@Override
public int deleteSysChatSessionBySessionIds(String[] sessionIds)
{
return sysChatSessionMapper.deleteSysChatSessionBySessionIds(sessionIds);
}
/**
* 删除兽医咨询聊天会话信息
*
* @param sessionId 兽医咨询聊天会话主键
* @return 结果
*/
@Override
public int deleteSysChatSessionBySessionId(String sessionId)
{
return sysChatSessionMapper.deleteSysChatSessionBySessionId(sessionId);
}
// ============ 新增的方法 ============
@Override
public List<SysChatSession> selectSessionsByUserId(Long userId) {
SysChatSession query = new SysChatSession();
query.setUserId(userId);
query.setDelFlag("0");
return sysChatSessionMapper.selectSysChatSessionList(query);
}
@Override
public List<SysChatSession> selectSessionsByExpertId(Long expertId) {
SysChatSession query = new SysChatSession();
query.setExpertId(expertId);
query.setDelFlag("0");
return sysChatSessionMapper.selectSysChatSessionList(query);
}
@Override
@Transactional
public String createOrGetSession(Long userId, Long expertId, String animalType, String symptomSummary) {
String sessionId = "user_" + userId + "_expert_" + expertId;
// 检查是否已存在该会话
SysChatSession existingSession = selectSysChatSessionBySessionId(sessionId);
if (existingSession == null || "2".equals(existingSession.getDelFlag())) {
// 创建新会话
SysChatSession session = new SysChatSession();
session.setSessionId(sessionId);
session.setUserId(userId);
session.setExpertId(expertId);
session.setAnimalType(animalType);
session.setSymptomSummary(symptomSummary);
session.setLastMessage("开始咨询");
session.setLastMessageTime(DateUtils.getNowDate());
session.setUnreadUser(0L);
session.setUnreadExpert(1L); // 专家有1条未读消息欢迎消息
session.setSessionStatus("0"); // 进行中
session.setDelFlag("0");
session.setCreateTime(DateUtils.getNowDate());
sysChatSessionMapper.insertSysChatSession(session);
} else if ("1".equals(existingSession.getSessionStatus())) {
// 如果会话已结束重新激活
existingSession.setSessionStatus("0");
existingSession.setUpdateTime(DateUtils.getNowDate());
sysChatSessionMapper.updateSysChatSession(existingSession);
}
return sessionId;
}
@Override
@Transactional
public int updateLastMessage(String sessionId, String lastMessage) {
SysChatSession session = new SysChatSession();
session.setSessionId(sessionId);
session.setLastMessage(lastMessage);
session.setLastMessageTime(DateUtils.getNowDate());
session.setUpdateTime(DateUtils.getNowDate());
return sysChatSessionMapper.updateSysChatSession(session);
}
@Override
@Transactional
public int incrementUnreadUser(String sessionId) {
SysChatSession session = selectSysChatSessionBySessionId(sessionId);
if (session != null) {
Long currentUnread = session.getUnreadUser() != null ? session.getUnreadUser() : 0L;
session.setUnreadUser(currentUnread + 1);
session.setUpdateTime(DateUtils.getNowDate());
return sysChatSessionMapper.updateSysChatSession(session);
}
return 0;
}
@Override
@Transactional
public int incrementUnreadExpert(String sessionId) {
SysChatSession session = selectSysChatSessionBySessionId(sessionId);
if (session != null) {
Long currentUnread = session.getUnreadExpert() != null ? session.getUnreadExpert() : 0L;
session.setUnreadExpert(currentUnread + 1);
session.setUpdateTime(DateUtils.getNowDate());
return sysChatSessionMapper.updateSysChatSession(session);
}
return 0;
}
@Override
@Transactional
public int markUserRead(String sessionId) {
SysChatSession session = new SysChatSession();
session.setSessionId(sessionId);
session.setUnreadUser(0L);
session.setUpdateTime(DateUtils.getNowDate());
return sysChatSessionMapper.updateSysChatSession(session);
}
@Override
@Transactional
public int markExpertRead(String sessionId) {
SysChatSession session = new SysChatSession();
session.setSessionId(sessionId);
session.setUnreadExpert(0L);
session.setUpdateTime(DateUtils.getNowDate());
return sysChatSessionMapper.updateSysChatSession(session);
}
}

93
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysExpertConsultationServiceImpl.java

@ -1,93 +0,0 @@
package com.chenhai.system.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.system.mapper.SysExpertConsultationMapper;
import com.chenhai.system.domain.SysExpertConsultation;
import com.chenhai.system.service.ISysExpertConsultationService;
/**
* 专家咨询Service业务层处理
*
* @author ruoyi
* @date 2026-01-12
*/
@Service
public class SysExpertConsultationServiceImpl implements ISysExpertConsultationService
{
@Autowired
private SysExpertConsultationMapper sysExpertConsultationMapper;
/**
* 查询专家咨询
*
* @param consultationId 专家咨询主键
* @return 专家咨询
*/
@Override
public SysExpertConsultation selectSysExpertConsultationByConsultationId(Long consultationId)
{
return sysExpertConsultationMapper.selectSysExpertConsultationByConsultationId(consultationId);
}
/**
* 查询专家咨询列表
*
* @param sysExpertConsultation 专家咨询
* @return 专家咨询
*/
@Override
public List<SysExpertConsultation> selectSysExpertConsultationList(SysExpertConsultation sysExpertConsultation)
{
return sysExpertConsultationMapper.selectSysExpertConsultationList(sysExpertConsultation);
}
/**
* 新增专家咨询
*
* @param sysExpertConsultation 专家咨询
* @return 结果
*/
@Override
public int insertSysExpertConsultation(SysExpertConsultation sysExpertConsultation)
{
return sysExpertConsultationMapper.insertSysExpertConsultation(sysExpertConsultation);
}
/**
* 修改专家咨询
*
* @param sysExpertConsultation 专家咨询
* @return 结果
*/
@Override
public int updateSysExpertConsultation(SysExpertConsultation sysExpertConsultation)
{
return sysExpertConsultationMapper.updateSysExpertConsultation(sysExpertConsultation);
}
/**
* 批量删除专家咨询
*
* @param consultationIds 需要删除的专家咨询主键
* @return 结果
*/
@Override
public int deleteSysExpertConsultationByConsultationIds(Long[] consultationIds)
{
return sysExpertConsultationMapper.deleteSysExpertConsultationByConsultationIds(consultationIds);
}
/**
* 删除专家咨询信息
*
* @param consultationId 专家咨询主键
* @return 结果
*/
@Override
public int deleteSysExpertConsultationByConsultationId(Long consultationId)
{
return sysExpertConsultationMapper.deleteSysExpertConsultationByConsultationId(consultationId);
}
}

93
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysKnowledgeQueryServiceImpl.java

@ -0,0 +1,93 @@
package com.chenhai.system.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.system.mapper.SysKnowledgeQueryMapper;
import com.chenhai.system.domain.SysKnowledgeQuery;
import com.chenhai.system.service.ISysKnowledgeQueryService;
/**
* 知识库查询Service业务层处理
*
* @author ruoyi
* @date 2026-01-21
*/
@Service
public class SysKnowledgeQueryServiceImpl implements ISysKnowledgeQueryService
{
@Autowired
private SysKnowledgeQueryMapper sysKnowledgeQueryMapper;
/**
* 查询知识库查询
*
* @param id 知识库查询主键
* @return 知识库查询
*/
@Override
public SysKnowledgeQuery selectSysKnowledgeQueryById(Long id)
{
return sysKnowledgeQueryMapper.selectSysKnowledgeQueryById(id);
}
/**
* 查询知识库查询列表
*
* @param sysKnowledgeQuery 知识库查询
* @return 知识库查询
*/
@Override
public List<SysKnowledgeQuery> selectSysKnowledgeQueryList(SysKnowledgeQuery sysKnowledgeQuery)
{
return sysKnowledgeQueryMapper.selectSysKnowledgeQueryList(sysKnowledgeQuery);
}
/**
* 新增知识库查询
*
* @param sysKnowledgeQuery 知识库查询
* @return 结果
*/
@Override
public int insertSysKnowledgeQuery(SysKnowledgeQuery sysKnowledgeQuery)
{
return sysKnowledgeQueryMapper.insertSysKnowledgeQuery(sysKnowledgeQuery);
}
/**
* 修改知识库查询
*
* @param sysKnowledgeQuery 知识库查询
* @return 结果
*/
@Override
public int updateSysKnowledgeQuery(SysKnowledgeQuery sysKnowledgeQuery)
{
return sysKnowledgeQueryMapper.updateSysKnowledgeQuery(sysKnowledgeQuery);
}
/**
* 批量删除知识库查询
*
* @param ids 需要删除的知识库查询主键
* @return 结果
*/
@Override
public int deleteSysKnowledgeQueryByIds(Long[] ids)
{
return sysKnowledgeQueryMapper.deleteSysKnowledgeQueryByIds(ids);
}
/**
* 删除知识库查询信息
*
* @param id 知识库查询主键
* @return 结果
*/
@Override
public int deleteSysKnowledgeQueryById(Long id)
{
return sysKnowledgeQueryMapper.deleteSysKnowledgeQueryById(id);
}
}

93
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysMedicineRecommendationServiceImpl.java

@ -0,0 +1,93 @@
package com.chenhai.system.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.system.mapper.SysMedicineRecommendationMapper;
import com.chenhai.system.domain.SysMedicineRecommendation;
import com.chenhai.system.service.ISysMedicineRecommendationService;
/**
* 药品推荐Service业务层处理
*
* @author ruoyi
* @date 2026-01-20
*/
@Service
public class SysMedicineRecommendationServiceImpl implements ISysMedicineRecommendationService
{
@Autowired
private SysMedicineRecommendationMapper sysMedicineRecommendationMapper;
/**
* 查询药品推荐
*
* @param id 药品推荐主键
* @return 药品推荐
*/
@Override
public SysMedicineRecommendation selectSysMedicineRecommendationById(Long id)
{
return sysMedicineRecommendationMapper.selectSysMedicineRecommendationById(id);
}
/**
* 查询药品推荐列表
*
* @param sysMedicineRecommendation 药品推荐
* @return 药品推荐
*/
@Override
public List<SysMedicineRecommendation> selectSysMedicineRecommendationList(SysMedicineRecommendation sysMedicineRecommendation)
{
return sysMedicineRecommendationMapper.selectSysMedicineRecommendationList(sysMedicineRecommendation);
}
/**
* 新增药品推荐
*
* @param sysMedicineRecommendation 药品推荐
* @return 结果
*/
@Override
public int insertSysMedicineRecommendation(SysMedicineRecommendation sysMedicineRecommendation)
{
return sysMedicineRecommendationMapper.insertSysMedicineRecommendation(sysMedicineRecommendation);
}
/**
* 修改药品推荐
*
* @param sysMedicineRecommendation 药品推荐
* @return 结果
*/
@Override
public int updateSysMedicineRecommendation(SysMedicineRecommendation sysMedicineRecommendation)
{
return sysMedicineRecommendationMapper.updateSysMedicineRecommendation(sysMedicineRecommendation);
}
/**
* 批量删除药品推荐
*
* @param ids 需要删除的药品推荐主键
* @return 结果
*/
@Override
public int deleteSysMedicineRecommendationByIds(Long[] ids)
{
return sysMedicineRecommendationMapper.deleteSysMedicineRecommendationByIds(ids);
}
/**
* 删除药品推荐信息
*
* @param id 药品推荐主键
* @return 结果
*/
@Override
public int deleteSysMedicineRecommendationById(Long id)
{
return sysMedicineRecommendationMapper.deleteSysMedicineRecommendationById(id);
}
}

16
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysPolicyInterpretationServiceImpl.java

@ -22,7 +22,7 @@ public class SysPolicyInterpretationServiceImpl implements ISysPolicyInterpretat
/** /**
* 查询政策解读 * 查询政策解读
*
*
* @param id 政策解读主键 * @param id 政策解读主键
* @return 政策解读 * @return 政策解读
*/ */
@ -143,4 +143,18 @@ public class SysPolicyInterpretationServiceImpl implements ISysPolicyInterpretat
{ {
return sysPolicyInterpretationMapper.unpublishSysPolicyInterpretationByIds(ids, removalReason); return sysPolicyInterpretationMapper.unpublishSysPolicyInterpretationByIds(ids, removalReason);
} }
/**
* 查询已上架政策解读列表
*
* @param sysPolicyInterpretation 政策解读查询条件
* @return 政策解读
*/
@Override
public List<SysPolicyInterpretation> selectPublishedSysPolicyInterpretationList(SysPolicyInterpretation sysPolicyInterpretation)
{
// 强制设置只查询已上架的数据
sysPolicyInterpretation.setPublishStatus("1");
return sysPolicyInterpretationMapper.selectPublishedSysPolicyInterpretationList(sysPolicyInterpretation);
}
} }

93
chenhai-system/src/main/java/com/chenhai/system/service/impl/SysQueryTipServiceImpl.java

@ -0,0 +1,93 @@
package com.chenhai.system.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chenhai.system.mapper.SysQueryTipMapper;
import com.chenhai.system.domain.SysQueryTip;
import com.chenhai.system.service.ISysQueryTipService;
/**
* 知识库查询提示Service业务层处理
*
* @author ruoyi
* @date 2026-01-22
*/
@Service
public class SysQueryTipServiceImpl implements ISysQueryTipService
{
@Autowired
private SysQueryTipMapper sysQueryTipMapper;
/**
* 查询知识库查询提示
*
* @param id 知识库查询提示主键
* @return 知识库查询提示
*/
@Override
public SysQueryTip selectSysQueryTipById(Long id)
{
return sysQueryTipMapper.selectSysQueryTipById(id);
}
/**
* 查询知识库查询提示列表
*
* @param sysQueryTip 知识库查询提示
* @return 知识库查询提示
*/
@Override
public List<SysQueryTip> selectSysQueryTipList(SysQueryTip sysQueryTip)
{
return sysQueryTipMapper.selectSysQueryTipList(sysQueryTip);
}
/**
* 新增知识库查询提示
*
* @param sysQueryTip 知识库查询提示
* @return 结果
*/
@Override
public int insertSysQueryTip(SysQueryTip sysQueryTip)
{
return sysQueryTipMapper.insertSysQueryTip(sysQueryTip);
}
/**
* 修改知识库查询提示
*
* @param sysQueryTip 知识库查询提示
* @return 结果
*/
@Override
public int updateSysQueryTip(SysQueryTip sysQueryTip)
{
return sysQueryTipMapper.updateSysQueryTip(sysQueryTip);
}
/**
* 批量删除知识库查询提示
*
* @param ids 需要删除的知识库查询提示主键
* @return 结果
*/
@Override
public int deleteSysQueryTipByIds(Long[] ids)
{
return sysQueryTipMapper.deleteSysQueryTipByIds(ids);
}
/**
* 删除知识库查询提示信息
*
* @param id 知识库查询提示主键
* @return 结果
*/
@Override
public int deleteSysQueryTipById(Long id)
{
return sysQueryTipMapper.deleteSysQueryTipById(id);
}
}

15
chenhai-system/src/main/java/com/chenhai/vet/domain/VetExperts.java

@ -76,6 +76,10 @@ public class VetExperts extends BaseEntity
@Excel(name = "从业经验") @Excel(name = "从业经验")
private String workExperience; private String workExperience;
/** 专家简介 */
@Excel(name = "专家简介")
private String introduction;
/** $column.columnComment */ /** $column.columnComment */
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
private Date createdAt; private Date createdAt;
@ -254,6 +258,16 @@ public class VetExperts extends BaseEntity
return workExperience; return workExperience;
} }
public void setIntroduction(String introduction)
{
this.introduction = introduction;
}
public String getIntroduction()
{
return introduction;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -274,6 +288,7 @@ public class VetExperts extends BaseEntity
.append("updatedAt", getUpdatedAt()) .append("updatedAt", getUpdatedAt())
.append("expert", getExpert()) .append("expert", getExpert())
.append("workExperience", getWorkExperience()) .append("workExperience", getWorkExperience())
.append("introduction", getIntroduction())
.toString(); .toString();
} }
} }

91
chenhai-system/src/main/java/com/chenhai/vet/domain/VetKnowledge.java

@ -1,10 +1,13 @@
package com.chenhai.vet.domain; package com.chenhai.vet.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.chenhai.common.annotation.Excel; import com.chenhai.common.annotation.Excel;
import com.chenhai.common.core.domain.BaseEntity; import com.chenhai.common.core.domain.BaseEntity;
import java.util.Date;
/** /**
* 兽医文章对象 vet_knowledge * 兽医文章对象 vet_knowledge
* *
@ -46,6 +49,31 @@ public class VetKnowledge extends BaseEntity
@Excel(name = "审核意见") @Excel(name = "审核意见")
private String auditComment; private String auditComment;
/** 发布时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "发布时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date publishTime;
/** 查看次数 */
@Excel(name = "查看次数")
private Integer viewCount;
/** 封面图片地址 */
@Excel(name = "封面图片")
private String coverImage;
/** 副标题 */
@Excel(name = "副标题")
private String subtitle;
/** 专家ID */
@Excel(name = "专家ID")
private Long expertId;
/** 专家名称(关联查询使用,非数据库字段) */
private String expertName;
private String expertAvatar;
public void setId(Long id) public void setId(Long id)
{ {
this.id = id; this.id = id;
@ -120,6 +148,64 @@ public class VetKnowledge extends BaseEntity
this.auditComment = auditComment; this.auditComment = auditComment;
} }
public Date getPublishTime() {
return publishTime;
}
public void setPublishTime(Date publishTime) {
this.publishTime = publishTime;
}
public Integer getViewCount() {
return viewCount;
}
public void setViewCount(Integer viewCount) {
this.viewCount = viewCount;
}
public Long getExpertId() {
return expertId;
}
public void setExpertId(Long expertId) {
this.expertId = expertId;
}
public void setExpertAvatar(String expertAvatar)
{
this.expertAvatar = expertAvatar;
}
public String getExpertAvatar()
{
return expertAvatar;
}
public String getExpertName() {
return expertName;
}
public void setExpertName(String expertName) {
this.expertName = expertName;
}
public String getCoverImage() {
return coverImage;
}
public void setCoverImage(String coverImage) {
this.coverImage = coverImage;
}
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -136,6 +222,11 @@ public class VetKnowledge extends BaseEntity
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.append("publishTime", getPublishTime())
.append("viewCount", getViewCount())
.append("expertId", getExpertId())
.append("coverImage", getCoverImage())
.append("subtitle", getSubtitle())
.toString(); .toString();
} }
} }

9
chenhai-system/src/main/java/com/chenhai/vet/domain/VetTrainingVideo.java

@ -82,6 +82,7 @@ public class VetTrainingVideo extends BaseEntity
/** 用户名称(非数据库字段) */ /** 用户名称(非数据库字段) */
private String userName; private String userName;
private String userAvatar;
public void setId(Long id) public void setId(Long id)
{ {
@ -259,6 +260,14 @@ public class VetTrainingVideo extends BaseEntity
this.userName = userName; this.userName = userName;
} }
public String getUserAvatar() {
return userAvatar;
}
public void setUserAvatar(String userAvatar) {
this.userAvatar = userAvatar;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)

13
chenhai-system/src/main/java/com/chenhai/vet/mapper/VetExpertsMapper.java

@ -59,4 +59,17 @@ public interface VetExpertsMapper
*/ */
public int deleteVetExpertsByExpertIds(Long[] expertIds); public int deleteVetExpertsByExpertIds(Long[] expertIds);
/**
* 搜索专家信息按真实姓名和擅长领域
*
* @param keyword 搜索关键词
* @return 专家信息集合
*/
public List<VetExperts> searchVetExperts(String keyword);
/**
* 只更新在线状态不影响其他字段
*/
int updateOnlineStatusOnly(VetExperts vetExperts);
} }

17
chenhai-system/src/main/java/com/chenhai/vet/mapper/VetKnowledgeMapper.java

@ -1,6 +1,8 @@
package com.chenhai.vet.mapper; package com.chenhai.vet.mapper;
import java.util.List; import java.util.List;
import com.chenhai.vet.domain.VetExperts;
import com.chenhai.vet.domain.VetKnowledge; import com.chenhai.vet.domain.VetKnowledge;
/** /**
@ -58,4 +60,19 @@ public interface VetKnowledgeMapper
* @return 结果 * @return 结果
*/ */
public int deleteVetKnowledgeByIds(Long[] ids); public int deleteVetKnowledgeByIds(Long[] ids);
/**
* 根据用户名查询专家信息
* @param username 用户名
* @return 专家信息
*/
VetExperts selectExpertByUsername(String username);
/**
* 根据用户ID查询专家信息
* @param userId 用户ID
* @return 专家信息
*/
VetExperts selectExpertByUserId(Long userId);
} }

8
chenhai-system/src/main/java/com/chenhai/vet/service/IVetExpertsService.java

@ -58,4 +58,12 @@ public interface IVetExpertsService
* @return 结果 * @return 结果
*/ */
public int deleteVetExpertsByExpertId(Long expertId); public int deleteVetExpertsByExpertId(Long expertId);
/**
* 搜索专家信息按真实姓名和擅长领域
*
* @param keyword 搜索关键词
* @return 专家信息集合
*/
public List<VetExperts> searchVetExperts(String keyword);
} }

17
chenhai-system/src/main/java/com/chenhai/vet/service/IVetKnowledgeService.java

@ -95,4 +95,21 @@ public interface IVetKnowledgeService
* @return 结果 * @return 结果
*/ */
AjaxResult offlineVetKnowledge(Long id, String auditComment); AjaxResult offlineVetKnowledge(Long id, String auditComment);
/**
* 查询已发布且审核通过的兽医文章列表公开接口
*
* @param vetKnowledge 兽医文章查询条件
* @return 兽医文章集合
*/
public List<VetKnowledge> selectPublishedKnowledgeList(VetKnowledge vetKnowledge);
/**
* 增加文章查看次数
*
* @param id 文章ID
* @return 结果
*/
public int addViewCount(Long id);
} }

1
chenhai-system/src/main/java/com/chenhai/vet/service/IVetTrainingVideoService.java

@ -12,6 +12,7 @@ public interface IVetTrainingVideoService {
*/ */
String uploadAndSave(VetTrainingVideo video, MultipartFile videoFile, MultipartFile coverImage); String uploadAndSave(VetTrainingVideo video, MultipartFile videoFile, MultipartFile coverImage);
/** /**
* 获取我的视频列表 * 获取我的视频列表
*/ */

158
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetExpertsServiceImpl.java

@ -44,8 +44,6 @@ public class VetExpertsServiceImpl implements IVetExpertsService
{ {
VetExperts expert = vetExpertsMapper.selectVetExpertsByExpertId(expertId); VetExperts expert = vetExpertsMapper.selectVetExpertsByExpertId(expertId);
if (expert != null) { if (expert != null) {
// 更新在线状态
updateOnlineStatus(expert);
// 如果userId不为空尝试从兽医表获取数据 // 如果userId不为空尝试从兽医表获取数据
if (expert.getUserId() != null) { if (expert.getUserId() != null) {
autoFillFromVetInfo(expert); autoFillFromVetInfo(expert);
@ -65,12 +63,9 @@ public class VetExpertsServiceImpl implements IVetExpertsService
@Override @Override
public List<VetExperts> selectVetExpertsList(VetExperts vetExperts) public List<VetExperts> selectVetExpertsList(VetExperts vetExperts)
{ {
List<VetExperts> list = vetExpertsMapper.selectVetExpertsList(vetExperts); List<VetExperts> list = vetExpertsMapper.selectVetExpertsList(vetExperts);
if (list != null) { if (list != null) {
for (VetExperts expert : list) { for (VetExperts expert : list) {
// 更新在线状态
updateOnlineStatus(expert);
// 如果userId不为空尝试从兽医表获取数据 // 如果userId不为空尝试从兽医表获取数据
if (expert.getUserId() != null) { if (expert.getUserId() != null) {
autoFillFromVetInfo(expert); autoFillFromVetInfo(expert);
@ -95,24 +90,22 @@ public class VetExpertsServiceImpl implements IVetExpertsService
// 1. 确保设置userId优先使用传入的其次使用当前登录用户 // 1. 确保设置userId优先使用传入的其次使用当前登录用户
ensureUserId(vetExperts); ensureUserId(vetExperts);
// 2. 设置在线状态新增时默认为在线
vetExperts.setIsOnline("在线"); // 改为汉字"在线"
// 3. 设置排序值在线排在前面
vetExperts.setSortOrder(1L); // 在线专家排序值较高
// 2. 设置在线状态新增时默认为离线
vetExperts.setIsOnline("离线");
vetExperts.setSortOrder(0L);
// 4. 自动填充默认值包含从兽医信息表获取数据
// 3. 自动填充默认值包含从兽医信息表获取数据
autoFillDefaultValues(vetExperts); autoFillDefaultValues(vetExperts);
// 5. 设置默认值如果从兽医表获取后仍然为空
// 4. 设置默认值如果从兽医表获取后仍然为空
setDefaultValues(vetExperts); setDefaultValues(vetExperts);
// 6. 设置创建时间和更新时间
// 5. 设置创建时间和更新时间
Date now = new Date(); Date now = new Date();
vetExperts.setCreatedAt(now); vetExperts.setCreatedAt(now);
vetExperts.setUpdatedAt(now); vetExperts.setUpdatedAt(now);
// 7. 设置操作人
// 6. 设置操作人
setAuditInfo(vetExperts); setAuditInfo(vetExperts);
return vetExpertsMapper.insertVetExperts(vetExperts); return vetExpertsMapper.insertVetExperts(vetExperts);
@ -131,8 +124,14 @@ public class VetExpertsServiceImpl implements IVetExpertsService
// 1. 确保userId不为空 // 1. 确保userId不为空
ensureUserId(vetExperts); ensureUserId(vetExperts);
// 2. 更新在线状态
updateOnlineStatus(vetExperts);
// 2. 保持原有的在线状态
if (vetExperts.getExpertId() != null && vetExperts.getIsOnline() == null) {
VetExperts existing = vetExpertsMapper.selectVetExpertsByExpertId(vetExperts.getExpertId());
if (existing != null) {
vetExperts.setIsOnline(existing.getIsOnline());
vetExperts.setSortOrder(existing.getSortOrder());
}
}
// 3. 自动填充默认值 // 3. 自动填充默认值
autoFillDefaultValues(vetExperts); autoFillDefaultValues(vetExperts);
@ -149,37 +148,11 @@ public class VetExpertsServiceImpl implements IVetExpertsService
return vetExpertsMapper.updateVetExperts(vetExperts); return vetExpertsMapper.updateVetExperts(vetExperts);
} }
/**
* 更新在线状态如果当前登录用户是该专家则设置为在线
*/
private void updateOnlineStatus(VetExperts vetExperts) {
if (vetExperts == null || vetExperts.getUserId() == null) {
return;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) {
// 如果当前登录用户就是该专家设置为在线
if (loginUser.getUserId().equals(vetExperts.getUserId())) {
vetExperts.setIsOnline("在线");
vetExperts.setSortOrder(1L); // 在线状态排序值高
} else {
vetExperts.setIsOnline("离线");
vetExperts.setSortOrder(0L); // 离线状态排序值低
}
} else {
// 没有登录用户设置为离线
vetExperts.setIsOnline("离线");
vetExperts.setSortOrder(0L);
}
}
/** /**
* 确保设置userId * 确保设置userId
*/ */
private void ensureUserId(VetExperts vetExperts) { private void ensureUserId(VetExperts vetExperts) {
if (vetExperts.getUserId() == null) { if (vetExperts.getUserId() == null) {
// 尝试获取当前登录用户ID
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null) { if (loginUser != null) {
vetExperts.setUserId(loginUser.getUserId()); vetExperts.setUserId(loginUser.getUserId());
@ -284,6 +257,11 @@ public class VetExpertsServiceImpl implements IVetExpertsService
&& !isFieldEmpty(vetInfo.getUser().getAvatar())) { && !isFieldEmpty(vetInfo.getUser().getAvatar())) {
vetExperts.setAvatar(vetInfo.getUser().getAvatar()); vetExperts.setAvatar(vetInfo.getUser().getAvatar());
} }
// 10. 专家简介新增
if (isFieldEmpty(vetExperts.getIntroduction()) && !isFieldEmpty(vetInfo.getIntroduction())) {
vetExperts.setIntroduction(vetInfo.getIntroduction());
}
} }
/** /**
@ -294,7 +272,6 @@ public class VetExpertsServiceImpl implements IVetExpertsService
return; return;
} }
// 如果专家信息中某些字段是默认值尝试从兽医表获取
VetPersonalInfo vetInfo = vetPersonalInfoMapper.selectVetPersonalInfoByUserId(expert.getUserId()); VetPersonalInfo vetInfo = vetPersonalInfoMapper.selectVetPersonalInfoByUserId(expert.getUserId());
if (vetInfo == null) { if (vetInfo == null) {
return; return;
@ -347,10 +324,17 @@ public class VetExpertsServiceImpl implements IVetExpertsService
expert.setAddress(vetInfo.getAddress()); expert.setAddress(vetInfo.getAddress());
} }
} }
// 专家简介新增
if (isFieldEmpty(expert.getIntroduction()) && !isFieldEmpty(vetInfo.getIntroduction())) {
expert.setIntroduction(vetInfo.getIntroduction());
} else if ("暂无简介".equals(expert.getIntroduction()) && !isFieldEmpty(vetInfo.getIntroduction())) {
expert.setIntroduction(vetInfo.getIntroduction());
}
} }
/** /**
* 设置默认值修改了在线状态和排序的默认值
* 设置默认值
*/ */
private void setDefaultValues(VetExperts vetExperts) { private void setDefaultValues(VetExperts vetExperts) {
// 1. 如果真实姓名为空 // 1. 如果真实姓名为空
@ -398,16 +382,9 @@ public class VetExpertsServiceImpl implements IVetExpertsService
vetExperts.setAvatar("/profile/avatar/default.jpg"); vetExperts.setAvatar("/profile/avatar/default.jpg");
} }
// 10. 如果在线状态为空需要根据登录状态设置
// 10. 如果在线状态为空设置为离线
if (isFieldEmpty(vetExperts.getIsOnline())) { if (isFieldEmpty(vetExperts.getIsOnline())) {
// 检查当前登录用户是否是该专家
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && vetExperts.getUserId() != null
&& loginUser.getUserId().equals(vetExperts.getUserId())) {
vetExperts.setIsOnline("在线"); // 当前登录用户是在线
} else {
vetExperts.setIsOnline("离线"); // 离线
}
vetExperts.setIsOnline("离线");
} }
// 11. 如果状态为空设置默认正常 // 11. 如果状态为空设置默认正常
@ -423,6 +400,57 @@ public class VetExpertsServiceImpl implements IVetExpertsService
vetExperts.setSortOrder(0L); // 离线排在后面 vetExperts.setSortOrder(0L); // 离线排在后面
} }
} }
// 13. 如果专家简介为空设置默认值新增
if (isFieldEmpty(vetExperts.getIntroduction())) {
// 根据专家信息生成默认简介
String defaultIntroduction = generateDefaultIntroduction(vetExperts);
vetExperts.setIntroduction(defaultIntroduction);
}
}
/**
* 生成默认专家简介新增方法
*/
private String generateDefaultIntroduction(VetExperts vetExperts) {
StringBuilder intro = new StringBuilder();
// 基本介绍
intro.append("我是");
if (!"未填写".equals(vetExperts.getRealName())) {
intro.append(vetExperts.getRealName());
} else {
intro.append("一位");
}
// 职称
if (!"未设置".equals(vetExperts.getTitle())) {
intro.append(",").append(vetExperts.getTitle());
}
// 从业经验
if (!"暂无".equals(vetExperts.getWorkExperience())) {
intro.append(",拥有").append(vetExperts.getWorkExperience()).append("从业经验");
}
// 擅长领域
if (!"待补充".equals(vetExperts.getExpertiseArea())) {
intro.append(",擅长").append(vetExperts.getExpertiseArea());
}
// 工作单位
if (!"待补充".equals(vetExperts.getAddress())) {
intro.append(",现就职于").append(vetExperts.getAddress());
}
intro.append("。");
// 如果没有其他信息返回简单默认值
if (intro.length() <= 10) {
return "暂无简介";
}
return intro.toString();
} }
/** /**
@ -455,4 +483,28 @@ public class VetExpertsServiceImpl implements IVetExpertsService
{ {
return vetExpertsMapper.deleteVetExpertsByExpertId(expertId); return vetExpertsMapper.deleteVetExpertsByExpertId(expertId);
} }
/**
* 搜索专家信息按真实姓名和擅长领域
*
* @param keyword 搜索关键词
* @return 专家信息集合
*/
@Override
public List<VetExperts> searchVetExperts(String keyword) {
// 调用Mapper进行搜索
List<VetExperts> list = vetExpertsMapper.searchVetExperts(keyword);
if (list != null) {
for (VetExperts expert : list) {
// 如果userId不为空尝试从兽医表获取数据
if (expert.getUserId() != null) {
autoFillFromVetInfo(expert);
}
// 确保显示默认值
setDefaultValues(expert);
}
}
return list;
}
} }

37
chenhai-system/src/main/java/com/chenhai/vet/service/impl/VetKnowledgeServiceImpl.java

@ -5,11 +5,13 @@ import java.util.List;
import com.chenhai.common.core.domain.AjaxResult; import com.chenhai.common.core.domain.AjaxResult;
import com.chenhai.common.utils.DateUtils; import com.chenhai.common.utils.DateUtils;
import com.chenhai.common.utils.SecurityUtils; import com.chenhai.common.utils.SecurityUtils;
import com.chenhai.vet.domain.VetExperts;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.chenhai.vet.mapper.VetKnowledgeMapper; import com.chenhai.vet.mapper.VetKnowledgeMapper;
import com.chenhai.vet.domain.VetKnowledge; import com.chenhai.vet.domain.VetKnowledge;
import com.chenhai.vet.service.IVetKnowledgeService; import com.chenhai.vet.service.IVetKnowledgeService;
import org.springframework.transaction.annotation.Transactional;
/** /**
* 兽医文章Service业务层处理 * 兽医文章Service业务层处理
@ -47,7 +49,6 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService
@Override @Override
public int insertVetKnowledge(VetKnowledge vetKnowledge) public int insertVetKnowledge(VetKnowledge vetKnowledge)
{ {
vetKnowledge.setCreateTime(DateUtils.getNowDate());
// 新增文章时默认状态为草稿审核状态为待审核 // 新增文章时默认状态为草稿审核状态为待审核
if (vetKnowledge.getArticleStatus() == null) { if (vetKnowledge.getArticleStatus() == null) {
vetKnowledge.setArticleStatus("0"); // 草稿 vetKnowledge.setArticleStatus("0"); // 草稿
@ -306,4 +307,38 @@ public class VetKnowledgeServiceImpl implements IVetKnowledgeService
return AjaxResult.error("文章下架失败: " + e.getMessage()); return AjaxResult.error("文章下架失败: " + e.getMessage());
} }
} }
/**
* 查询已发布且审核通过的兽医文章列表
* 只返回状态为已发布(1)且审核通过(2)的文章
*/
@Override
public List<VetKnowledge> selectPublishedKnowledgeList(VetKnowledge vetKnowledge) {
// 强制设置查询条件为已发布且审核通过
vetKnowledge.setArticleStatus("1"); // 已发布
vetKnowledge.setAuditStatus("2"); // 审核通过
return vetKnowledgeMapper.selectVetKnowledgeList(vetKnowledge);
}
/**
* 增加文章查看次数
*/
@Override
@Transactional
public int addViewCount(Long id) {
try {
VetKnowledge current = vetKnowledgeMapper.selectVetKnowledgeById(id);
if (current != null) {
VetKnowledge vetKnowledge = new VetKnowledge();
vetKnowledge.setId(id);
vetKnowledge.setViewCount((current.getViewCount() == null ? 0 : current.getViewCount()) + 1);
vetKnowledge.setUpdateTime(DateUtils.getNowDate());
return vetKnowledgeMapper.updateVetKnowledge(vetKnowledge);
}
return 0;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
} }

106
chenhai-system/src/main/resources/mapper/system/SysChatMessageMapper.xml

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.system.mapper.SysChatMessageMapper">
<resultMap type="SysChatMessage" id="SysChatMessageResult">
<result property="messageId" column="message_id" />
<result property="sessionId" column="session_id" />
<result property="senderType" column="sender_type" />
<result property="senderId" column="sender_id" />
<result property="content" column="content" />
<result property="msgType" column="msg_type" />
<result property="isRead" column="is_read" />
<result property="readTime" column="read_time" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectSysChatMessageVo">
select message_id, session_id, sender_type, sender_id, content, msg_type, is_read, read_time, del_flag, create_by, create_time, update_by, update_time from sys_chat_message
</sql>
<select id="selectSysChatMessageList" parameterType="SysChatMessage" resultMap="SysChatMessageResult">
<include refid="selectSysChatMessageVo"/>
<where>
<if test="sessionId != null and sessionId != ''"> and session_id = #{sessionId}</if>
<if test="senderType != null and senderType != ''"> and sender_type = #{senderType}</if>
<if test="senderId != null "> and sender_id = #{senderId}</if>
<if test="content != null and content != ''"> and content = #{content}</if>
<if test="msgType != null and msgType != ''"> and msg_type = #{msgType}</if>
<if test="isRead != null and isRead != ''"> and is_read = #{isRead}</if>
<if test="readTime != null "> and read_time = #{readTime}</if>
</where>
</select>
<select id="selectSysChatMessageByMessageId" parameterType="Long" resultMap="SysChatMessageResult">
<include refid="selectSysChatMessageVo"/>
where message_id = #{messageId}
</select>
<insert id="insertSysChatMessage" parameterType="SysChatMessage" useGeneratedKeys="true" keyProperty="messageId">
insert into sys_chat_message
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="sessionId != null and sessionId != ''">session_id,</if>
<if test="senderType != null and senderType != ''">sender_type,</if>
<if test="senderId != null">sender_id,</if>
<if test="content != null and content != ''">content,</if>
<if test="msgType != null">msg_type,</if>
<if test="isRead != null">is_read,</if>
<if test="readTime != null">read_time,</if>
<if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="sessionId != null and sessionId != ''">#{sessionId},</if>
<if test="senderType != null and senderType != ''">#{senderType},</if>
<if test="senderId != null">#{senderId},</if>
<if test="content != null and content != ''">#{content},</if>
<if test="msgType != null">#{msgType},</if>
<if test="isRead != null">#{isRead},</if>
<if test="readTime != null">#{readTime},</if>
<if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateSysChatMessage" parameterType="SysChatMessage">
update sys_chat_message
<trim prefix="SET" suffixOverrides=",">
<if test="sessionId != null and sessionId != ''">session_id = #{sessionId},</if>
<if test="senderType != null and senderType != ''">sender_type = #{senderType},</if>
<if test="senderId != null">sender_id = #{senderId},</if>
<if test="content != null and content != ''">content = #{content},</if>
<if test="msgType != null">msg_type = #{msgType},</if>
<if test="isRead != null">is_read = #{isRead},</if>
<if test="readTime != null">read_time = #{readTime},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where message_id = #{messageId}
</update>
<delete id="deleteSysChatMessageByMessageId" parameterType="Long">
delete from sys_chat_message where message_id = #{messageId}
</delete>
<delete id="deleteSysChatMessageByMessageIds" parameterType="String">
delete from sys_chat_message where message_id in
<foreach item="messageId" collection="array" open="(" separator="," close=")">
#{messageId}
</foreach>
</delete>
</mapper>

122
chenhai-system/src/main/resources/mapper/system/SysChatSessionMapper.xml

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.system.mapper.SysChatSessionMapper">
<resultMap type="SysChatSession" id="SysChatSessionResult">
<result property="sessionId" column="session_id" />
<result property="userId" column="user_id" />
<result property="expertId" column="expert_id" />
<result property="animalType" column="animal_type" />
<result property="symptomSummary" column="symptom_summary" />
<result property="lastMessage" column="last_message" />
<result property="lastMessageTime" column="last_message_time" />
<result property="unreadUser" column="unread_user" />
<result property="unreadExpert" column="unread_expert" />
<result property="sessionStatus" column="session_status" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectSysChatSessionVo">
select session_id, user_id, expert_id, animal_type, symptom_summary, last_message, last_message_time, unread_user, unread_expert, session_status, del_flag, create_by, create_time, update_by, update_time, remark from sys_chat_session
</sql>
<select id="selectSysChatSessionList" parameterType="SysChatSession" resultMap="SysChatSessionResult">
<include refid="selectSysChatSessionVo"/>
<where>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="expertId != null "> and expert_id = #{expertId}</if>
<if test="animalType != null and animalType != ''"> and animal_type = #{animalType}</if>
<if test="symptomSummary != null and symptomSummary != ''"> and symptom_summary = #{symptomSummary}</if>
<if test="lastMessage != null and lastMessage != ''"> and last_message = #{lastMessage}</if>
<if test="lastMessageTime != null "> and last_message_time = #{lastMessageTime}</if>
<if test="unreadUser != null "> and unread_user = #{unreadUser}</if>
<if test="unreadExpert != null "> and unread_expert = #{unreadExpert}</if>
<if test="sessionStatus != null and sessionStatus != ''"> and session_status = #{sessionStatus}</if>
</where>
</select>
<select id="selectSysChatSessionBySessionId" parameterType="String" resultMap="SysChatSessionResult">
<include refid="selectSysChatSessionVo"/>
where session_id = #{sessionId}
</select>
<insert id="insertSysChatSession" parameterType="SysChatSession">
insert into sys_chat_session
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="sessionId != null">session_id,</if>
<if test="userId != null">user_id,</if>
<if test="expertId != null">expert_id,</if>
<if test="animalType != null">animal_type,</if>
<if test="symptomSummary != null">symptom_summary,</if>
<if test="lastMessage != null">last_message,</if>
<if test="lastMessageTime != null">last_message_time,</if>
<if test="unreadUser != null">unread_user,</if>
<if test="unreadExpert != null">unread_expert,</if>
<if test="sessionStatus != null">session_status,</if>
<if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="sessionId != null">#{sessionId},</if>
<if test="userId != null">#{userId},</if>
<if test="expertId != null">#{expertId},</if>
<if test="animalType != null">#{animalType},</if>
<if test="symptomSummary != null">#{symptomSummary},</if>
<if test="lastMessage != null">#{lastMessage},</if>
<if test="lastMessageTime != null">#{lastMessageTime},</if>
<if test="unreadUser != null">#{unreadUser},</if>
<if test="unreadExpert != null">#{unreadExpert},</if>
<if test="sessionStatus != null">#{sessionStatus},</if>
<if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateSysChatSession" parameterType="SysChatSession">
update sys_chat_session
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="expertId != null">expert_id = #{expertId},</if>
<if test="animalType != null">animal_type = #{animalType},</if>
<if test="symptomSummary != null">symptom_summary = #{symptomSummary},</if>
<if test="lastMessage != null">last_message = #{lastMessage},</if>
<if test="lastMessageTime != null">last_message_time = #{lastMessageTime},</if>
<if test="unreadUser != null">unread_user = #{unreadUser},</if>
<if test="unreadExpert != null">unread_expert = #{unreadExpert},</if>
<if test="sessionStatus != null">session_status = #{sessionStatus},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where session_id = #{sessionId}
</update>
<delete id="deleteSysChatSessionBySessionId" parameterType="String">
delete from sys_chat_session where session_id = #{sessionId}
</delete>
<delete id="deleteSysChatSessionBySessionIds" parameterType="String">
delete from sys_chat_session where session_id in
<foreach item="sessionId" collection="array" open="(" separator="," close=")">
#{sessionId}
</foreach>
</delete>
</mapper>

136
chenhai-system/src/main/resources/mapper/system/SysExpertConsultationMapper.xml

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.system.mapper.SysExpertConsultationMapper">
<resultMap type="SysExpertConsultation" id="SysExpertConsultationResult">
<result property="consultationId" column="consultation_id" />
<result property="userId" column="user_id" />
<result property="expertId" column="expert_id" />
<result property="formId" column="form_id" />
<result property="consultationType" column="consultation_type" />
<result property="consultationStatus" column="consultation_status" />
<result property="consultationTitle" column="consultation_title" />
<result property="initialContent" column="initial_content" />
<result property="initialAttachments" column="initial_attachments" />
<result property="messages" column="messages" />
<result property="rating" column="rating" />
<result property="evaluation" column="evaluation" />
<result property="evaluationTags" column="evaluation_tags" />
<result property="evaluationTime" column="evaluation_time" />
<result property="startTime" column="start_time" />
<result property="endTime" column="end_time" />
<result property="createdTime" column="created_time" />
<result property="updatedTime" column="updated_time" />
</resultMap>
<sql id="selectSysExpertConsultationVo">
select consultation_id, user_id, expert_id, form_id, consultation_type, consultation_status, consultation_title, initial_content, initial_attachments, messages, rating, evaluation, evaluation_tags, evaluation_time, start_time, end_time, created_time, updated_time from sys_expert_consultation
</sql>
<select id="selectSysExpertConsultationList" parameterType="SysExpertConsultation" resultMap="SysExpertConsultationResult">
<include refid="selectSysExpertConsultationVo"/>
<where>
<if test="userId != null "> and user_id = #{userId}</if>
<if test="expertId != null "> and expert_id = #{expertId}</if>
<if test="formId != null "> and form_id = #{formId}</if>
<if test="consultationType != null and consultationType != ''"> and consultation_type = #{consultationType}</if>
<if test="consultationStatus != null and consultationStatus != ''"> and consultation_status = #{consultationStatus}</if>
<if test="consultationTitle != null and consultationTitle != ''"> and consultation_title = #{consultationTitle}</if>
<if test="initialContent != null and initialContent != ''"> and initial_content = #{initialContent}</if>
<if test="initialAttachments != null and initialAttachments != ''"> and initial_attachments = #{initialAttachments}</if>
<if test="messages != null and messages != ''"> and messages = #{messages}</if>
<if test="rating != null "> and rating = #{rating}</if>
<if test="evaluation != null and evaluation != ''"> and evaluation = #{evaluation}</if>
<if test="evaluationTags != null and evaluationTags != ''"> and evaluation_tags = #{evaluationTags}</if>
<if test="evaluationTime != null "> and evaluation_time = #{evaluationTime}</if>
<if test="startTime != null "> and start_time = #{startTime}</if>
<if test="endTime != null "> and end_time = #{endTime}</if>
<if test="createdTime != null "> and created_time = #{createdTime}</if>
<if test="updatedTime != null "> and updated_time = #{updatedTime}</if>
</where>
</select>
<select id="selectSysExpertConsultationByConsultationId" parameterType="Long" resultMap="SysExpertConsultationResult">
<include refid="selectSysExpertConsultationVo"/>
where consultation_id = #{consultationId}
</select>
<insert id="insertSysExpertConsultation" parameterType="SysExpertConsultation" useGeneratedKeys="true" keyProperty="consultationId">
insert into sys_expert_consultation
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId != null">user_id,</if>
<if test="expertId != null">expert_id,</if>
<if test="formId != null">form_id,</if>
<if test="consultationType != null">consultation_type,</if>
<if test="consultationStatus != null">consultation_status,</if>
<if test="consultationTitle != null">consultation_title,</if>
<if test="initialContent != null">initial_content,</if>
<if test="initialAttachments != null">initial_attachments,</if>
<if test="messages != null">messages,</if>
<if test="rating != null">rating,</if>
<if test="evaluation != null">evaluation,</if>
<if test="evaluationTags != null">evaluation_tags,</if>
<if test="evaluationTime != null">evaluation_time,</if>
<if test="startTime != null">start_time,</if>
<if test="endTime != null">end_time,</if>
<if test="createdTime != null">created_time,</if>
<if test="updatedTime != null">updated_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">#{userId},</if>
<if test="expertId != null">#{expertId},</if>
<if test="formId != null">#{formId},</if>
<if test="consultationType != null">#{consultationType},</if>
<if test="consultationStatus != null">#{consultationStatus},</if>
<if test="consultationTitle != null">#{consultationTitle},</if>
<if test="initialContent != null">#{initialContent},</if>
<if test="initialAttachments != null">#{initialAttachments},</if>
<if test="messages != null">#{messages},</if>
<if test="rating != null">#{rating},</if>
<if test="evaluation != null">#{evaluation},</if>
<if test="evaluationTags != null">#{evaluationTags},</if>
<if test="evaluationTime != null">#{evaluationTime},</if>
<if test="startTime != null">#{startTime},</if>
<if test="endTime != null">#{endTime},</if>
<if test="createdTime != null">#{createdTime},</if>
<if test="updatedTime != null">#{updatedTime},</if>
</trim>
</insert>
<update id="updateSysExpertConsultation" parameterType="SysExpertConsultation">
update sys_expert_consultation
<trim prefix="SET" suffixOverrides=",">
<if test="userId != null">user_id = #{userId},</if>
<if test="expertId != null">expert_id = #{expertId},</if>
<if test="formId != null">form_id = #{formId},</if>
<if test="consultationType != null">consultation_type = #{consultationType},</if>
<if test="consultationStatus != null">consultation_status = #{consultationStatus},</if>
<if test="consultationTitle != null">consultation_title = #{consultationTitle},</if>
<if test="initialContent != null">initial_content = #{initialContent},</if>
<if test="initialAttachments != null">initial_attachments = #{initialAttachments},</if>
<if test="messages != null">messages = #{messages},</if>
<if test="rating != null">rating = #{rating},</if>
<if test="evaluation != null">evaluation = #{evaluation},</if>
<if test="evaluationTags != null">evaluation_tags = #{evaluationTags},</if>
<if test="evaluationTime != null">evaluation_time = #{evaluationTime},</if>
<if test="startTime != null">start_time = #{startTime},</if>
<if test="endTime != null">end_time = #{endTime},</if>
<if test="createdTime != null">created_time = #{createdTime},</if>
<if test="updatedTime != null">updated_time = #{updatedTime},</if>
</trim>
where consultation_id = #{consultationId}
</update>
<delete id="deleteSysExpertConsultationByConsultationId" parameterType="Long">
delete from sys_expert_consultation where consultation_id = #{consultationId}
</delete>
<delete id="deleteSysExpertConsultationByConsultationIds" parameterType="String">
delete from sys_expert_consultation where consultation_id in
<foreach item="consultationId" collection="array" open="(" separator="," close=")">
#{consultationId}
</foreach>
</delete>
</mapper>

85
chenhai-system/src/main/resources/mapper/system/SysKnowledgeQueryMapper.xml

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.system.mapper.SysKnowledgeQueryMapper">
<resultMap type="SysKnowledgeQuery" id="SysKnowledgeQueryResult">
<result property="id" column="id" />
<result property="title" column="title" />
<result property="content" column="content" />
<result property="categoryType" column="category_type" />
<result property="keywords" column="keywords" />
<result property="publishTime" column="publish_time" />
</resultMap>
<sql id="selectSysKnowledgeQueryVo">
select id, title, content, category_type, keywords, publish_time from sys_knowledge_query
</sql>
<select id="selectSysKnowledgeQueryList" parameterType="SysKnowledgeQuery" resultMap="SysKnowledgeQueryResult">
<include refid="selectSysKnowledgeQueryVo"/>
<where>
<if test="title != null and title != ''"> and title = #{title}</if>
<if test="content != null and content != ''"> and content = #{content}</if>
<if test="categoryType != null and categoryType != ''"> and category_type = #{categoryType}</if>
<if test="keywords != null and keywords != ''"> and keywords = #{keywords}</if>
<if test="publishTime != null"> and publish_time = #{publishTime}</if>
<!-- 添加搜索条件 -->
<if test="searchKey != null and searchKey != ''">
and (
title like concat('%', #{searchKey}, '%')
or content like concat('%', #{searchKey}, '%')
or keywords like concat('%', #{searchKey}, '%')
or category_type like concat('%', #{searchKey}, '%')
)
</if>
</where>
</select>
<select id="selectSysKnowledgeQueryById" parameterType="Long" resultMap="SysKnowledgeQueryResult">
<include refid="selectSysKnowledgeQueryVo"/>
where id = #{id}
</select>
<insert id="insertSysKnowledgeQuery" parameterType="SysKnowledgeQuery" useGeneratedKeys="true" keyProperty="id">
insert into sys_knowledge_query
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">title,</if>
<if test="content != null">content,</if>
<if test="categoryType != null">category_type,</if>
<if test="keywords != null">keywords,</if>
<if test="publishTime != null">publish_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if>
<if test="content != null">#{content},</if>
<if test="categoryType != null">#{categoryType},</if>
<if test="keywords != null">#{keywords},</if>
<if test="publishTime != null">#{publishTime},</if>
</trim>
</insert>
<update id="updateSysKnowledgeQuery" parameterType="SysKnowledgeQuery">
update sys_knowledge_query
<trim prefix="SET" suffixOverrides=",">
<if test="title != null and title != ''">title = #{title},</if>
<if test="content != null">content = #{content},</if>
<if test="categoryType != null">category_type = #{categoryType},</if>
<if test="keywords != null">keywords = #{keywords},</if>
<if test="publishTime != null">publish_time = #{publishTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSysKnowledgeQueryById" parameterType="Long">
delete from sys_knowledge_query where id = #{id}
</delete>
<delete id="deleteSysKnowledgeQueryByIds" parameterType="String">
delete from sys_knowledge_query where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

277
chenhai-system/src/main/resources/mapper/system/SysMedicineRecommendationMapper.xml

@ -0,0 +1,277 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.system.mapper.SysMedicineRecommendationMapper">
<resultMap type="SysMedicineRecommendation" id="SysMedicineRecommendationResult">
<result property="id" column="id" />
<result property="medicineName" column="medicine_name" />
<result property="medicineType" column="medicine_type" />
<result property="specification" column="specification" />
<result property="price" column="price" />
<result property="originalPrice" column="original_price" />
<result property="soldQuantity" column="sold_quantity" />
<result property="indications" column="indications" />
<result property="usageDosage" column="usage_dosage" />
<result property="precautions" column="precautions" />
<result property="storageMethod" column="storage_method" />
<result property="expiryDate" column="expiry_date" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
<result property="manufacturer" column="manufacturer" />
<result property="salesType" column="sales_type" />
<result property="expertId" column="expert_id" />
<result property="recommendReason" column="recommend_reason" />
<result property="recommendTime" column="recommend_time" />
<result property="storeName" column="store_name" />
<result property="storeAddress" column="store_address" />
<result property="storePhone" column="store_phone" />
<result property="businessHours" column="business_hours" />
<result property="storeRemark" column="store_remark" />
<result property="longitude" column="longitude" />
<result property="latitude" column="latitude" />
<result property="images" column="images" />
<result property="imageUrl" column="image_url" />
<!-- 修改这里的关联查询,使用join方式(推荐) -->
<association property="expertAvatar" column="expert_id"
select="com.chenhai.system.mapper.SysMedicineRecommendationMapper.getExpertAvatarById" />
<association property="expertName" column="expert_id"
select="com.chenhai.system.mapper.SysMedicineRecommendationMapper.getExpertNameById" />
<association property="expertExpert" column="expert_id"
select="com.chenhai.system.mapper.SysMedicineRecommendationMapper.getExpertExpertById" />
<association property="expertIntroduction" column="expert_id"
select="com.chenhai.system.mapper.SysMedicineRecommendationMapper.getExpertIntroductionById" />
<association property="expertAddress" column="expert_id"
select="com.chenhai.system.mapper.SysMedicineRecommendationMapper.getExpertAddressById" />
<association property="expertExpertiseArea" column="expert_id"
select="com.chenhai.system.mapper.SysMedicineRecommendationMapper.getExpertExpertiseAreaById" />
<association property="expertWorkExperience" column="expert_id"
select="com.chenhai.system.mapper.SysMedicineRecommendationMapper.getExpertWorkExperienceById" />
</resultMap>
<!-- 或者保持原来的SELECT查询,但要修改关联查询的ID -->
<select id="getExpertAvatarById" parameterType="Long" resultType="String">
SELECT avatar FROM vet_experts WHERE expert_id = #{expertId}
</select>
<select id="getExpertNameById" parameterType="Long" resultType="String">
SELECT real_name FROM vet_experts WHERE expert_id = #{expertId}
</select>
<select id="getExpertExpertById" parameterType="Long" resultType="String">
SELECT expert FROM vet_experts WHERE expert_id = #{expertId}
</select>
<select id="getExpertIntroductionById" parameterType="Long" resultType="String">
SELECT introduction FROM vet_experts WHERE expert_id = #{expertId}
</select>
<select id="getExpertAddressById" parameterType="Long" resultType="String">
SELECT address FROM vet_experts WHERE expert_id = #{expertId}
</select>
<select id="getExpertExpertiseAreaById" parameterType="Long" resultType="String">
SELECT expertise_area FROM vet_experts WHERE expert_id = #{expertId}
</select>
<select id="getExpertWorkExperienceById" parameterType="Long" resultType="String">
SELECT work_experience FROM vet_experts WHERE expert_id = #{expertId}
</select>
<!-- 修改基础查询SQL,添加专家表关联查询(更高效的方式) -->
<sql id="selectSysMedicineRecommendationVo">
select
m.id,
m.medicine_name,
m.medicine_type,
m.specification,
m.price,
m.original_price,
m.sold_quantity,
m.indications,
m.usage_dosage,
m.precautions,
m.storage_method,
m.expiry_date,
m.created_at,
m.updated_at,
m.manufacturer,
m.sales_type,
m.expert_id,
m.recommend_reason,
m.recommend_time,
m.store_name,
m.store_address,
m.store_phone,
m.business_hours,
m.store_remark,
m.longitude,
m.latitude,
m.images,
m.image_url,
e.avatar as expert_avatar,
e.real_name as expert_name,
e.expert as expert_expert,
e.introduction as expert_introduction,
e.address as expert_address,
e.expertise_area as expertise_area,
e.work_experience as work_experience
from sys_medicine_recommendation m
left join vet_experts e on m.expert_id = e.expert_id
left join sys_dict_data d on m.medicine_type = d.dict_value
and d.dict_type = 'medicine_type' <!-- 添加字典表JOIN -->
</sql>
<select id="selectSysMedicineRecommendationList" parameterType="SysMedicineRecommendation" resultMap="SysMedicineRecommendationResult">
<include refid="selectSysMedicineRecommendationVo"/>
<where>
<if test="medicineName != null and medicineName != ''"> and medicine_name like concat('%', #{medicineName}, '%')</if>
<if test="medicineType != null and medicineType != ''"> and medicine_type = #{medicineType}</if>
<if test="specification != null and specification != ''"> and specification = #{specification}</if>
<if test="price != null "> and price = #{price}</if>
<if test="originalPrice != null "> and original_price = #{originalPrice}</if>
<if test="soldQuantity != null "> and sold_quantity = #{soldQuantity}</if>
<if test="indications != null and indications != ''"> and indications = #{indications}</if>
<if test="usageDosage != null and usageDosage != ''"> and usage_dosage = #{usageDosage}</if>
<if test="precautions != null and precautions != ''"> and precautions = #{precautions}</if>
<if test="storageMethod != null and storageMethod != ''"> and storage_method = #{storageMethod}</if>
<if test="expiryDate != null and expiryDate != ''"> and expiry_date = #{expiryDate}</if>
<if test="createdAt != null "> and created_at = #{createdAt}</if>
<if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
<if test="manufacturer != null and manufacturer != ''"> and manufacturer like concat('%', #{manufacturer}, '%')</if>
<if test="salesType != null and salesType != ''"> and sales_type = #{salesType}</if>
<if test="expertId != null "> and expert_id = #{expertId}</if>
<if test="recommendReason != null and recommendReason != ''"> and recommend_reason like concat('%', #{recommendReason}, '%')</if>
<if test="recommendTime != null "> and recommend_time = #{recommendTime}</if>
<if test="storeName != null and storeName != ''"> and store_name like concat('%', #{storeName}, '%')</if>
<if test="storeAddress != null and storeAddress != ''"> and store_address like concat('%', #{storeAddress}, '%')</if>
<if test="images != null and images != ''"> and images like concat('%', #{images}, '%')</if>
<if test="imageUrl != null and imageUrl != ''"> and image_url like concat('%', #{imageUrl}, '%')</if>
<!-- 新增搜索关键词条件 -->
<if test="searchKeywords != null and searchKeywords != ''">
and (
medicine_name like concat('%', #{searchKeywords}, '%')
or indications like concat('%', #{searchKeywords}, '%')
or manufacturer like concat('%', #{searchKeywords}, '%')
or store_name like concat('%', #{searchKeywords}, '%')
or usage_dosage like concat('%', #{searchKeywords}, '%')
or e.real_name like concat('%', #{searchKeywords}, '%') <!-- 搜索专家姓名 -->
or e.title like concat('%', #{searchKeywords}, '%') <!-- 搜索专家职称 -->
)
</if>
</where>
</select>
<select id="selectSysMedicineRecommendationById" parameterType="Long" resultMap="SysMedicineRecommendationResult">
<include refid="selectSysMedicineRecommendationVo"/>
where id = #{id}
</select>
<insert id="insertSysMedicineRecommendation" parameterType="SysMedicineRecommendation" useGeneratedKeys="true" keyProperty="id">
insert into sys_medicine_recommendation
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="medicineName != null and medicineName != ''">medicine_name,</if>
<if test="medicineType != null and medicineType != ''">medicine_type,</if>
<if test="specification != null and specification != ''">specification,</if>
<if test="price != null">price,</if>
<if test="originalPrice != null">original_price,</if>
<if test="soldQuantity != null">sold_quantity,</if>
<if test="indications != null and indications != ''">indications,</if>
<if test="usageDosage != null and usageDosage != ''">usage_dosage,</if>
<if test="precautions != null and precautions != ''">precautions,</if>
<if test="storageMethod != null and storageMethod != ''">storage_method,</if>
<if test="expiryDate != null and expiryDate != ''">expiry_date,</if>
<if test="createdAt != null">created_at,</if>
<if test="updatedAt != null">updated_at,</if>
<if test="manufacturer != null and manufacturer != ''">manufacturer,</if>
<if test="salesType != null and salesType != ''">sales_type,</if>
<if test="expertId != null">expert_id,</if>
<if test="recommendReason != null and recommendReason != ''">recommend_reason,</if>
<if test="recommendTime != null">recommend_time,</if>
<if test="storeName != null and storeName != ''">store_name,</if>
<if test="storeAddress != null and storeAddress != ''">store_address,</if>
<if test="storePhone != null and storePhone != ''">store_phone,</if>
<if test="businessHours != null and businessHours != ''">business_hours,</if>
<if test="storeRemark != null and storeRemark != ''">store_remark,</if>
<if test="longitude != null">longitude,</if>
<if test="latitude != null">latitude,</if>
<if test="images != null and images != ''">images,</if>
<if test="imageUrl != null and imageUrl != ''">image_url,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="medicineName != null and medicineName != ''">#{medicineName},</if>
<if test="medicineType != null and medicineType != ''">#{medicineType},</if>
<if test="specification != null and specification != ''">#{specification},</if>
<if test="price != null">#{price},</if>
<if test="originalPrice != null">#{originalPrice},</if>
<if test="soldQuantity != null">#{soldQuantity},</if>
<if test="indications != null and indications != ''">#{indications},</if>
<if test="usageDosage != null and usageDosage != ''">#{usageDosage},</if>
<if test="precautions != null and precautions != ''">#{precautions},</if>
<if test="storageMethod != null and storageMethod != ''">#{storageMethod},</if>
<if test="expiryDate != null and expiryDate != ''">#{expiryDate},</if>
<if test="createdAt != null">#{createdAt},</if>
<if test="updatedAt != null">#{updatedAt},</if>
<if test="manufacturer != null and manufacturer != ''">#{manufacturer},</if>
<if test="salesType != null and salesType != ''">#{salesType},</if>
<if test="expertId != null">#{expertId},</if>
<if test="recommendReason != null and recommendReason != ''">#{recommendReason},</if>
<if test="recommendTime != null">#{recommendTime},</if>
<if test="storeName != null and storeName != ''">#{storeName},</if>
<if test="storeAddress != null and storeAddress != ''">#{storeAddress},</if>
<if test="storePhone != null and storePhone != ''">#{storePhone},</if>
<if test="businessHours != null and businessHours != ''">#{businessHours},</if>
<if test="storeRemark != null and storeRemark != ''">#{storeRemark},</if>
<if test="longitude != null">#{longitude},</if>
<if test="latitude != null">#{latitude},</if>
<if test="images != null and images != ''">#{images},</if>
<if test="imageUrl != null and imageUrl != ''">#{imageUrl},</if>
</trim>
</insert>
<update id="updateSysMedicineRecommendation" parameterType="SysMedicineRecommendation">
update sys_medicine_recommendation
<trim prefix="SET" suffixOverrides=",">
<if test="medicineName != null and medicineName != ''">medicine_name = #{medicineName},</if>
<if test="medicineType != null and medicineType != ''">medicine_type = #{medicineType},</if>
<if test="specification != null and specification != ''">specification = #{specification},</if>
<if test="price != null">price = #{price},</if>
<if test="originalPrice != null">original_price = #{originalPrice},</if>
<if test="soldQuantity != null">sold_quantity = #{soldQuantity},</if>
<if test="indications != null and indications != ''">indications = #{indications},</if>
<if test="usageDosage != null and usageDosage != ''">usage_dosage = #{usageDosage},</if>
<if test="precautions != null and precautions != ''">precautions = #{precautions},</if>
<if test="storageMethod != null and storageMethod != ''">storage_method = #{storageMethod},</if>
<if test="expiryDate != null and expiryDate != ''">expiry_date = #{expiryDate},</if>
<if test="createdAt != null">created_at = #{createdAt},</if>
<if test="updatedAt != null">updated_at = #{updatedAt},</if>
<if test="manufacturer != null and manufacturer != ''">manufacturer = #{manufacturer},</if>
<if test="salesType != null and salesType != ''">sales_type = #{salesType},</if>
<if test="expertId != null">expert_id = #{expertId},</if>
<if test="recommendReason != null">recommend_reason = #{recommendReason},</if>
<if test="recommendTime != null">recommend_time = #{recommendTime},</if>
<if test="storeName != null and storeName != ''">store_name = #{storeName},</if>
<if test="storeAddress != null and storeAddress != ''">store_address = #{storeAddress},</if>
<if test="storePhone != null and storePhone != ''">store_phone = #{storePhone},</if>
<if test="businessHours != null and businessHours != ''">business_hours = #{businessHours},</if>
<if test="storeRemark != null and storeRemark != ''">store_remark = #{storeRemark},</if>
<if test="longitude != null">longitude = #{longitude},</if>
<if test="latitude != null">latitude = #{latitude},</if>
<if test="images != null">images = #{images},</if>
<if test="imageUrl != null">image_url = #{imageUrl},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSysMedicineRecommendationById" parameterType="Long">
delete from sys_medicine_recommendation where id = #{id}
</delete>
<delete id="deleteSysMedicineRecommendationByIds" parameterType="String">
delete from sys_medicine_recommendation where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

22
chenhai-system/src/main/resources/mapper/system/SysPolicyInterpretationMapper.xml

@ -19,10 +19,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" /> <result property="updateTime" column="update_time" />
<result property="remark" column="remark" /> <result property="remark" column="remark" />
<result property="policyCategory" column="policy_category" />
</resultMap> </resultMap>
<sql id="selectSysPolicyInterpretationVo"> <sql id="selectSysPolicyInterpretationVo">
select id, title, policy_file, release_date, issuing_agency, content, publish_status, removal_reason, del_flag, create_by, create_time, update_by, update_time, remark from sys_policy_interpretation
select id, title, policy_file, release_date, issuing_agency, content, publish_status, removal_reason, del_flag, create_by, create_time, update_by, update_time, remark, policy_category from sys_policy_interpretation
</sql> </sql>
<select id="selectSysPolicyInterpretationList" parameterType="SysPolicyInterpretation" resultMap="SysPolicyInterpretationResult"> <select id="selectSysPolicyInterpretationList" parameterType="SysPolicyInterpretation" resultMap="SysPolicyInterpretationResult">
@ -35,6 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="content != null and content != ''"> and content = #{content}</if> <if test="content != null and content != ''"> and content = #{content}</if>
<if test="publishStatus != null and publishStatus != ''"> and publish_status = #{publishStatus}</if> <if test="publishStatus != null and publishStatus != ''"> and publish_status = #{publishStatus}</if>
<if test="removalReason != null and removalReason != ''"> and removal_reason = #{removalReason}</if> <if test="removalReason != null and removalReason != ''"> and removal_reason = #{removalReason}</if>
<if test="policyCategory != null and policyCategory != ''"> and policy_category = #{policyCategory}</if>
</where> </where>
</select> </select>
@ -60,6 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null">update_by,</if> <if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if> <if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if> <if test="remark != null">remark,</if>
<if test="policyCategory != null">policy_category,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
@ -76,6 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null">#{updateBy},</if> <if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if> <if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if> <if test="remark != null">#{remark},</if>
<if test="policyCategory != null">#{policyCategory},</if>
</trim> </trim>
</insert> </insert>
@ -95,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="updateBy != null">update_by = #{updateBy},</if> <if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if> <if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if> <if test="remark != null">remark = #{remark},</if>
<if test="policyCategory != null">policy_category = #{policyCategory},</if>
</trim> </trim>
where id = #{id} where id = #{id}
</update> </update>
@ -151,4 +156,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{id} #{id}
</foreach> </foreach>
</update> </update>
<!-- 查询已上架政策解读列表 -->
<select id="selectPublishedSysPolicyInterpretationList" parameterType="SysPolicyInterpretation" resultMap="SysPolicyInterpretationResult">
<include refid="selectSysPolicyInterpretationVo"/>
<where>
publish_status = '1' <!-- 固定筛选已上架 -->
and del_flag = '0' <!-- 确保未被删除 -->
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="policyFile != null and policyFile != ''"> and policy_file = #{policyFile}</if>
<if test="releaseDate != null "> and release_date = #{releaseDate}</if>
<if test="issuingAgency != null and issuingAgency != ''"> and issuing_agency like concat('%', #{issuingAgency}, '%')</if>
<if test="content != null and content != ''"> and content like concat('%', #{content}, '%')</if>
<if test="policyCategory != null and policyCategory != ''"> and policy_category = #{policyCategory}</if>
</where>
</select>
</mapper> </mapper>

63
chenhai-system/src/main/resources/mapper/system/SysQueryTipMapper.xml

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenhai.system.mapper.SysQueryTipMapper">
<resultMap type="SysQueryTip" id="SysQueryTipResult">
<result property="id" column="id" />
<result property="queryId" column="query_id" />
<result property="tips" column="tips" />
</resultMap>
<sql id="selectSysQueryTipVo">
select id, query_id, tips from sys_query_tip
</sql>
<select id="selectSysQueryTipList" parameterType="SysQueryTip" resultMap="SysQueryTipResult">
<include refid="selectSysQueryTipVo"/>
<where>
<if test="queryId != null "> and query_id = #{queryId}</if>
<if test="tips != null and tips != ''"> and tips = #{tips}</if>
</where>
</select>
<select id="selectSysQueryTipById" parameterType="Long" resultMap="SysQueryTipResult">
<include refid="selectSysQueryTipVo"/>
where id = #{id}
</select>
<insert id="insertSysQueryTip" parameterType="SysQueryTip">
insert into sys_query_tip
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if>
<if test="queryId != null">query_id,</if>
<if test="tips != null">tips,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if>
<if test="queryId != null">#{queryId},</if>
<if test="tips != null">#{tips},</if>
</trim>
</insert>
<update id="updateSysQueryTip" parameterType="SysQueryTip">
update sys_query_tip
<trim prefix="SET" suffixOverrides=",">
<if test="queryId != null">query_id = #{queryId},</if>
<if test="tips != null">tips = #{tips},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSysQueryTipById" parameterType="Long">
delete from sys_query_tip where id = #{id}
</delete>
<delete id="deleteSysQueryTipByIds" parameterType="String">
delete from sys_query_tip where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

34
chenhai-system/src/main/resources/mapper/vet/VetExpertsMapper.xml

@ -22,11 +22,12 @@
<result property="updatedAt" column="updated_at" /> <result property="updatedAt" column="updated_at" />
<result property="expert" column="expert" /> <result property="expert" column="expert" />
<result property="workExperience" column="work_experience" /> <result property="workExperience" column="work_experience" />
<result property="introduction" column="introduction" />
</resultMap> </resultMap>
<sql id="selectVetExpertsVo"> <sql id="selectVetExpertsVo">
select expert_id, user_id, avatar, real_name, iphone, email, address, select expert_id, user_id, avatar, real_name, iphone, email, address,
expertise_area, is_online, remark, sort_order, status, created_at, updated_at, title, expert, work_experience
expertise_area, is_online, remark, sort_order, status, created_at, updated_at, title, expert, work_experience, introduction
from vet_experts from vet_experts
</sql> </sql>
@ -48,6 +49,7 @@
<if test="title != null and title != ''"> and title = #{title}</if> <if test="title != null and title != ''"> and title = #{title}</if>
<if test="expert != null and expert != ''"> and expert = #{expert}</if> <if test="expert != null and expert != ''"> and expert = #{expert}</if>
<if test="workExperience != null and workExperience != ''"> and work_experience = #{workExperience})</if> <if test="workExperience != null and workExperience != ''"> and work_experience = #{workExperience})</if>
<if test="introduction != null and introduction != ''"> and introduction like concat('%', #{introduction}, '%')</if>
</where> </where>
</select> </select>
@ -75,6 +77,7 @@
<if test="title != null">title,</if> <if test="title != null">title,</if>
<if test="expert != null">expert,</if> <if test="expert != null">expert,</if>
<if test="workExperience != null">work_experience,</if> <if test="workExperience != null">work_experience,</if>
<if test="introduction != null">introduction,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">#{userId},</if> <if test="userId != null">#{userId},</if>
@ -93,6 +96,7 @@
<if test="title != null">#{title},</if> <if test="title != null">#{title},</if>
<if test="expert != null">#{expert},</if> <if test="expert != null">#{expert},</if>
<if test="workExperience != null">#{workExperience},</if> <if test="workExperience != null">#{workExperience},</if>
<if test="introduction != null">#{introduction},</if>
</trim> </trim>
</insert> </insert>
@ -115,6 +119,7 @@
<if test="title != null">title = #{title},</if> <if test="title != null">title = #{title},</if>
<if test="expert != null">expert = #{expert},</if> <if test="expert != null">expert = #{expert},</if>
<if test="workExperience != null">work_experience = #{workExperience},</if> <if test="workExperience != null">work_experience = #{workExperience},</if>
<if test="introduction != null">introduction = #{introduction},</if>
</trim> </trim>
where expert_id = #{expertId} where expert_id = #{expertId}
</update> </update>
@ -129,4 +134,31 @@
#{expertId} #{expertId}
</foreach> </foreach>
</delete> </delete>
<!-- 添加搜索专家信息的SQL查询 -->
<select id="searchVetExperts" parameterType="String" resultMap="VetExpertsResult">
<include refid="selectVetExpertsVo"/>
<where>
status = '0' <!-- 只查询状态正常的专家(0-正常,1-停用) -->
<if test="keyword != null and keyword != ''">
and (
real_name like concat('%', #{keyword}, '%')
or expertise_area like concat('%', #{keyword}, '%')
)
</if>
</where>
order by
is_online desc <!-- 在线状态优先 -->
</select>
<!-- 添加只更新在线状态的方法 -->
<update id="updateOnlineStatusOnly" parameterType="VetExperts">
update vet_experts
<set>
is_online = #{isOnline},
sort_order = #{sortOrder},
updated_at = now()
</set>
where expert_id = #{expertId}
</update>
</mapper> </mapper>

59
chenhai-system/src/main/resources/mapper/vet/VetKnowledgeMapper.xml

@ -18,10 +18,49 @@
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" /> <result property="updateTime" column="update_time" />
<result property="remark" column="remark" /> <result property="remark" column="remark" />
<result property="publishTime" column="publish_time" />
<result property="viewCount" column="view_count" />
<result property="expertId" column="expert_id" />
<result property="expertName" column="expert_name" />
<result property="expertAvatar" column="expert_avatar"/>
<result property="coverImage" column="cover_image" />
<result property="subtitle" column="subtitle" />
</resultMap> </resultMap>
<select id="selectExpertByUsername" parameterType="String" resultType="VetExperts">
SELECT * FROM vet_experts
WHERE user_id = (SELECT user_id FROM sys_user WHERE user_name = #{username})
</select>
<select id="selectExpertByUserId" parameterType="Long" resultType="VetExperts">
SELECT * FROM vet_experts WHERE user_id = #{userId}
</select>
<!-- 修改查询语句,关联专家表 -->
<sql id="selectVetKnowledgeVo"> <sql id="selectVetKnowledgeVo">
select id, title, content, category, sensitive_words, article_status, audit_status, audit_comment, create_by, create_time, update_by, update_time, remark from vet_knowledge
select
vk.id,
vk.title,
vk.content,
vk.category,
vk.sensitive_words,
vk.article_status,
vk.audit_status,
vk.audit_comment,
vk.create_by,
vk.create_time,
vk.update_by,
vk.update_time,
vk.remark,
vk.publish_time,
vk.view_count,
vk.cover_image,
vk.subtitle,
vk.expert_id,
ve.real_name as expert_name, <!-- 添加专家姓名 -->
ve.avatar as expert_avatar
from vet_knowledge vk
left join vet_experts ve on vk.expert_id = ve.expert_id
</sql> </sql>
<select id="selectVetKnowledgeList" parameterType="VetKnowledge" resultMap="VetKnowledgeResult"> <select id="selectVetKnowledgeList" parameterType="VetKnowledge" resultMap="VetKnowledgeResult">
@ -33,6 +72,9 @@
<if test="sensitiveWords != null and sensitiveWords != ''"> and sensitive_words like concat('%', #{sensitiveWords}, '%')</if> <if test="sensitiveWords != null and sensitiveWords != ''"> and sensitive_words like concat('%', #{sensitiveWords}, '%')</if>
<if test="articleStatus != null and articleStatus != ''"> and article_status = #{articleStatus}</if> <if test="articleStatus != null and articleStatus != ''"> and article_status = #{articleStatus}</if>
<if test="auditStatus != null and auditStatus != ''"> and audit_status = #{auditStatus}</if> <if test="auditStatus != null and auditStatus != ''"> and audit_status = #{auditStatus}</if>
<if test="expertId != null and expertId != ''"> and expert_id = #{expertId}</if>
<if test="coverImage != null and coverImage != ''"> and cover_image = #{coverImage}</if>
<if test="subtitle != null and subtitle != ''"> and subtitle like concat('%', #{subtitle}, '%')</if>
</where> </where>
</select> </select>
@ -56,6 +98,11 @@
<if test="updateBy != null">update_by,</if> <if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if> <if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if> <if test="remark != null">remark,</if>
<if test="publishTime != null">publish_time,</if>
<if test="viewCount != null">view_count,</if>
<if test="expertId != null">expert_id,</if>
<if test="coverImage != null">cover_image,</if>
<if test="subtitle != null and subtitle != ''">subtitle,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="title != null and title != ''">#{title},</if> <if test="title != null and title != ''">#{title},</if>
@ -70,6 +117,11 @@
<if test="updateBy != null">#{updateBy},</if> <if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if> <if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if> <if test="remark != null">#{remark},</if>
<if test="publishTime != null">#{publishTime},</if>
<if test="viewCount != null">#{viewCount},</if>
<if test="expertId != null">#{expertId},</if>
<if test="coverImage != null">#{coverImage},</if>
<if test="subtitle != null and subtitle != ''">#{subtitle},</if>
</trim> </trim>
</insert> </insert>
@ -88,6 +140,11 @@
<if test="updateBy != null">update_by = #{updateBy},</if> <if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if> <if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if> <if test="remark != null">remark = #{remark},</if>
<if test="publishTime != null">publish_time = #{publishTime},</if>
<if test="viewCount != null">view_count = #{viewCount},</if>
<if test="expertId != null">expert_id = #{expertId},</if>
<if test="coverImage != null">cover_image = #{coverImage},</if>
<if test="subtitle != null and subtitle != ''">subtitle = #{subtitle},</if>
</trim> </trim>
where id = #{id} where id = #{id}
</update> </update>

13
chenhai-system/src/main/resources/mapper/vet/VetTrainingVideoMapper.xml

@ -22,6 +22,7 @@
<result property="userName" column="user_name"/> <result property="userName" column="user_name"/>
<result property="auditUserId" column="audit_user_id"/> <result property="auditUserId" column="audit_user_id"/>
<result property="auditTime" column="audit_time"/> <result property="auditTime" column="audit_time"/>
<result property="userAvatar" column="user_avatar"/>
</resultMap> </resultMap>
<insert id="insertVideo" parameterType="VetTrainingVideo" useGeneratedKeys="true" keyProperty="id"> <insert id="insertVideo" parameterType="VetTrainingVideo" useGeneratedKeys="true" keyProperty="id">
@ -39,7 +40,7 @@
</insert> </insert>
<select id="selectMyVideos" resultMap="VideoResult"> <select id="selectMyVideos" resultMap="VideoResult">
SELECT v.*, u.nick_name as user_name
SELECT v.*, u.nick_name as user_name,u.avatar as user_avatar
FROM vet_training_video v FROM vet_training_video v
LEFT JOIN sys_user u ON v.user_id = u.user_id LEFT JOIN sys_user u ON v.user_id = u.user_id
WHERE v.user_id = #{userId} WHERE v.user_id = #{userId}
@ -59,7 +60,7 @@
</select> </select>
<select id="selectPublicVideos" resultMap="VideoResult"> <select id="selectPublicVideos" resultMap="VideoResult">
SELECT v.*, u.nick_name as user_name
SELECT v.*, u.nick_name as user_name,u.avatar as user_avatar
FROM vet_training_video v FROM vet_training_video v
LEFT JOIN sys_user u ON v.user_id = u.user_id LEFT JOIN sys_user u ON v.user_id = u.user_id
WHERE v.status = '1' WHERE v.status = '1'
@ -77,7 +78,7 @@
</select> </select>
<select id="selectVideoById" resultMap="VideoResult"> <select id="selectVideoById" resultMap="VideoResult">
SELECT v.*, u.nick_name as user_name
SELECT v.*, u.nick_name as user_name,u.avatar as user_avatar
FROM vet_training_video v FROM vet_training_video v
LEFT JOIN sys_user u ON v.user_id = u.user_id LEFT JOIN sys_user u ON v.user_id = u.user_id
WHERE v.id = #{id} WHERE v.id = #{id}
@ -90,7 +91,7 @@
</update> </update>
<select id="selectHotVideos" resultMap="VideoResult"> <select id="selectHotVideos" resultMap="VideoResult">
SELECT v.*, u.nick_name as user_name
SELECT v.*, u.nick_name as user_name,u.avatar as user_avatar
FROM vet_training_video v FROM vet_training_video v
LEFT JOIN sys_user u ON v.user_id = u.user_id LEFT JOIN sys_user u ON v.user_id = u.user_id
WHERE v.status = '1' WHERE v.status = '1'
@ -100,7 +101,7 @@
</select> </select>
<select id="searchVideos" resultMap="VideoResult"> <select id="searchVideos" resultMap="VideoResult">
SELECT v.*, u.nick_name as user_name
SELECT v.*, u.nick_name as user_name,u.avatar as user_avatar
FROM vet_training_video v FROM vet_training_video v
LEFT JOIN sys_user u ON v.user_id = u.user_id LEFT JOIN sys_user u ON v.user_id = u.user_id
WHERE v.status = '1' WHERE v.status = '1'
@ -135,7 +136,7 @@
</update> </update>
<select id="selectPendingAuditVideos" resultMap="VideoResult"> <select id="selectPendingAuditVideos" resultMap="VideoResult">
SELECT v.*, u.nick_name as user_name
SELECT v.*, u.nick_name as user_name,u.avatar as user_avatar
FROM vet_training_video v FROM vet_training_video v
LEFT JOIN sys_user u ON v.user_id = u.user_id LEFT JOIN sys_user u ON v.user_id = u.user_id
WHERE v.audit_status = '0' WHERE v.audit_status = '0'

72
chenhai-ui/src/api/system/chat.js

@ -0,0 +1,72 @@
// /api/chat/chat.js - 修改为使用现有接口
import request from '@/utils/request'
// 使用现有的专家接口获取专家信息
export function getExpertInfo(expertId) {
return request({
url: '/vet/experts/' + expertId,
method: 'get'
})
}
// 使用现有的会话接口创建会话
export function createOrGetSession(data) {
return request({
url: '/system/session/createOrGetSession',
method: 'post',
data: data
})
}
// 使用现有的消息接口发送消息
export function sendTextMessage(data) {
return request({
url: '/system/message/send',
method: 'post',
data: data
})
}
// 使用现有的消息接口获取会话消息
export function getSessionMessages(sessionId) {
const query = {
sessionId: sessionId,
delFlag: '0'
}
return request({
url: '/system/message/list',
method: 'get',
params: query
})
}
// 标记消息为已读(通过修改消息接口)
export function markMessagesAsRead(sessionId, senderType) {
return request({
url: '/system/message/markAllRead',
method: 'post',
data: { sessionId, senderType }
})
}
// 获取用户会话列表
export function getUserSessions(userId) {
const query = {
userId: userId,
delFlag: '0'
}
return request({
url: '/system/session/list',
method: 'get',
params: query
})
}
// 结束会话
export function endSession(sessionId, reason) {
return request({
url: '/system/session/end',
method: 'post',
data: { sessionId, reason }
})
}

44
chenhai-ui/src/api/system/consultation.js

@ -1,44 +0,0 @@
import request from '@/utils/request'
// 查询专家咨询列表
export function listConsultation(query) {
return request({
url: '/system/consultation/list',
method: 'get',
params: query
})
}
// 查询专家咨询详细
export function getConsultation(consultationId) {
return request({
url: '/system/consultation/' + consultationId,
method: 'get'
})
}
// 新增专家咨询
export function addConsultation(data) {
return request({
url: '/system/consultation',
method: 'post',
data: data
})
}
// 修改专家咨询
export function updateConsultation(data) {
return request({
url: '/system/consultation',
method: 'put',
data: data
})
}
// 删除专家咨询
export function delConsultation(consultationId) {
return request({
url: '/system/consultation/' + consultationId,
method: 'delete'
})
}

44
chenhai-ui/src/api/system/message.js

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询兽医咨询聊天消息列表
export function listMessage(query) {
return request({
url: '/system/message/list',
method: 'get',
params: query
})
}
// 查询兽医咨询聊天消息详细
export function getMessage(messageId) {
return request({
url: '/system/message/' + messageId,
method: 'get'
})
}
// 新增兽医咨询聊天消息
export function addMessage(data) {
return request({
url: '/system/message',
method: 'post',
data: data
})
}
// 修改兽医咨询聊天消息
export function updateMessage(data) {
return request({
url: '/system/message',
method: 'put',
data: data
})
}
// 删除兽医咨询聊天消息
export function delMessage(messageId) {
return request({
url: '/system/message/' + messageId,
method: 'delete'
})
}

44
chenhai-ui/src/api/system/query.js

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询知识库查询列表
export function listQuery(query) {
return request({
url: '/system/query/list',
method: 'get',
params: query
})
}
// 查询知识库查询详细
export function getQuery(id) {
return request({
url: '/system/query/' + id,
method: 'get'
})
}
// 新增知识库查询
export function addQuery(data) {
return request({
url: '/system/query',
method: 'post',
data: data
})
}
// 修改知识库查询
export function updateQuery(data) {
return request({
url: '/system/query',
method: 'put',
data: data
})
}
// 删除知识库查询
export function delQuery(id) {
return request({
url: '/system/query/' + id,
method: 'delete'
})
}

44
chenhai-ui/src/api/system/recommendation.js

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询药品推荐列表
export function listRecommendation(query) {
return request({
url: '/system/recommendation/list',
method: 'get',
params: query
})
}
// 查询药品推荐详细
export function getRecommendation(id) {
return request({
url: '/system/recommendation/' + id,
method: 'get'
})
}
// 新增药品推荐
export function addRecommendation(data) {
return request({
url: '/system/recommendation',
method: 'post',
data: data
})
}
// 修改药品推荐
export function updateRecommendation(data) {
return request({
url: '/system/recommendation',
method: 'put',
data: data
})
}
// 删除药品推荐
export function delRecommendation(id) {
return request({
url: '/system/recommendation/' + id,
method: 'delete'
})
}

44
chenhai-ui/src/api/system/session.js

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询兽医咨询聊天会话列表
export function listSession(query) {
return request({
url: '/system/session/list',
method: 'get',
params: query
})
}
// 查询兽医咨询聊天会话详细
export function getSession(sessionId) {
return request({
url: '/system/session/' + sessionId,
method: 'get'
})
}
// 新增兽医咨询聊天会话
export function addSession(data) {
return request({
url: '/system/session',
method: 'post',
data: data
})
}
// 修改兽医咨询聊天会话
export function updateSession(data) {
return request({
url: '/system/session',
method: 'put',
data: data
})
}
// 删除兽医咨询聊天会话
export function delSession(sessionId) {
return request({
url: '/system/session/' + sessionId,
method: 'delete'
})
}

44
chenhai-ui/src/api/system/tip.js

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询知识库查询提示列表
export function listTip(query) {
return request({
url: '/system/tip/list',
method: 'get',
params: query
})
}
// 查询知识库查询提示详细
export function getTip(id) {
return request({
url: '/system/tip/' + id,
method: 'get'
})
}
// 新增知识库查询提示
export function addTip(data) {
return request({
url: '/system/tip',
method: 'post',
data: data
})
}
// 修改知识库查询提示
export function updateTip(data) {
return request({
url: '/system/tip',
method: 'put',
data: data
})
}
// 删除知识库查询提示
export function delTip(id) {
return request({
url: '/system/tip/' + id,
method: 'delete'
})
}

68
chenhai-ui/src/router/index.js

@ -30,6 +30,74 @@ import Layout from '@/layout'
// 公共路由 // 公共路由
export const constantRoutes = [ export const constantRoutes = [
// 专家管理路由
{
path: '/vet/experts',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/vet/experts/index'),
name: 'VetExperts',
meta: {
title: '专家管理',
icon: 'user',
permissions: ['vet:experts:list']
}
}
]
},
// 聊天页面路由
{
path: '/chat',
component: Layout,
children: [
{
path: 'index',
component: () => import('@/views/chat/index'),
name: 'ChatIndex',
meta: {
title: '在线咨询',
icon: 'message'
}
}
]
},
// 在路由文件中添加以下路由
{
path: '/vet/experts',
component: Layout,
redirect: '/expert/chat/list',
meta: {
title: '专家中心',
icon: 'expert',
roles: ['vetnotshenhe', 'admin']
},
children: [
{
path: 'chat/list',
component: () => import('@/views/chat/expert'), // 专家会话列表
name: 'ExpertChatList',
meta: {
title: '我的咨询',
icon: 'list',
roles: ['vetnotshenhe', 'admin']
}
},
{
path: 'chat/index',
component: () => import('@/views/chat/expert'), // 专家聊天页面
name: 'ExpertChat',
meta: {
title: '专家聊天',
icon: 'message',
roles: ['vetnotshenhe', 'admin']
}
}
]
},
{ {
path: '/redirect', path: '/redirect',
component: Layout, component: Layout,

1178
chenhai-ui/src/views/chat/expert.vue
File diff suppressed because it is too large
View File

1353
chenhai-ui/src/views/chat/index.vue
File diff suppressed because it is too large
View File

460
chenhai-ui/src/views/system/consultation/index.vue

@ -1,460 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户ID" prop="userId">
<el-input
v-model="queryParams.userId"
placeholder="请输入用户ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="专家ID" prop="expertId">
<el-input
v-model="queryParams.expertId"
placeholder="请输入专家ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="关联问诊单ID" prop="formId">
<el-input
v-model="queryParams.formId"
placeholder="请输入关联问诊单ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="咨询标题" prop="consultationTitle">
<el-input
v-model="queryParams.consultationTitle"
placeholder="请输入咨询标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户评分(1-5分)" prop="rating">
<el-input
v-model="queryParams.rating"
placeholder="请输入用户评分(1-5分)"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="用户评价内容" prop="evaluation">
<el-input
v-model="queryParams.evaluation"
placeholder="请输入用户评价内容"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="评价时间" prop="evaluationTime">
<el-date-picker clearable
v-model="queryParams.evaluationTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择评价时间">
</el-date-picker>
</el-form-item>
<el-form-item label="咨询开始时间" prop="startTime">
<el-date-picker clearable
v-model="queryParams.startTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择咨询开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="咨询结束时间" prop="endTime">
<el-date-picker clearable
v-model="queryParams.endTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择咨询结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="创建时间" prop="createdTime">
<el-date-picker clearable
v-model="queryParams.createdTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择创建时间">
</el-date-picker>
</el-form-item>
<el-form-item label="更新时间" prop="updatedTime">
<el-date-picker clearable
v-model="queryParams.updatedTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择更新时间">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:consultation:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:consultation:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:consultation:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:consultation:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="consultationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="咨询ID" align="center" prop="consultationId" />
<el-table-column label="用户ID" align="center" prop="userId" />
<el-table-column label="专家ID" align="center" prop="expertId" />
<el-table-column label="关联问诊单ID" align="center" prop="formId" />
<el-table-column label="咨询类型: 1-图文咨询, 2-电话咨询, 3-视频咨询" align="center" prop="consultationType" />
<el-table-column label="咨询状态: 0-待接诊, 1-进行中, 2-已完成, 3-已取消" align="center" prop="consultationStatus" />
<el-table-column label="咨询标题" align="center" prop="consultationTitle" />
<el-table-column label="用户初始咨询内容" align="center" prop="initialContent" />
<el-table-column label="用户初始附件(JSON数组)" align="center" prop="initialAttachments" />
<el-table-column label="对话消息(JSON格式)" align="center" prop="messages" />
<el-table-column label="用户评分(1-5分)" align="center" prop="rating" />
<el-table-column label="用户评价内容" align="center" prop="evaluation" />
<el-table-column label="评价标签(JSON数组)" align="center" prop="evaluationTags" />
<el-table-column label="评价时间" align="center" prop="evaluationTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.evaluationTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="咨询开始时间" align="center" prop="startTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="咨询结束时间" align="center" prop="endTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createdTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createdTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updatedTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updatedTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:consultation:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:consultation:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改专家咨询对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户ID" />
</el-form-item>
<el-form-item label="专家ID" prop="expertId">
<el-input v-model="form.expertId" placeholder="请输入专家ID" />
</el-form-item>
<el-form-item label="关联问诊单ID" prop="formId">
<el-input v-model="form.formId" placeholder="请输入关联问诊单ID" />
</el-form-item>
<el-form-item label="咨询标题" prop="consultationTitle">
<el-input v-model="form.consultationTitle" placeholder="请输入咨询标题" />
</el-form-item>
<el-form-item label="用户初始咨询内容">
<editor v-model="form.initialContent" :min-height="192"/>
</el-form-item>
<el-form-item label="对话消息(JSON格式)" prop="messages">
<el-input v-model="form.messages" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="用户评分(1-5分)" prop="rating">
<el-input v-model="form.rating" placeholder="请输入用户评分(1-5分)" />
</el-form-item>
<el-form-item label="用户评价内容" prop="evaluation">
<el-input v-model="form.evaluation" placeholder="请输入用户评价内容" />
</el-form-item>
<el-form-item label="评价时间" prop="evaluationTime">
<el-date-picker clearable
v-model="form.evaluationTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择评价时间">
</el-date-picker>
</el-form-item>
<el-form-item label="咨询开始时间" prop="startTime">
<el-date-picker clearable
v-model="form.startTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择咨询开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="咨询结束时间" prop="endTime">
<el-date-picker clearable
v-model="form.endTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择咨询结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="创建时间" prop="createdTime">
<el-date-picker clearable
v-model="form.createdTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择创建时间">
</el-date-picker>
</el-form-item>
<el-form-item label="更新时间" prop="updatedTime">
<el-date-picker clearable
v-model="form.updatedTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择更新时间">
</el-date-picker>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listConsultation, getConsultation, delConsultation, addConsultation, updateConsultation } from "@/api/system/consultation"
export default {
name: "Consultation",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
consultationList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
userId: null,
expertId: null,
formId: null,
consultationType: null,
consultationStatus: null,
consultationTitle: null,
initialContent: null,
initialAttachments: null,
messages: null,
rating: null,
evaluation: null,
evaluationTags: null,
evaluationTime: null,
startTime: null,
endTime: null,
createdTime: null,
updatedTime: null
},
//
form: {},
//
rules: {
userId: [
{ required: true, message: "用户ID不能为空", trigger: "blur" }
],
expertId: [
{ required: true, message: "专家ID不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询专家咨询列表 */
getList() {
this.loading = true
listConsultation(this.queryParams).then(response => {
this.consultationList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
consultationId: null,
userId: null,
expertId: null,
formId: null,
consultationType: null,
consultationStatus: null,
consultationTitle: null,
initialContent: null,
initialAttachments: null,
messages: null,
rating: null,
evaluation: null,
evaluationTags: null,
evaluationTime: null,
startTime: null,
endTime: null,
createdTime: null,
updatedTime: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.consultationId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加专家咨询"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const consultationId = row.consultationId || this.ids
getConsultation(consultationId).then(response => {
this.form = response.data
this.open = true
this.title = "修改专家咨询"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.consultationId != null) {
updateConsultation(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addConsultation(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const consultationIds = row.consultationId || this.ids
this.$modal.confirm('是否确认删除专家咨询编号为"' + consultationIds + '"的数据项?').then(function() {
return delConsultation(consultationIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/consultation/export', {
...this.queryParams
}, `consultation_${new Date().getTime()}.xlsx`)
}
}
}
</script>

20
chenhai-ui/src/views/system/interpretation/index.vue

@ -111,7 +111,6 @@
<el-table v-loading="loading" :data="interpretationList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="interpretationList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" />
<el-table-column label="标题" align="center" prop="title" /> <el-table-column label="标题" align="center" prop="title" />
<el-table-column label="政策文件" align="center" prop="policyFile" width="120"> <el-table-column label="政策文件" align="center" prop="policyFile" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
@ -136,6 +135,11 @@
<div v-html="scope.row.content ? scope.row.content.substring(0, 50) + '...' : '-'"></div> <div v-html="scope.row.content ? scope.row.content.substring(0, 50) + '...' : '-'"></div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="政策分类" align="center" prop="policyCategory" width="100">
<template slot-scope="scope">
<dict-tag :options="dict.type.policy_category" :value="scope.row.policyCategory"/>
</template>
</el-table-column>
<el-table-column label="上架状态" align="center" prop="publishStatus" width="100"> <el-table-column label="上架状态" align="center" prop="publishStatus" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.sys_publish_status" :value="scope.row.publishStatus"/> <dict-tag :options="dict.type.sys_publish_status" :value="scope.row.publishStatus"/>
@ -213,14 +217,10 @@
<el-form-item label="解读内容"> <el-form-item label="解读内容">
<editor v-model="form.content" :min-height="192"/> <editor v-model="form.content" :min-height="192"/>
</el-form-item> </el-form-item>
<el-form-item label="上架状态" prop="publishStatus">
<el-radio-group v-model="form.publishStatus">
<el-radio
v-for="dict in dict.type.sys_publish_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
<el-form-item label="政策类型" prop="policyCategory">
<el-select v-model="form.policyCategory" placeholder="请选择政策类型" clearable>
<el-option v-for="dict in dict.type.policy_category" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" type="textarea" :rows="3" /> <el-input v-model="form.remark" placeholder="请输入备注" type="textarea" :rows="3" />
@ -252,7 +252,7 @@ import { listInterpretation, getInterpretation, delInterpretation, addInterpreta
export default { export default {
name: "Interpretation", name: "Interpretation",
dicts: ['sys_publish_status'],
dicts: ['sys_publish_status','policy_category'],
data() { data() {
return { return {
// //

328
chenhai-ui/src/views/system/message/index.vue

@ -0,0 +1,328 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="会话ID" prop="sessionId">
<el-input
v-model="queryParams.sessionId"
placeholder="请输入会话ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="发送者ID" prop="senderId">
<el-input
v-model="queryParams.senderId"
placeholder="请输入发送者ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否已读:0-未读,1-已读" prop="isRead">
<el-input
v-model="queryParams.isRead"
placeholder="请输入是否已读:0-未读,1-已读"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="阅读时间" prop="readTime">
<el-date-picker clearable
v-model="queryParams.readTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择阅读时间">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:message:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:message:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:message:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:message:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="messageList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="消息ID" align="center" prop="messageId" />
<el-table-column label="会话ID" align="center" prop="sessionId" />
<el-table-column label="发送者类型:0-用户,1-专家" align="center" prop="senderType" />
<el-table-column label="发送者ID" align="center" prop="senderId" />
<el-table-column label="消息内容" align="center" prop="content" />
<el-table-column label="消息类型:text-文本,image-图片" align="center" prop="msgType" />
<el-table-column label="是否已读:0-未读,1-已读" align="center" prop="isRead" />
<el-table-column label="阅读时间" align="center" prop="readTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.readTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:message:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:message:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改兽医咨询聊天消息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="会话ID" prop="sessionId">
<el-input v-model="form.sessionId" placeholder="请输入会话ID" />
</el-form-item>
<el-form-item label="发送者ID" prop="senderId">
<el-input v-model="form.senderId" placeholder="请输入发送者ID" />
</el-form-item>
<el-form-item label="消息内容">
<editor v-model="form.content" :min-height="192"/>
</el-form-item>
<el-form-item label="是否已读:0-未读,1-已读" prop="isRead">
<el-input v-model="form.isRead" placeholder="请输入是否已读:0-未读,1-已读" />
</el-form-item>
<el-form-item label="阅读时间" prop="readTime">
<el-date-picker clearable
v-model="form.readTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择阅读时间">
</el-date-picker>
</el-form-item>
<el-form-item label="删除标志" prop="delFlag">
<el-input v-model="form.delFlag" placeholder="请输入删除标志" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listMessage, getMessage, delMessage, addMessage, updateMessage } from "@/api/system/message"
export default {
name: "Message",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
messageList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
sessionId: null,
senderType: null,
senderId: null,
content: null,
msgType: null,
isRead: null,
readTime: null,
},
//
form: {},
//
rules: {
sessionId: [
{ required: true, message: "会话ID不能为空", trigger: "blur" }
],
senderType: [
{ required: true, message: "发送者类型:0-用户,1-专家不能为空", trigger: "change" }
],
senderId: [
{ required: true, message: "发送者ID不能为空", trigger: "blur" }
],
content: [
{ required: true, message: "消息内容不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询兽医咨询聊天消息列表 */
getList() {
this.loading = true
listMessage(this.queryParams).then(response => {
this.messageList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
messageId: null,
sessionId: null,
senderType: null,
senderId: null,
content: null,
msgType: null,
isRead: null,
readTime: null,
delFlag: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.messageId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加兽医咨询聊天消息"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const messageId = row.messageId || this.ids
getMessage(messageId).then(response => {
this.form = response.data
this.open = true
this.title = "修改兽医咨询聊天消息"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.messageId != null) {
updateMessage(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addMessage(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const messageIds = row.messageId || this.ids
this.$modal.confirm('是否确认删除兽医咨询聊天消息编号为"' + messageIds + '"的数据项?').then(function() {
return delMessage(messageIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/message/export', {
...this.queryParams
}, `message_${new Date().getTime()}.xlsx`)
}
}
}
</script>

286
chenhai-ui/src/views/system/query/index.vue

@ -0,0 +1,286 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="标题" prop="title">
<el-input
v-model="queryParams.title"
placeholder="请输入标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="关键词" prop="keywords">
<el-input
v-model="queryParams.keywords"
placeholder="请输入关键词"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:query:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:query:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:query:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:query:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="queryList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="标题" align="center" prop="title" />
<el-table-column label="具体内容" align="center" prop="content" />
<el-table-column label="分类" align="center" prop="categoryType" />
<el-table-column label="关键词" align="center" prop="keywords" />
<el-table-column label="时间" align="center" prop="publishTime" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:query:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:query:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改知识库查询对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="标题”" prop="title">
<el-input v-model="form.title" placeholder="请输入标题" />
</el-form-item>
<el-form-item label="知识库分类" prop="categoryType">
<el-select v-model="form.categoryType" placeholder="请选择知识库分类" clearable>
<el-option v-for="dict in dict.type.category_type1" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item label="具体内容" prop="content">
<el-input v-model="form.content" placeholder="请输入具体内容" />
</el-form-item>
<el-form-item label="关键词" prop="keywords">
<el-input v-model="form.keywords" placeholder="请输入关键词" />
</el-form-item>
<el-form-item label="时间" prop="publishTime">
<el-date-picker
v-model="form.publishTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择时间"
style="width: 100%;"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listQuery, getQuery, delQuery, addQuery, updateQuery } from "@/api/system/query"
export default {
name: "Query",
dicts: ['category_type1'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
queryList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
title: null,
content: null,
categoryType: null,
keywords: null
},
//
form: {},
//
rules: {
title: [
{ required: true, message: "标题,如“猪瘟防治”不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询知识库查询列表 */
getList() {
this.loading = true
listQuery(this.queryParams).then(response => {
this.queryList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: null,
title: null,
content: null,
categoryType: null,
keywords: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加知识库查询"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getQuery(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改知识库查询"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateQuery(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addQuery(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除知识库查询编号为"' + ids + '"的数据项?').then(function() {
return delQuery(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/query/export', {
...this.queryParams
}, `query_${new Date().getTime()}.xlsx`)
}
}
}
</script>

1012
chenhai-ui/src/views/system/recommendation/index.vue
File diff suppressed because it is too large
View File

347
chenhai-ui/src/views/system/session/index.vue

@ -0,0 +1,347 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户ID" prop="userId">
<el-input
v-model="queryParams.userId"
placeholder="请输入用户ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="专家ID" prop="expertId">
<el-input
v-model="queryParams.expertId"
placeholder="请输入专家ID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="最后消息时间" prop="lastMessageTime">
<el-date-picker clearable
v-model="queryParams.lastMessageTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择最后消息时间">
</el-date-picker>
</el-form-item>
<el-form-item label="用户未读数" prop="unreadUser">
<el-input
v-model="queryParams.unreadUser"
placeholder="请输入用户未读数"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="专家未读数" prop="unreadExpert">
<el-input
v-model="queryParams.unreadExpert"
placeholder="请输入专家未读数"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:session:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:session:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:session:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:session:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="sessionList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="会话ID,格式:user_{uid}_expert_{eid}" align="center" prop="sessionId" />
<el-table-column label="用户ID" align="center" prop="userId" />
<el-table-column label="专家ID" align="center" prop="expertId" />
<el-table-column label="动物类型" align="center" prop="animalType" />
<el-table-column label="症状摘要" align="center" prop="symptomSummary" />
<el-table-column label="最后一条消息" align="center" prop="lastMessage" />
<el-table-column label="最后消息时间" align="center" prop="lastMessageTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastMessageTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="用户未读数" align="center" prop="unreadUser" />
<el-table-column label="专家未读数" align="center" prop="unreadExpert" />
<el-table-column label="0-进行中 1-已结束" align="center" prop="sessionStatus" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:session:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:session:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改兽医咨询聊天会话对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户ID" />
</el-form-item>
<el-form-item label="专家ID" prop="expertId">
<el-input v-model="form.expertId" placeholder="请输入专家ID" />
</el-form-item>
<el-form-item label="症状摘要" prop="symptomSummary">
<el-input v-model="form.symptomSummary" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="最后一条消息" prop="lastMessage">
<el-input v-model="form.lastMessage" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="最后消息时间" prop="lastMessageTime">
<el-date-picker clearable
v-model="form.lastMessageTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择最后消息时间">
</el-date-picker>
</el-form-item>
<el-form-item label="用户未读数" prop="unreadUser">
<el-input v-model="form.unreadUser" placeholder="请输入用户未读数" />
</el-form-item>
<el-form-item label="专家未读数" prop="unreadExpert">
<el-input v-model="form.unreadExpert" placeholder="请输入专家未读数" />
</el-form-item>
<el-form-item label="删除标志" prop="delFlag">
<el-input v-model="form.delFlag" placeholder="请输入删除标志" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listSession, getSession, delSession, addSession, updateSession } from "@/api/system/session"
export default {
name: "Session",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
sessionList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
userId: null,
expertId: null,
animalType: null,
symptomSummary: null,
lastMessage: null,
lastMessageTime: null,
unreadUser: null,
unreadExpert: null,
sessionStatus: null,
},
//
form: {},
//
rules: {
userId: [
{ required: true, message: "用户ID不能为空", trigger: "blur" }
],
expertId: [
{ required: true, message: "专家ID不能为空", trigger: "blur" }
],
}
}
},
created() {
this.getList()
},
methods: {
/** 查询兽医咨询聊天会话列表 */
getList() {
this.loading = true
listSession(this.queryParams).then(response => {
this.sessionList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
sessionId: null,
userId: null,
expertId: null,
animalType: null,
symptomSummary: null,
lastMessage: null,
lastMessageTime: null,
unreadUser: null,
unreadExpert: null,
sessionStatus: null,
delFlag: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
remark: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.sessionId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加兽医咨询聊天会话"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const sessionId = row.sessionId || this.ids
getSession(sessionId).then(response => {
this.form = response.data
this.open = true
this.title = "修改兽医咨询聊天会话"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.sessionId != null) {
updateSession(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addSession(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const sessionIds = row.sessionId || this.ids
this.$modal.confirm('是否确认删除兽医咨询聊天会话编号为"' + sessionIds + '"的数据项?').then(function() {
return delSession(sessionIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/session/export', {
...this.queryParams
}, `session_${new Date().getTime()}.xlsx`)
}
}
}
</script>

246
chenhai-ui/src/views/system/tip/index.vue

@ -0,0 +1,246 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="提示" prop="tips">
<el-input
v-model="queryParams.tips"
placeholder="请输入提示"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:tip:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:tip:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:tip:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:tip:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="tipList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="提示" align="center" prop="tips" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:tip:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:tip:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改知识库查询提示对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="提示" prop="tips">
<el-input v-model="form.tips" placeholder="请输入提示" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listTip, getTip, delTip, addTip, updateTip } from "@/api/system/tip"
export default {
name: "Tip",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
tipList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
queryId: null,
tips: null
},
//
form: {},
//
rules: {
}
}
},
created() {
this.getList()
},
methods: {
/** 查询知识库查询提示列表 */
getList() {
this.loading = true
listTip(this.queryParams).then(response => {
this.tipList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: null,
queryId: null,
tips: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = "添加知识库查询提示"
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getTip(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改知识库查询提示"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
updateTip(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addTip(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除知识库查询提示编号为"' + ids + '"的数据项?').then(function() {
return delTip(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/tip/export', {
...this.queryParams
}, `tip_${new Date().getTime()}.xlsx`)
}
}
}
</script>

124
chenhai-ui/src/views/vet/experts/index.vue

@ -51,6 +51,11 @@
<el-table v-loading="loading" :data="expertsList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="expertsList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="头像" align="center" prop="avatar" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.avatar" :width="50" :height="50" />
</template>
</el-table-column>
<el-table-column label="真实姓名" align="center" prop="realName" /> <el-table-column label="真实姓名" align="center" prop="realName" />
<el-table-column label="联系电话" align="center" prop="iphone" /> <el-table-column label="联系电话" align="center" prop="iphone" />
<el-table-column label="电子邮箱" align="center" prop="email" /> <el-table-column label="电子邮箱" align="center" prop="email" />
@ -59,16 +64,17 @@
<el-table-column label="专家类型" align="center" prop="expert" /> <el-table-column label="专家类型" align="center" prop="expert" />
<el-table-column label="擅长领域" align="center" prop="expertiseArea" /> <el-table-column label="擅长领域" align="center" prop="expertiseArea" />
<el-table-column label="工作单位" align="center" prop="address" /> <el-table-column label="工作单位" align="center" prop="address" />
<el-table-column label="简介" align="center" prop="introduction" />
<el-table-column label="在线状态" align="center" prop="isOnline" /> <el-table-column label="在线状态" align="center" prop="isOnline" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
size="mini"
type="text"
icon="el-icon-chat-dot-round"
@click="handleConsultation(scope.row)"
v-hasPermi="['system:consultation:view']"
>咨询</el-button>
size="mini"
type="text"
icon="el-icon-chat-dot-round"
@click="handleChat(scope.row)"
v-hasPermi="['system:chat:view']"
>聊天咨询</el-button>
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -118,35 +124,15 @@
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
<!-- 专家咨询对话框 -->
<el-dialog
:title="`专家咨询 - ${selectedExpertName}`"
:visible.sync="consultationDialogVisible"
width="90%"
top="5vh"
append-to-body>
<consultation-component
:expert-id="selectedExpertId"
:expert-name="selectedExpertName"
v-if="consultationDialogVisible"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="consultationDialogVisible = false"> </el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { listExperts, getExperts, delExperts, addExperts, updateExperts } from "@/api/vet/experts" import { listExperts, getExperts, delExperts, addExperts, updateExperts } from "@/api/vet/experts"
import ConsultationComponent from '@/views/system/consultation/index.vue'
export default { export default {
name: "Experts", name: "Experts",
dicts: ['is_online'], dicts: ['is_online'],
components: {
ConsultationComponent
},
data() { data() {
return { return {
// //
@ -167,12 +153,6 @@ export default {
title: "", title: "",
// //
open: false, open: false,
//
consultationDialogVisible: false,
// ID
selectedExpertId: null,
//
selectedExpertName: '',
// //
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
@ -180,20 +160,29 @@ export default {
userId: null, userId: null,
realName: null, realName: null,
expertiseArea: null, expertiseArea: null,
contactInfo: null,
isOnline: null, isOnline: null,
sortOrder: null, sortOrder: null,
status: null,
createdAt: null,
updatedAt: null
status: null
}, },
// //
form: {},
form: {
expertId: null,
userId: null,
realName: null,
expertiseArea: null,
contactInfo: null,
isOnline: null,
sortOrder: null,
status: null
},
// //
rules: { rules: {
userId: [ userId: [
{ required: true, message: "关联用户ID不能为空", trigger: "blur" } { required: true, message: "关联用户ID不能为空", trigger: "blur" }
], ],
realName: [
{ required: true, message: "真实姓名不能为空", trigger: "blur" }
]
} }
} }
}, },
@ -232,9 +221,7 @@ export default {
contactInfo: null, contactInfo: null,
isOnline: null, isOnline: null,
sortOrder: null, sortOrder: null,
status: null,
createdAt: null,
updatedAt: null
status: null
} }
this.resetForm("form") this.resetForm("form")
}, },
@ -251,7 +238,7 @@ export default {
// //
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map(item => item.expertId) this.ids = selection.map(item => item.expertId)
this.single = selection.length!==1
this.single = selection.length !== 1
this.multiple = !selection.length this.multiple = !selection.length
}, },
/** 新增按钮操作 */ /** 新增按钮操作 */
@ -270,11 +257,37 @@ export default {
this.title = "修改专家信息" this.title = "修改专家信息"
}) })
}, },
/** 咨询按钮操作 */
handleConsultation(row) {
this.selectedExpertId = row.expertId
this.selectedExpertName = row.realName
this.consultationDialogVisible = true
/** 聊天咨询按钮操作 */
handleChat(row) {
//
const userInfo = this.$store.getters.userInfo || {}
const roles = userInfo.roles || []
const userRole = roles[0] || '' //
console.log('当前用户角色:', roles, '主要角色:', userRole)
//
if (userRole === 'vetnotshenhe' || userRole === 'admin') {
// -
this.$router.push({
path: '@/views/chat/expert',
query: {
expertId: row.expertId,
expertName: row.realName,
//
mode: 'expert_initiate'
}
})
} else {
// muhu-
this.$router.push({
path: '/chat/index',
query: {
expertId: row.expertId,
expertName: row.realName
}
})
}
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
@ -315,3 +328,22 @@ export default {
} }
} }
</script> </script>
<style scoped>
/* 添加一些样式优化 */
.app-container {
padding: 20px;
}
.mb8 {
margin-bottom: 20px;
}
.el-table {
margin-top: 20px;
}
.el-button--mini {
margin-right: 5px;
}
</style>

79
chenhai-ui/src/views/vet/knowledge/index.vue

@ -127,7 +127,24 @@
<el-table v-loading="loading" :data="knowledgeList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="knowledgeList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="发布专家" align="center" width="120">
<template slot-scope="scope">
<div v-if="scope.row.expertName" style="font-weight: bold;">
{{ scope.row.expertName }}
</div>
<span v-else style="color: #999;">-</span>
</template>
</el-table-column>
<el-table-column label="封面" align="center" prop="coverImage" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.coverImage" :width="50" :height="50" />
</template>
</el-table-column>
<el-table-column label="文章标题" align="center" prop="title" min-width="200" show-overflow-tooltip /> <el-table-column label="文章标题" align="center" prop="title" min-width="200" show-overflow-tooltip />
<el-table-column label="文章副标题" align="center" prop="subtitle" min-width="200" show-overflow-tooltip />
<el-table-column label="文章内容" align="center" prop="content" min-width="200" show-overflow-tooltip />
<el-table-column label="发布时间" align="center" prop="publishTime" min-width="200" show-overflow-tooltip />
<el-table-column label="查看次数" align="center" prop="viewCount" min-width="200" show-overflow-tooltip />
<!-- 文章分类列 - 使用 el-tag 显示颜色 --> <!-- 文章分类列 - 使用 el-tag 显示颜色 -->
<el-table-column label="文章分类" align="center" prop="category" width="120"> <el-table-column label="文章分类" align="center" prop="category" width="120">
@ -162,8 +179,6 @@
<span v-else>-</span> <span v-else>-</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建人" align="center" prop="createBy" width="100" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
@ -247,11 +262,36 @@
<!-- 新增/修改文章对话框 --> <!-- 新增/修改文章对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> <el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="推荐专家" prop="expertId">
<el-select
v-model="form.expertId"
placeholder="请选择推荐专家"
clearable
filterable
style="width: 100%;"
>
<el-option
v-for="expert in expertList"
:key="expert.expertId"
:label="expert.realName"
:value="expert.expertId"
/>
</el-select>
<div style="font-size: 12px; color: #999; margin-top: 5px;">
提示选择为您推荐药品的专家
</div>
</el-form-item>
<el-form-item label="封面" prop="coverImage">
<image-upload v-model="form.coverImage" />
</el-form-item>
<el-form-item label="文章标题" prop="title"> <el-form-item label="文章标题" prop="title">
<el-input v-model="form.title" placeholder="请输入文章标题" /> <el-input v-model="form.title" placeholder="请输入文章标题" />
</el-form-item> </el-form-item>
<el-form-item label="文章副标题" prop="subtitle">
<el-input v-model="form.subtitle" placeholder="请输入文章副标题" />
</el-form-item>
<el-form-item label="文章内容" prop="content"> <el-form-item label="文章内容" prop="content">
<editor v-model="form.content" :min-height="300"/>
<el-input v-model="form.content" placeholder="请输入文章内容" />
</el-form-item> </el-form-item>
<el-form-item label="文章分类" prop="category"> <el-form-item label="文章分类" prop="category">
<el-select v-model="form.category" placeholder="请选择文章分类"> <el-select v-model="form.category" placeholder="请选择文章分类">
@ -263,6 +303,15 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="发布时间" prop="publishTime">
<el-date-picker
v-model="form.publishTime"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择时间"
style="width: 100%;"
/>
</el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注信息" /> <el-input v-model="form.remark" type="textarea" placeholder="请输入备注信息" />
</el-form-item> </el-form-item>
@ -346,7 +395,8 @@ import {
onlineVetKnowledge, onlineVetKnowledge,
offlineVetKnowledge offlineVetKnowledge
} from "@/api/vet/knowledge" } from "@/api/vet/knowledge"
import { getDicts } from "@/api/system/dict/data" //
import { getDicts } from "@/api/system/dict/data"
import {listExperts} from "@/api/vet/experts"; //
export default { export default {
name: "Knowledge", name: "Knowledge",
@ -397,6 +447,8 @@ export default {
categoryOptions: [], // categoryOptions: [], //
articleStatusOptions: [], // articleStatusOptions: [], //
auditStatusOptions: [], // auditStatusOptions: [], //
//
expertList: [], //
// //
rules: { rules: {
title: [ title: [
@ -414,6 +466,7 @@ export default {
created() { created() {
this.getDictsData() // this.getDictsData() //
this.getList() this.getList()
this.getExpertList()
}, },
methods: { methods: {
/** 获取字典数据 */ /** 获取字典数据 */
@ -443,6 +496,24 @@ export default {
}) })
}, },
/** 获取专家列表 */
getExpertList() {
listExperts({
pageNum: 1,
pageSize: 1000,
status: '0'
}).then(response => {
if (response.code === 200) {
this.expertList = response.rows || [];
}
}).catch(() => {
this.expertList = [
{ expertId: 1, realName: '张医生', title: '主任医师' },
{ expertId: 2, realName: '李医生', title: '副主任医师' }
];
});
},
/** 查询兽医文章列表 */ /** 查询兽医文章列表 */
getList() { getList() {
this.loading = true this.loading = true

147
chenhai-ui/src/views/vet/training/TrainingHome.vue

@ -144,7 +144,7 @@
<!-- 视频列表表格 --> <!-- 视频列表表格 -->
<el-table v-loading="loading" :data="videoList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="videoList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="视频封面" align="center" width="120">
<el-table-column label="视频" align="center" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="video-cover" @click="showVideoDetail(scope.row)"> <div class="video-cover" @click="showVideoDetail(scope.row)">
<img <img
@ -166,6 +166,12 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="封面" align="center" prop="coverImage" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.coverImage" :width="50" :height="50" />
</template>
</el-table-column>
<el-table-column label="视频标题" align="left" prop="title" min-width="200" show-overflow-tooltip /> <el-table-column label="视频标题" align="left" prop="title" min-width="200" show-overflow-tooltip />
<el-table-column label="分类" align="center" prop="category" width="100"> <el-table-column label="分类" align="center" prop="category" width="100">
@ -318,7 +324,6 @@
drag drag
:action="uploadUrl" :action="uploadUrl"
:headers="uploadHeaders" :headers="uploadHeaders"
:data="uploadData"
:before-upload="beforeUpload" :before-upload="beforeUpload"
:on-success="handleUploadSuccess" :on-success="handleUploadSuccess"
:on-error="handleUploadError" :on-error="handleUploadError"
@ -337,6 +342,10 @@
</div> </div>
</el-upload> </el-upload>
<el-form-item label="封面图片" prop="coverImage">
<image-upload v-model="uploadForm.coverImage" />
</el-form-item>
<!-- 文件信息显示 --> <!-- 文件信息显示 -->
<div v-if="selectedFile" class="file-info"> <div v-if="selectedFile" class="file-info">
<div class="file-info-content"> <div class="file-info-content">
@ -518,7 +527,7 @@
<script> <script>
import trainingApi from '@/api/vet/training' import trainingApi from '@/api/vet/training'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { getDicts } from '@/api/system/dict/data' // API
import { getDicts } from '@/api/system/dict/data'
export default { export default {
name: 'TrainingHome', name: 'TrainingHome',
@ -587,7 +596,6 @@ export default {
uploadHeaders: { uploadHeaders: {
'Authorization': 'Bearer ' + getToken() 'Authorization': 'Bearer ' + getToken()
}, },
uploadData: {},
// ========== ========== // ========== ==========
detailOpen: false, detailOpen: false,
@ -622,7 +630,7 @@ export default {
created() { created() {
this.getList() this.getList()
this.checkAdminRole() this.checkAdminRole()
this.loadDicts() //
this.loadDicts()
}, },
methods: { methods: {
@ -641,11 +649,6 @@ export default {
const categoryRes = await getDicts('video_category') const categoryRes = await getDicts('video_category')
this.categoryOptions = categoryRes.data || [] this.categoryOptions = categoryRes.data || []
console.log('字典加载完成:', {
statusOptions: this.statusOptions,
auditStatusOptions: this.auditStatusOptions,
categoryOptions: this.categoryOptions
})
} catch (error) { } catch (error) {
console.error('加载字典失败:', error) console.error('加载字典失败:', error)
// API使 // API使
@ -728,19 +731,13 @@ export default {
response = await trainingApi.getPendingAuditVideos(this.queryParams) response = await trainingApi.getPendingAuditVideos(this.queryParams)
} }
if (response && response.rows) {
this.videoList = response.rows.map(item => ({
...item,
status: String(item.status || '0'),
auditStatus: String(item.auditStatus || '0')
}))
this.total = response.total || response.rows.length
} else if (response && response.code === 200 && response.data) {
this.videoList = response.data.rows || []
this.total = response.data.total || 0
if (response && response.code === 200) {
this.videoList = response.rows || []
this.total = response.total || 0
} else { } else {
this.videoList = [] this.videoList = []
this.total = 0 this.total = 0
this.$message.error('加载失败')
} }
} catch (error) { } catch (error) {
console.error('加载视频列表失败:', error) console.error('加载视频列表失败:', error)
@ -758,7 +755,9 @@ export default {
/** 重置按钮操作 */ /** 重置按钮操作 */
resetQuery() { resetQuery() {
this.resetForm('queryForm')
if (this.$refs.queryForm) {
this.$refs.queryForm.resetFields()
}
this.queryParams = { this.queryParams = {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
@ -884,7 +883,6 @@ export default {
return return
} }
//
this.uploading = true this.uploading = true
this.uploadProgress = 0 this.uploadProgress = 0
@ -893,6 +891,7 @@ export default {
formData.append('title', this.uploadForm.title) formData.append('title', this.uploadForm.title)
formData.append('videoFile', this.selectedFile) formData.append('videoFile', this.selectedFile)
formData.append('category', this.uploadForm.category) formData.append('category', this.uploadForm.category)
if (this.uploadForm.description) { if (this.uploadForm.description) {
formData.append('description', this.uploadForm.description) formData.append('description', this.uploadForm.description)
} }
@ -903,7 +902,7 @@ export default {
this.uploading = false this.uploading = false
this.uploadProgress = 100 this.uploadProgress = 100
if (response.code === 200 || response.code === undefined) {
if (response.code === 200) {
this.$message.success('上传成功!视频已自动提交审核') this.$message.success('上传成功!视频已自动提交审核')
this.uploadOpen = false this.uploadOpen = false
this.activeTab = 'my' this.activeTab = 'my'
@ -917,7 +916,7 @@ export default {
this.uploading = false this.uploading = false
this.uploadProgress = 0 this.uploadProgress = 0
console.error('上传失败:', error) console.error('上传失败:', error)
this.$message.error(error.message || '上传失败,请重试')
this.$message.error('上传失败,请重试')
}) })
} }
}) })
@ -925,32 +924,22 @@ export default {
// ========== ========== // ========== ==========
/** 提交审核(批量或单个)- 统一修复 */
/** 提交审核(批量或单个) */
async handleSubmitAudit(videoId) { async handleSubmitAudit(videoId) {
console.log('提交审核,传入参数:', videoId)
let id let id
// 1videoId
if (videoId && typeof videoId !== 'object' && videoId !== '') { if (videoId && typeof videoId !== 'object' && videoId !== '') {
id = videoId id = videoId
}
// 2使
else if (this.ids.length === 1) {
} else if (this.ids.length === 1) {
id = this.ids[0] id = this.ids[0]
}
// 3
else if (typeof videoId === 'object') {
//
} else if (typeof videoId === 'object') {
if (this.ids.length === 1) { if (this.ids.length === 1) {
id = this.ids[0] id = this.ids[0]
} else { } else {
this.$message.warning('请先选择一个视频') this.$message.warning('请先选择一个视频')
return return
} }
}
// 4
else {
} else {
this.$message.warning('请选择需要提交审核的视频') this.$message.warning('请选择需要提交审核的视频')
return return
} }
@ -967,7 +956,6 @@ export default {
type: 'warning' type: 'warning'
}) })
console.log('调用提交审核API,视频ID:', id)
await trainingApi.submitForAudit(id) await trainingApi.submitForAudit(id)
this.$message.success('提交审核成功') this.$message.success('提交审核成功')
this.getList() this.getList()
@ -1005,31 +993,22 @@ export default {
} }
}, },
/** 审核(批量或单个)- 统一修复 */
/** 审核(批量或单个) */
handleAuditDialog(videoId) { handleAuditDialog(videoId) {
console.log('打开审核对话框,传入参数:', videoId)
let id let id
// 1videoId
if (videoId && typeof videoId !== 'object' && videoId !== '') { if (videoId && typeof videoId !== 'object' && videoId !== '') {
id = videoId id = videoId
}
// 2使
else if (this.ids.length === 1) {
} else if (this.ids.length === 1) {
id = this.ids[0] id = this.ids[0]
}
// 3
else if (typeof videoId === 'object') {
} else if (typeof videoId === 'object') {
if (this.ids.length === 1) { if (this.ids.length === 1) {
id = this.ids[0] id = this.ids[0]
} else { } else {
this.$message.warning('请先选择一个视频') this.$message.warning('请先选择一个视频')
return return
} }
}
// 4
else {
} else {
this.$message.warning('请选择需要审核的视频') this.$message.warning('请选择需要审核的视频')
return return
} }
@ -1039,7 +1018,6 @@ export default {
return return
} }
console.log('设置审核表单,视频ID:', id)
this.auditForm.id = id this.auditForm.id = id
this.auditForm.auditStatus = '1' this.auditForm.auditStatus = '1'
this.auditForm.auditOpinion = '' this.auditForm.auditOpinion = ''
@ -1064,7 +1042,7 @@ export default {
} }
}, },
/** 提交审核(管理员审核)- 最终修复版 */
/** 提交审核(管理员审核) */
async submitAudit() { async submitAudit() {
try { try {
// 1. // 1.
@ -1082,8 +1060,6 @@ export default {
type: 'warning' type: 'warning'
}) })
console.log('管理员审核,视频ID:', this.auditForm.id)
// 3. API // 3. API
const response = await trainingApi.auditVideo( const response = await trainingApi.auditVideo(
this.auditForm.id, this.auditForm.id,
@ -1103,20 +1079,14 @@ export default {
} catch (error) { } catch (error) {
if (error === 'cancel') return if (error === 'cancel') return
console.error('审核错误详情:', {
message: error.message,
response: error.response?.data,
status: error.response?.status
})
console.error('审核错误:', error)
this.$message.error('审核失败,请检查参数') this.$message.error('审核失败,请检查参数')
} }
}, },
// ========== / ========== // ========== / ==========
/** 上架视频(批量或单个)- 统一修复 */
/** 上架视频(批量或单个) */
async handlePublish(videoId) { async handlePublish(videoId) {
let id let id
@ -1154,7 +1124,7 @@ export default {
} }
}, },
/** 下架视频(批量或单个)- 统一修复 */
/** 下架视频(批量或单个) */
async handleOffline(videoId) { async handleOffline(videoId) {
let id let id
@ -1197,7 +1167,6 @@ export default {
/** 编辑视频 */ /** 编辑视频 */
handleEdit(row) { handleEdit(row) {
this.$message.info('编辑功能开发中...') this.$message.info('编辑功能开发中...')
// TODO:
}, },
/** 查看视频详情 */ /** 查看视频详情 */
@ -1325,10 +1294,7 @@ export default {
/** 获取封面图片 */ /** 获取封面图片 */
getCoverImage(video) { getCoverImage(video) {
if (video.coverImage &&
video.coverImage !== 'null' &&
video.coverImage !== 'undefined' &&
video.coverImage !== '') {
if (video.coverImage && video.coverImage !== 'null' && video.coverImage !== '') {
return this.getFullUrl(video.coverImage) return this.getFullUrl(video.coverImage)
} }
return this.getCategoryDefaultCover(video.category || 'other') return this.getCategoryDefaultCover(video.category || 'other')
@ -1339,6 +1305,7 @@ export default {
const color = this.getCategoryColor(category) const color = this.getCategoryColor(category)
const text = this.getCategoryText(category) const text = this.getCategoryText(category)
// SVG
const svgString = `<svg width="120" height="80" xmlns="http://www.w3.org/2000/svg"> const svgString = `<svg width="120" height="80" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="${color}" /> <rect width="100%" height="100%" fill="${color}" />
<text x="50%" y="50%" font-family="Arial, sans-serif" font-size="12" <text x="50%" y="50%" font-family="Arial, sans-serif" font-size="12"
@ -1347,21 +1314,19 @@ export default {
</text> </text>
</svg>` </svg>`
const base64 = btoa(unescape(encodeURIComponent(svgString)))
return `data:image/svg+xml;base64,${base64}`
return 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgString)))
}, },
/** 获取分类颜色 */ /** 获取分类颜色 */
getCategoryColor(category) { getCategoryColor(category) {
// listClass
const item = this.categoryOptions.find(item => item.dictValue === category) const item = this.categoryOptions.find(item => item.dictValue === category)
const type = item ? (item.listClass || 'info') : 'info' const type = item ? (item.listClass || 'info') : 'info'
const colorMap = { const colorMap = {
'primary': '#667eea',
'success': '#67cf77',
'danger': '#ff6b6b',
'warning': '#ffb366',
'primary': '#409EFF',
'success': '#67C23A',
'danger': '#F56C6C',
'warning': '#E6A23C',
'info': '#909399' 'info': '#909399'
} }
return colorMap[type] || colorMap.info return colorMap[type] || colorMap.info
@ -1382,10 +1347,8 @@ export default {
url = url.trim() url = url.trim()
if (url.startsWith('http://') ||
url.startsWith('https://') ||
url.startsWith('data:') ||
url.startsWith('blob:')) {
if (url.startsWith('http://') || url.startsWith('https://') ||
url.startsWith('data:') || url.startsWith('blob:')) {
return url return url
} }
@ -1393,7 +1356,7 @@ export default {
return window.location.origin + url return window.location.origin + url
} }
return window.location.origin + '/uploads/' + url
return window.location.origin + '/profile/upload/' + url
}, },
/** 获取视频URL */ /** 获取视频URL */
@ -1427,25 +1390,7 @@ export default {
if (!dateStr) return '' if (!dateStr) return ''
try { try {
const date = new Date(dateStr) const date = new Date(dateStr)
const now = new Date()
const diff = now - date
const diffDays = Math.floor(diff / (1000 * 60 * 60 * 24))
if (diffDays === 0) {
return '今天 ' + date.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit'
})
} else if (diffDays === 1) {
return '昨天 ' + date.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit'
})
} else if (diffDays < 7) {
return diffDays + '天前'
} else {
return date.toLocaleDateString('zh-CN')
}
return date.toLocaleString('zh-CN')
} catch (error) { } catch (error) {
return dateStr return dateStr
} }

Loading…
Cancel
Save