客服模块
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
package org.xyzh.workcase.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.xyzh.common.wechat.kefu.message.KefuMessageService;
|
||||
import org.xyzh.workcase.handler.WorkcaseKefuHandler;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* @description 工单模块的微信客服配置
|
||||
* 注册 WorkcaseKefuHandler 到消息服务
|
||||
* @filename WeChatKefuConfig.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-19
|
||||
*/
|
||||
@Configuration
|
||||
public class WeChatKefuConfig {
|
||||
|
||||
@Autowired
|
||||
private KefuMessageService kefuMessageService;
|
||||
|
||||
@Autowired
|
||||
private WorkcaseKefuHandler workcaseKefuHandler;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
kefuMessageService.setHandler(workcaseKefuHandler);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
package org.xyzh.workcase.controller;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
import org.xyzh.api.ai.dto.ChatPrepareData;
|
||||
import org.xyzh.api.ai.dto.TbChat;
|
||||
import org.xyzh.api.ai.dto.TbChatMessage;
|
||||
import org.xyzh.api.workcase.dto.TbWordCloudDTO;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseDTO;
|
||||
import org.xyzh.api.workcase.service.WorkcaseChatService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.utils.validation.ValidationResult;
|
||||
import org.xyzh.common.utils.validation.ValidationUtils;
|
||||
import org.xyzh.common.wechat.kefu.message.KefuMessageService;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import java.util.Arrays;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* @description 工单对话控制器
|
||||
* - AI对话管理
|
||||
* - 微信客服消息接收
|
||||
* - 词云管理
|
||||
* @filename WorkcaseChatController.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-19
|
||||
*/
|
||||
@Tag(name = "工单对话")
|
||||
@RestController
|
||||
@RequestMapping("/workcase/chat")
|
||||
public class WorkcaseChatContorller {
|
||||
|
||||
@DubboReference(version = "1.0.0", group = "workcase", check = false)
|
||||
private WorkcaseChatService workcaseChatService;
|
||||
|
||||
@Autowired
|
||||
private KefuMessageService kefuMessageService;
|
||||
|
||||
// ========================= AI对话管理 =========================
|
||||
|
||||
@Operation(summary = "创建对话")
|
||||
@PostMapping
|
||||
public ResultDomain<TbChat> createChat(@RequestBody TbChat chat) {
|
||||
ValidationResult vr = ValidationUtils.validate(chat, Arrays.asList(
|
||||
ValidationUtils.requiredString("userId", "用户ID")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseChatService.createChat(chat);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新对话")
|
||||
@PutMapping
|
||||
public ResultDomain<TbChat> updateChat(@RequestBody TbChat chat) {
|
||||
ValidationResult vr = ValidationUtils.validate(chat, Arrays.asList(
|
||||
ValidationUtils.requiredString("chatId", "对话ID")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseChatService.updateChat(chat);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询对话列表")
|
||||
@PostMapping("/list")
|
||||
public ResultDomain<TbChat> getChatList(@RequestBody TbChat filter) {
|
||||
return workcaseChatService.getChatList(filter);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取对话消息列表")
|
||||
@PostMapping("/message/list")
|
||||
public ResultDomain<TbChatMessage> getChatMessageList(@RequestBody TbChat filter) {
|
||||
ValidationResult vr = ValidationUtils.validate(filter, Arrays.asList(
|
||||
ValidationUtils.requiredString("chatId", "对话ID")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseChatService.getChatMessageList(filter);
|
||||
}
|
||||
|
||||
@Operation(summary = "准备对话会话")
|
||||
@PostMapping("/prepare")
|
||||
public ResultDomain<String> prepareChatMessageSession(@RequestBody ChatPrepareData prepareData) {
|
||||
ValidationResult vr = ValidationUtils.validate(prepareData, Arrays.asList(
|
||||
ValidationUtils.requiredString("chatId", "对话ID"),
|
||||
ValidationUtils.requiredString("query", "用户问题")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseChatService.prepareChatMessageSession(prepareData);
|
||||
}
|
||||
|
||||
@Operation(summary = "流式对话(SSE)")
|
||||
@GetMapping(value = "/stream/{sessionId}", produces = "text/event-stream")
|
||||
public SseEmitter streamChatMessage(@PathVariable String sessionId) {
|
||||
return workcaseChatService.streamChatMessageWithSse(sessionId);
|
||||
}
|
||||
|
||||
@Operation(summary = "停止对话")
|
||||
@PostMapping("/stop/{taskId}")
|
||||
public ResultDomain<Boolean> stopChat(@RequestBody TbChat filter, @PathVariable String taskId) {
|
||||
return workcaseChatService.stopChatMessageByTaskId(filter, taskId);
|
||||
}
|
||||
|
||||
@Operation(summary = "评论对话消息")
|
||||
@PostMapping("/comment")
|
||||
public ResultDomain<Boolean> commentChatMessage(@RequestBody TbChat filter,
|
||||
@RequestParam String messageId, @RequestParam String comment) {
|
||||
return workcaseChatService.commentChatMessage(filter, messageId, comment);
|
||||
}
|
||||
|
||||
// ========================= 对话分析 =========================
|
||||
|
||||
@Operation(summary = "分析对话(AI预填工单信息)")
|
||||
@GetMapping("/analyze/{chatId}")
|
||||
public ResultDomain<TbWorkcaseDTO> analyzeChat(@PathVariable String chatId) {
|
||||
return workcaseChatService.analyzeChat(chatId);
|
||||
}
|
||||
|
||||
@Operation(summary = "总结对话")
|
||||
@PostMapping("/summary/{chatId}")
|
||||
public ResultDomain<TbWorkcaseDTO> summaryChat(@PathVariable String chatId) {
|
||||
return workcaseChatService.summaryChat(chatId);
|
||||
}
|
||||
|
||||
// ========================= 微信客服消息回调 =========================
|
||||
|
||||
@Operation(summary = "微信客服消息回调验证(GET)")
|
||||
@GetMapping("/kefu/callback")
|
||||
public String kefuCallbackVerify(
|
||||
@RequestParam("msg_signature") String msgSignature,
|
||||
@RequestParam("timestamp") String timestamp,
|
||||
@RequestParam("nonce") String nonce,
|
||||
@RequestParam("echostr") String echostr) {
|
||||
// TODO: 验证签名并返回 echostr
|
||||
// 实际应使用微信提供的加解密工具验证
|
||||
return echostr;
|
||||
}
|
||||
|
||||
@Operation(summary = "微信客服消息回调(POST)")
|
||||
@PostMapping("/kefu/callback")
|
||||
public String kefuCallback(
|
||||
@RequestParam("msg_signature") String msgSignature,
|
||||
@RequestParam("timestamp") String timestamp,
|
||||
@RequestParam("nonce") String nonce,
|
||||
@RequestBody String xmlBody) {
|
||||
// TODO: 解密消息,调用同步接口拉取消息
|
||||
// 收到回调后,应调用 kefuMessageService.syncMessages() 拉取新消息
|
||||
// 然后通过 processMessages() 处理消息
|
||||
return "success";
|
||||
}
|
||||
|
||||
@Operation(summary = "手动同步客服消息")
|
||||
@PostMapping("/kefu/sync")
|
||||
public ResultDomain<String> syncKefuMessages(
|
||||
@RequestParam(required = false) String cursor,
|
||||
@RequestParam(required = false) String token,
|
||||
@RequestParam(required = false, defaultValue = "100") Integer limit) {
|
||||
var response = kefuMessageService.syncMessages(cursor, token, limit);
|
||||
if (response != null && response.isSuccess()) {
|
||||
kefuMessageService.processMessages(response);
|
||||
return ResultDomain.success("同步成功", response.getNextCursor());
|
||||
}
|
||||
return ResultDomain.failure("同步失败");
|
||||
}
|
||||
|
||||
// ========================= 词云管理 =========================
|
||||
|
||||
@Operation(summary = "添加词云")
|
||||
@PostMapping("/wordcloud")
|
||||
public ResultDomain<TbWordCloudDTO> addWordCloud(@RequestBody TbWordCloudDTO wordCloud) {
|
||||
ValidationResult vr = ValidationUtils.validate(wordCloud, Arrays.asList(
|
||||
ValidationUtils.requiredString("word", "词语"),
|
||||
ValidationUtils.requiredString("category", "分类")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseChatService.addWordCloud(wordCloud);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新词云")
|
||||
@PutMapping("/wordcloud")
|
||||
public ResultDomain<TbWordCloudDTO> updateWordCloud(@RequestBody TbWordCloudDTO wordCloud) {
|
||||
ValidationResult vr = ValidationUtils.validate(wordCloud, Arrays.asList(
|
||||
ValidationUtils.requiredString("wordCloudId", "词云ID")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseChatService.updateWordCloud(wordCloud);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询词云列表")
|
||||
@PostMapping("/wordcloud/list")
|
||||
public ResultDomain<TbWordCloudDTO> getWordCloudList(@RequestBody TbWordCloudDTO filter) {
|
||||
return workcaseChatService.getWordCloudList(filter);
|
||||
}
|
||||
|
||||
@Operation(summary = "分页查询词云")
|
||||
@PostMapping("/wordcloud/page")
|
||||
public ResultDomain<TbWordCloudDTO> getWordCloudPage(@RequestBody PageRequest<TbWordCloudDTO> pageRequest) {
|
||||
ValidationResult vr = ValidationUtils.validate(pageRequest, Arrays.asList(
|
||||
ValidationUtils.requiredNumber("pageParam.page", "页码", 1, null),
|
||||
ValidationUtils.requiredNumber("pageParam.pageSize", "每页数量", 1, 100)
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseChatService.getWordCloudPage(pageRequest);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package org.xyzh.workcase.controller;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
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.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseDTO;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseDeviceDTO;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseProcessDTO;
|
||||
import org.xyzh.api.workcase.service.WorkcaseService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.utils.validation.ValidationResult;
|
||||
import org.xyzh.common.utils.validation.ValidationUtils;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
|
||||
import java.util.Arrays;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* @description 工单管理控制器
|
||||
* @filename WorkcaseController.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-19
|
||||
*/
|
||||
@Tag(name = "工单管理")
|
||||
@RestController
|
||||
@RequestMapping("/workcase")
|
||||
public class WorkcaseController {
|
||||
|
||||
@DubboReference(version = "1.0.0", group = "workcase", check = false)
|
||||
private WorkcaseService workcaseService;
|
||||
|
||||
// ========================= 工单管理 =========================
|
||||
|
||||
@Operation(summary = "创建工单")
|
||||
@PostMapping
|
||||
public ResultDomain<TbWorkcaseDTO> createWorkcase(@RequestBody TbWorkcaseDTO workcase) {
|
||||
ValidationResult vr = ValidationUtils.validate(workcase, Arrays.asList(
|
||||
ValidationUtils.requiredString("userId", "用户ID"),
|
||||
ValidationUtils.requiredString("type", "问题类型")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.createWorkcase(workcase);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新工单")
|
||||
@PutMapping
|
||||
public ResultDomain<TbWorkcaseDTO> updateWorkcase(@RequestBody TbWorkcaseDTO workcase) {
|
||||
ValidationResult vr = ValidationUtils.validate(workcase, Arrays.asList(
|
||||
ValidationUtils.requiredString("workcaseId", "工单ID")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.updateWorkcase(workcase);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除工单")
|
||||
@DeleteMapping("/{workcaseId}")
|
||||
public ResultDomain<TbWorkcaseDTO> deleteWorkcase(@PathVariable String workcaseId) {
|
||||
TbWorkcaseDTO workcase = new TbWorkcaseDTO();
|
||||
workcase.setWorkcaseId(workcaseId);
|
||||
return workcaseService.deleteWorkcase(workcase);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取工单详情")
|
||||
@GetMapping("/{workcaseId}")
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcaseById(@PathVariable String workcaseId) {
|
||||
return workcaseService.getWorkcaseById(workcaseId);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询工单列表")
|
||||
@PostMapping("/list")
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcaseList(@RequestBody TbWorkcaseDTO filter) {
|
||||
return workcaseService.getWorkcaseList(filter);
|
||||
}
|
||||
|
||||
@Operation(summary = "分页查询工单")
|
||||
@PostMapping("/page")
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcasePage(@RequestBody PageRequest<TbWorkcaseDTO> pageRequest) {
|
||||
ValidationResult vr = ValidationUtils.validate(pageRequest, Arrays.asList(
|
||||
ValidationUtils.requiredNumber("pageParam.page", "页码", 1, null),
|
||||
ValidationUtils.requiredNumber("pageParam.pageSize", "每页数量", 1, 100)
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.getWorkcasePage(pageRequest);
|
||||
}
|
||||
|
||||
// ========================= CRM同步接口 =========================
|
||||
|
||||
@Operation(summary = "同步工单到CRM")
|
||||
@PostMapping("/sync/crm")
|
||||
public ResultDomain<Void> syncWorkcaseToCrm(@RequestBody TbWorkcaseDTO workcase) {
|
||||
ValidationResult vr = ValidationUtils.validate(workcase, Arrays.asList(
|
||||
ValidationUtils.requiredString("workcaseId", "工单ID")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.syncWorkcaseToCrm(workcase);
|
||||
}
|
||||
|
||||
@Operation(summary = "接收CRM工单更新(CRM回调)")
|
||||
@PostMapping("/receive/crm")
|
||||
public ResultDomain<Void> receiveWorkcaseFromCrm(@RequestBody String jsonBody) {
|
||||
JSONObject json = JSONObject.parseObject(jsonBody);
|
||||
return workcaseService.receiveWorkcaseFromCrm(json);
|
||||
}
|
||||
|
||||
// ========================= 工单处理过程 =========================
|
||||
|
||||
@Operation(summary = "创建工单处理过程")
|
||||
@PostMapping("/process")
|
||||
public ResultDomain<TbWorkcaseProcessDTO> createWorkcaseProcess(@RequestBody TbWorkcaseProcessDTO process) {
|
||||
ValidationResult vr = ValidationUtils.validate(process, Arrays.asList(
|
||||
ValidationUtils.requiredString("workcaseId", "工单ID"),
|
||||
ValidationUtils.requiredString("action", "操作类型")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.createWorkcaseProcess(process);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新工单处理过程")
|
||||
@PutMapping("/process")
|
||||
public ResultDomain<TbWorkcaseProcessDTO> updateWorkcaseProcess(@RequestBody TbWorkcaseProcessDTO process) {
|
||||
ValidationResult vr = ValidationUtils.validate(process, Arrays.asList(
|
||||
ValidationUtils.requiredString("processId", "处理过程ID")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.updateWorkcaseProcess(process);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除工单处理过程")
|
||||
@DeleteMapping("/process/{processId}")
|
||||
public ResultDomain<TbWorkcaseProcessDTO> deleteWorkcaseProcess(@PathVariable String processId) {
|
||||
TbWorkcaseProcessDTO process = new TbWorkcaseProcessDTO();
|
||||
process.setProcessId(processId);
|
||||
return workcaseService.deleteWorkcaseProcess(process);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询工单处理过程列表")
|
||||
@PostMapping("/process/list")
|
||||
public ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessList(@RequestBody TbWorkcaseProcessDTO filter) {
|
||||
return workcaseService.getWorkcaseProcessList(filter);
|
||||
}
|
||||
|
||||
@Operation(summary = "分页查询工单处理过程")
|
||||
@PostMapping("/process/page")
|
||||
public ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessPage(@RequestBody PageRequest<TbWorkcaseProcessDTO> pageRequest) {
|
||||
ValidationResult vr = ValidationUtils.validate(pageRequest, Arrays.asList(
|
||||
ValidationUtils.requiredNumber("pageParam.page", "页码", 1, null),
|
||||
ValidationUtils.requiredNumber("pageParam.pageSize", "每页数量", 1, 100)
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.getWorkcaseProcessPage(pageRequest);
|
||||
}
|
||||
|
||||
// ========================= 工单设备管理 =========================
|
||||
|
||||
@Operation(summary = "创建工单设备")
|
||||
@PostMapping("/device")
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> createWorkcaseDevice(@RequestBody TbWorkcaseDeviceDTO device) {
|
||||
ValidationResult vr = ValidationUtils.validate(device, Arrays.asList(
|
||||
ValidationUtils.requiredString("workcaseId", "工单ID"),
|
||||
ValidationUtils.requiredString("device", "设备名称")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.createWorkcaseDevice(device);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新工单设备")
|
||||
@PutMapping("/device")
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> updateWorkcaseDevice(@RequestBody TbWorkcaseDeviceDTO device) {
|
||||
ValidationResult vr = ValidationUtils.validate(device, Arrays.asList(
|
||||
ValidationUtils.requiredString("workcaseId", "工单ID"),
|
||||
ValidationUtils.requiredString("device", "设备名称")
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.updateWorkcaseDevice(device);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除工单设备")
|
||||
@DeleteMapping("/device/{workcaseId}/{device}")
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> deleteWorkcaseDevice(@PathVariable String workcaseId, @PathVariable String device) {
|
||||
TbWorkcaseDeviceDTO deviceDTO = new TbWorkcaseDeviceDTO();
|
||||
deviceDTO.setWorkcaseId(workcaseId);
|
||||
deviceDTO.setDevice(device);
|
||||
return workcaseService.deleteWorkcaseDevice(deviceDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询工单设备列表")
|
||||
@PostMapping("/device/list")
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDeviceList(@RequestBody TbWorkcaseDeviceDTO filter) {
|
||||
return workcaseService.getWorkcaseDeviceList(filter);
|
||||
}
|
||||
|
||||
@Operation(summary = "分页查询工单设备")
|
||||
@PostMapping("/device/page")
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDevicePage(@RequestBody PageRequest<TbWorkcaseDeviceDTO> pageRequest) {
|
||||
ValidationResult vr = ValidationUtils.validate(pageRequest, Arrays.asList(
|
||||
ValidationUtils.requiredNumber("pageParam.page", "页码", 1, null),
|
||||
ValidationUtils.requiredNumber("pageParam.pageSize", "每页数量", 1, 100)
|
||||
));
|
||||
if (!vr.isValid()) {
|
||||
return ResultDomain.failure(vr.getAllErrors());
|
||||
}
|
||||
return workcaseService.getWorkcaseDevicePage(pageRequest);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package org.xyzh.workcase.handler;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.xyzh.api.ai.dto.TbChatMessage;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseDTO;
|
||||
import org.xyzh.api.workcase.service.WorkcaseChatService;
|
||||
import org.xyzh.api.workcase.service.WorkcaseService;
|
||||
import org.xyzh.common.wechat.kefu.message.KefuMessageHandler;
|
||||
import org.xyzh.common.wechat.kefu.message.KefuMessageService;
|
||||
import org.xyzh.common.wechat.pojo.kefu.KefuSyncMsgResponse.KefuSyncMsg;
|
||||
|
||||
/**
|
||||
* @description 工单模块的微信客服处理器实现
|
||||
* 处理微信客服消息,同步到工单系统
|
||||
* @filename WorkcaseKefuHandler.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-19
|
||||
*/
|
||||
@Component
|
||||
public class WorkcaseKefuHandler implements KefuMessageHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WorkcaseKefuHandler.class);
|
||||
|
||||
@Autowired
|
||||
private KefuMessageService kefuMessageService;
|
||||
|
||||
@DubboReference(version = "1.0.0", group = "workcase", check = false)
|
||||
private WorkcaseService workcaseService;
|
||||
|
||||
@DubboReference(version = "1.0.0", group = "workcase", check = false)
|
||||
private WorkcaseChatService workcaseChatService;
|
||||
|
||||
@Override
|
||||
public void onEnterSession(String openKfid, String externalUserid, String scene, String sceneParam, String welcomeCode) {
|
||||
logger.info("工单客服-用户进入会话: externalUserid={}, scene={}, sceneParam={}", externalUserid, scene, sceneParam);
|
||||
|
||||
// sceneParam 可能包含 workcaseId,用于关联工单
|
||||
if (sceneParam != null && !sceneParam.isEmpty()) {
|
||||
TbWorkcaseDTO filter = new TbWorkcaseDTO();
|
||||
filter.setWorkcaseId(sceneParam);
|
||||
var result = workcaseService.getWorkcaseById(sceneParam);
|
||||
|
||||
if (result != null && result.getSuccess() && result.getData() != null) {
|
||||
TbWorkcaseDTO workcase = result.getData();
|
||||
// 发送工单信息作为欢迎语
|
||||
String welcomeMsg = buildWelcomeMessage(workcase);
|
||||
kefuMessageService.sendWelcomeMessage(welcomeCode, welcomeMsg);
|
||||
logger.info("已发送工单欢迎语: workcaseId={}", workcase.getWorkcaseId());
|
||||
} else {
|
||||
// 发送通用欢迎语
|
||||
kefuMessageService.sendWelcomeMessage(welcomeCode, "您好,欢迎使用客服服务,请问有什么可以帮您?");
|
||||
}
|
||||
} else {
|
||||
kefuMessageService.sendWelcomeMessage(welcomeCode, "您好,欢迎使用客服服务,请问有什么可以帮您?");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextMessage(String openKfid, String externalUserid, String msgid, String content, Long sendTime) {
|
||||
logger.info("工单客服-收到文本消息: externalUserid={}, content={}", externalUserid, content);
|
||||
|
||||
// 同步消息到 tb_chat_message 表
|
||||
// TODO: 根据 externalUserid 查找关联的 chatId,然后保存消息
|
||||
TbChatMessage chatMessage = new TbChatMessage();
|
||||
chatMessage.setRole("user");
|
||||
chatMessage.setContent(content);
|
||||
// workcaseChatService.saveChatMessage(chatMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImageMessage(String openKfid, String externalUserid, String msgid, String mediaId, Long sendTime) {
|
||||
logger.info("工单客服-收到图片消息: externalUserid={}, mediaId={}", externalUserid, mediaId);
|
||||
|
||||
// 下载图片并保存
|
||||
// TODO: 实现图片消息处理
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStatusChange(String openKfid, String externalUserid, String changeType,
|
||||
String oldServicerUserid, String newServicerUserid) {
|
||||
logger.info("工单客服-会话状态变更: externalUserid={}, changeType={}, newServicer={}",
|
||||
externalUserid, changeType, newServicerUserid);
|
||||
|
||||
// 更新工单处理人
|
||||
// TODO: 根据 externalUserid 查找关联工单,更新 processor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsgSendFail(String openKfid, String externalUserid, String failMsgid, String failType) {
|
||||
logger.warn("工单客服-消息发送失败: externalUserid={}, failMsgid={}, failType={}",
|
||||
externalUserid, failMsgid, failType);
|
||||
|
||||
// 记录失败日志,可能需要重试
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOtherMessage(KefuSyncMsg msg) {
|
||||
logger.info("工单客服-收到其他消息: msgtype={}", msg.getMsgtype());
|
||||
}
|
||||
|
||||
private String buildWelcomeMessage(TbWorkcaseDTO workcase) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("您好,您的工单已创建。\n");
|
||||
sb.append("工单编号:").append(workcase.getWorkcaseId()).append("\n");
|
||||
if (workcase.getType() != null) {
|
||||
sb.append("问题类型:").append(workcase.getType()).append("\n");
|
||||
}
|
||||
if (workcase.getDevice() != null) {
|
||||
sb.append("设备:").append(workcase.getDevice()).append("\n");
|
||||
}
|
||||
sb.append("我们将尽快为您处理。");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.xyzh.workcase.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.api.workcase.dto.TbWordCloudDTO;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
|
||||
/**
|
||||
* @description 词云数据访问层
|
||||
* @filename TbWordCloudMapper.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-19
|
||||
*/
|
||||
@Mapper
|
||||
public interface TbWordCloudMapper {
|
||||
|
||||
/**
|
||||
* 插入词云
|
||||
*/
|
||||
int insertWordCloud(TbWordCloudDTO wordCloud);
|
||||
|
||||
/**
|
||||
* 更新词云(只更新非null字段)
|
||||
*/
|
||||
int updateWordCloud(TbWordCloudDTO wordCloud);
|
||||
|
||||
/**
|
||||
* 根据ID查询词云
|
||||
*/
|
||||
TbWordCloudDTO selectWordCloudById(@Param("wordId") String wordId);
|
||||
|
||||
/**
|
||||
* 查询单条词云(用于更新词频等场景)
|
||||
*/
|
||||
TbWordCloudDTO selectWordCloudOne(@Param("filter") TbWordCloudDTO filter);
|
||||
|
||||
/**
|
||||
* 查询词云列表
|
||||
*/
|
||||
List<TbWordCloudDTO> selectWordCloudList(@Param("filter") TbWordCloudDTO filter);
|
||||
|
||||
/**
|
||||
* 分页查询词云
|
||||
*/
|
||||
List<TbWordCloudDTO> selectWordCloudPage(@Param("filter") TbWordCloudDTO filter, @Param("pageParam") PageParam pageParam);
|
||||
|
||||
/**
|
||||
* 统计词云数量
|
||||
*/
|
||||
long countWordClouds(@Param("filter") TbWordCloudDTO filter);
|
||||
|
||||
/**
|
||||
* 增加词频
|
||||
*/
|
||||
int incrementFrequency(@Param("wordId") String wordId, @Param("count") int count);
|
||||
|
||||
}
|
||||
@@ -1,113 +1,294 @@
|
||||
package org.xyzh.workcase.service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
import org.xyzh.api.ai.dto.ChatPrepareData;
|
||||
import org.xyzh.api.ai.dto.TbChat;
|
||||
import org.xyzh.api.ai.dto.TbChatMessage;
|
||||
import org.xyzh.api.ai.service.AgentChatService;
|
||||
import org.xyzh.api.workcase.dto.TbWordCloudDTO;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseDTO;
|
||||
import org.xyzh.api.workcase.service.WorkcaseChatService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.redis.service.RedisService;
|
||||
import org.xyzh.common.utils.id.IdUtil;
|
||||
import org.xyzh.workcase.mapper.TbWordCloudMapper;
|
||||
|
||||
@DubboService(version = "1.0.0",group = "workcase",timeout = 30000,retries = 0)
|
||||
public class WorkcaseChatServiceImpl implements WorkcaseChatService{
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(WorkcaseChatServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWordCloudDTO> addWordCloud(TbWordCloudDTO wordCloud) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
private static final String CHAT_COUNT_KEY_PREFIX = "workcase:chat:count:";
|
||||
private static final int TRANSFER_HUMAN_THRESHOLD = 3;
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> analyzeChat(String chatId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@DubboReference(version = "1.0.0", group = "ai", check = false)
|
||||
private AgentChatService agentChatService;
|
||||
|
||||
@Override
|
||||
public ResultDomain<Boolean> commentChatMessage(TbChat filter, String messageId, String comment) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
@Autowired
|
||||
private TbWordCloudMapper wordCloudMapper;
|
||||
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
// ========================= 聊天管理 ==========================
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbChat> createChat(TbChat chat) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbChat> getChatList(TbChat filter) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbChatMessage> getChatMessageList(TbChat filter) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbChat> getChatPage(PageRequest<TbChat> pageRequest) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWordCloudDTO> getWordCloudList(TbWordCloudDTO filter) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWordCloudDTO> getWordCloudPage(PageRequest<TbWordCloudDTO> pageRequest) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<String> prepareChatMessageSession(ChatPrepareData prepareData) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Boolean> stopChatMessageByTaskId(TbChat filter, String taskId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SseEmitter streamChatMessageWithSse(String sessionId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> summaryChat(String chatId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
logger.info("创建对话: userId={}", chat.getUserId());
|
||||
ResultDomain<TbChat> result = agentChatService.createChat(chat);
|
||||
if (result.getSuccess() && result.getData() != null) {
|
||||
redisService.set(CHAT_COUNT_KEY_PREFIX + result.getData().getChatId(), 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbChat> updateChat(TbChat chat) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
logger.info("更新对话: chatId={}", chat.getChatId());
|
||||
return agentChatService.updateChat(chat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbChat> getChatList(TbChat filter) {
|
||||
return agentChatService.getChatList(filter);
|
||||
}
|
||||
|
||||
// ========================= 聊天信息管理 ======================
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbChatMessage> getChatMessageList(TbChat filter) {
|
||||
return agentChatService.getChatMessageList(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<String> prepareChatMessageSession(ChatPrepareData prepareData) {
|
||||
logger.info("准备对话会话: chatId={}, query={}", prepareData.getChatId(), prepareData.getQuery());
|
||||
|
||||
String chatId = prepareData.getChatId();
|
||||
Object countObj = redisService.get(CHAT_COUNT_KEY_PREFIX + chatId);
|
||||
int chatCount = (countObj != null) ? (Integer) countObj : 0;
|
||||
chatCount++;
|
||||
redisService.set(CHAT_COUNT_KEY_PREFIX + chatId, chatCount);
|
||||
|
||||
ResultDomain<String> result = agentChatService.prepareChatMessageSession(prepareData);
|
||||
|
||||
if (result.getSuccess() && chatCount >= TRANSFER_HUMAN_THRESHOLD) {
|
||||
logger.info("已达到{}次AI对话,建议转人工: chatId={}", TRANSFER_HUMAN_THRESHOLD, chatId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SseEmitter streamChatMessageWithSse(String sessionId) {
|
||||
return agentChatService.streamChatMessageWithSse(sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Boolean> stopChatMessageByTaskId(TbChat filter, String taskId) {
|
||||
return agentChatService.stopChatMessageByTaskId(filter, taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Boolean> commentChatMessage(TbChat filter, String messageId, String comment) {
|
||||
return agentChatService.commentChatMessage(filter, messageId, comment);
|
||||
}
|
||||
|
||||
// =============================== 对话分析 ==========================
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> analyzeChat(String chatId) {
|
||||
logger.info("分析对话内容,生成工单预填信息: chatId={}", chatId);
|
||||
|
||||
TbChat filter = new TbChat();
|
||||
filter.setChatId(chatId);
|
||||
ResultDomain<TbChatMessage> msgResult = agentChatService.getChatMessageList(filter);
|
||||
|
||||
if (!msgResult.getSuccess() || msgResult.getDataList() == null || msgResult.getDataList().isEmpty()) {
|
||||
return ResultDomain.failure("获取对话消息失败或消息为空");
|
||||
}
|
||||
|
||||
List<TbChatMessage> messages = msgResult.getDataList();
|
||||
|
||||
// ============== 伪代码:调用AI分析对话,自动生成工单预填信息 ==============
|
||||
// 步骤5:AI根据聊天对话,自动生成部分工单信息,预填入小程序的工单创建表单
|
||||
//
|
||||
// 1. 构建对话上下文
|
||||
// StringBuilder conversationContext = new StringBuilder();
|
||||
// for (TbChatMessage msg : messages) {
|
||||
// conversationContext.append(msg.getRole()).append(": ").append(msg.getContent()).append("\n");
|
||||
// }
|
||||
//
|
||||
// 2. 调用Dify工作流或Agent进行对话分析
|
||||
// DifyWorkflowRequest request = new DifyWorkflowRequest();
|
||||
// request.setWorkflowId("workcase-analysis-workflow");
|
||||
// request.setInputs(Map.of("conversation", conversationContext.toString()));
|
||||
// DifyWorkflowResponse response = difyService.runWorkflow(request);
|
||||
//
|
||||
// 3. 解析AI分析结果,提取工单预填信息
|
||||
// JSONObject analysisResult = JSON.parseObject(response.getOutputs());
|
||||
// TbWorkcaseDTO workcase = new TbWorkcaseDTO();
|
||||
// workcase.setType(analysisResult.getString("type")); // 问题类型:如"设备故障"、"维修申请"
|
||||
// workcase.setDevice(analysisResult.getString("device")); // 设备名称:如"燃气管道"、"电梯"
|
||||
// workcase.setDeviceCode(analysisResult.getString("deviceCode")); // 设备编号(如果用户提到)
|
||||
// workcase.setEmergency(analysisResult.getString("emergency")); // 紧急程度:normal/urgent/critical
|
||||
// workcase.setRemark(analysisResult.getString("description")); // 问题描述摘要
|
||||
// ============== 伪代码结束 ==============
|
||||
|
||||
// 模拟AI分析结果(实际应由AI返回)
|
||||
TbWorkcaseDTO workcase = new TbWorkcaseDTO();
|
||||
workcase.setType("设备故障");
|
||||
workcase.setDevice("待用户确认");
|
||||
workcase.setDeviceCode("");
|
||||
workcase.setEmergency("normal");
|
||||
workcase.setRemark("对话ID:" + chatId + " | " + buildConversationSummary(messages));
|
||||
|
||||
logger.info("对话分析完成,工单预填信息已生成: chatId={}", chatId);
|
||||
return ResultDomain.success("对话分析完成", workcase);
|
||||
}
|
||||
|
||||
private String buildConversationSummary(List<TbChatMessage> messages) {
|
||||
StringBuilder summary = new StringBuilder();
|
||||
for (TbChatMessage msg : messages) {
|
||||
if ("user".equals(msg.getRole())) {
|
||||
summary.append(msg.getContent()).append(" ");
|
||||
}
|
||||
}
|
||||
String result = summary.toString().trim();
|
||||
return result.length() > 200 ? result.substring(0, 200) + "..." : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> summaryChat(String chatId) {
|
||||
logger.info("总结对话: chatId={}", chatId);
|
||||
|
||||
TbChat filter = new TbChat();
|
||||
filter.setChatId(chatId);
|
||||
ResultDomain<TbChatMessage> msgResult = agentChatService.getChatMessageList(filter);
|
||||
|
||||
if (!msgResult.getSuccess() || msgResult.getDataList() == null) {
|
||||
return ResultDomain.failure("获取对话消息失败");
|
||||
}
|
||||
|
||||
List<TbChatMessage> messages = msgResult.getDataList();
|
||||
|
||||
// TODO: 调用AI进行对话总结,提取关键词更新词云
|
||||
// 伪代码:
|
||||
// String summary = aiService.summarize(messages);
|
||||
// List<String> keywords = aiService.extractKeywords(messages);
|
||||
// updateWordCloud(keywords);
|
||||
|
||||
extractAndUpdateWordCloud(messages);
|
||||
|
||||
TbWorkcaseDTO summary = new TbWorkcaseDTO();
|
||||
logger.info("对话总结完成: chatId={}", chatId);
|
||||
return ResultDomain.success("对话总结完成", summary);
|
||||
}
|
||||
|
||||
private void extractAndUpdateWordCloud(List<TbChatMessage> messages) {
|
||||
// TODO: 调用AI提取关键词
|
||||
// 伪代码:List<String> keywords = aiService.extractKeywords(messages);
|
||||
|
||||
// 模拟提取的关键词
|
||||
String[] mockKeywords = {"故障", "维修", "设备"};
|
||||
String today = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
|
||||
|
||||
for (String keyword : mockKeywords) {
|
||||
TbWordCloudDTO queryFilter = new TbWordCloudDTO();
|
||||
queryFilter.setWord(keyword);
|
||||
queryFilter.setCategory("fault");
|
||||
queryFilter.setStatDate(today);
|
||||
TbWordCloudDTO existing = wordCloudMapper.selectWordCloudOne(queryFilter);
|
||||
if (existing != null) {
|
||||
wordCloudMapper.incrementFrequency(existing.getWordId(), 1);
|
||||
} else {
|
||||
TbWordCloudDTO wordCloud = new TbWordCloudDTO();
|
||||
wordCloud.setWordId(IdUtil.generateUUID());
|
||||
wordCloud.setWord(keyword);
|
||||
wordCloud.setCategory("fault");
|
||||
wordCloud.setStatDate(today);
|
||||
wordCloud.setFrequency("1");
|
||||
wordCloudMapper.insertWordCloud(wordCloud);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============================== 词云管理 ==========================
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWordCloudDTO> addWordCloud(TbWordCloudDTO wordCloud) {
|
||||
logger.info("添加词云: word={}", wordCloud.getWord());
|
||||
|
||||
if (wordCloud.getWordId() == null || wordCloud.getWordId().isEmpty()) {
|
||||
wordCloud.setWordId(IdUtil.generateUUID());
|
||||
}
|
||||
if (wordCloud.getStatDate() == null || wordCloud.getStatDate().isEmpty()) {
|
||||
wordCloud.setStatDate(LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE));
|
||||
}
|
||||
if (wordCloud.getFrequency() == null) {
|
||||
wordCloud.setFrequency("1");
|
||||
}
|
||||
|
||||
TbWordCloudDTO queryFilter = new TbWordCloudDTO();
|
||||
queryFilter.setWord(wordCloud.getWord());
|
||||
queryFilter.setCategory(wordCloud.getCategory());
|
||||
queryFilter.setStatDate(wordCloud.getStatDate());
|
||||
TbWordCloudDTO existing = wordCloudMapper.selectWordCloudOne(queryFilter);
|
||||
|
||||
if (existing != null) {
|
||||
wordCloudMapper.incrementFrequency(existing.getWordId(), Integer.parseInt(wordCloud.getFrequency()));
|
||||
TbWordCloudDTO updated = wordCloudMapper.selectWordCloudById(existing.getWordId());
|
||||
return ResultDomain.success("词频更新成功", updated);
|
||||
}
|
||||
|
||||
int rows = wordCloudMapper.insertWordCloud(wordCloud);
|
||||
if (rows > 0) {
|
||||
return ResultDomain.success("添加成功", wordCloud);
|
||||
}
|
||||
return ResultDomain.failure("添加失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWordCloudDTO> updateWordCloud(TbWordCloudDTO wordCloud) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
logger.info("更新词云: wordId={}", wordCloud.getWordId());
|
||||
|
||||
int rows = wordCloudMapper.updateWordCloud(wordCloud);
|
||||
if (rows > 0) {
|
||||
TbWordCloudDTO updated = wordCloudMapper.selectWordCloudById(wordCloud.getWordId());
|
||||
return ResultDomain.success("更新成功", updated);
|
||||
}
|
||||
return ResultDomain.failure("更新失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWordCloudDTO> getWordCloudList(TbWordCloudDTO filter) {
|
||||
List<TbWordCloudDTO> list = wordCloudMapper.selectWordCloudList(filter);
|
||||
return ResultDomain.success("查询成功", list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWordCloudDTO> getWordCloudPage(PageRequest<TbWordCloudDTO> pageRequest) {
|
||||
TbWordCloudDTO filter = pageRequest.getFilter();
|
||||
PageParam pageParam = pageRequest.getPageParam();
|
||||
|
||||
List<TbWordCloudDTO> list = wordCloudMapper.selectWordCloudPage(filter, pageParam);
|
||||
long total = wordCloudMapper.countWordClouds(filter);
|
||||
|
||||
pageParam.setTotal((int) total);
|
||||
PageDomain<TbWordCloudDTO> pageDomain = new PageDomain<>(pageParam, list);
|
||||
return ResultDomain.success("查询成功", pageDomain);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,128 +1,435 @@
|
||||
package org.xyzh.workcase.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseDTO;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseDeviceDTO;
|
||||
import org.xyzh.api.workcase.dto.TbWorkcaseProcessDTO;
|
||||
import org.xyzh.api.workcase.service.WorkcaseChatService;
|
||||
import org.xyzh.api.workcase.service.WorkcaseService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.utils.id.IdUtil;
|
||||
import org.xyzh.workcase.enums.WorkcaseProcessAction;
|
||||
import org.xyzh.workcase.mapper.TbWorkcaseDeviceMapper;
|
||||
import org.xyzh.workcase.mapper.TbWorkcaseMapper;
|
||||
import org.xyzh.workcase.mapper.TbWorkcaseProcessMapper;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
@DubboService(version = "1.0.0",group = "workcase",timeout = 30000,retries = 0)
|
||||
public class WorkcaseServiceImpl implements WorkcaseService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(WorkcaseServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
private TbWorkcaseMapper workcaseMapper;
|
||||
|
||||
@Autowired
|
||||
private TbWorkcaseProcessMapper workcaseProcessMapper;
|
||||
|
||||
@Autowired
|
||||
private TbWorkcaseDeviceMapper workcaseDeviceMapper;
|
||||
|
||||
@DubboReference(version = "1.0.0", group = "workcase", check = false)
|
||||
private WorkcaseChatService workcaseChatService;
|
||||
|
||||
// ====================== 工单管理 ======================
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> createWorkcase(TbWorkcaseDTO workcase) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> createWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> createWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> deleteWorkcase(TbWorkcaseDTO workcase) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> deleteWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> deleteWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcaseById(String workcaseId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDeviceList(TbWorkcaseDeviceDTO filter) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDevicePage(PageRequest<TbWorkcaseDeviceDTO> pageRequest) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcaseList(TbWorkcaseDTO filter) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcasePage(PageRequest<TbWorkcaseDTO> pageRequest) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessList(TbWorkcaseProcessDTO filter) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessPage(PageRequest<TbWorkcaseProcessDTO> pageRequest) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Void> receiveWorkcaseFromCrm(JSON json) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Void> syncWorkcaseToCrm(TbWorkcaseDTO workcase) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
logger.info("创建工单: userId={}, type={}", workcase.getUserId(), workcase.getType());
|
||||
|
||||
if (workcase.getWorkcaseId() == null || workcase.getWorkcaseId().isEmpty()) {
|
||||
workcase.setWorkcaseId(IdUtil.generateUUID());
|
||||
}
|
||||
if (workcase.getOptsn() == null || workcase.getOptsn().isEmpty()) {
|
||||
workcase.setOptsn(IdUtil.getOptsn());
|
||||
}
|
||||
if (workcase.getStatus() == null || workcase.getStatus().isEmpty()) {
|
||||
workcase.setStatus("pending");
|
||||
}
|
||||
if (workcase.getEmergency() == null || workcase.getEmergency().isEmpty()) {
|
||||
workcase.setEmergency("normal");
|
||||
}
|
||||
|
||||
int rows = workcaseMapper.insertWorkcase(workcase);
|
||||
if (rows > 0) {
|
||||
TbWorkcaseProcessDTO process = new TbWorkcaseProcessDTO();
|
||||
process.setProcessId(IdUtil.generateUUID());
|
||||
process.setOptsn(IdUtil.getOptsn());
|
||||
process.setWorkcaseId(workcase.getWorkcaseId());
|
||||
process.setAction(WorkcaseProcessAction.INFO.getName());
|
||||
process.setMessage("工单创建");
|
||||
process.setCreator(workcase.getCreator());
|
||||
workcaseProcessMapper.insertWorkcaseProcess(process);
|
||||
|
||||
syncWorkcaseToCrm(workcase);
|
||||
sendWechatKefuWelcome(workcase);
|
||||
|
||||
return ResultDomain.success("创建成功", workcase);
|
||||
}
|
||||
return ResultDomain.failure("创建失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> updateWorkcase(TbWorkcaseDTO workcase) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
logger.info("更新工单: workcaseId={}, status={}", workcase.getWorkcaseId(), workcase.getStatus());
|
||||
|
||||
TbWorkcaseDTO existing = workcaseMapper.selectWorkcaseById(workcase.getWorkcaseId());
|
||||
if (existing == null) {
|
||||
return ResultDomain.failure("工单不存在");
|
||||
}
|
||||
|
||||
String oldStatus = existing.getStatus();
|
||||
int rows = workcaseMapper.updateWorkcase(workcase);
|
||||
|
||||
if (rows > 0) {
|
||||
TbWorkcaseDTO updated = workcaseMapper.selectWorkcaseById(workcase.getWorkcaseId());
|
||||
|
||||
if (workcase.getStatus() != null && !workcase.getStatus().equals(oldStatus)) {
|
||||
TbWorkcaseProcessDTO process = new TbWorkcaseProcessDTO();
|
||||
process.setProcessId(IdUtil.generateUUID());
|
||||
process.setOptsn(IdUtil.getOptsn());
|
||||
process.setWorkcaseId(workcase.getWorkcaseId());
|
||||
process.setCreator(workcase.getCreator());
|
||||
|
||||
if ("done".equals(workcase.getStatus())) {
|
||||
process.setAction(WorkcaseProcessAction.FINISH.getName());
|
||||
process.setMessage("工单完成");
|
||||
workcaseChatService.summaryChat(existing.getWorkcaseId());
|
||||
} else if ("cancelled".equals(workcase.getStatus())) {
|
||||
process.setAction(WorkcaseProcessAction.REPEAL.getName());
|
||||
process.setMessage("工单撤销");
|
||||
workcaseChatService.summaryChat(existing.getWorkcaseId());
|
||||
} else {
|
||||
process.setAction(WorkcaseProcessAction.INFO.getName());
|
||||
process.setMessage("状态变更: " + oldStatus + " -> " + workcase.getStatus());
|
||||
}
|
||||
workcaseProcessMapper.insertWorkcaseProcess(process);
|
||||
}
|
||||
|
||||
syncWorkcaseToCrm(updated);
|
||||
|
||||
return ResultDomain.success("更新成功", updated);
|
||||
}
|
||||
return ResultDomain.failure("更新失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> updateWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
public ResultDomain<TbWorkcaseDTO> deleteWorkcase(TbWorkcaseDTO workcase) {
|
||||
logger.info("删除工单: workcaseId={}", workcase.getWorkcaseId());
|
||||
|
||||
int rows = workcaseMapper.deleteWorkcase(workcase);
|
||||
if (rows > 0) {
|
||||
return ResultDomain.success("删除成功", workcase);
|
||||
}
|
||||
return ResultDomain.failure("删除失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcaseById(String workcaseId) {
|
||||
TbWorkcaseDTO workcase = workcaseMapper.selectWorkcaseById(workcaseId);
|
||||
if (workcase != null) {
|
||||
return ResultDomain.success("查询成功", workcase);
|
||||
}
|
||||
return ResultDomain.failure("工单不存在");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcaseList(TbWorkcaseDTO filter) {
|
||||
List<TbWorkcaseDTO> list = workcaseMapper.selectWorkcaseList(filter);
|
||||
return ResultDomain.success("查询成功", list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDTO> getWorkcasePage(PageRequest<TbWorkcaseDTO> pageRequest) {
|
||||
TbWorkcaseDTO filter = pageRequest.getFilter();
|
||||
PageParam pageParam = pageRequest.getPageParam();
|
||||
|
||||
List<TbWorkcaseDTO> list = workcaseMapper.selectWorkcasePage(filter, pageParam);
|
||||
long total = workcaseMapper.countWorkcases(filter);
|
||||
|
||||
pageParam.setTotal((int) total);
|
||||
PageDomain<TbWorkcaseDTO> pageDomain = new PageDomain<>(pageParam, list);
|
||||
return ResultDomain.success("查询成功", pageDomain);
|
||||
}
|
||||
|
||||
// ====================== 同步到CRM和接收 ===================
|
||||
|
||||
@Override
|
||||
public ResultDomain<Void> syncWorkcaseToCrm(TbWorkcaseDTO workcase) {
|
||||
logger.info("同步工单到CRM: workcaseId={}", workcase.getWorkcaseId());
|
||||
|
||||
// ============== 伪代码:同步工单到CRM系统 ==============
|
||||
// 1. 构建CRM请求数据
|
||||
// JSONObject crmData = new JSONObject();
|
||||
// crmData.put("workcaseId", workcase.getWorkcaseId());
|
||||
// crmData.put("userId", workcase.getUserId());
|
||||
// crmData.put("username", workcase.getUsername());
|
||||
// crmData.put("phone", workcase.getPhone());
|
||||
// crmData.put("type", workcase.getType());
|
||||
// crmData.put("device", workcase.getDevice());
|
||||
// crmData.put("deviceCode", workcase.getDeviceCode());
|
||||
// crmData.put("emergency", workcase.getEmergency());
|
||||
// crmData.put("status", workcase.getStatus());
|
||||
// crmData.put("createTime", workcase.getCreateTime());
|
||||
|
||||
// 2. 调用CRM接口
|
||||
// String crmApiUrl = "https://crm.example.com/api/workcase/sync";
|
||||
// HttpHeaders headers = new HttpHeaders();
|
||||
// headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
// headers.set("Authorization", "Bearer " + crmToken);
|
||||
// HttpEntity<String> request = new HttpEntity<>(crmData.toJSONString(), headers);
|
||||
// ResponseEntity<String> response = restTemplate.postForEntity(crmApiUrl, request, String.class);
|
||||
|
||||
// 3. 处理响应
|
||||
// if (response.getStatusCode() == HttpStatus.OK) {
|
||||
// JSONObject result = JSON.parseObject(response.getBody());
|
||||
// String crmWorkcaseId = result.getString("crmWorkcaseId");
|
||||
// logger.info("同步成功,CRM工单ID: {}", crmWorkcaseId);
|
||||
// } else {
|
||||
// logger.error("同步失败: {}", response.getBody());
|
||||
// return ResultDomain.failure("同步CRM失败");
|
||||
// }
|
||||
// ============== 伪代码结束 ==============
|
||||
|
||||
logger.info("CRM同步完成(伪代码): workcaseId={}", workcase.getWorkcaseId());
|
||||
return ResultDomain.success("同步成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<Void> receiveWorkcaseFromCrm(JSONObject json) {
|
||||
logger.info("接收CRM工单更新");
|
||||
|
||||
// ============== 伪代码:接收CRM的工单处理结果 ==============
|
||||
// 1. 解析CRM推送的数据
|
||||
// JSONObject crmData = (JSONObject) json;
|
||||
// String workcaseId = crmData.getString("workcaseId");
|
||||
// String status = crmData.getString("status");
|
||||
// String processor = crmData.getString("processor");
|
||||
// String message = crmData.getString("message");
|
||||
|
||||
// 2. 更新本地工单
|
||||
// TbWorkcaseDTO workcase = new TbWorkcaseDTO();
|
||||
// workcase.setWorkcaseId(workcaseId);
|
||||
// workcase.setStatus(status);
|
||||
// workcase.setProcessor(processor);
|
||||
// workcaseMapper.updateWorkcase(workcase);
|
||||
|
||||
// 3. 记录处理过程
|
||||
// TbWorkcaseProcessDTO process = new TbWorkcaseProcessDTO();
|
||||
// process.setProcessId(UUID.randomUUID().toString().replace("-", ""));
|
||||
// process.setOptsn(SnowflakeIdUtil.nextIdStr());
|
||||
// process.setWorkcaseId(workcaseId);
|
||||
// process.setAction(WorkcaseProcessAction.INFO.getName());
|
||||
// process.setMessage("CRM更新: " + message);
|
||||
// process.setProcessor(processor);
|
||||
// process.setCreator("CRM_SYSTEM");
|
||||
// workcaseProcessMapper.insertWorkcaseProcess(process);
|
||||
|
||||
// 4. 如果工单完成或撤销,触发总结
|
||||
// if ("done".equals(status) || "cancelled".equals(status)) {
|
||||
// workcaseChatService.summaryChat(workcaseId);
|
||||
// }
|
||||
// ============== 伪代码结束 ==============
|
||||
|
||||
logger.info("CRM工单接收处理完成(伪代码)");
|
||||
return ResultDomain.success("接收成功");
|
||||
}
|
||||
|
||||
private void sendWechatKefuWelcome(TbWorkcaseDTO workcase) {
|
||||
logger.info("发送微信客服欢迎语: workcaseId={}", workcase.getWorkcaseId());
|
||||
|
||||
// ============== 伪代码:发送微信客服欢迎语 ==============
|
||||
// 1. 构建欢迎语内容(包含工单基本信息)
|
||||
// StringBuilder welcomeMsg = new StringBuilder();
|
||||
// welcomeMsg.append("【工单信息】\n");
|
||||
// welcomeMsg.append("工单编号:").append(workcase.getOptsn()).append("\n");
|
||||
// welcomeMsg.append("故障类型:").append(workcase.getType()).append("\n");
|
||||
// welcomeMsg.append("设备名称:").append(workcase.getDevice()).append("\n");
|
||||
// welcomeMsg.append("紧急程度:").append("emergency".equals(workcase.getEmergency()) ? "紧急" : "普通").append("\n");
|
||||
// welcomeMsg.append("联系人:").append(workcase.getUsername()).append("\n");
|
||||
// welcomeMsg.append("联系电话:").append(workcase.getPhone()).append("\n");
|
||||
// welcomeMsg.append("\n客服将尽快为您处理,请稍候...");
|
||||
|
||||
// 2. 获取微信客服接入链接
|
||||
// String kefuUrl = wechatKefuService.getKefuUrl(workcase.getUserId());
|
||||
|
||||
// 3. 调用微信客服API发送欢迎语
|
||||
// JSONObject msgBody = new JSONObject();
|
||||
// msgBody.put("touser", workcase.getUserId()); // 微信openid
|
||||
// msgBody.put("msgtype", "text");
|
||||
// JSONObject textContent = new JSONObject();
|
||||
// textContent.put("content", welcomeMsg.toString());
|
||||
// msgBody.put("text", textContent);
|
||||
|
||||
// String accessToken = wechatService.getAccessToken();
|
||||
// String apiUrl = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;
|
||||
// restTemplate.postForEntity(apiUrl, msgBody.toJSONString(), String.class);
|
||||
|
||||
// 4. 记录客服会话开始
|
||||
// wechatKefuService.startSession(workcase.getUserId(), workcase.getWorkcaseId());
|
||||
// ============== 伪代码结束 ==============
|
||||
|
||||
logger.info("微信客服欢迎语发送完成(伪代码): workcaseId={}", workcase.getWorkcaseId());
|
||||
}
|
||||
|
||||
// ====================== 工单处理过程 ======================
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> createWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess) {
|
||||
logger.info("创建工单过程: workcaseId={}, action={}", workcaseProcess.getWorkcaseId(), workcaseProcess.getAction());
|
||||
|
||||
if (workcaseProcess.getProcessId() == null || workcaseProcess.getProcessId().isEmpty()) {
|
||||
workcaseProcess.setProcessId(IdUtil.generateUUID());
|
||||
}
|
||||
if (workcaseProcess.getOptsn() == null || workcaseProcess.getOptsn().isEmpty()) {
|
||||
workcaseProcess.setOptsn(IdUtil.getOptsn());
|
||||
}
|
||||
|
||||
String action = workcaseProcess.getAction();
|
||||
if (WorkcaseProcessAction.ASSIGN.getName().equals(action) ||
|
||||
WorkcaseProcessAction.REDEPLOY.getName().equals(action)) {
|
||||
if (workcaseProcess.getProcessor() != null) {
|
||||
TbWorkcaseDTO workcase = new TbWorkcaseDTO();
|
||||
workcase.setWorkcaseId(workcaseProcess.getWorkcaseId());
|
||||
workcase.setProcessor(workcaseProcess.getProcessor());
|
||||
workcase.setStatus("processing");
|
||||
workcaseMapper.updateWorkcase(workcase);
|
||||
}
|
||||
} else if (WorkcaseProcessAction.FINISH.getName().equals(action)) {
|
||||
TbWorkcaseDTO workcase = new TbWorkcaseDTO();
|
||||
workcase.setWorkcaseId(workcaseProcess.getWorkcaseId());
|
||||
workcase.setStatus("done");
|
||||
workcaseMapper.updateWorkcase(workcase);
|
||||
workcaseChatService.summaryChat(workcaseProcess.getWorkcaseId());
|
||||
} else if (WorkcaseProcessAction.REPEAL.getName().equals(action)) {
|
||||
TbWorkcaseDTO workcase = new TbWorkcaseDTO();
|
||||
workcase.setWorkcaseId(workcaseProcess.getWorkcaseId());
|
||||
workcase.setStatus("cancelled");
|
||||
workcaseMapper.updateWorkcase(workcase);
|
||||
workcaseChatService.summaryChat(workcaseProcess.getWorkcaseId());
|
||||
}
|
||||
|
||||
int rows = workcaseProcessMapper.insertWorkcaseProcess(workcaseProcess);
|
||||
if (rows > 0) {
|
||||
TbWorkcaseDTO workcase = workcaseMapper.selectWorkcaseById(workcaseProcess.getWorkcaseId());
|
||||
if (workcase != null) {
|
||||
syncWorkcaseToCrm(workcase);
|
||||
}
|
||||
return ResultDomain.success("创建成功", workcaseProcess);
|
||||
}
|
||||
return ResultDomain.failure("创建失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> updateWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
logger.info("更新工单过程: processId={}", workcaseProcess.getProcessId());
|
||||
|
||||
int rows = workcaseProcessMapper.updateWorkcaseProcess(workcaseProcess);
|
||||
if (rows > 0) {
|
||||
TbWorkcaseProcessDTO updated = workcaseProcessMapper.selectWorkcaseProcessById(workcaseProcess.getProcessId());
|
||||
return ResultDomain.success("更新成功", updated);
|
||||
}
|
||||
return ResultDomain.failure("更新失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> deleteWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess) {
|
||||
logger.info("删除工单过程: processId={}", workcaseProcess.getProcessId());
|
||||
|
||||
int rows = workcaseProcessMapper.deleteWorkcaseProcess(workcaseProcess.getProcessId());
|
||||
if (rows > 0) {
|
||||
return ResultDomain.success("删除成功", workcaseProcess);
|
||||
}
|
||||
return ResultDomain.failure("删除失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessList(TbWorkcaseProcessDTO filter) {
|
||||
List<TbWorkcaseProcessDTO> list = workcaseProcessMapper.selectWorkcaseProcessList(filter);
|
||||
return ResultDomain.success("查询成功", list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessPage(PageRequest<TbWorkcaseProcessDTO> pageRequest) {
|
||||
TbWorkcaseProcessDTO filter = pageRequest.getFilter();
|
||||
PageParam pageParam = pageRequest.getPageParam();
|
||||
|
||||
List<TbWorkcaseProcessDTO> list = workcaseProcessMapper.selectWorkcaseProcessPage(filter, pageParam);
|
||||
long total = workcaseProcessMapper.countWorkcaseProcesses(filter);
|
||||
|
||||
pageParam.setTotal((int) total);
|
||||
PageDomain<TbWorkcaseProcessDTO> pageDomain = new PageDomain<>(pageParam, list);
|
||||
return ResultDomain.success("查询成功", pageDomain);
|
||||
}
|
||||
|
||||
// ====================== 工单设备管理 ======================
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> createWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice) {
|
||||
logger.info("创建工单设备: workcaseId={}, device={}", workcaseDevice.getWorkcaseId(), workcaseDevice.getDevice());
|
||||
|
||||
if (workcaseDevice.getOptsn() == null || workcaseDevice.getOptsn().isEmpty()) {
|
||||
workcaseDevice.setOptsn(IdUtil.getOptsn());
|
||||
}
|
||||
|
||||
int rows = workcaseDeviceMapper.insertWorkcaseDevice(workcaseDevice);
|
||||
if (rows > 0) {
|
||||
return ResultDomain.success("创建成功", workcaseDevice);
|
||||
}
|
||||
return ResultDomain.failure("创建失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> updateWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice) {
|
||||
logger.info("更新工单设备: workcaseId={}, fileId={}", workcaseDevice.getWorkcaseId(), workcaseDevice.getFileId());
|
||||
|
||||
int rows = workcaseDeviceMapper.updateWorkcaseDevice(workcaseDevice);
|
||||
if (rows > 0) {
|
||||
TbWorkcaseDeviceDTO updated = workcaseDeviceMapper.selectWorkcaseDeviceById(
|
||||
workcaseDevice.getWorkcaseId(), workcaseDevice.getFileId());
|
||||
return ResultDomain.success("更新成功", updated);
|
||||
}
|
||||
return ResultDomain.failure("更新失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> deleteWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice) {
|
||||
logger.info("删除工单设备: workcaseId={}, fileId={}", workcaseDevice.getWorkcaseId(), workcaseDevice.getFileId());
|
||||
|
||||
int rows = workcaseDeviceMapper.deleteWorkcaseDevice(workcaseDevice.getWorkcaseId(), workcaseDevice.getFileId());
|
||||
if (rows > 0) {
|
||||
return ResultDomain.success("删除成功", workcaseDevice);
|
||||
}
|
||||
return ResultDomain.failure("删除失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDeviceList(TbWorkcaseDeviceDTO filter) {
|
||||
List<TbWorkcaseDeviceDTO> list = workcaseDeviceMapper.selectWorkcaseDeviceList(filter);
|
||||
return ResultDomain.success("查询成功", list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDevicePage(PageRequest<TbWorkcaseDeviceDTO> pageRequest) {
|
||||
TbWorkcaseDeviceDTO filter = pageRequest.getFilter();
|
||||
PageParam pageParam = pageRequest.getPageParam();
|
||||
|
||||
List<TbWorkcaseDeviceDTO> list = workcaseDeviceMapper.selectWorkcaseDevicePage(filter, pageParam);
|
||||
long total = workcaseDeviceMapper.countWorkcaseDevices(filter);
|
||||
|
||||
pageParam.setTotal((int) total);
|
||||
PageDomain<TbWorkcaseDeviceDTO> pageDomain = new PageDomain<>(pageParam, list);
|
||||
return ResultDomain.success("查询成功", pageDomain);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,18 +5,22 @@ server:
|
||||
# context-path: /urban-lifeline/workcase # 微服务架构下,context-path由Gateway管理
|
||||
|
||||
# ================== Auth ====================
|
||||
urban-lifeline:
|
||||
auth:
|
||||
enabled: true
|
||||
whitelist:
|
||||
- /swagger-ui/**
|
||||
- /swagger-ui.html
|
||||
- /v3/api-docs/**
|
||||
- /webjars/**
|
||||
- /favicon.ico
|
||||
- /error
|
||||
- /actuator/health
|
||||
- /actuator/info
|
||||
auth:
|
||||
enabled: true
|
||||
gate-way: true
|
||||
whitelist:
|
||||
- /swagger-ui/**
|
||||
- /swagger-ui.html
|
||||
- /v3/api-docs/**
|
||||
- /webjars/**
|
||||
- /favicon.ico
|
||||
- /error
|
||||
- /actuator/health
|
||||
- /actuator/info
|
||||
# 微信客服回调接口(无需鉴权)
|
||||
- /workcase/chat/kefu/callback
|
||||
# CRM回调接口(无需鉴权,但需签名验证)
|
||||
- /workcase/receive/crm
|
||||
|
||||
security:
|
||||
aes:
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
<?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="org.xyzh.workcase.mapper.TbWordCloudMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="org.xyzh.api.workcase.dto.TbWordCloudDTO">
|
||||
<id column="word_id" property="wordId" jdbcType="VARCHAR"/>
|
||||
<result column="word" property="word" jdbcType="VARCHAR"/>
|
||||
<result column="frequency" property="frequency" jdbcType="VARCHAR"/>
|
||||
<result column="category" property="category" jdbcType="VARCHAR"/>
|
||||
<result column="stat_date" property="statDate" jdbcType="VARCHAR"/>
|
||||
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
word_id, word, frequency, category, stat_date, create_time, update_time
|
||||
</sql>
|
||||
|
||||
<insert id="insertWordCloud" parameterType="org.xyzh.api.workcase.dto.TbWordCloudDTO">
|
||||
INSERT INTO workcase.tb_word_cloud (
|
||||
word_id, word, stat_date
|
||||
<if test="frequency != null">, frequency</if>
|
||||
<if test="category != null">, category</if>
|
||||
) VALUES (
|
||||
#{wordId}, #{word}, #{statDate}::date
|
||||
<if test="frequency != null">, #{frequency}</if>
|
||||
<if test="category != null">, #{category}</if>
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updateWordCloud" parameterType="org.xyzh.api.workcase.dto.TbWordCloudDTO">
|
||||
UPDATE workcase.tb_word_cloud
|
||||
<set>
|
||||
<if test="word != null and word != ''">word = #{word},</if>
|
||||
<if test="frequency != null">frequency = #{frequency},</if>
|
||||
<if test="category != null">category = #{category},</if>
|
||||
update_time = now()
|
||||
</set>
|
||||
WHERE word_id = #{wordId}
|
||||
</update>
|
||||
|
||||
<select id="selectWordCloudById" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM workcase.tb_word_cloud
|
||||
WHERE word_id = #{wordId}
|
||||
</select>
|
||||
|
||||
<select id="selectWordCloudOne" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM workcase.tb_word_cloud
|
||||
<where>
|
||||
<if test="filter.wordId != null and filter.wordId != ''">
|
||||
AND word_id = #{filter.wordId}
|
||||
</if>
|
||||
<if test="filter.word != null and filter.word != ''">
|
||||
AND word = #{filter.word}
|
||||
</if>
|
||||
<if test="filter.category != null and filter.category != ''">
|
||||
AND category = #{filter.category}
|
||||
</if>
|
||||
<if test="filter.statDate != null and filter.statDate != ''">
|
||||
AND stat_date = #{filter.statDate}::date
|
||||
</if>
|
||||
</where>
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectWordCloudList" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM workcase.tb_word_cloud
|
||||
<where>
|
||||
<if test="filter.wordId != null and filter.wordId != ''">
|
||||
AND word_id = #{filter.wordId}
|
||||
</if>
|
||||
<if test="filter.word != null and filter.word != ''">
|
||||
AND word LIKE CONCAT('%', #{filter.word}, '%')
|
||||
</if>
|
||||
<if test="filter.category != null and filter.category != ''">
|
||||
AND category = #{filter.category}
|
||||
</if>
|
||||
<if test="filter.statDate != null and filter.statDate != ''">
|
||||
AND stat_date = #{filter.statDate}::date
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY frequency DESC, create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectWordCloudPage" resultMap="BaseResultMap">
|
||||
SELECT <include refid="Base_Column_List"/>
|
||||
FROM workcase.tb_word_cloud
|
||||
<where>
|
||||
<if test="filter.wordId != null and filter.wordId != ''">
|
||||
AND word_id = #{filter.wordId}
|
||||
</if>
|
||||
<if test="filter.word != null and filter.word != ''">
|
||||
AND word LIKE CONCAT('%', #{filter.word}, '%')
|
||||
</if>
|
||||
<if test="filter.category != null and filter.category != ''">
|
||||
AND category = #{filter.category}
|
||||
</if>
|
||||
<if test="filter.statDate != null and filter.statDate != ''">
|
||||
AND stat_date = #{filter.statDate}::date
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY frequency DESC, create_time DESC
|
||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||
</select>
|
||||
|
||||
<select id="countWordClouds" resultType="long">
|
||||
SELECT COUNT(*)
|
||||
FROM workcase.tb_word_cloud
|
||||
<where>
|
||||
<if test="filter.wordId != null and filter.wordId != ''">
|
||||
AND word_id = #{filter.wordId}
|
||||
</if>
|
||||
<if test="filter.word != null and filter.word != ''">
|
||||
AND word LIKE CONCAT('%', #{filter.word}, '%')
|
||||
</if>
|
||||
<if test="filter.category != null and filter.category != ''">
|
||||
AND category = #{filter.category}
|
||||
</if>
|
||||
<if test="filter.statDate != null and filter.statDate != ''">
|
||||
AND stat_date = #{filter.statDate}::date
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<update id="incrementFrequency">
|
||||
UPDATE workcase.tb_word_cloud
|
||||
SET frequency = frequency + #{count}, update_time = now()
|
||||
WHERE word_id = #{wordId}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user