打分评价

This commit is contained in:
2025-12-29 16:17:27 +08:00
parent 23b4383563
commit a33720b9f6
23 changed files with 880 additions and 72 deletions

View File

@@ -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, -- 创建人(系统自动创建)

View File

@@ -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;

View File

@@ -208,4 +208,16 @@ public interface ChatRoomService {
*/
ResultDomain<CustomerServiceVO> assignCustomerService(String roomId);
// ========================= 聊天室评分管理 ==========================
/**
* @description 提交聊天室服务评分
* @param roomId 聊天室ID
* @param commentLevel 评分1-5星
* @param userId 评分用户ID
* @author cascade
* @since 2025-12-29
*/
ResultDomain<Boolean> submitCommentLevel(String roomId, Integer commentLevel, String userId);
}

View File

@@ -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;

View File

@@ -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<Boolean> submitComment(
@PathVariable("roomId") String roomId,
@RequestBody Map<String, Integer> 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}")

View File

@@ -764,4 +764,60 @@ public class ChatRoomServiceImpl implements ChatRoomService {
logger.error("发布列表更新到Redis失败", e);
}
}
// ========================= 聊天室评分管理 ==========================
@Override
@Transactional
public ResultDomain<Boolean> 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());
}
}
}

View File

@@ -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());

View File

@@ -15,6 +15,7 @@
<result column="message_count" property="messageCount" jdbcType="INTEGER"/>
<result column="last_message_time" property="lastMessageTime" jdbcType="TIMESTAMP"/>
<result column="last_message" property="lastMessage" jdbcType="VARCHAR"/>
<result column="comment_level" property="commentLevel" jdbcType="INTEGER"/>
<result column="closed_by" property="closedBy" jdbcType="VARCHAR"/>
<result column="closed_time" property="closedTime" jdbcType="TIMESTAMP"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/>
@@ -38,6 +39,7 @@
<result column="unread_count" property="unreadCount" jdbcType="INTEGER"/>
<result column="last_message_time" property="lastMessageTime" jdbcType="TIMESTAMP"/>
<result column="last_message" property="lastMessage" jdbcType="VARCHAR"/>
<result column="comment_level" property="commentLevel" jdbcType="INTEGER"/>
<result column="closed_by" property="closedBy" jdbcType="VARCHAR"/>
<result column="closed_time" property="closedTime" jdbcType="TIMESTAMP"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/>
@@ -49,7 +51,7 @@
<sql id="Base_Column_List">
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
</sql>
@@ -84,6 +86,7 @@
<if test="messageCount != null">message_count = #{messageCount},</if>
<if test="lastMessageTime != null">last_message_time = #{lastMessageTime},</if>
<if test="lastMessage != null">last_message = #{lastMessage},</if>
<if test="commentLevel != null">comment_level = #{commentLevel},</if>
<if test="closedBy != null">closed_by = #{closedBy},</if>
<if test="closedTime != null">closed_time = #{closedTime},</if>
update_time = now()
@@ -120,9 +123,9 @@
</select>
<select id="selectChatRoomPage" resultMap="VOResultMap">
SELECT r.room_id, r.optsn, r.workcase_id, r.room_name, r.room_type, r.status,
r.guest_id, r.guest_name, r.ai_session_id, r.message_count,
r.last_message_time, r.last_message, r.closed_by, r.closed_time,
SELECT r.room_id, r.optsn, r.workcase_id, r.room_name, r.room_type, r.status,
r.guest_id, r.guest_name, r.ai_session_id, r.message_count,
r.last_message_time, r.last_message, r.comment_level, r.closed_by, r.closed_time,
r.creator, r.create_time, r.update_time, r.delete_time, r.deleted,
COALESCE(m.unread_count, 0) as unread_count
FROM workcase.tb_chat_room r