diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index eade666a..1c2ca350 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -77,6 +77,12 @@
ruoyi-generator
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/config/WebSocketConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/config/WebSocketConfig.java
new file mode 100644
index 00000000..ceacb3a7
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/config/WebSocketConfig.java
@@ -0,0 +1,23 @@
+package com.ruoyi.web.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * WebSocket配置
+ *
+ * @author ruoyi
+ */
+@Configuration
+public class WebSocketConfig {
+
+ /**
+ * 注入ServerEndpointExporter,
+ * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
+ */
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/customer/CustomerServiceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/customer/CustomerServiceController.java
new file mode 100644
index 00000000..3e814628
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/customer/CustomerServiceController.java
@@ -0,0 +1,286 @@
+package com.ruoyi.web.controller.customer;
+
+import java.util.List;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+
+import com.ruoyi.system.domain.UserSessions;
+import com.ruoyi.system.domain.ManualServiceSessions;
+import com.ruoyi.customer.service.ICustomerServiceService;
+import com.ruoyi.system.domain.ChatHistory;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 客服系统Controller
+ *
+ * @author ruoyi
+ * @date 2024-01-01
+ */
+@Controller
+@RequestMapping("/customer/service")
+public class CustomerServiceController extends BaseController
+{
+ private String prefix = "customer/service";
+
+ @Autowired
+ private ICustomerServiceService customerServiceService;
+
+ @RequiresPermissions("customer:service:view")
+ @GetMapping()
+ public String service()
+ {
+ return prefix + "/index";
+ }
+
+ /**
+ * 查询会话列表
+ */
+ @RequiresPermissions("customer:service:list")
+ @PostMapping("/list")
+ @ResponseBody
+ public TableDataInfo list(UserSessions userSessions)
+ {
+ startPage();
+ List list = customerServiceService.selectUserSessionsList(userSessions);
+ return getDataTable(list);
+ }
+
+ /**
+ * 获取所有活跃会话
+ */
+ @GetMapping("/sessions")
+ @ResponseBody
+ public AjaxResult getSessions()
+ {
+ try {
+ List sessions = customerServiceService.getActiveSessions();
+ return AjaxResult.success(sessions);
+ } catch (Exception e) {
+ logger.error("获取会话列表失败", e);
+ return AjaxResult.error("获取会话列表失败");
+ }
+ }
+
+ /**
+ * 获取指定会话信息
+ */
+ @GetMapping("/sessions/{sessionId}")
+ @ResponseBody
+ public AjaxResult getSession(@PathVariable Long sessionId)
+ {
+ try {
+ UserSessions session = customerServiceService.selectUserSessionsById(sessionId);
+ return AjaxResult.success(session);
+ } catch (Exception e) {
+ logger.error("获取会话信息失败", e);
+ return AjaxResult.error("获取会话信息失败");
+ }
+ }
+
+ /**
+ * 获取会话聊天记录
+ */
+ @GetMapping("/messages/{sessionId}")
+ @ResponseBody
+ public AjaxResult getChatHistory(@PathVariable Long sessionId)
+ {
+ try {
+ List messages = customerServiceService.getChatHistoryBySessionId(sessionId);
+ return AjaxResult.success(messages);
+ } catch (Exception e) {
+ logger.error("获取聊天记录失败", e);
+ return AjaxResult.error("获取聊天记录失败");
+ }
+ }
+
+ /**
+ * 发送消息
+ */
+ @PostMapping("/send")
+ @ResponseBody
+ public AjaxResult sendMessage(ChatHistory chatHistory)
+ {
+ try {
+ // 设置发送者信息
+ chatHistory.setSenderId(getUserId());
+ chatHistory.setSenderType("SERVICE");
+
+ int result = customerServiceService.sendMessage(chatHistory);
+ if (result > 0) {
+ return AjaxResult.success("消息发送成功");
+ } else {
+ return AjaxResult.error("消息发送失败");
+ }
+ } catch (Exception e) {
+ logger.error("发送消息失败", e);
+ return AjaxResult.error("发送消息失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 转人工服务
+ */
+ @PostMapping("/transfer")
+ @ResponseBody
+ public AjaxResult transferToManual(Long sessionId, String reason)
+ {
+ try {
+ ManualServiceSessions manualSession = new ManualServiceSessions();
+ manualSession.setSessionId(sessionId);
+ manualSession.setReason(reason);
+ manualSession.setStatus("PENDING");
+ manualSession.setCreateBy(getLoginName());
+
+ int result = customerServiceService.createManualServiceRequest(manualSession);
+ if (result > 0) {
+ return AjaxResult.success("转人工请求已提交");
+ } else {
+ return AjaxResult.error("转人工请求提交失败");
+ }
+ } catch (Exception e) {
+ logger.error("转人工服务失败", e);
+ return AjaxResult.error("转人工服务失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 获取转人工请求列表
+ */
+ @GetMapping("/manual-requests")
+ @ResponseBody
+ public AjaxResult getManualRequests()
+ {
+ try {
+ List requests = customerServiceService.getPendingManualRequests();
+ return AjaxResult.success(requests);
+ } catch (Exception e) {
+ logger.error("获取转人工请求失败", e);
+ return AjaxResult.error("获取转人工请求失败");
+ }
+ }
+
+ /**
+ * 接受转人工请求
+ */
+ @PostMapping("/manual-requests/{requestId}/accept")
+ @ResponseBody
+ public AjaxResult acceptManualRequest(@PathVariable Long requestId)
+ {
+ try {
+ ManualServiceSessions manualSession = new ManualServiceSessions();
+ manualSession.setUserId(requestId);
+ manualSession.setStatus("ACCEPTED");
+ manualSession.setServiceId(getUserId());
+ manualSession.setUpdateBy(getLoginName());
+
+ int result = customerServiceService.updateManualServiceRequest(manualSession);
+ if (result > 0) {
+ return AjaxResult.success("已接受转人工请求");
+ } else {
+ return AjaxResult.error("操作失败");
+ }
+ } catch (Exception e) {
+ logger.error("接受转人工请求失败", e);
+ return AjaxResult.error("操作失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 拒绝转人工请求
+ */
+ @PostMapping("/manual-requests/{requestId}/reject")
+ @ResponseBody
+ public AjaxResult rejectManualRequest(@PathVariable Long requestId)
+ {
+ try {
+ ManualServiceSessions manualSession = new ManualServiceSessions();
+ manualSession.setUserId(requestId);
+ manualSession.setStatus("REJECTED");
+ manualSession.setServiceId(getUserId());
+ manualSession.setUpdateBy(getLoginName());
+
+ int result = customerServiceService.updateManualServiceRequest(manualSession);
+ if (result > 0) {
+ return AjaxResult.success("已拒绝转人工请求");
+ } else {
+ return AjaxResult.error("操作失败");
+ }
+ } catch (Exception e) {
+ logger.error("拒绝转人工请求失败", e);
+ return AjaxResult.error("操作失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 更新客服状态
+ */
+ @PostMapping("/status")
+ @ResponseBody
+ public AjaxResult updateServiceStatus(String status)
+ {
+ try {
+ int result = customerServiceService.updateServiceStatus(getUserId(), status);
+ if (result > 0) {
+ return AjaxResult.success("状态更新成功");
+ } else {
+ return AjaxResult.error("状态更新失败");
+ }
+ } catch (Exception e) {
+ logger.error("更新客服状态失败", e);
+ return AjaxResult.error("状态更新失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 导出会话列表
+ */
+ @RequiresPermissions("customer:service:export")
+ @Log(title = "客服会话", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ @ResponseBody
+ public AjaxResult export(UserSessions userSessions)
+ {
+ List list = customerServiceService.selectUserSessionsList(userSessions);
+ ExcelUtil util = new ExcelUtil(UserSessions.class);
+ return util.exportExcel(list, "会话数据");
+ }
+
+ /**
+ * 获取客服统计信息
+ */
+ @GetMapping("/statistics")
+ @ResponseBody
+ public AjaxResult getStatistics()
+ {
+ try {
+ // 获取今日统计数据
+ int todaySessions = customerServiceService.getTodaySessionCount();
+ int todayMessages = customerServiceService.getTodayMessageCount();
+ int pendingRequests = customerServiceService.getPendingRequestCount();
+ int onlineServices = customerServiceService.getOnlineServiceCount();
+
+ AjaxResult result = AjaxResult.success();
+ result.put("todaySessions", todaySessions);
+ result.put("todayMessages", todayMessages);
+ result.put("pendingRequests", pendingRequests);
+ result.put("onlineServices", onlineServices);
+
+ return result;
+ } catch (Exception e) {
+ logger.error("获取统计信息失败", e);
+ return AjaxResult.error("获取统计信息失败");
+ }
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/websocket/CustomerServiceWebSocket.java b/ruoyi-admin/src/main/java/com/ruoyi/web/websocket/CustomerServiceWebSocket.java
new file mode 100644
index 00000000..f7fd668f
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/websocket/CustomerServiceWebSocket.java
@@ -0,0 +1,164 @@
+package com.ruoyi.web.websocket;
+
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+ import com.alibaba.fastjson.JSON;
+
+/**
+ * 客服系统WebSocket服务
+ *
+ * @author ruoyi
+ */
+@ServerEndpoint("/websocket/customer/{userId}")
+@Component
+public class CustomerServiceWebSocket {
+
+ private static final Logger log = LoggerFactory.getLogger(CustomerServiceWebSocket.class);
+
+ /** 静态变量,用来记录当前在线连接数 */
+ private static final AtomicInteger onlineCount = new AtomicInteger(0);
+
+ /** concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象 */
+ private static final ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();
+
+ /** 与某个客户端的连接会话,需要通过它来给客户端发送数据 */
+ private Session session;
+
+ /** 接收userId */
+ private String userId = "";
+
+ /**
+ * 连接建立成功调用的方法
+ */
+ @OnOpen
+ public void onOpen(Session session, @PathParam("userId") String userId) {
+ this.session = session;
+ this.userId = userId;
+ if (webSocketMap.containsKey(userId)) {
+ webSocketMap.remove(userId);
+ webSocketMap.put(userId, this);
+ } else {
+ webSocketMap.put(userId, this);
+ addOnlineCount();
+ }
+
+ log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());
+
+ try {
+ sendMessage("连接成功");
+ } catch (IOException e) {
+ log.error("用户:" + userId + ",网络异常!!!!!!");
+ }
+ }
+
+ /**
+ * 连接关闭调用的方法
+ */
+ @OnClose
+ public void onClose() {
+ if (webSocketMap.containsKey(userId)) {
+ webSocketMap.remove(userId);
+ subOnlineCount();
+ }
+ log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
+ }
+
+ /**
+ * 收到客户端消息后调用的方法
+ *
+ * @param message 客户端发送过来的消息
+ */
+ @OnMessage
+ public void onMessage(String message, Session session) {
+ log.info("用户消息:" + userId + ",报文:" + message);
+
+ // 解析消息
+ if (message != null && !message.isEmpty()) {
+ try {
+ com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(message);
+ String toUserId = jsonObject.getString("toUserId");
+ String messageContent = jsonObject.getString("message");
+ String messageType = jsonObject.getString("type");
+
+ // 传输给对应toUserId用户的websocket
+ if (toUserId != null && webSocketMap.containsKey(toUserId)) {
+ webSocketMap.get(toUserId).sendMessage(JSON.toJSONString(jsonObject));
+ } else {
+ log.error("请求的userId:" + toUserId + "不在该服务器上");
+ }
+ } catch (Exception e) {
+ log.error("消息解析异常", e);
+ }
+ }
+ }
+
+ /**
+ * 发生错误时调用
+ */
+ @OnError
+ public void onError(Session session, Throwable error) {
+ log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+ error.printStackTrace();
+ }
+
+ /**
+ * 实现服务器主动推送
+ */
+ public void sendMessage(String message) throws IOException {
+ this.session.getBasicRemote().sendText(message);
+ }
+
+ /**
+ * 发送自定义消息
+ */
+ public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
+ log.info("发送消息到:" + userId + ",报文:" + message);
+ if (userId != null && webSocketMap.containsKey(userId)) {
+ webSocketMap.get(userId).sendMessage(message);
+ } else {
+ log.error("用户" + userId + ",不在线!");
+ }
+ }
+
+ /**
+ * 获得此时的在线人数
+ */
+ public static synchronized int getOnlineCount() {
+ return onlineCount.get();
+ }
+
+ /**
+ * 在线人数加1
+ */
+ public static synchronized void addOnlineCount() {
+ onlineCount.incrementAndGet();
+ }
+
+ /**
+ * 在线人数减1
+ */
+ public static synchronized void subOnlineCount() {
+ onlineCount.decrementAndGet();
+ }
+
+ /**
+ * 获取在线用户列表
+ */
+ public static ConcurrentHashMap getWebSocketMap() {
+ return webSocketMap;
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/resources/templates/customer/service/index.html b/ruoyi-admin/src/main/resources/templates/customer/service/index.html
new file mode 100644
index 00000000..ab6f8ca2
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/templates/customer/service/index.html
@@ -0,0 +1,594 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/customer/service/ICustomerServiceService.java b/ruoyi-system/src/main/java/com/ruoyi/customer/service/ICustomerServiceService.java
new file mode 100644
index 00000000..7f980c0f
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/customer/service/ICustomerServiceService.java
@@ -0,0 +1,242 @@
+package com.ruoyi.customer.service;
+
+import java.util.List;
+import com.ruoyi.system.domain.ChatHistory;
+import com.ruoyi.system.domain.UserSessions;
+import com.ruoyi.system.domain.ManualServiceSessions;
+
+/**
+ * 客服系统Service接口
+ *
+ * @author ruoyi
+ * @date 2024-01-01
+ */
+public interface ICustomerServiceService
+{
+ /**
+ * 查询用户会话
+ *
+ * @param sessionId 用户会话ID
+ * @return 用户会话
+ */
+ public UserSessions selectUserSessionsById(Long sessionId);
+
+ /**
+ * 查询用户会话列表
+ *
+ * @param userSessions 用户会话
+ * @return 用户会话集合
+ */
+ public List selectUserSessionsList(UserSessions userSessions);
+
+ /**
+ * 获取活跃会话列表
+ *
+ * @return 活跃会话集合
+ */
+ public List getActiveSessions();
+
+ /**
+ * 新增用户会话
+ *
+ * @param userSessions 用户会话
+ * @return 结果
+ */
+ public int insertUserSessions(UserSessions userSessions);
+
+ /**
+ * 修改用户会话
+ *
+ * @param userSessions 用户会话
+ * @return 结果
+ */
+ public int updateUserSessions(UserSessions userSessions);
+
+ /**
+ * 批量删除用户会话
+ *
+ * @param sessionIds 需要删除的用户会话ID
+ * @return 结果
+ */
+ public int deleteUserSessionsByIds(Long[] sessionIds);
+
+ /**
+ * 删除用户会话信息
+ *
+ * @param sessionId 用户会话ID
+ * @return 结果
+ */
+ public int deleteUserSessionsById(Long sessionId);
+
+ /**
+ * 根据会话ID获取聊天记录
+ *
+ * @param sessionId 会话ID
+ * @return 聊天记录列表
+ */
+ public List getChatHistoryBySessionId(Long sessionId);
+
+ /**
+ * 发送消息
+ *
+ * @param chatHistory 聊天记录
+ * @return 结果
+ */
+ public int sendMessage(ChatHistory chatHistory);
+
+ /**
+ * 创建转人工服务请求
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ public int createManualServiceRequest(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 更新转人工服务请求
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ public int updateManualServiceRequest(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 获取待处理的转人工请求
+ *
+ * @return 转人工请求列表
+ */
+ public List getPendingManualRequests();
+
+ /**
+ * 更新客服状态
+ *
+ * @param serviceId 客服ID
+ * @param status 状态
+ * @return 结果
+ */
+ public int updateServiceStatus(Long serviceId, String status);
+
+ /**
+ * 获取今日会话数量
+ *
+ * @return 会话数量
+ */
+ public int getTodaySessionCount();
+
+ /**
+ * 获取今日消息数量
+ *
+ * @return 消息数量
+ */
+ public int getTodayMessageCount();
+
+ /**
+ * 获取待处理请求数量
+ *
+ * @return 请求数量
+ */
+ public int getPendingRequestCount();
+
+ /**
+ * 获取在线客服数量
+ *
+ * @return 客服数量
+ */
+ public int getOnlineServiceCount();
+
+ /**
+ * 查询聊天记录
+ *
+ * @param messageId 聊天记录ID
+ * @return 聊天记录
+ */
+ public ChatHistory selectChatHistoryById(Long messageId);
+
+ /**
+ * 查询聊天记录列表
+ *
+ * @param chatHistory 聊天记录
+ * @return 聊天记录集合
+ */
+ public List selectChatHistoryList(ChatHistory chatHistory);
+
+ /**
+ * 新增聊天记录
+ *
+ * @param chatHistory 聊天记录
+ * @return 结果
+ */
+ public int insertChatHistory(ChatHistory chatHistory);
+
+ /**
+ * 修改聊天记录
+ *
+ * @param chatHistory 聊天记录
+ * @return 结果
+ */
+ public int updateChatHistory(ChatHistory chatHistory);
+
+ /**
+ * 批量删除聊天记录
+ *
+ * @param messageIds 需要删除的聊天记录ID
+ * @return 结果
+ */
+ public int deleteChatHistoryByIds(Long[] messageIds);
+
+ /**
+ * 删除聊天记录信息
+ *
+ * @param messageId 聊天记录ID
+ * @return 结果
+ */
+ public int deleteChatHistoryById(Long messageId);
+
+ /**
+ * 查询转人工服务会话
+ *
+ * @param id 转人工服务会话ID
+ * @return 转人工服务会话
+ */
+ public ManualServiceSessions selectManualServiceSessionsById(Long id);
+
+ /**
+ * 查询转人工服务会话列表
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 转人工服务会话集合
+ */
+ public List selectManualServiceSessionsList(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 新增转人工服务会话
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ public int insertManualServiceSessions(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 修改转人工服务会话
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ public int updateManualServiceSessions(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 批量删除转人工服务会话
+ *
+ * @param ids 需要删除的转人工服务会话ID
+ * @return 结果
+ */
+ public int deleteManualServiceSessionsByIds(Long[] ids);
+
+ /**
+ * 删除转人工服务会话信息
+ *
+ * @param id 转人工服务会话ID
+ * @return 结果
+ */
+ public int deleteManualServiceSessionsById(Long id);
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/customer/service/impl/CustomerServiceServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/customer/service/impl/CustomerServiceServiceImpl.java
new file mode 100644
index 00000000..4429c18f
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/customer/service/impl/CustomerServiceServiceImpl.java
@@ -0,0 +1,394 @@
+package com.ruoyi.customer.service.impl;
+
+import java.util.List;
+import java.util.Date;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.system.mapper.ChatHistoryMapper;
+import com.ruoyi.system.mapper.UserSessionsMapper;
+import com.ruoyi.system.mapper.ManualServiceSessionsMapper;
+import com.ruoyi.system.domain.ChatHistory;
+import com.ruoyi.system.domain.UserSessions;
+import com.ruoyi.system.domain.ManualServiceSessions;
+import com.ruoyi.customer.service.ICustomerServiceService;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.core.text.Convert;
+
+/**
+ * 客服系统Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2024-01-01
+ */
+@Service
+public class CustomerServiceServiceImpl implements ICustomerServiceService
+{
+ @Autowired
+ private UserSessionsMapper userSessionsMapper;
+
+ @Autowired
+ private ChatHistoryMapper chatHistoryMapper;
+
+ @Autowired
+ private ManualServiceSessionsMapper manualServiceSessionsMapper;
+
+ /**
+ * 查询用户会话
+ *
+ * @param sessionId 用户会话ID
+ * @return 用户会话
+ */
+ @Override
+ public UserSessions selectUserSessionsById(Long sessionId)
+ {
+ return userSessionsMapper.selectUserSessionsById(sessionId);
+ }
+
+ /**
+ * 查询用户会话列表
+ *
+ * @param userSessions 用户会话
+ * @return 用户会话
+ */
+ @Override
+ public List selectUserSessionsList(UserSessions userSessions)
+ {
+ return userSessionsMapper.selectUserSessionsList(userSessions);
+ }
+
+ /**
+ * 获取活跃会话列表
+ *
+ * @return 活跃会话集合
+ */
+ @Override
+ public List getActiveSessions()
+ {
+ UserSessions userSessions = new UserSessions();
+ userSessions.setStatus("active");
+ return userSessionsMapper.selectUserSessionsList(userSessions);
+ }
+
+ /**
+ * 新增用户会话
+ *
+ * @param userSessions 用户会话
+ * @return 结果
+ */
+ @Override
+ public int insertUserSessions(UserSessions userSessions)
+ {
+ userSessions.setCreateTime(DateUtils.getNowDate());
+ return userSessionsMapper.insertUserSessions(userSessions);
+ }
+
+ /**
+ * 修改用户会话
+ *
+ * @param userSessions 用户会话
+ * @return 结果
+ */
+ @Override
+ public int updateUserSessions(UserSessions userSessions)
+ {
+ userSessions.setUpdateTime(DateUtils.getNowDate());
+ return userSessionsMapper.updateUserSessions(userSessions);
+ }
+
+ /**
+ * 删除用户会话对象
+ *
+ * @param sessionIds 需要删除的数据ID
+ * @return 结果
+ */
+ @Override
+ public int deleteUserSessionsByIds(Long[] sessionIds)
+ {
+ return userSessionsMapper.deleteUserSessionsByIds(sessionIds);
+ }
+
+ /**
+ * 删除用户会话信息
+ *
+ * @param sessionId 用户会话ID
+ * @return 结果
+ */
+ @Override
+ public int deleteUserSessionsById(Long sessionId)
+ {
+ return userSessionsMapper.deleteUserSessionsById(sessionId);
+ }
+
+ /**
+ * 根据会话ID获取聊天记录
+ *
+ * @param sessionId 会话ID
+ * @return 聊天记录列表
+ */
+ @Override
+ public List getChatHistoryBySessionId(Long sessionId)
+ {
+ ChatHistory chatHistory = new ChatHistory();
+ chatHistory.setSessionId(sessionId);
+ return chatHistoryMapper.selectChatHistoryList(chatHistory);
+ }
+
+ /**
+ * 发送消息
+ *
+ * @param chatHistory 聊天记录
+ * @return 结果
+ */
+ @Override
+ public int sendMessage(ChatHistory chatHistory)
+ {
+ chatHistory.setCreateTime(DateUtils.getNowDate());
+ return chatHistoryMapper.insertChatHistory(chatHistory);
+ }
+
+ /**
+ * 创建转人工服务请求
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ @Override
+ public int createManualServiceRequest(ManualServiceSessions manualServiceSessions)
+ {
+ manualServiceSessions.setCreateTime(DateUtils.getNowDate());
+ manualServiceSessions.setStatus("pending");
+ return manualServiceSessionsMapper.insertManualServiceSessions(manualServiceSessions);
+ }
+
+ /**
+ * 更新转人工服务请求
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ @Override
+ public int updateManualServiceRequest(ManualServiceSessions manualServiceSessions)
+ {
+ manualServiceSessions.setUpdateTime(DateUtils.getNowDate());
+ return manualServiceSessionsMapper.updateManualServiceSessions(manualServiceSessions);
+ }
+
+ /**
+ * 获取待处理的转人工请求
+ *
+ * @return 转人工请求列表
+ */
+ @Override
+ public List getPendingManualRequests()
+ {
+ ManualServiceSessions manualServiceSessions = new ManualServiceSessions();
+ manualServiceSessions.setStatus("pending");
+ return manualServiceSessionsMapper.selectManualServiceSessionsList(manualServiceSessions);
+ }
+
+ /**
+ * 更新客服状态
+ *
+ * @param serviceId 客服ID
+ * @param status 状态
+ * @return 结果
+ */
+ @Override
+ public int updateServiceStatus(Long serviceId, String status)
+ {
+ // 这里可以扩展为更新sys_user_online表或其他相关表
+ return 1;
+ }
+
+ /**
+ * 获取今日会话数量
+ *
+ * @return 会话数量
+ */
+ @Override
+ public int getTodaySessionCount()
+ {
+ return 0;
+ }
+
+ /**
+ * 获取今日消息数量
+ *
+ * @return 消息数量
+ */
+ @Override
+ public int getTodayMessageCount()
+ {
+ return 0;
+ }
+
+ /**
+ * 获取待处理请求数量
+ *
+ * @return 请求数量
+ */
+ @Override
+ public int getPendingRequestCount()
+ {
+ return 0;
+ }
+
+ /**
+ * 获取在线客服数量
+ *
+ * @return 客服数量
+ */
+ @Override
+ public int getOnlineServiceCount()
+ {
+ // 这里可以查询sys_user_online表获取在线客服数量
+ return 5; // 临时返回固定值
+ }
+
+ /**
+ * 查询聊天记录
+ *
+ * @param messageId 聊天记录ID
+ * @return 聊天记录
+ */
+ @Override
+ public ChatHistory selectChatHistoryById(Long messageId)
+ {
+ return chatHistoryMapper.selectChatHistoryById(messageId);
+ }
+
+ /**
+ * 查询聊天记录列表
+ *
+ * @param chatHistory 聊天记录
+ * @return 聊天记录
+ */
+ @Override
+ public List selectChatHistoryList(ChatHistory chatHistory)
+ {
+ return chatHistoryMapper.selectChatHistoryList(chatHistory);
+ }
+
+ /**
+ * 新增聊天记录
+ *
+ * @param chatHistory 聊天记录
+ * @return 结果
+ */
+ @Override
+ public int insertChatHistory(ChatHistory chatHistory)
+ {
+ chatHistory.setCreateTime(DateUtils.getNowDate());
+ return chatHistoryMapper.insertChatHistory(chatHistory);
+ }
+
+ /**
+ * 修改聊天记录
+ *
+ * @param chatHistory 聊天记录
+ * @return 结果
+ */
+ @Override
+ public int updateChatHistory(ChatHistory chatHistory)
+ {
+ return chatHistoryMapper.updateChatHistory(chatHistory);
+ }
+
+ /**
+ * 删除聊天记录对象
+ *
+ * @param messageIds 需要删除的数据ID
+ * @return 结果
+ */
+ @Override
+ public int deleteChatHistoryByIds(Long[] messageIds)
+ {
+ return chatHistoryMapper.deleteChatHistoryByIds(messageIds);
+ }
+
+ /**
+ * 删除聊天记录信息
+ *
+ * @param messageId 聊天记录ID
+ * @return 结果
+ */
+ @Override
+ public int deleteChatHistoryById(Long messageId)
+ {
+ return chatHistoryMapper.deleteChatHistoryById(messageId);
+ }
+
+ /**
+ * 查询转人工服务会话
+ *
+ * @param id 转人工服务会话ID
+ * @return 转人工服务会话
+ */
+ @Override
+ public ManualServiceSessions selectManualServiceSessionsById(Long id)
+ {
+ return manualServiceSessionsMapper.selectManualServiceSessionsById(id);
+ }
+
+ /**
+ * 查询转人工服务会话列表
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 转人工服务会话
+ */
+ @Override
+ public List selectManualServiceSessionsList(ManualServiceSessions manualServiceSessions)
+ {
+ return manualServiceSessionsMapper.selectManualServiceSessionsList(manualServiceSessions);
+ }
+
+ /**
+ * 新增转人工服务会话
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ @Override
+ public int insertManualServiceSessions(ManualServiceSessions manualServiceSessions)
+ {
+ manualServiceSessions.setCreateTime(DateUtils.getNowDate());
+ return manualServiceSessionsMapper.insertManualServiceSessions(manualServiceSessions);
+ }
+
+ /**
+ * 修改转人工服务会话
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ @Override
+ public int updateManualServiceSessions(ManualServiceSessions manualServiceSessions)
+ {
+ manualServiceSessions.setUpdateTime(DateUtils.getNowDate());
+ return manualServiceSessionsMapper.updateManualServiceSessions(manualServiceSessions);
+ }
+
+ /**
+ * 删除转人工服务会话对象
+ *
+ * @param ids 需要删除的数据ID
+ * @return 结果
+ */
+ @Override
+ public int deleteManualServiceSessionsByIds(Long[] ids)
+ {
+ return manualServiceSessionsMapper.deleteManualServiceSessionsByIds(ids);
+ }
+
+ /**
+ * 删除转人工服务会话信息
+ *
+ * @param id 转人工服务会话ID
+ * @return 结果
+ */
+ @Override
+ public int deleteManualServiceSessionsById(Long id)
+ {
+ return manualServiceSessionsMapper.deleteManualServiceSessionsById(id);
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ChatHistory.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ChatHistory.java
index 235ac0bc..975b5840 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ChatHistory.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ChatHistory.java
@@ -1,5 +1,7 @@
package com.ruoyi.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.ruoyi.common.annotation.Excel;
@@ -18,6 +20,10 @@ public class ChatHistory extends BaseEntity
/** 主键ID */
private Long id;
+ /** 消息ID */
+ @Excel(name = "消息ID")
+ private Long messageId;
+
/** 用户ID */
@Excel(name = "用户ID")
private String userId;
@@ -26,6 +32,10 @@ public class ChatHistory extends BaseEntity
@Excel(name = "会话ID")
private String sessionId;
+ /** 会话ID(Long类型,兼容customer包)*/
+ @Excel(name = "会话ID")
+ private Long sessionIdLong;
+
/** 消息类型 */
@Excel(name = "消息类型", readConverterExp = "user=用户消息,service=客服消息")
private String messageType;
@@ -34,6 +44,10 @@ public class ChatHistory extends BaseEntity
@Excel(name = "消息内容")
private String content;
+ /** 消息内容(兼容customer包字段名)*/
+ @Excel(name = "消息内容")
+ private String messageContent;
+
/** 是否包含链接 */
@Excel(name = "是否包含链接", readConverterExp = "0=否,1=是")
private Integer isLink;
@@ -42,6 +56,27 @@ public class ChatHistory extends BaseEntity
@Excel(name = "是否为按钮消息", readConverterExp = "0=否,1=是")
private Integer isButton;
+ /** 发送者ID */
+ @Excel(name = "发送者ID")
+ private Long senderId;
+
+ /** 接收者ID */
+ @Excel(name = "接收者ID")
+ private Long receiverId;
+
+ /** 发送时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "发送时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date sentAt;
+
+ /** 是否已读 */
+ @Excel(name = "是否已读")
+ private String isRead;
+
+ /** 发送者类型 */
+ @Excel(name = "发送者类型")
+ private String senderType;
+
public void setId(Long id)
{
this.id = id;
@@ -105,18 +140,113 @@ public class ChatHistory extends BaseEntity
{
return isButton;
}
+ public void setSenderId(Long senderId)
+ {
+ this.senderId = senderId;
+ }
+
+ public Long getSenderId()
+ {
+ return senderId;
+ }
+ public void setReceiverId(Long receiverId)
+ {
+ this.receiverId = receiverId;
+ }
+
+ public Long getReceiverId()
+ {
+ return receiverId;
+ }
+ public void setSentAt(Date sentAt)
+ {
+ this.sentAt = sentAt;
+ }
+
+ public Date getSentAt()
+ {
+ return sentAt;
+ }
+ public void setIsRead(String isRead)
+ {
+ this.isRead = isRead;
+ }
+
+ public String getIsRead()
+ {
+ return isRead;
+ }
+ public void setMessageId(Long messageId)
+ {
+ this.messageId = messageId;
+ }
+
+ public Long getMessageId()
+ {
+ return messageId;
+ }
+ public void setSessionIdLong(Long sessionIdLong)
+ {
+ this.sessionIdLong = sessionIdLong;
+ }
+
+ public Long getSessionIdLong()
+ {
+ return sessionIdLong;
+ }
+ public void setMessageContent(String messageContent)
+ {
+ this.messageContent = messageContent;
+ }
+
+ public String getMessageContent()
+ {
+ return messageContent != null ? messageContent : content;
+ }
+ public void setSenderType(String senderType)
+ {
+ this.senderType = senderType;
+ }
+
+ public String getSenderType()
+ {
+ return senderType;
+ }
+
+ // 兼容性方法:支持Long类型的sessionId
+ public void setSessionId(Long sessionId)
+ {
+ this.sessionIdLong = sessionId;
+ this.sessionId = sessionId != null ? sessionId.toString() : null;
+ }
+
+ // 兼容性方法:同时设置content和messageContent
+ public void setMessage(String message)
+ {
+ this.content = message;
+ this.messageContent = message;
+ }
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
+ .append("messageId", getMessageId())
.append("userId", getUserId())
.append("sessionId", getSessionId())
+ .append("sessionIdLong", getSessionIdLong())
.append("messageType", getMessageType())
.append("content", getContent())
+ .append("messageContent", getMessageContent())
.append("isLink", getIsLink())
.append("isButton", getIsButton())
+ .append("senderId", getSenderId())
+ .append("receiverId", getReceiverId())
+ .append("sentAt", getSentAt())
+ .append("isRead", getIsRead())
+ .append("senderType", getSenderType())
.append("createTime", getCreateTime())
+ .append("updateTime", getUpdateTime())
.toString();
}
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/ManualServiceSessions.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ManualServiceSessions.java
new file mode 100644
index 00000000..2f9e3282
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/ManualServiceSessions.java
@@ -0,0 +1,184 @@
+package com.ruoyi.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.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 转人工服务会话对象 manual_service_sessions
+ *
+ * @author ruoyi
+ * @date 2024-01-01
+ */
+public class ManualServiceSessions extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 转人工会话ID */
+ private Long manualSessionId;
+
+ /** 原会话ID */
+ @Excel(name = "原会话ID")
+ private Long sessionId;
+
+ /** 用户ID */
+ @Excel(name = "用户ID")
+ private Long userId;
+
+ /** 客服ID */
+ @Excel(name = "客服ID")
+ private Long serviceId;
+
+ /** 转人工请求时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "转人工请求时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date requestTime;
+
+ /** 接受时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "接受时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date acceptTime;
+
+ /** 结束时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date endTime;
+
+ /** 状态 */
+ @Excel(name = "状态")
+ private String status;
+
+ /** 转人工原因 */
+ @Excel(name = "转人工原因")
+ private String reason;
+
+ /** 满意度评分 */
+ @Excel(name = "满意度评分")
+ private Integer rating;
+
+ /** 评价内容 */
+ @Excel(name = "评价内容")
+ private String feedback;
+
+ public void setManualSessionId(Long manualSessionId)
+ {
+ this.manualSessionId = manualSessionId;
+ }
+
+ public Long getManualSessionId()
+ {
+ return manualSessionId;
+ }
+ public void setSessionId(Long sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+ public Long getSessionId()
+ {
+ return sessionId;
+ }
+ public void setUserId(Long userId)
+ {
+ this.userId = userId;
+ }
+
+ public Long getUserId()
+ {
+ return userId;
+ }
+ public void setServiceId(Long serviceId)
+ {
+ this.serviceId = serviceId;
+ }
+
+ public Long getServiceId()
+ {
+ return serviceId;
+ }
+ public void setRequestTime(Date requestTime)
+ {
+ this.requestTime = requestTime;
+ }
+
+ public Date getRequestTime()
+ {
+ return requestTime;
+ }
+ public void setAcceptTime(Date acceptTime)
+ {
+ this.acceptTime = acceptTime;
+ }
+
+ public Date getAcceptTime()
+ {
+ return acceptTime;
+ }
+ public void setEndTime(Date endTime)
+ {
+ this.endTime = endTime;
+ }
+
+ public Date getEndTime()
+ {
+ return endTime;
+ }
+ public void setStatus(String status)
+ {
+ this.status = status;
+ }
+
+ public String getStatus()
+ {
+ return status;
+ }
+ public void setReason(String reason)
+ {
+ this.reason = reason;
+ }
+
+ public String getReason()
+ {
+ return reason;
+ }
+ public void setRating(Integer rating)
+ {
+ this.rating = rating;
+ }
+
+ public Integer getRating()
+ {
+ return rating;
+ }
+ public void setFeedback(String feedback)
+ {
+ this.feedback = feedback;
+ }
+
+ public String getFeedback()
+ {
+ return feedback;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("manualSessionId", getManualSessionId())
+ .append("sessionId", getSessionId())
+ .append("userId", getUserId())
+ .append("serviceId", getServiceId())
+ .append("requestTime", getRequestTime())
+ .append("acceptTime", getAcceptTime())
+ .append("endTime", getEndTime())
+ .append("status", getStatus())
+ .append("reason", getReason())
+ .append("rating", getRating())
+ .append("feedback", getFeedback())
+ .append("createTime", getCreateTime())
+ .append("updateTime", getUpdateTime())
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSessions.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSessions.java
new file mode 100644
index 00000000..5a5f75a5
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/UserSessions.java
@@ -0,0 +1,114 @@
+package com.ruoyi.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.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 用户会话对象 user_sessions
+ *
+ * @author ruoyi
+ * @date 2024-01-01
+ */
+public class UserSessions extends BaseEntity
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 会话ID */
+ private Long sessionId;
+
+ /** 用户ID */
+ @Excel(name = "用户ID")
+ private Long userId;
+
+ /** 会话开始时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "会话开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date sessionStart;
+
+ /** 会话结束时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "会话结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date sessionEnd;
+
+ /** 会话状态 */
+ @Excel(name = "会话状态")
+ private String status;
+
+ /** 最后活动时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "最后活动时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ private Date lastActivity;
+
+ public void setSessionId(Long sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+ public Long getSessionId()
+ {
+ return sessionId;
+ }
+ public void setUserId(Long userId)
+ {
+ this.userId = userId;
+ }
+
+ public Long getUserId()
+ {
+ return userId;
+ }
+ public void setSessionStart(Date sessionStart)
+ {
+ this.sessionStart = sessionStart;
+ }
+
+ public Date getSessionStart()
+ {
+ return sessionStart;
+ }
+ public void setSessionEnd(Date sessionEnd)
+ {
+ this.sessionEnd = sessionEnd;
+ }
+
+ public Date getSessionEnd()
+ {
+ return sessionEnd;
+ }
+ public void setStatus(String status)
+ {
+ this.status = status;
+ }
+
+ public String getStatus()
+ {
+ return status;
+ }
+ public void setLastActivity(Date lastActivity)
+ {
+ this.lastActivity = lastActivity;
+ }
+
+ public Date getLastActivity()
+ {
+ return lastActivity;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+ .append("sessionId", getSessionId())
+ .append("userId", getUserId())
+ .append("sessionStart", getSessionStart())
+ .append("sessionEnd", getSessionEnd())
+ .append("status", getStatus())
+ .append("lastActivity", getLastActivity())
+ .append("createTime", getCreateTime())
+ .append("updateTime", getUpdateTime())
+ .toString();
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/ChatHistoryMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/ChatHistoryMapper.java
index e097438b..b7e2405c 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/ChatHistoryMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/ChatHistoryMapper.java
@@ -92,10 +92,58 @@ public interface ChatHistoryMapper
public int deleteChatHistoryBySessionId(String sessionId);
/**
- * 删除指定用户的聊天记录
+ * 根据用户ID删除聊天记录
*
* @param userId 用户ID
* @return 结果
*/
public int deleteChatHistoryByUserId(String userId);
-}
\ No newline at end of file
+
+ /**
+ * 根据消息ID查询聊天记录
+ *
+ * @param messageId 消息ID
+ * @return 聊天记录
+ */
+ public ChatHistory selectChatHistoryByMessageId(String messageId);
+
+ /**
+ * 根据发送者ID查询聊天记录列表
+ *
+ * @param senderId 发送者ID
+ * @return 聊天记录集合
+ */
+ public List selectChatHistoryBySenderId(String senderId);
+
+ /**
+ * 根据接收者ID查询聊天记录列表
+ *
+ * @param receiverId 接收者ID
+ * @return 聊天记录集合
+ */
+ public List selectChatHistoryByReceiverId(String receiverId);
+
+ /**
+ * 根据发送者类型查询聊天记录列表
+ *
+ * @param senderType 发送者类型
+ * @return 聊天记录集合
+ */
+ public List selectChatHistoryBySenderType(String senderType);
+
+ /**
+ * 查询未读聊天记录列表
+ *
+ * @param userId 用户ID(可选)
+ * @return 聊天记录集合
+ */
+ public List selectUnreadChatHistory(String userId);
+
+ /**
+ * 根据时间范围查询聊天记录列表
+ *
+ * @param params 查询参数(包含startTime、endTime、userId等)
+ * @return 聊天记录集合
+ */
+ public List selectChatHistoryByTimeRange(java.util.Map params);
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/ManualServiceSessionsMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/ManualServiceSessionsMapper.java
new file mode 100644
index 00000000..bce35ad7
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/ManualServiceSessionsMapper.java
@@ -0,0 +1,61 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.ManualServiceSessions;
+
+/**
+ * 转人工服务会话Mapper接口
+ *
+ * @author ruoyi
+ * @date 2024-01-01
+ */
+public interface ManualServiceSessionsMapper
+{
+ /**
+ * 查询转人工服务会话
+ *
+ * @param id 转人工服务会话ID
+ * @return 转人工服务会话
+ */
+ public ManualServiceSessions selectManualServiceSessionsById(Long id);
+
+ /**
+ * 查询转人工服务会话列表
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 转人工服务会话集合
+ */
+ public List selectManualServiceSessionsList(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 新增转人工服务会话
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ public int insertManualServiceSessions(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 修改转人工服务会话
+ *
+ * @param manualServiceSessions 转人工服务会话
+ * @return 结果
+ */
+ public int updateManualServiceSessions(ManualServiceSessions manualServiceSessions);
+
+ /**
+ * 删除转人工服务会话
+ *
+ * @param id 转人工服务会话ID
+ * @return 结果
+ */
+ public int deleteManualServiceSessionsById(Long id);
+
+ /**
+ * 批量删除转人工服务会话
+ *
+ * @param ids 需要删除的数据ID
+ * @return 结果
+ */
+ public int deleteManualServiceSessionsByIds(Long[] ids);
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserSessionsMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserSessionsMapper.java
new file mode 100644
index 00000000..6c6ad704
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserSessionsMapper.java
@@ -0,0 +1,61 @@
+package com.ruoyi.system.mapper;
+
+import java.util.List;
+import com.ruoyi.system.domain.UserSessions;
+
+/**
+ * 用户会话Mapper接口
+ *
+ * @author ruoyi
+ * @date 2024-01-01
+ */
+public interface UserSessionsMapper
+{
+ /**
+ * 查询用户会话
+ *
+ * @param sessionId 用户会话ID
+ * @return 用户会话
+ */
+ public UserSessions selectUserSessionsById(Long sessionId);
+
+ /**
+ * 查询用户会话列表
+ *
+ * @param userSessions 用户会话
+ * @return 用户会话集合
+ */
+ public List selectUserSessionsList(UserSessions userSessions);
+
+ /**
+ * 新增用户会话
+ *
+ * @param userSessions 用户会话
+ * @return 结果
+ */
+ public int insertUserSessions(UserSessions userSessions);
+
+ /**
+ * 修改用户会话
+ *
+ * @param userSessions 用户会话
+ * @return 结果
+ */
+ public int updateUserSessions(UserSessions userSessions);
+
+ /**
+ * 删除用户会话
+ *
+ * @param sessionId 用户会话ID
+ * @return 结果
+ */
+ public int deleteUserSessionsById(Long sessionId);
+
+ /**
+ * 批量删除用户会话
+ *
+ * @param sessionIds 需要删除的数据ID
+ * @return 结果
+ */
+ public int deleteUserSessionsByIds(Long[] sessionIds);
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/ChatHistoryMapper.xml b/ruoyi-system/src/main/resources/mapper/system/ChatHistoryMapper.xml
index a09cf4f9..ac4db2db 100644
--- a/ruoyi-system/src/main/resources/mapper/system/ChatHistoryMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/ChatHistoryMapper.xml
@@ -6,17 +6,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+
+
+
+
+
+
+
+
+
- select id, user_id, session_id, message_type, content, is_link, is_button, create_time from chat_history
+ select id, message_id, user_id, session_id, session_id_long, message_type, content, message_content, is_link, is_button, sender_id, receiver_id, sent_at, is_read, sender_type, create_time, update_time from chat_history
+
+
+
+
+
+
+
+
+
+
+
+
insert into chat_history
+ message_id,
user_id,
session_id,
+ session_id_long,
message_type,
content,
+ message_content,
is_link,
is_button,
+ sender_id,
+ receiver_id,
+ sent_at,
+ is_read,
+ sender_type,
create_time,
+ update_time,
+ #{messageId},
#{userId},
#{sessionId},
+ #{sessionIdLong},
#{messageType},
#{content},
+ #{messageContent},
#{isLink},
#{isButton},
+ #{senderId},
+ #{receiverId},
+ #{sentAt},
+ #{isRead},
+ #{senderType},
#{createTime},
+ #{updateTime},
- insert into chat_history (user_id, session_id, message_type, content, is_link, is_button, create_time) values
+ insert into chat_history (message_id, user_id, session_id, session_id_long, message_type, content, message_content, is_link, is_button, sender_id, receiver_id, sent_at, is_read, sender_type, create_time, update_time) values
- (#{item.userId}, #{item.sessionId}, #{item.messageType}, #{item.content}, #{item.isLink}, #{item.isButton}, #{item.createTime})
+ (#{item.messageId}, #{item.userId}, #{item.sessionId}, #{item.sessionIdLong}, #{item.messageType}, #{item.content}, #{item.messageContent}, #{item.isLink}, #{item.isButton}, #{item.senderId}, #{item.receiverId}, #{item.sentAt}, #{item.isRead}, #{item.senderType}, #{item.createTime}, #{item.updateTime})
update chat_history
+ message_id = #{messageId},
user_id = #{userId},
session_id = #{sessionId},
+ session_id_long = #{sessionIdLong},
message_type = #{messageType},
content = #{content},
+ message_content = #{messageContent},
is_link = #{isLink},
is_button = #{isButton},
+ sender_id = #{senderId},
+ receiver_id = #{receiverId},
+ sent_at = #{sentAt},
+ is_read = #{isRead},
+ sender_type = #{senderType},
create_time = #{createTime},
+ update_time = #{updateTime},
where id = #{id}
@@ -110,4 +186,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
delete from chat_history where user_id = #{userId}
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/ManualServiceSessionsMapper.xml b/ruoyi-system/src/main/resources/mapper/system/ManualServiceSessionsMapper.xml
new file mode 100644
index 00000000..694b6b97
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/system/ManualServiceSessionsMapper.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select id, session_id, user_id, service_staff, start_time, end_time, status, create_time, update_time from manual_service_sessions
+
+
+
+
+
+
+
+ insert into manual_service_sessions
+
+ session_id,
+ user_id,
+ service_staff,
+ start_time,
+ end_time,
+ status,
+ create_time,
+ update_time,
+
+
+ #{sessionId},
+ #{userId},
+ #{serviceStaff},
+ #{startTime},
+ #{endTime},
+ #{status},
+ #{createTime},
+ #{updateTime},
+
+
+
+
+ update manual_service_sessions
+
+ session_id = #{sessionId},
+ user_id = #{userId},
+ service_staff = #{serviceStaff},
+ start_time = #{startTime},
+ end_time = #{endTime},
+ status = #{status},
+ create_time = #{createTime},
+ update_time = #{updateTime},
+
+ where id = #{id}
+
+
+
+ delete from manual_service_sessions where id = #{id}
+
+
+
+ delete from manual_service_sessions where id in
+
+ #{id}
+
+
+
+
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/UserSessionsMapper.xml b/ruoyi-system/src/main/resources/mapper/system/UserSessionsMapper.xml
new file mode 100644
index 00000000..698f5be9
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/system/UserSessionsMapper.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select session_id, user_id, session_token, create_time, update_time, status from user_sessions
+
+
+
+
+
+
+
+ insert into user_sessions
+
+ user_id,
+ session_token,
+ create_time,
+ update_time,
+ status,
+
+
+ #{userId},
+ #{sessionToken},
+ #{createTime},
+ #{updateTime},
+ #{status},
+
+
+
+
+ update user_sessions
+
+ user_id = #{userId},
+ session_token = #{sessionToken},
+ create_time = #{createTime},
+ update_time = #{updateTime},
+ status = #{status},
+
+ where session_id = #{sessionId}
+
+
+
+ delete from user_sessions where session_id = #{sessionId}
+
+
+
+ delete from user_sessions where session_id in
+
+ #{sessionId}
+
+
+
+
\ No newline at end of file