From a33720b9f6b302731e4447221ee6dddfee758838 Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Mon, 29 Dec 2025 16:17:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=93=E5=88=86=E8=AF=84=E4=BB=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../postgres/sql/createTableWorkcase.sql | 3 +- .../xyzh/api/workcase/dto/TbChatRoomDTO.java | 3 + .../api/workcase/service/ChatRoomService.java | 12 ++ .../org/xyzh/api/workcase/vo/ChatRoomVO.java | 5 +- .../controller/WorkcaseChatContorller.java | 27 ++++ .../workcase/service/ChatRoomServiceImpl.java | 56 +++++++ .../workcase/service/WorkcaseServiceImpl.java | 28 ++++ .../resources/mapper/TbChatRoomMapper.xml | 11 +- .../workcase/src/api/workcase/workcaseChat.ts | 14 ++ .../workcase/src/types/workcase/chatRoom.ts | 2 + .../views/public/ChatRoom/ChatRoomView.vue | 39 +++-- .../CommentMessageCard.scss | 0 .../CommentMessageCard/CommentMessageCard.vue | 9 -- .../public/ChatRoom/chatRoom/ChatRoom.scss | 29 ++++ .../public/ChatRoom/chatRoom/ChatRoom.vue | 139 ++++++++++++------ .../CommentMessageCard.scss | 103 +++++++++++++ .../CommentMessageCard/CommentMessageCard.vue | 134 +++++++++++++++++ .../api/workcase/workcaseChat.ts | 15 ++ .../CommentMessageCard.scss | 118 +++++++++++++++ .../CommentMessageCard.uvue | 116 +++++++++++++++ .../pages/chatRoom/chatRoom/chatRoom.scss | 24 ++- .../pages/chatRoom/chatRoom/chatRoom.uvue | 63 +++++++- .../types/workcase/chatRoom.ts | 2 + 23 files changed, 880 insertions(+), 72 deletions(-) delete mode 100644 urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/CommentMessageCard/CommentMessageCard.scss delete mode 100644 urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/CommentMessageCard/CommentMessageCard.vue create mode 100644 urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/chatRoom/CommentMessageCard/CommentMessageCard.scss create mode 100644 urbanLifelineWeb/packages/workcase/src/views/public/ChatRoom/chatRoom/CommentMessageCard/CommentMessageCard.vue create mode 100644 urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/CommentMessageCard/CommentMessageCard.scss create mode 100644 urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/CommentMessageCard/CommentMessageCard.uvue diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql index 82198517..6afc2457 100644 --- a/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql +++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql @@ -30,7 +30,7 @@ DROP TABLE IF EXISTS workcase.tb_chat_room CASCADE; CREATE TABLE workcase.tb_chat_room( optsn VARCHAR(50) NOT NULL, -- 流水号 room_id VARCHAR(50) NOT NULL, -- 聊天室ID - workcase_id VARCHAR(50) DEFAULT NULL, -- 关联工单ID + workcase_id VARCHAR(50) DEFAULT NULL, -- 关联工单ID room_name VARCHAR(200) NOT NULL, -- 聊天室名称(如:工单#12345的客服支持) room_type VARCHAR(20) NOT NULL DEFAULT 'workcase', -- 聊天室类型:workcase-工单客服 status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态:active-活跃 closed-已关闭 archived-已归档 @@ -40,6 +40,7 @@ CREATE TABLE workcase.tb_chat_room( message_count INTEGER NOT NULL DEFAULT 0, -- 消息总数 last_message_time TIMESTAMPTZ DEFAULT NULL, -- 最后消息时间 last_message TEXT DEFAULT NULL, -- 最后一条消息内容(用于列表展示) + comment_level INTEGER DEFAULT 0, -- 服务评分(1-5) closed_by VARCHAR(50) DEFAULT NULL, -- 关闭人 closed_time TIMESTAMPTZ DEFAULT NULL, -- 关闭时间 creator VARCHAR(50) NOT NULL, -- 创建人(系统自动创建) diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbChatRoomDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbChatRoomDTO.java index 24f4487e..9afcea0f 100644 --- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbChatRoomDTO.java +++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbChatRoomDTO.java @@ -60,6 +60,9 @@ public class TbChatRoomDTO extends BaseDTO { @Schema(description = "最后一条消息内容") private String lastMessage; + @Schema(description = "服务评分(1-5星)") + private Integer commentLevel; + @Schema(description = "关闭人") private String closedBy; diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/ChatRoomService.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/ChatRoomService.java index 24097862..3389b485 100644 --- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/ChatRoomService.java +++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/ChatRoomService.java @@ -208,4 +208,16 @@ public interface ChatRoomService { */ ResultDomain assignCustomerService(String roomId); + // ========================= 聊天室评分管理 ========================== + + /** + * @description 提交聊天室服务评分 + * @param roomId 聊天室ID + * @param commentLevel 评分(1-5星) + * @param userId 评分用户ID + * @author cascade + * @since 2025-12-29 + */ + ResultDomain submitCommentLevel(String roomId, Integer commentLevel, String userId); + } diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/vo/ChatRoomVO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/vo/ChatRoomVO.java index 9a4ef1fb..0b4848f4 100644 --- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/vo/ChatRoomVO.java +++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/vo/ChatRoomVO.java @@ -62,7 +62,10 @@ public class ChatRoomVO extends BaseVO { @Schema(description = "最后一条消息内容") private String lastMessage; - + + @Schema(description = "服务评分(1-5星)") + private Integer commentLevel; + @Schema(description = "关闭人") private String closedBy; diff --git a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/controller/WorkcaseChatContorller.java b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/controller/WorkcaseChatContorller.java index a1cdec58..b4dcc6ce 100644 --- a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/controller/WorkcaseChatContorller.java +++ b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/controller/WorkcaseChatContorller.java @@ -1,6 +1,7 @@ package org.xyzh.workcase.controller; import jakarta.servlet.http.HttpServletRequest; +import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -40,6 +41,7 @@ import io.swagger.v3.oas.annotations.Operation; import java.util.Arrays; import java.util.Date; +import java.util.Map; import io.swagger.v3.oas.annotations.tags.Tag; @@ -109,6 +111,31 @@ public class WorkcaseChatContorller { return chatRoomService.closeChatRoom(roomId, closedBy); } + /** + * 提交聊天室服务评分 + * @param roomId 聊天室ID + * @param commentLevel 评分(1-5星) + * @return 提交结果 + */ + @Operation(summary = "提交聊天室服务评分") + @PreAuthorize("hasAuthority('workcase:room:view')") + @PostMapping("/room/{roomId}/comment") + public ResultDomain submitComment( + @PathVariable("roomId") String roomId, + @RequestBody Map body) { + + Integer commentLevel = body.get("commentLevel"); + if (commentLevel == null || commentLevel < 1 || commentLevel > 5) { + return ResultDomain.failure("评分必须在1-5之间"); + } + + // 获取当前登录用户ID + String userId = LoginUtil.getCurrentUserId(); + + // 调用服务层提交评分 + return chatRoomService.submitCommentLevel(roomId, commentLevel, userId); + } + @Operation(summary = "获取聊天室详情") @PreAuthorize("hasAuthority('workcase:room:view')") @GetMapping("/room/{roomId}") diff --git a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java index 1485756a..adf5095b 100644 --- a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java +++ b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/ChatRoomServiceImpl.java @@ -764,4 +764,60 @@ public class ChatRoomServiceImpl implements ChatRoomService { logger.error("发布列表更新到Redis失败", e); } } + + // ========================= 聊天室评分管理 ========================== + + @Override + @Transactional + public ResultDomain submitCommentLevel(String roomId, Integer commentLevel, String userId) { + logger.info("提交聊天室服务评分: roomId={}, commentLevel={}, userId={}", roomId, commentLevel, userId); + + // 参数校验 + if (NonUtils.isEmpty(roomId)) { + return ResultDomain.failure("聊天室ID不能为空"); + } + if (commentLevel == null || commentLevel < 1 || commentLevel > 5) { + return ResultDomain.failure("评分必须在1-5星之间"); + } + + try { + // 1. 检查聊天室是否存在 + TbChatRoomDTO chatRoom = chatRoomMapper.selectChatRoomById(roomId); + if (chatRoom == null) { + return ResultDomain.failure("聊天室不存在"); + } + + // 2. 检查用户是否是聊天室成员(来客) + if (!userId.equals(chatRoom.getGuestId())) { + return ResultDomain.failure("只有来客可以对服务进行评分"); + } + + // 3. 检查是否已评分 + if (chatRoom.getCommentLevel() != null && chatRoom.getCommentLevel() > 0) { + return ResultDomain.failure("已经评分过了,不能重复评分"); + } + + // 4. 更新评分 + TbChatRoomDTO updateRoom = new TbChatRoomDTO(); + updateRoom.setRoomId(roomId); + updateRoom.setCommentLevel(commentLevel); + + int rows = chatRoomMapper.updateChatRoom(updateRoom); + if (rows > 0) { + logger.info("聊天室服务评分成功: roomId={}, commentLevel={}", roomId, commentLevel); + + // TODO: 后续可以在这里更新客服人员的平均满意度评分 + // updateCustomerServiceSatisfaction(chatRoom, commentLevel); + + return ResultDomain.success("评分成功",true); + } else { + return ResultDomain.failure("评分提交失败"); + } + + } catch (Exception e) { + logger.error("提交聊天室服务评分失败: roomId={}, commentLevel={}", roomId, commentLevel, e); + return ResultDomain.failure("评分提交失败: " + e.getMessage()); + } + } } + diff --git a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/WorkcaseServiceImpl.java b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/WorkcaseServiceImpl.java index 0d56f4b2..a1516482 100644 --- a/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/WorkcaseServiceImpl.java +++ b/urbanLifelineServ/workcase/src/main/java/org/xyzh/workcase/service/WorkcaseServiceImpl.java @@ -370,10 +370,38 @@ public class WorkcaseServiceImpl implements WorkcaseService { workcaseMapper.updateWorkcase(workcase); } } else if (WorkcaseProcessAction.FINISH.getName().equals(action)) { + // 1. 更新工单状态为已完成 TbWorkcaseDTO workcase = new TbWorkcaseDTO(); workcase.setWorkcaseId(workcaseProcess.getWorkcaseId()); workcase.setStatus("done"); workcaseMapper.updateWorkcase(workcase); + + // 2. 发送系统评分消息到聊天室 + try { + TbWorkcaseDTO workcaseData = workcaseMapper.selectWorkcaseById(workcaseProcess.getWorkcaseId()); + if (workcaseData != null && workcaseData.getRoomId() != null) { + // 创建系统评分消息 + org.xyzh.api.workcase.dto.TbChatRoomMessageDTO commentMessage = new org.xyzh.api.workcase.dto.TbChatRoomMessageDTO(); + commentMessage.setMessageId(IdUtil.generateUUID()); + commentMessage.setOptsn(IdUtil.getOptsn()); + commentMessage.setRoomId(workcaseData.getRoomId()); + commentMessage.setSenderId("system"); + commentMessage.setSenderType("system"); // 系统消息 + commentMessage.setSenderName("系统"); + commentMessage.setMessageType("comment"); // 评分消息 + commentMessage.setContent("请为本次服务评分"); + commentMessage.setStatus("sent"); + commentMessage.setCreator("system"); + + // 发送消息到聊天室 + chatRoomService.sendMessage(commentMessage); + logger.info("工单完成,已发送系统评分消息: workcaseId={}, roomId={}", + workcaseProcess.getWorkcaseId(), workcaseData.getRoomId()); + } + } catch (Exception e) { + logger.error("发送系统评分消息失败: workcaseId={}", workcaseProcess.getWorkcaseId(), e); + // 不影响工单完成流程,只记录错误日志 + } } else if (WorkcaseProcessAction.REPEAL.getName().equals(action)) { TbWorkcaseDTO workcase = new TbWorkcaseDTO(); workcase.setWorkcaseId(workcaseProcess.getWorkcaseId()); diff --git a/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatRoomMapper.xml b/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatRoomMapper.xml index 95559895..85179362 100644 --- a/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatRoomMapper.xml +++ b/urbanLifelineServ/workcase/src/main/resources/mapper/TbChatRoomMapper.xml @@ -15,6 +15,7 @@ + @@ -38,6 +39,7 @@ + @@ -49,7 +51,7 @@ room_id, optsn, workcase_id, room_name, room_type, status, guest_id, guest_name, - ai_session_id, message_count, last_message_time, last_message, closed_by, closed_time, + ai_session_id, message_count, last_message_time, last_message, comment_level, closed_by, closed_time, creator, create_time, update_time, delete_time, deleted @@ -84,6 +86,7 @@ message_count = #{messageCount}, last_message_time = #{lastMessageTime}, last_message = #{lastMessage}, + comment_level = #{commentLevel}, closed_by = #{closedBy}, closed_time = #{closedTime}, update_time = now() @@ -120,9 +123,9 @@