新增 后台的客户对话页面
This commit is contained in:
parent
9b1abac458
commit
a13c5a0ff1
|
|
@ -77,6 +77,12 @@
|
||||||
<artifactId>ruoyi-generator</artifactId>
|
<artifactId>ruoyi-generator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- WebSocket支持 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<UserSessions> list = customerServiceService.selectUserSessionsList(userSessions);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有活跃会话
|
||||||
|
*/
|
||||||
|
@GetMapping("/sessions")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult getSessions()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
List<UserSessions> 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<ChatHistory> 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<ManualServiceSessions> 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<UserSessions> list = customerServiceService.selectUserSessionsList(userSessions);
|
||||||
|
ExcelUtil<UserSessions> util = new ExcelUtil<UserSessions>(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("获取统计信息失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<String, CustomerServiceWebSocket> 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<String, CustomerServiceWebSocket> getWebSocketMap() {
|
||||||
|
return webSocketMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,594 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<th:block th:include="include :: header('客服系统')" />
|
||||||
|
<link th:href="@{/css/plugins/webuploader/webuploader.thumbnail.css}" rel="stylesheet"/>
|
||||||
|
<style>
|
||||||
|
.customer-service-container {
|
||||||
|
height: calc(100vh - 30px);
|
||||||
|
display: flex;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-list {
|
||||||
|
width: 300px;
|
||||||
|
border-right: 1px solid #e7eaec;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-item {
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom: 1px solid #f1f1f1;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-item:hover {
|
||||||
|
background-color: #f8f8f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-item.active {
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
border-left: 3px solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-avatar {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #1890ff;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-name {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-last-msg {
|
||||||
|
color: #666;
|
||||||
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-time {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-status {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-online { background: #52c41a; }
|
||||||
|
.status-offline { background: #d9d9d9; }
|
||||||
|
.status-busy { background: #faad14; }
|
||||||
|
|
||||||
|
.chat-area {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-header {
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-bottom: 1px solid #e7eaec;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-messages {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
background: #f8f8f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item.sent {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
max-width: 60%;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item.received .message-content {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #e7eaec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item.sent .message-content {
|
||||||
|
background: #1890ff;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-time {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-input {
|
||||||
|
padding: 15px 20px;
|
||||||
|
border-top: 1px solid #e7eaec;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-toolbar {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-area {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-text {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 60px;
|
||||||
|
max-height: 120px;
|
||||||
|
resize: none;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-service-panel {
|
||||||
|
width: 280px;
|
||||||
|
border-left: 1px solid #e7eaec;
|
||||||
|
background: #fafafa;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom: 1px solid #e7eaec;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-request-item {
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom: 1px solid #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-user {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-reason {
|
||||||
|
color: #666;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-time {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm {
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="gray-bg">
|
||||||
|
<div class="wrapper wrapper-content">
|
||||||
|
<div class="customer-service-container">
|
||||||
|
<!-- 左侧会话列表 -->
|
||||||
|
<div class="session-list">
|
||||||
|
<div class="panel-header">
|
||||||
|
<i class="fa fa-comments"></i> 会话列表
|
||||||
|
<span class="badge badge-primary pull-right" id="sessionCount">0</span>
|
||||||
|
</div>
|
||||||
|
<div id="sessionListContainer">
|
||||||
|
<!-- 会话列表将通过JavaScript动态加载 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 中间聊天区域 -->
|
||||||
|
<div class="chat-area">
|
||||||
|
<div class="chat-header">
|
||||||
|
<div id="currentSessionInfo">
|
||||||
|
<span class="text-muted">请选择一个会话开始对话</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chat-messages" id="chatMessages">
|
||||||
|
<!-- 聊天消息将通过JavaScript动态加载 -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chat-input">
|
||||||
|
<div class="input-toolbar">
|
||||||
|
<button type="button" class="btn btn-sm btn-default" onclick="insertEmoji('😊')">
|
||||||
|
<i class="fa fa-smile-o"></i> 表情
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-default" onclick="uploadFile()">
|
||||||
|
<i class="fa fa-paperclip"></i> 文件
|
||||||
|
</button>
|
||||||
|
<!-- <button type="button" class="btn btn-sm btn-warning pull-right" onclick="transferToManual()">
|
||||||
|
<i class="fa fa-user"></i> 转人工
|
||||||
|
</button> -->
|
||||||
|
</div>
|
||||||
|
<div class="input-area">
|
||||||
|
<textarea class="form-control input-text" id="messageInput"
|
||||||
|
placeholder="请输入消息内容..."
|
||||||
|
onkeydown="handleKeyDown(event)"></textarea>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="sendMessage()">
|
||||||
|
<i class="fa fa-send"></i> 发送
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧转人工消息列表 -->
|
||||||
|
<div class="manual-service-panel">
|
||||||
|
<div class="panel-header">
|
||||||
|
<i class="fa fa-user-plus"></i> 转人工请求
|
||||||
|
<span class="badge badge-warning pull-right" id="manualRequestCount">0</span>
|
||||||
|
</div>
|
||||||
|
<div id="manualRequestContainer">
|
||||||
|
<!-- 转人工请求列表将通过JavaScript动态加载 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<th:block th:include="include :: footer" />
|
||||||
|
<script th:src="@{/js/plugins/layer/layer.min.js}"></script>
|
||||||
|
<script th:src="@{/js/plugins/webuploader/webuploader.min.js}"></script>
|
||||||
|
<script>
|
||||||
|
var currentSessionId = null;
|
||||||
|
var wsConnection = null;
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
initWebSocket();
|
||||||
|
loadSessionList();
|
||||||
|
loadManualRequests();
|
||||||
|
|
||||||
|
// 每30秒刷新一次数据
|
||||||
|
setInterval(function() {
|
||||||
|
loadSessionList();
|
||||||
|
loadManualRequests();
|
||||||
|
}, 30000);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化WebSocket连接
|
||||||
|
function initWebSocket() {
|
||||||
|
if (typeof(WebSocket) == "undefined") {
|
||||||
|
console.log("您的浏览器不支持WebSocket");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wsUrl = "ws://" + window.location.host + "/websocket/customer-service";
|
||||||
|
wsConnection = new WebSocket(wsUrl);
|
||||||
|
|
||||||
|
wsConnection.onopen = function() {
|
||||||
|
console.log("WebSocket连接已建立");
|
||||||
|
};
|
||||||
|
|
||||||
|
wsConnection.onmessage = function(event) {
|
||||||
|
var message = JSON.parse(event.data);
|
||||||
|
handleWebSocketMessage(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
wsConnection.onclose = function() {
|
||||||
|
console.log("WebSocket连接已关闭");
|
||||||
|
// 尝试重连
|
||||||
|
setTimeout(initWebSocket, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
wsConnection.onerror = function(error) {
|
||||||
|
console.log("WebSocket连接错误:", error);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理WebSocket消息
|
||||||
|
function handleWebSocketMessage(message) {
|
||||||
|
switch(message.type) {
|
||||||
|
case 'NEW_MESSAGE':
|
||||||
|
if (message.sessionId == currentSessionId) {
|
||||||
|
appendMessage(message.content, false, message.timestamp);
|
||||||
|
}
|
||||||
|
loadSessionList(); // 刷新会话列表
|
||||||
|
break;
|
||||||
|
case 'SESSION_UPDATE':
|
||||||
|
loadSessionList();
|
||||||
|
break;
|
||||||
|
case 'MANUAL_REQUEST':
|
||||||
|
loadManualRequests();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载会话列表
|
||||||
|
function loadSessionList() {
|
||||||
|
$.get('/customer/service/sessions', function(data) {
|
||||||
|
var html = '';
|
||||||
|
if (data.code === 0 && data.data) {
|
||||||
|
data.data.forEach(function(session) {
|
||||||
|
var statusClass = getStatusClass(session.status);
|
||||||
|
var avatar = session.customerName ? session.customerName.charAt(0).toUpperCase() : 'U';
|
||||||
|
var activeClass = session.sessionId == currentSessionId ? 'active' : '';
|
||||||
|
|
||||||
|
html += '<div class="session-item ' + activeClass + '" onclick="selectSession(' + session.sessionId + ')">';
|
||||||
|
html += ' <div style="display: flex; align-items: center;">';
|
||||||
|
html += ' <div class="session-avatar">' + avatar + '</div>';
|
||||||
|
html += ' <div class="session-info">';
|
||||||
|
html += ' <div class="session-name">' + (session.customerName || '访客' + session.sessionId) + '</div>';
|
||||||
|
html += ' <div class="session-last-msg">' + (session.lastMessage || '暂无消息') + '</div>';
|
||||||
|
html += ' <div class="session-time">' + formatTime(session.lastMessageTime) + '</div>';
|
||||||
|
html += ' </div>';
|
||||||
|
html += ' <div class="session-status ' + statusClass + '"></div>';
|
||||||
|
html += ' </div>';
|
||||||
|
html += '</div>';
|
||||||
|
});
|
||||||
|
$('#sessionCount').text(data.data.length);
|
||||||
|
}
|
||||||
|
$('#sessionListContainer').html(html);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择会话
|
||||||
|
function selectSession(sessionId) {
|
||||||
|
currentSessionId = sessionId;
|
||||||
|
$('.session-item').removeClass('active');
|
||||||
|
$('[onclick="selectSession(' + sessionId + ')"]').addClass('active');
|
||||||
|
|
||||||
|
loadChatHistory(sessionId);
|
||||||
|
updateCurrentSessionInfo(sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载聊天历史
|
||||||
|
function loadChatHistory(sessionId) {
|
||||||
|
$.get('/customer/service/messages/' + sessionId, function(data) {
|
||||||
|
var html = '';
|
||||||
|
if (data.code === 0 && data.data) {
|
||||||
|
data.data.forEach(function(message) {
|
||||||
|
html += createMessageHtml(message.content, message.senderType === 'CUSTOMER', message.createTime);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$('#chatMessages').html(html);
|
||||||
|
scrollToBottom();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建消息HTML
|
||||||
|
function createMessageHtml(content, isReceived, timestamp) {
|
||||||
|
var messageClass = isReceived ? 'received' : 'sent';
|
||||||
|
var html = '<div class="message-item ' + messageClass + '">';
|
||||||
|
html += ' <div class="message-content">';
|
||||||
|
html += ' <div>' + content + '</div>';
|
||||||
|
html += ' <div class="message-time">' + formatTime(timestamp) + '</div>';
|
||||||
|
html += ' </div>';
|
||||||
|
html += '</div>';
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
function sendMessage() {
|
||||||
|
if (!currentSessionId) {
|
||||||
|
layer.msg('请先选择一个会话');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var content = $('#messageInput').val().trim();
|
||||||
|
if (!content) {
|
||||||
|
layer.msg('请输入消息内容');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var messageData = {
|
||||||
|
sessionId: currentSessionId,
|
||||||
|
content: content,
|
||||||
|
senderType: 'SERVICE'
|
||||||
|
};
|
||||||
|
|
||||||
|
$.post('/customer/service/send', messageData, function(data) {
|
||||||
|
if (data.code === 0) {
|
||||||
|
appendMessage(content, false, new Date());
|
||||||
|
$('#messageInput').val('');
|
||||||
|
loadSessionList(); // 刷新会话列表
|
||||||
|
} else {
|
||||||
|
layer.msg('发送失败: ' + data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加消息到聊天区域
|
||||||
|
function appendMessage(content, isReceived, timestamp) {
|
||||||
|
var messageHtml = createMessageHtml(content, isReceived, timestamp);
|
||||||
|
$('#chatMessages').append(messageHtml);
|
||||||
|
scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 滚动到底部
|
||||||
|
function scrollToBottom() {
|
||||||
|
var chatMessages = document.getElementById('chatMessages');
|
||||||
|
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理键盘事件
|
||||||
|
function handleKeyDown(event) {
|
||||||
|
if (event.ctrlKey && event.keyCode === 13) {
|
||||||
|
sendMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转人工
|
||||||
|
function transferToManual() {
|
||||||
|
if (!currentSessionId) {
|
||||||
|
layer.msg('请先选择一个会话');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.prompt({
|
||||||
|
title: '转人工服务',
|
||||||
|
formType: 2,
|
||||||
|
value: '',
|
||||||
|
area: ['300px', '200px']
|
||||||
|
}, function(reason, index) {
|
||||||
|
$.post('/customer/service/transfer', {
|
||||||
|
sessionId: currentSessionId,
|
||||||
|
reason: reason
|
||||||
|
}, function(data) {
|
||||||
|
if (data.code === 0) {
|
||||||
|
layer.msg('转人工请求已提交');
|
||||||
|
loadManualRequests();
|
||||||
|
} else {
|
||||||
|
layer.msg('转人工失败: ' + data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
layer.close(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载转人工请求列表
|
||||||
|
function loadManualRequests() {
|
||||||
|
$.get('/customer/service/manual-requests', function(data) {
|
||||||
|
var html = '';
|
||||||
|
if (data.code === 0 && data.data) {
|
||||||
|
data.data.forEach(function(request) {
|
||||||
|
html += '<div class="manual-request-item">';
|
||||||
|
html += ' <div class="request-user">' + (request.customerName || '访客' + request.sessionId) + '</div>';
|
||||||
|
html += ' <div class="request-reason">' + (request.reason || '无') + '</div>';
|
||||||
|
html += ' <div class="request-time">' + formatTime(request.createTime) + '</div>';
|
||||||
|
html += ' <div class="request-actions">';
|
||||||
|
html += ' <button class="btn btn-success btn-sm" onclick="acceptManualRequest(' + request.id + ')">';
|
||||||
|
html += ' <i class="fa fa-check"></i> 接受';
|
||||||
|
html += ' </button>';
|
||||||
|
html += ' <button class="btn btn-default btn-sm" onclick="rejectManualRequest(' + request.id + ')">';
|
||||||
|
html += ' <i class="fa fa-times"></i> 拒绝';
|
||||||
|
html += ' </button>';
|
||||||
|
html += ' </div>';
|
||||||
|
html += '</div>';
|
||||||
|
});
|
||||||
|
$('#manualRequestCount').text(data.data.length);
|
||||||
|
}
|
||||||
|
$('#manualRequestContainer').html(html);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接受转人工请求
|
||||||
|
function acceptManualRequest(requestId) {
|
||||||
|
$.post('/customer/service/manual-requests/' + requestId + '/accept', function(data) {
|
||||||
|
if (data.code === 0) {
|
||||||
|
layer.msg('已接受转人工请求');
|
||||||
|
loadManualRequests();
|
||||||
|
loadSessionList();
|
||||||
|
} else {
|
||||||
|
layer.msg('操作失败: ' + data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拒绝转人工请求
|
||||||
|
function rejectManualRequest(requestId) {
|
||||||
|
$.post('/customer/service/manual-requests/' + requestId + '/reject', function(data) {
|
||||||
|
if (data.code === 0) {
|
||||||
|
layer.msg('已拒绝转人工请求');
|
||||||
|
loadManualRequests();
|
||||||
|
} else {
|
||||||
|
layer.msg('操作失败: ' + data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新当前会话信息
|
||||||
|
function updateCurrentSessionInfo(sessionId) {
|
||||||
|
$.get('/customer/service/sessions/' + sessionId, function(data) {
|
||||||
|
if (data.code === 0 && data.data) {
|
||||||
|
var session = data.data;
|
||||||
|
var html = '<strong>' + (session.customerName || '访客' + session.sessionId) + '</strong>';
|
||||||
|
html += ' <span class="text-muted">(' + getStatusText(session.status) + ')</span>';
|
||||||
|
$('#currentSessionInfo').html(html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态样式类
|
||||||
|
function getStatusClass(status) {
|
||||||
|
switch(status) {
|
||||||
|
case 'ONLINE': return 'status-online';
|
||||||
|
case 'BUSY': return 'status-busy';
|
||||||
|
default: return 'status-offline';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
function getStatusText(status) {
|
||||||
|
switch(status) {
|
||||||
|
case 'ONLINE': return '在线';
|
||||||
|
case 'BUSY': return '忙碌';
|
||||||
|
case 'OFFLINE': return '离线';
|
||||||
|
default: return '未知';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
function formatTime(timestamp) {
|
||||||
|
if (!timestamp) return '';
|
||||||
|
var date = new Date(timestamp);
|
||||||
|
var now = new Date();
|
||||||
|
var diff = now - date;
|
||||||
|
|
||||||
|
if (diff < 60000) { // 1分钟内
|
||||||
|
return '刚刚';
|
||||||
|
} else if (diff < 3600000) { // 1小时内
|
||||||
|
return Math.floor(diff / 60000) + '分钟前';
|
||||||
|
} else if (diff < 86400000) { // 24小时内
|
||||||
|
return Math.floor(diff / 3600000) + '小时前';
|
||||||
|
} else {
|
||||||
|
return date.getMonth() + 1 + '/' + date.getDate() + ' ' +
|
||||||
|
String(date.getHours()).padStart(2, '0') + ':' +
|
||||||
|
String(date.getMinutes()).padStart(2, '0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入表情
|
||||||
|
function insertEmoji(emoji) {
|
||||||
|
var input = document.getElementById('messageInput');
|
||||||
|
var start = input.selectionStart;
|
||||||
|
var end = input.selectionEnd;
|
||||||
|
var text = input.value;
|
||||||
|
input.value = text.substring(0, start) + emoji + text.substring(end);
|
||||||
|
input.focus();
|
||||||
|
input.setSelectionRange(start + emoji.length, start + emoji.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件上传
|
||||||
|
function uploadFile() {
|
||||||
|
layer.msg('文件上传功能开发中...');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -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<UserSessions> selectUserSessionsList(UserSessions userSessions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取活跃会话列表
|
||||||
|
*
|
||||||
|
* @return 活跃会话集合
|
||||||
|
*/
|
||||||
|
public List<UserSessions> 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<ChatHistory> 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<ManualServiceSessions> 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<ChatHistory> 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<ManualServiceSessions> 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);
|
||||||
|
}
|
||||||
|
|
@ -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<UserSessions> selectUserSessionsList(UserSessions userSessions)
|
||||||
|
{
|
||||||
|
return userSessionsMapper.selectUserSessionsList(userSessions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取活跃会话列表
|
||||||
|
*
|
||||||
|
* @return 活跃会话集合
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<UserSessions> 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<ChatHistory> 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<ManualServiceSessions> 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<ChatHistory> 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<ManualServiceSessions> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.ruoyi.system.domain;
|
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.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
|
|
@ -18,6 +20,10 @@ public class ChatHistory extends BaseEntity
|
||||||
/** 主键ID */
|
/** 主键ID */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
/** 消息ID */
|
||||||
|
@Excel(name = "消息ID")
|
||||||
|
private Long messageId;
|
||||||
|
|
||||||
/** 用户ID */
|
/** 用户ID */
|
||||||
@Excel(name = "用户ID")
|
@Excel(name = "用户ID")
|
||||||
private String userId;
|
private String userId;
|
||||||
|
|
@ -26,6 +32,10 @@ public class ChatHistory extends BaseEntity
|
||||||
@Excel(name = "会话ID")
|
@Excel(name = "会话ID")
|
||||||
private String sessionId;
|
private String sessionId;
|
||||||
|
|
||||||
|
/** 会话ID(Long类型,兼容customer包)*/
|
||||||
|
@Excel(name = "会话ID")
|
||||||
|
private Long sessionIdLong;
|
||||||
|
|
||||||
/** 消息类型 */
|
/** 消息类型 */
|
||||||
@Excel(name = "消息类型", readConverterExp = "user=用户消息,service=客服消息")
|
@Excel(name = "消息类型", readConverterExp = "user=用户消息,service=客服消息")
|
||||||
private String messageType;
|
private String messageType;
|
||||||
|
|
@ -34,6 +44,10 @@ public class ChatHistory extends BaseEntity
|
||||||
@Excel(name = "消息内容")
|
@Excel(name = "消息内容")
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
|
/** 消息内容(兼容customer包字段名)*/
|
||||||
|
@Excel(name = "消息内容")
|
||||||
|
private String messageContent;
|
||||||
|
|
||||||
/** 是否包含链接 */
|
/** 是否包含链接 */
|
||||||
@Excel(name = "是否包含链接", readConverterExp = "0=否,1=是")
|
@Excel(name = "是否包含链接", readConverterExp = "0=否,1=是")
|
||||||
private Integer isLink;
|
private Integer isLink;
|
||||||
|
|
@ -42,6 +56,27 @@ public class ChatHistory extends BaseEntity
|
||||||
@Excel(name = "是否为按钮消息", readConverterExp = "0=否,1=是")
|
@Excel(name = "是否为按钮消息", readConverterExp = "0=否,1=是")
|
||||||
private Integer isButton;
|
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)
|
public void setId(Long id)
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
@ -105,18 +140,113 @@ public class ChatHistory extends BaseEntity
|
||||||
{
|
{
|
||||||
return isButton;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
.append("id", getId())
|
.append("id", getId())
|
||||||
|
.append("messageId", getMessageId())
|
||||||
.append("userId", getUserId())
|
.append("userId", getUserId())
|
||||||
.append("sessionId", getSessionId())
|
.append("sessionId", getSessionId())
|
||||||
|
.append("sessionIdLong", getSessionIdLong())
|
||||||
.append("messageType", getMessageType())
|
.append("messageType", getMessageType())
|
||||||
.append("content", getContent())
|
.append("content", getContent())
|
||||||
|
.append("messageContent", getMessageContent())
|
||||||
.append("isLink", getIsLink())
|
.append("isLink", getIsLink())
|
||||||
.append("isButton", getIsButton())
|
.append("isButton", getIsButton())
|
||||||
|
.append("senderId", getSenderId())
|
||||||
|
.append("receiverId", getReceiverId())
|
||||||
|
.append("sentAt", getSentAt())
|
||||||
|
.append("isRead", getIsRead())
|
||||||
|
.append("senderType", getSenderType())
|
||||||
.append("createTime", getCreateTime())
|
.append("createTime", getCreateTime())
|
||||||
|
.append("updateTime", getUpdateTime())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -92,10 +92,58 @@ public interface ChatHistoryMapper
|
||||||
public int deleteChatHistoryBySessionId(String sessionId);
|
public int deleteChatHistoryBySessionId(String sessionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除指定用户的聊天记录
|
* 根据用户ID删除聊天记录
|
||||||
*
|
*
|
||||||
* @param userId 用户ID
|
* @param userId 用户ID
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int deleteChatHistoryByUserId(String userId);
|
public int deleteChatHistoryByUserId(String userId);
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 根据消息ID查询聊天记录
|
||||||
|
*
|
||||||
|
* @param messageId 消息ID
|
||||||
|
* @return 聊天记录
|
||||||
|
*/
|
||||||
|
public ChatHistory selectChatHistoryByMessageId(String messageId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据发送者ID查询聊天记录列表
|
||||||
|
*
|
||||||
|
* @param senderId 发送者ID
|
||||||
|
* @return 聊天记录集合
|
||||||
|
*/
|
||||||
|
public List<ChatHistory> selectChatHistoryBySenderId(String senderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据接收者ID查询聊天记录列表
|
||||||
|
*
|
||||||
|
* @param receiverId 接收者ID
|
||||||
|
* @return 聊天记录集合
|
||||||
|
*/
|
||||||
|
public List<ChatHistory> selectChatHistoryByReceiverId(String receiverId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据发送者类型查询聊天记录列表
|
||||||
|
*
|
||||||
|
* @param senderType 发送者类型
|
||||||
|
* @return 聊天记录集合
|
||||||
|
*/
|
||||||
|
public List<ChatHistory> selectChatHistoryBySenderType(String senderType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询未读聊天记录列表
|
||||||
|
*
|
||||||
|
* @param userId 用户ID(可选)
|
||||||
|
* @return 聊天记录集合
|
||||||
|
*/
|
||||||
|
public List<ChatHistory> selectUnreadChatHistory(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据时间范围查询聊天记录列表
|
||||||
|
*
|
||||||
|
* @param params 查询参数(包含startTime、endTime、userId等)
|
||||||
|
* @return 聊天记录集合
|
||||||
|
*/
|
||||||
|
public List<ChatHistory> selectChatHistoryByTimeRange(java.util.Map<String, Object> params);
|
||||||
|
}
|
||||||
|
|
@ -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<ManualServiceSessions> 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);
|
||||||
|
}
|
||||||
|
|
@ -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<UserSessions> 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);
|
||||||
|
}
|
||||||
|
|
@ -6,17 +6,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
|
||||||
<resultMap type="ChatHistory" id="ChatHistoryResult">
|
<resultMap type="ChatHistory" id="ChatHistoryResult">
|
||||||
<result property="id" column="id" />
|
<result property="id" column="id" />
|
||||||
|
<result property="messageId" column="message_id" />
|
||||||
<result property="userId" column="user_id" />
|
<result property="userId" column="user_id" />
|
||||||
<result property="sessionId" column="session_id" />
|
<result property="sessionId" column="session_id" />
|
||||||
|
<result property="sessionIdLong" column="session_id_long" />
|
||||||
<result property="messageType" column="message_type" />
|
<result property="messageType" column="message_type" />
|
||||||
<result property="content" column="content" />
|
<result property="content" column="content" />
|
||||||
|
<result property="messageContent" column="message_content" />
|
||||||
<result property="isLink" column="is_link" />
|
<result property="isLink" column="is_link" />
|
||||||
<result property="isButton" column="is_button" />
|
<result property="isButton" column="is_button" />
|
||||||
|
<result property="senderId" column="sender_id" />
|
||||||
|
<result property="receiverId" column="receiver_id" />
|
||||||
|
<result property="sentAt" column="sent_at" />
|
||||||
|
<result property="isRead" column="is_read" />
|
||||||
|
<result property="senderType" column="sender_type" />
|
||||||
<result property="createTime" column="create_time" />
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectChatHistoryVo">
|
<sql id="selectChatHistoryVo">
|
||||||
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
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectChatHistoryList" parameterType="ChatHistory" resultMap="ChatHistoryResult">
|
<select id="selectChatHistoryList" parameterType="ChatHistory" resultMap="ChatHistoryResult">
|
||||||
|
|
@ -48,46 +57,113 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
where user_id = #{userId}
|
where user_id = #{userId}
|
||||||
order by create_time asc
|
order by create_time asc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectChatHistoryByMessageId" parameterType="String" resultMap="ChatHistoryResult">
|
||||||
|
<include refid="selectChatHistoryVo"/>
|
||||||
|
where message_id = #{messageId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectChatHistoryBySenderId" parameterType="String" resultMap="ChatHistoryResult">
|
||||||
|
<include refid="selectChatHistoryVo"/>
|
||||||
|
where sender_id = #{senderId}
|
||||||
|
order by create_time asc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectChatHistoryByReceiverId" parameterType="String" resultMap="ChatHistoryResult">
|
||||||
|
<include refid="selectChatHistoryVo"/>
|
||||||
|
where receiver_id = #{receiverId}
|
||||||
|
order by create_time asc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectChatHistoryBySenderType" parameterType="String" resultMap="ChatHistoryResult">
|
||||||
|
<include refid="selectChatHistoryVo"/>
|
||||||
|
where sender_type = #{senderType}
|
||||||
|
order by create_time asc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectUnreadChatHistory" parameterType="String" resultMap="ChatHistoryResult">
|
||||||
|
<include refid="selectChatHistoryVo"/>
|
||||||
|
where is_read = 0
|
||||||
|
<if test="userId != null and userId != ''"> and user_id = #{userId}</if>
|
||||||
|
order by create_time asc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectChatHistoryByTimeRange" parameterType="map" resultMap="ChatHistoryResult">
|
||||||
|
<include refid="selectChatHistoryVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="startTime != null"> and sent_at >= #{startTime}</if>
|
||||||
|
<if test="endTime != null"> and sent_at <= #{endTime}</if>
|
||||||
|
<if test="userId != null and userId != ''"> and user_id = #{userId}</if>
|
||||||
|
</where>
|
||||||
|
order by sent_at asc
|
||||||
|
</select>
|
||||||
|
|
||||||
<insert id="insertChatHistory" parameterType="ChatHistory" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertChatHistory" parameterType="ChatHistory" useGeneratedKeys="true" keyProperty="id">
|
||||||
insert into chat_history
|
insert into chat_history
|
||||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="messageId != null">message_id,</if>
|
||||||
<if test="userId != null">user_id,</if>
|
<if test="userId != null">user_id,</if>
|
||||||
<if test="sessionId != null">session_id,</if>
|
<if test="sessionId != null">session_id,</if>
|
||||||
|
<if test="sessionIdLong != null">session_id_long,</if>
|
||||||
<if test="messageType != null">message_type,</if>
|
<if test="messageType != null">message_type,</if>
|
||||||
<if test="content != null">content,</if>
|
<if test="content != null">content,</if>
|
||||||
|
<if test="messageContent != null">message_content,</if>
|
||||||
<if test="isLink != null">is_link,</if>
|
<if test="isLink != null">is_link,</if>
|
||||||
<if test="isButton != null">is_button,</if>
|
<if test="isButton != null">is_button,</if>
|
||||||
|
<if test="senderId != null">sender_id,</if>
|
||||||
|
<if test="receiverId != null">receiver_id,</if>
|
||||||
|
<if test="sentAt != null">sent_at,</if>
|
||||||
|
<if test="isRead != null">is_read,</if>
|
||||||
|
<if test="senderType != null">sender_type,</if>
|
||||||
<if test="createTime != null">create_time,</if>
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
</trim>
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="messageId != null">#{messageId},</if>
|
||||||
<if test="userId != null">#{userId},</if>
|
<if test="userId != null">#{userId},</if>
|
||||||
<if test="sessionId != null">#{sessionId},</if>
|
<if test="sessionId != null">#{sessionId},</if>
|
||||||
|
<if test="sessionIdLong != null">#{sessionIdLong},</if>
|
||||||
<if test="messageType != null">#{messageType},</if>
|
<if test="messageType != null">#{messageType},</if>
|
||||||
<if test="content != null">#{content},</if>
|
<if test="content != null">#{content},</if>
|
||||||
|
<if test="messageContent != null">#{messageContent},</if>
|
||||||
<if test="isLink != null">#{isLink},</if>
|
<if test="isLink != null">#{isLink},</if>
|
||||||
<if test="isButton != null">#{isButton},</if>
|
<if test="isButton != null">#{isButton},</if>
|
||||||
|
<if test="senderId != null">#{senderId},</if>
|
||||||
|
<if test="receiverId != null">#{receiverId},</if>
|
||||||
|
<if test="sentAt != null">#{sentAt},</if>
|
||||||
|
<if test="isRead != null">#{isRead},</if>
|
||||||
|
<if test="senderType != null">#{senderType},</if>
|
||||||
<if test="createTime != null">#{createTime},</if>
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
</trim>
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<insert id="batchInsertChatHistory" parameterType="java.util.List">
|
<insert id="batchInsertChatHistory" parameterType="java.util.List">
|
||||||
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
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{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})
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<update id="updateChatHistory" parameterType="ChatHistory">
|
<update id="updateChatHistory" parameterType="ChatHistory">
|
||||||
update chat_history
|
update chat_history
|
||||||
<trim prefix="SET" suffixOverrides=",">
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="messageId != null">message_id = #{messageId},</if>
|
||||||
<if test="userId != null">user_id = #{userId},</if>
|
<if test="userId != null">user_id = #{userId},</if>
|
||||||
<if test="sessionId != null">session_id = #{sessionId},</if>
|
<if test="sessionId != null">session_id = #{sessionId},</if>
|
||||||
|
<if test="sessionIdLong != null">session_id_long = #{sessionIdLong},</if>
|
||||||
<if test="messageType != null">message_type = #{messageType},</if>
|
<if test="messageType != null">message_type = #{messageType},</if>
|
||||||
<if test="content != null">content = #{content},</if>
|
<if test="content != null">content = #{content},</if>
|
||||||
|
<if test="messageContent != null">message_content = #{messageContent},</if>
|
||||||
<if test="isLink != null">is_link = #{isLink},</if>
|
<if test="isLink != null">is_link = #{isLink},</if>
|
||||||
<if test="isButton != null">is_button = #{isButton},</if>
|
<if test="isButton != null">is_button = #{isButton},</if>
|
||||||
|
<if test="senderId != null">sender_id = #{senderId},</if>
|
||||||
|
<if test="receiverId != null">receiver_id = #{receiverId},</if>
|
||||||
|
<if test="sentAt != null">sent_at = #{sentAt},</if>
|
||||||
|
<if test="isRead != null">is_read = #{isRead},</if>
|
||||||
|
<if test="senderType != null">sender_type = #{senderType},</if>
|
||||||
<if test="createTime != null">create_time = #{createTime},</if>
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
@ -110,4 +186,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<delete id="deleteChatHistoryByUserId" parameterType="String">
|
<delete id="deleteChatHistoryByUserId" parameterType="String">
|
||||||
delete from chat_history where user_id = #{userId}
|
delete from chat_history where user_id = #{userId}
|
||||||
</delete>
|
</delete>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?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.ruoyi.system.mapper.ManualServiceSessionsMapper">
|
||||||
|
|
||||||
|
<resultMap type="ManualServiceSessions" id="ManualServiceSessionsResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="sessionId" column="session_id" />
|
||||||
|
<result property="userId" column="user_id" />
|
||||||
|
<result property="serviceStaff" column="service_staff" />
|
||||||
|
<result property="startTime" column="start_time" />
|
||||||
|
<result property="endTime" column="end_time" />
|
||||||
|
<result property="status" column="status" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectManualServiceSessionsVo">
|
||||||
|
select id, session_id, user_id, service_staff, start_time, end_time, status, create_time, update_time from manual_service_sessions
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectManualServiceSessionsList" parameterType="ManualServiceSessions" resultMap="ManualServiceSessionsResult">
|
||||||
|
<include refid="selectManualServiceSessionsVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="sessionId != null "> and session_id = #{sessionId}</if>
|
||||||
|
<if test="userId != null "> and user_id = #{userId}</if>
|
||||||
|
<if test="serviceStaff != null and serviceStaff != ''"> and service_staff = #{serviceStaff}</if>
|
||||||
|
<if test="status != null and status != ''"> and status = #{status}</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectManualServiceSessionsById" parameterType="Long" resultMap="ManualServiceSessionsResult">
|
||||||
|
<include refid="selectManualServiceSessionsVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertManualServiceSessions" parameterType="ManualServiceSessions" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into manual_service_sessions
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="sessionId != null">session_id,</if>
|
||||||
|
<if test="userId != null">user_id,</if>
|
||||||
|
<if test="serviceStaff != null">service_staff,</if>
|
||||||
|
<if test="startTime != null">start_time,</if>
|
||||||
|
<if test="endTime != null">end_time,</if>
|
||||||
|
<if test="status != null">status,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="sessionId != null">#{sessionId},</if>
|
||||||
|
<if test="userId != null">#{userId},</if>
|
||||||
|
<if test="serviceStaff != null">#{serviceStaff},</if>
|
||||||
|
<if test="startTime != null">#{startTime},</if>
|
||||||
|
<if test="endTime != null">#{endTime},</if>
|
||||||
|
<if test="status != null">#{status},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateManualServiceSessions" parameterType="ManualServiceSessions">
|
||||||
|
update manual_service_sessions
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="sessionId != null">session_id = #{sessionId},</if>
|
||||||
|
<if test="userId != null">user_id = #{userId},</if>
|
||||||
|
<if test="serviceStaff != null">service_staff = #{serviceStaff},</if>
|
||||||
|
<if test="startTime != null">start_time = #{startTime},</if>
|
||||||
|
<if test="endTime != null">end_time = #{endTime},</if>
|
||||||
|
<if test="status != null">status = #{status},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteManualServiceSessionsById" parameterType="Long">
|
||||||
|
delete from manual_service_sessions where id = #{id}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteManualServiceSessionsByIds" parameterType="String">
|
||||||
|
delete from manual_service_sessions where id in
|
||||||
|
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?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.ruoyi.system.mapper.UserSessionsMapper">
|
||||||
|
|
||||||
|
<resultMap type="UserSessions" id="UserSessionsResult">
|
||||||
|
<result property="sessionId" column="session_id" />
|
||||||
|
<result property="userId" column="user_id" />
|
||||||
|
<result property="sessionToken" column="session_token" />
|
||||||
|
<result property="createTime" column="create_time" />
|
||||||
|
<result property="updateTime" column="update_time" />
|
||||||
|
<result property="status" column="status" />
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectUserSessionsVo">
|
||||||
|
select session_id, user_id, session_token, create_time, update_time, status from user_sessions
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectUserSessionsList" parameterType="UserSessions" resultMap="UserSessionsResult">
|
||||||
|
<include refid="selectUserSessionsVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="userId != null "> and user_id = #{userId}</if>
|
||||||
|
<if test="sessionToken != null and sessionToken != ''"> and session_token = #{sessionToken}</if>
|
||||||
|
<if test="status != null and status != ''"> and status = #{status}</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectUserSessionsById" parameterType="Long" resultMap="UserSessionsResult">
|
||||||
|
<include refid="selectUserSessionsVo"/>
|
||||||
|
where session_id = #{sessionId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insertUserSessions" parameterType="UserSessions" useGeneratedKeys="true" keyProperty="sessionId">
|
||||||
|
insert into user_sessions
|
||||||
|
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="userId != null">user_id,</if>
|
||||||
|
<if test="sessionToken != null">session_token,</if>
|
||||||
|
<if test="createTime != null">create_time,</if>
|
||||||
|
<if test="updateTime != null">update_time,</if>
|
||||||
|
<if test="status != null">status,</if>
|
||||||
|
</trim>
|
||||||
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
|
<if test="userId != null">#{userId},</if>
|
||||||
|
<if test="sessionToken != null">#{sessionToken},</if>
|
||||||
|
<if test="createTime != null">#{createTime},</if>
|
||||||
|
<if test="updateTime != null">#{updateTime},</if>
|
||||||
|
<if test="status != null">#{status},</if>
|
||||||
|
</trim>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateUserSessions" parameterType="UserSessions">
|
||||||
|
update user_sessions
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="userId != null">user_id = #{userId},</if>
|
||||||
|
<if test="sessionToken != null">session_token = #{sessionToken},</if>
|
||||||
|
<if test="createTime != null">create_time = #{createTime},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
<if test="status != null">status = #{status},</if>
|
||||||
|
</trim>
|
||||||
|
where session_id = #{sessionId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteUserSessionsById" parameterType="Long">
|
||||||
|
delete from user_sessions where session_id = #{sessionId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteUserSessionsByIds" parameterType="String">
|
||||||
|
delete from user_sessions where session_id in
|
||||||
|
<foreach item="sessionId" collection="array" open="(" separator="," close=")">
|
||||||
|
#{sessionId}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue