工单模块
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -199,4 +199,5 @@ cython_debug/
|
|||||||
|
|
||||||
# PyPI configuration file
|
# PyPI configuration file
|
||||||
.pypirc
|
.pypirc
|
||||||
江西城市生命线-可交互原型/frontend/node_modules/*
|
江西城市生命线-可交互原型/frontend/node_modules/*
|
||||||
|
THAI-Platform/*
|
||||||
@@ -33,6 +33,7 @@ CREATE TABLE ai.tb_chat(
|
|||||||
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
user_id VARCHAR(50) NOT NULL, -- 用户ID
|
||||||
user_type BOOLEAN NOT NULL DEFAULT true, -- 用户类型 true-系统内部人员 false-系统外部人员
|
user_type BOOLEAN NOT NULL DEFAULT true, -- 用户类型 true-系统内部人员 false-系统外部人员
|
||||||
title VARCHAR(500) NOT NULL, -- 对话标题
|
title VARCHAR(500) NOT NULL, -- 对话标题
|
||||||
|
channel VARCHAR(50) DEFAULT 'agent' -- 对话渠道 agent、wechat
|
||||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
|
|||||||
@@ -20,27 +20,93 @@ CREATE TABLE sys.tb_guest(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
-- 客服对话记录,客服对话消息,包含ai、员工回答和来客提问
|
-- 客服对话记录,客服对话消息,包含ai、员工回答和来客提问,从ai.tb_chat同步ai对话时的数据
|
||||||
-- 直接使用ai.tb_chat和ai.tb_chat_message,user_type为false,表示该对话为来客对话
|
-- 先是ai对话,后转人工
|
||||||
-- 这里,需要把在微信客服上的聊天同步到ai.tb_chat_message
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- 工单表
|
-- 工单表
|
||||||
DROP TABLE IF EXISTS workcase.tb_workcase CASCADE;
|
DROP TABLE IF EXISTS workcase.tb_workcase CASCADE;
|
||||||
CREATE TABLE workcase.tb_workcase(
|
CREATE TABLE workcase.tb_workcase(
|
||||||
optsn VARCHAR(50) NOT NULL, -- 流水号
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
|
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
|
||||||
|
chat_id VARCHAR(50) NOT NULL, -- 对话ID
|
||||||
user_id VARCHAR(50) NOT NULL, -- 来客ID
|
user_id VARCHAR(50) NOT NULL, -- 来客ID
|
||||||
username VARCHAR(200) NOT NULL, -- 来客姓名
|
username VARCHAR(200) NOT NULL, -- 来客姓名
|
||||||
phone VARCHAR(20) NOT NULL, -- 来客电话
|
phone VARCHAR(20) NOT NULL, -- 来客电话
|
||||||
type VARCHAR(50) NOT NULL, -- 故障类型
|
type VARCHAR(50) NOT NULL, -- 故障类型
|
||||||
device VARCHAR(50) NOT NULL, -- 设备型号
|
device VARCHAR(50) NOT NULL, -- 设备名称
|
||||||
|
device_code VARCHAR(50) NOT NULL, -- 设备代码
|
||||||
|
imgs VARCHAR(50)[] DEFAULT '[]', -- 工单图片id
|
||||||
emergency VARCHAR(50) NOT NULL DEFAULT 'normal', -- 紧急程度 normal-普通 emergency-紧急
|
emergency VARCHAR(50) NOT NULL DEFAULT 'normal', -- 紧急程度 normal-普通 emergency-紧急
|
||||||
status VARCHAR(50) NOT NULL DEFAULT 'pending', -- 状态 pending-待处理 processing-处理中 done-已完成
|
status VARCHAR(50) NOT NULL DEFAULT 'pending', -- 状态 pending-待处理 processing-处理中 done-已完成
|
||||||
processor VARCHAR(50) DEFAULT NULL, -- 处理人
|
processor VARCHAR(50) DEFAULT NULL, -- 处理人
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 创建人
|
||||||
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
|
||||||
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
|
||||||
PRIMARY KEY (workcase_id),
|
PRIMARY KEY (workcase_id),
|
||||||
|
UNIQUE (chat_id),
|
||||||
UNIQUE (optsn)
|
UNIQUE (optsn)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 工单处理过程表(包含工单流转)
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_workcase_process CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_workcase_process(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
|
||||||
|
process_id VARCHAR(50) NOT NULL, -- 过程id
|
||||||
|
action VARCHAR(50) NOT NULL, -- 动作 info:记录,assign:指派,redeploy:转派,repeal:撤销,finish:完成
|
||||||
|
message VARCHAR(200) DEFAULT NULL, -- 消息
|
||||||
|
files VARCHAR(50)[] DEFAULT '[]', -- 携带文件
|
||||||
|
processor VARCHAR(50) DEFAULT NULL, -- 处理人(指派、转派专属)
|
||||||
|
remark VARCHAR(500) DEFAULT NULL, -- 备注
|
||||||
|
creator VARCHAR(50) NOT NULL, -- 过程发起人
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
PRIMARY KEY (process_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 工单设备涉及的文件表
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_workcase_device CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_workcase_device(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
|
||||||
|
device VARCHAR(50) NOT NULL, -- 设备名称
|
||||||
|
device_code VARCHAR(50) DEFAULT NULL, -- 设备代码
|
||||||
|
file_id VARCHAR(50) NOT NULL, -- 文件id
|
||||||
|
file_name VARCHAR(50) NOT NULL, -- 文件名
|
||||||
|
file_root_id VARCHAR(50) DEFAULT NULL, -- 文件根id
|
||||||
|
PRIMARY KEY(workcase_id, file_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 来客对话、工单过程中生成的词云表
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_word_cloud CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_word_cloud(
|
||||||
|
optsn VARCHAR(50) NOT NULL, -- 流水号
|
||||||
|
word_id VARCHAR(50) NOT NULL, -- 词条ID
|
||||||
|
word VARCHAR(100) NOT NULL, -- 词语
|
||||||
|
frequency INTEGER NOT NULL DEFAULT 1, -- 词频
|
||||||
|
source_type VARCHAR(20) NOT NULL, -- 来源类型 chat-聊天 workcase-工单
|
||||||
|
source_id VARCHAR(50) DEFAULT NULL, -- 来源ID(chat_id/workcase_id,NULL表示全局统计)
|
||||||
|
category VARCHAR(50) DEFAULT NULL, -- 分类(如:故障类型、设备名称、情绪词等)
|
||||||
|
stat_date DATE NOT NULL, -- 统计日期(按天聚合)
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
PRIMARY KEY (word_id),
|
||||||
|
UNIQUE (word, source_type, source_id, stat_date) -- 同一天同一来源的词唯一
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS workcase.tb_word_cloud CASCADE;
|
||||||
|
CREATE TABLE workcase.tb_word_cloud(
|
||||||
|
word_id VARCHAR(50) NOT NULL, -- 词条ID
|
||||||
|
word VARCHAR(100) NOT NULL, -- 词语
|
||||||
|
frequency INTEGER NOT NULL DEFAULT 1, -- 词频
|
||||||
|
category VARCHAR(50) DEFAULT NULL, -- 分类:fault-故障类型 device-设备 emotion-情绪词
|
||||||
|
stat_date DATE NOT NULL, -- 统计日期(按天聚合)
|
||||||
|
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
|
||||||
|
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
|
||||||
|
PRIMARY KEY (word_id),
|
||||||
|
UNIQUE (word, category, stat_date) -- 同一天同一分类的词唯一
|
||||||
);
|
);
|
||||||
@@ -45,6 +45,10 @@
|
|||||||
<groupId>org.xyzh.common</groupId>
|
<groupId>org.xyzh.common</groupId>
|
||||||
<artifactId>common-utils</artifactId>
|
<artifactId>common-utils</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.xyzh.common</groupId>
|
<groupId>org.xyzh.common</groupId>
|
||||||
<artifactId>common-exception</artifactId>
|
<artifactId>common-exception</artifactId>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<result column="chat_id" property="chatId" jdbcType="VARCHAR"/>
|
<result column="chat_id" property="chatId" jdbcType="VARCHAR"/>
|
||||||
<result column="role" property="role" jdbcType="VARCHAR"/>
|
<result column="role" property="role" jdbcType="VARCHAR"/>
|
||||||
<result column="content" property="content" jdbcType="VARCHAR"/>
|
<result column="content" property="content" jdbcType="VARCHAR"/>
|
||||||
<result column="files" property="files" jdbcType="ARRAY" typeHandler="org.xyzh.common.utils.json.StringArrayTypeHandler"/>
|
<result column="files" property="files" jdbcType="ARRAY" typeHandler="org.xyzh.common.jdbc.handler.StringArrayTypeHandler"/>
|
||||||
<result column="comment" property="comment" jdbcType="VARCHAR"/>
|
<result column="comment" property="comment" jdbcType="VARCHAR"/>
|
||||||
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||||
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
|
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
) VALUES (
|
) VALUES (
|
||||||
#{optsn}, #{messageId}, #{chatId}, #{role}, #{content}
|
#{optsn}, #{messageId}, #{chatId}, #{role}, #{content}
|
||||||
<if test="difyMessageId != null">, #{difyMessageId}</if>
|
<if test="difyMessageId != null">, #{difyMessageId}</if>
|
||||||
<if test="files != null">, #{files, typeHandler=org.xyzh.common.utils.json.StringArrayTypeHandler}</if>
|
<if test="files != null">, #{files, typeHandler=org.xyzh.common.jdbc.handler.StringArrayTypeHandler}</if>
|
||||||
<if test="comment != null">, #{comment}</if>
|
<if test="comment != null">, #{comment}</if>
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ public interface GuestService {
|
|||||||
*/
|
*/
|
||||||
ResultDomain<TbGuestDTO> selectGuestOne(TbGuestDTO guest);
|
ResultDomain<TbGuestDTO> selectGuestOne(TbGuestDTO guest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 根据微信id查询来客
|
||||||
|
* @param wechatId
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
ResultDomain<TbGuestDTO> selectGuestByWechatId(String wechatId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 查询来客列表
|
* @description 查询来客列表
|
||||||
* @param guest 来客信息
|
* @param guest 来客信息
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.xyzh</groupId>
|
<groupId>org.xyzh.apis</groupId>
|
||||||
<artifactId>api-workcase</artifactId>
|
<artifactId>api-workcase</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
|
|
||||||
@@ -18,4 +18,10 @@
|
|||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.apis</groupId>
|
||||||
|
<artifactId>api-ai</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package org.xyzh;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
System.out.println("Hello world!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.xyzh.api.workcase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工单服务接口
|
|
||||||
* 用于客服工单管理
|
|
||||||
*/
|
|
||||||
public interface WorkcaseService {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package org.xyzh.api.workcase.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import org.xyzh.common.dto.BaseDTO;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 会话DTO
|
|
||||||
* 用于创建和更新会话
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Schema(description = "会话DTO")
|
|
||||||
public class TbConversationDTO extends BaseDTO {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Schema(description = "会话ID(更新时需要)")
|
|
||||||
private String conversationId;
|
|
||||||
|
|
||||||
@Schema(description = "客户ID")
|
|
||||||
private String customerId;
|
|
||||||
|
|
||||||
@Schema(description = "会话类型:ai-AI客服/human-人工客服/transfer-转接", defaultValue = "ai")
|
|
||||||
private String conversationType;
|
|
||||||
|
|
||||||
@Schema(description = "渠道:wechat-微信/web-网页/app-应用/phone-电话", defaultValue = "wechat")
|
|
||||||
private String channel;
|
|
||||||
|
|
||||||
@Schema(description = "智能体ID或客服人员ID")
|
|
||||||
private String agentId;
|
|
||||||
|
|
||||||
@Schema(description = "座席类型:ai-AI/human-人工", defaultValue = "ai")
|
|
||||||
private String agentType;
|
|
||||||
|
|
||||||
@Schema(description = "会话开始时间", format = "date-time")
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date sessionStartTime;
|
|
||||||
|
|
||||||
@Schema(description = "会话结束时间", format = "date-time")
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date sessionEndTime;
|
|
||||||
|
|
||||||
@Schema(description = "会话时长(秒)")
|
|
||||||
private Integer durationSeconds;
|
|
||||||
|
|
||||||
@Schema(description = "消息数量", defaultValue = "0")
|
|
||||||
private Integer messageCount;
|
|
||||||
|
|
||||||
@Schema(description = "会话状态:active-进行中/closed-已结束/transferred-已转接/timeout-超时", defaultValue = "active")
|
|
||||||
private String conversationStatus;
|
|
||||||
|
|
||||||
@Schema(description = "满意度评分(1-5星)")
|
|
||||||
private Integer satisfactionRating;
|
|
||||||
|
|
||||||
@Schema(description = "满意度反馈")
|
|
||||||
private String satisfactionFeedback;
|
|
||||||
|
|
||||||
@Schema(description = "会话摘要(AI生成)")
|
|
||||||
private String summary;
|
|
||||||
|
|
||||||
@Schema(description = "会话标签")
|
|
||||||
private List<String> tags;
|
|
||||||
|
|
||||||
@Schema(description = "会话元数据")
|
|
||||||
private JsonNode metadata;
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package org.xyzh.api.workcase.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import org.xyzh.common.dto.BaseDTO;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户信息DTO
|
|
||||||
* 用于创建和更新客户信息
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Schema(description = "客户信息DTO")
|
|
||||||
public class TbCustomerDTO extends BaseDTO {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Schema(description = "客户ID(更新时需要)")
|
|
||||||
private String customerId;
|
|
||||||
|
|
||||||
@Schema(description = "客户编号")
|
|
||||||
private String customerNo;
|
|
||||||
|
|
||||||
@Schema(description = "客户姓名")
|
|
||||||
private String customerName;
|
|
||||||
|
|
||||||
@Schema(description = "客户类型:individual-个人/enterprise-企业", defaultValue = "individual")
|
|
||||||
private String customerType;
|
|
||||||
|
|
||||||
@Schema(description = "公司名称")
|
|
||||||
private String companyName;
|
|
||||||
|
|
||||||
@Schema(description = "电话")
|
|
||||||
private String phone;
|
|
||||||
|
|
||||||
@Schema(description = "邮箱")
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
@Schema(description = "微信OpenID")
|
|
||||||
private String wechatOpenid;
|
|
||||||
|
|
||||||
@Schema(description = "微信UnionID")
|
|
||||||
private String wechatUnionid;
|
|
||||||
|
|
||||||
@Schema(description = "头像URL")
|
|
||||||
private String avatar;
|
|
||||||
|
|
||||||
@Schema(description = "性别:0-未知/1-男/2-女", defaultValue = "0")
|
|
||||||
private Integer gender;
|
|
||||||
|
|
||||||
@Schema(description = "地址")
|
|
||||||
private String address;
|
|
||||||
|
|
||||||
@Schema(description = "客户等级:vip/important/normal/potential", defaultValue = "normal")
|
|
||||||
private String customerLevel;
|
|
||||||
|
|
||||||
@Schema(description = "客户来源:wechat-微信/web-网站/phone-电话/referral-推荐")
|
|
||||||
private String customerSource;
|
|
||||||
|
|
||||||
@Schema(description = "客户标签数组")
|
|
||||||
private List<String> tags;
|
|
||||||
|
|
||||||
@Schema(description = "备注")
|
|
||||||
private String notes;
|
|
||||||
|
|
||||||
@Schema(description = "CRM系统客户ID")
|
|
||||||
private String crmCustomerId;
|
|
||||||
|
|
||||||
@Schema(description = "最后联系时间", format = "date-time")
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date lastContactTime;
|
|
||||||
|
|
||||||
@Schema(description = "咨询总次数", defaultValue = "0")
|
|
||||||
private Integer totalConsultations;
|
|
||||||
|
|
||||||
@Schema(description = "订单总数", defaultValue = "0")
|
|
||||||
private Integer totalOrders;
|
|
||||||
|
|
||||||
@Schema(description = "总消费金额", defaultValue = "0")
|
|
||||||
private BigDecimal totalAmount;
|
|
||||||
|
|
||||||
@Schema(description = "满意度评分(1-5)")
|
|
||||||
private BigDecimal satisfactionScore;
|
|
||||||
|
|
||||||
@Schema(description = "状态:active-活跃/inactive-非活跃/blacklist-黑名单", defaultValue = "active")
|
|
||||||
private String status;
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
package org.xyzh.api.workcase.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import org.xyzh.common.dto.BaseDTO;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工单DTO
|
|
||||||
* 用于创建和更新工单
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Schema(description = "工单DTO")
|
|
||||||
public class TbTicketDTO extends BaseDTO {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Schema(description = "工单ID(更新时需要)")
|
|
||||||
private String ticketId;
|
|
||||||
|
|
||||||
@Schema(description = "工单编号")
|
|
||||||
private String ticketNo;
|
|
||||||
|
|
||||||
@Schema(description = "客户ID")
|
|
||||||
private String customerId;
|
|
||||||
|
|
||||||
@Schema(description = "关联会话ID")
|
|
||||||
private String conversationId;
|
|
||||||
|
|
||||||
@Schema(description = "工单类型:consultation-咨询/complaint-投诉/suggestion-建议/repair-维修/installation-安装/other-其他")
|
|
||||||
private String ticketType;
|
|
||||||
|
|
||||||
@Schema(description = "工单分类")
|
|
||||||
private String ticketCategory;
|
|
||||||
|
|
||||||
@Schema(description = "优先级:urgent-紧急/high-高/normal-普通/low-低", defaultValue = "normal")
|
|
||||||
private String priority;
|
|
||||||
|
|
||||||
@Schema(description = "工单标题")
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
@Schema(description = "问题描述")
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
@Schema(description = "附件ID数组")
|
|
||||||
private List<String> attachments;
|
|
||||||
|
|
||||||
@Schema(description = "工单来源:ai-AI生成/manual-人工创建/system-系统自动", defaultValue = "ai")
|
|
||||||
private String ticketSource;
|
|
||||||
|
|
||||||
@Schema(description = "分配给(处理人)")
|
|
||||||
private String assignedTo;
|
|
||||||
|
|
||||||
@Schema(description = "分配部门")
|
|
||||||
private String assignedDept;
|
|
||||||
|
|
||||||
@Schema(description = "工单状态:pending-待处理/processing-处理中/resolved-已解决/closed-已关闭/cancelled-已取消", defaultValue = "pending")
|
|
||||||
private String ticketStatus;
|
|
||||||
|
|
||||||
@Schema(description = "解决方案")
|
|
||||||
private String resolution;
|
|
||||||
|
|
||||||
@Schema(description = "解决时间", format = "date-time")
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date resolutionTime;
|
|
||||||
|
|
||||||
@Schema(description = "关闭时间", format = "date-time")
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date closeTime;
|
|
||||||
|
|
||||||
@Schema(description = "首次响应时间", format = "date-time")
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date responseTime;
|
|
||||||
|
|
||||||
@Schema(description = "SLA截止时间", format = "date-time")
|
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date slaDeadline;
|
|
||||||
|
|
||||||
@Schema(description = "是否逾期", defaultValue = "false")
|
|
||||||
private Boolean isOverdue;
|
|
||||||
|
|
||||||
@Schema(description = "客户评分(1-5星)")
|
|
||||||
private Integer customerRating;
|
|
||||||
|
|
||||||
@Schema(description = "客户反馈")
|
|
||||||
private String customerFeedback;
|
|
||||||
|
|
||||||
@Schema(description = "CRM系统工单ID")
|
|
||||||
private String crmTicketId;
|
|
||||||
|
|
||||||
@Schema(description = "同步状态:pending-待同步/synced-已同步/failed-失败", defaultValue = "pending")
|
|
||||||
private String syncStatus;
|
|
||||||
|
|
||||||
@Schema(description = "工单标签")
|
|
||||||
private List<String> tags;
|
|
||||||
|
|
||||||
@Schema(description = "工单元数据")
|
|
||||||
private JsonNode metadata;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package org.xyzh.api.workcase.dto;
|
||||||
|
|
||||||
|
import org.xyzh.common.dto.BaseDTO;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "词云表对象")
|
||||||
|
public class TbWordCloudDTO extends BaseDTO{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "词条ID")
|
||||||
|
private String wordId;
|
||||||
|
|
||||||
|
@Schema(description = "词语")
|
||||||
|
private String word;
|
||||||
|
|
||||||
|
@Schema(description = "词频")
|
||||||
|
private String frequency;
|
||||||
|
|
||||||
|
@Schema(description = "分类")
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
@Schema(description = "统计日期")
|
||||||
|
private String statDate;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package org.xyzh.api.workcase.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.xyzh.common.dto.BaseDTO;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 工单表数据对象DTO
|
||||||
|
* @filename TbWorkcaseDTO.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "工单表对象")
|
||||||
|
public class TbWorkcaseDTO extends BaseDTO{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "工单ID")
|
||||||
|
private String workcaseId;
|
||||||
|
|
||||||
|
@Schema(description = "来客ID")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Schema(description = "来客姓名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "来客电话")
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
@Schema(description = "故障类型")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "设备名称")
|
||||||
|
private String device;
|
||||||
|
|
||||||
|
@Schema(description = "设备代码")
|
||||||
|
private String deviceCode;
|
||||||
|
|
||||||
|
@Schema(description = "工单图片列表")
|
||||||
|
private List<String> imgs;
|
||||||
|
|
||||||
|
@Schema(description = "紧急程度 normal-普通 emergency-紧急")
|
||||||
|
private String emergency;
|
||||||
|
|
||||||
|
@Schema(description = "状态 pending-待处理 processing-处理中 done-已完成")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "处理人ID")
|
||||||
|
private String processor;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.xyzh.api.workcase.dto;
|
||||||
|
|
||||||
|
import org.xyzh.common.dto.BaseDTO;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 工单设备涉及的文件DTO
|
||||||
|
* @filename TbWorkcaseDeviceDTO.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "工单设备涉及的文件DTO")
|
||||||
|
public class TbWorkcaseDeviceDTO extends BaseDTO {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "工单ID")
|
||||||
|
private String workcaseId;
|
||||||
|
|
||||||
|
@Schema(description = "设备名称")
|
||||||
|
private String device;
|
||||||
|
|
||||||
|
@Schema(description = "设备代码")
|
||||||
|
private String deviceCode;
|
||||||
|
|
||||||
|
@Schema(description = "文件ID")
|
||||||
|
private String fileId;
|
||||||
|
|
||||||
|
@Schema(description = "文件名")
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
@Schema(description = "文件根ID")
|
||||||
|
private String fileRootId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.xyzh.api.workcase.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.xyzh.common.dto.BaseDTO;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 工单过程表DTO
|
||||||
|
* @filename TbWorkcaseProcessDTO.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "工单过程表DTO")
|
||||||
|
public class TbWorkcaseProcessDTO extends BaseDTO {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "工单ID")
|
||||||
|
private String workcaseId;
|
||||||
|
|
||||||
|
@Schema(description = "过程ID")
|
||||||
|
private String processId;
|
||||||
|
|
||||||
|
@Schema(description = "动作 info:记录,assign:指派,redeploy:转派,repeal:撤销,finish:完成")
|
||||||
|
private String action;
|
||||||
|
|
||||||
|
@Schema(description = "消息")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
@Schema(description = "携带文件列表")
|
||||||
|
private List<String> files;
|
||||||
|
|
||||||
|
@Schema(description = "处理人(指派、转派专属)")
|
||||||
|
private String processor;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
package org.xyzh.api.workcase.service;
|
||||||
|
|
||||||
|
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.common.core.domain.ResultDomain;
|
||||||
|
import org.xyzh.common.core.page.PageRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 客服聊天服务,涉及agent回答客户和微信客服回答客户
|
||||||
|
* @filename WorkcaseChatService.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
public interface WorkcaseChatService {
|
||||||
|
|
||||||
|
// ========================= 聊天管理 ==========================
|
||||||
|
/**
|
||||||
|
* @description 来客创建聊天对话
|
||||||
|
* @param
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
ResultDomain<TbChat> createChat(TbChat chat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 更新聊天名称
|
||||||
|
* @param
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
ResultDomain<TbChat> updateChat(TbChat chat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取聊天列表
|
||||||
|
* @param agentId 智能体ID
|
||||||
|
* @return 聊天列表
|
||||||
|
*/
|
||||||
|
ResultDomain<TbChat> getChatList(TbChat filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取聊天分页
|
||||||
|
* @param pageRequest
|
||||||
|
* @return 聊天分页
|
||||||
|
*/
|
||||||
|
ResultDomain<TbChat> getChatPage(PageRequest<TbChat> pageRequest);
|
||||||
|
|
||||||
|
// ========================= 聊天信息管理 ======================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取会话消息列表
|
||||||
|
* @param filter 会话过滤条件(包含agentId, chatId, userId, userType)
|
||||||
|
* @return 会话消息列表
|
||||||
|
*/
|
||||||
|
ResultDomain<TbChatMessage> getChatMessageList(TbChat filter);
|
||||||
|
|
||||||
|
// 用户转人工后,就不和智能体聊天了,在微信客服里聊天
|
||||||
|
/**
|
||||||
|
* 准备聊天数据(POST传递复杂参数)
|
||||||
|
* @param prepareData 对话准备数据(包含agentId, chatId, query, files, userId, userType)
|
||||||
|
* @return ResultDomain<String> 返回sessionId
|
||||||
|
*/
|
||||||
|
ResultDomain<String> prepareChatMessageSession(ChatPrepareData prepareData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流式对话(SSE)- 使用sessionId建立SSE连接 产生chatMessage
|
||||||
|
* @param sessionId 会话标识
|
||||||
|
* @return SseEmitter 流式推送对象
|
||||||
|
*/
|
||||||
|
SseEmitter streamChatMessageWithSse(String sessionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止对话生成(通过Dify TaskID)
|
||||||
|
* @param filter 会话过滤条件(包含agentId, userId, userType)
|
||||||
|
* @param taskId Dify任务ID
|
||||||
|
* @return 停止结果
|
||||||
|
*/
|
||||||
|
ResultDomain<Boolean> stopChatMessageByTaskId(TbChat filter, String taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评价
|
||||||
|
* @param filter 会话过滤条件(包含agentId, chatId, userId, userType)
|
||||||
|
* @param messageId 消息ID
|
||||||
|
* @param comment 评价
|
||||||
|
* @return 评价结果
|
||||||
|
*/
|
||||||
|
ResultDomain<Boolean> commentChatMessage(TbChat filter, String messageId, String comment);
|
||||||
|
|
||||||
|
// =============================== 对话分析 ==========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对话分析, 提取出工单相关的内容,这里有智能体调用等
|
||||||
|
* @param chatId 对话ID
|
||||||
|
* @return 对话分析结果
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDTO> analyzeChat(String chatId);
|
||||||
|
|
||||||
|
// 对话总结
|
||||||
|
ResultDomain<TbWorkcaseDTO> summaryChat(String chatId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// =============================== 对话、工单等词云管理 ==========================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 添加词云
|
||||||
|
* @param wordCloud 词云对象
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWordCloudDTO> addWordCloud(TbWordCloudDTO wordCloud);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 更新词云
|
||||||
|
* @param wordCloud 词云对象
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWordCloudDTO> updateWordCloud(TbWordCloudDTO wordCloud);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取词云列表
|
||||||
|
* @param filter 词云过滤条件
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWordCloudDTO> getWordCloudList(TbWordCloudDTO filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取词云分页
|
||||||
|
* @param pageRequest 分页请求
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWordCloudDTO> getWordCloudPage(PageRequest<TbWordCloudDTO> pageRequest);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package org.xyzh.api.workcase.service;
|
||||||
|
|
||||||
|
import org.xyzh.api.workcase.dto.TbWorkcaseDTO;
|
||||||
|
import org.xyzh.api.workcase.dto.TbWorkcaseDeviceDTO;
|
||||||
|
import org.xyzh.api.workcase.dto.TbWorkcaseProcessDTO;
|
||||||
|
import org.xyzh.common.core.domain.ResultDomain;
|
||||||
|
import org.xyzh.common.core.page.PageRequest;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工单服务接口
|
||||||
|
* 用于客服工单管理
|
||||||
|
*/
|
||||||
|
public interface WorkcaseService {
|
||||||
|
|
||||||
|
// ====================== 工单管理 ======================
|
||||||
|
/**
|
||||||
|
* @description 创建工单
|
||||||
|
* @param workcase
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDTO> createWorkcase(TbWorkcaseDTO workcase);
|
||||||
|
/**
|
||||||
|
* @description 更新工单
|
||||||
|
* @param workcase
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDTO> updateWorkcase(TbWorkcaseDTO workcase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 删除工单
|
||||||
|
* @param workcase
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDTO> deleteWorkcase(TbWorkcaseDTO workcase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取工单列表
|
||||||
|
* @param filter
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDTO> getWorkcaseList(TbWorkcaseDTO filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取工单分页
|
||||||
|
* @param pageRequest
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDTO> getWorkcasePage(PageRequest<TbWorkcaseDTO> pageRequest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取工单详情
|
||||||
|
* @param workcaseId
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDTO> getWorkcaseById(String workcaseId);
|
||||||
|
|
||||||
|
// ====================== 同步到CRM和接收 ===================
|
||||||
|
/**
|
||||||
|
* @description 同步工单到CRM
|
||||||
|
* @param workcase
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<Void> syncWorkcaseToCrm(TbWorkcaseDTO workcase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 接收CRM的工单处理结果
|
||||||
|
* @param json
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<Void> receiveWorkcaseFromCrm(JSON json);
|
||||||
|
|
||||||
|
// ====================== 工单处理过程 ======================
|
||||||
|
/**
|
||||||
|
* @description 创建工单处理过程
|
||||||
|
* @param workcaseProcess
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseProcessDTO> createWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 更新工单处理过程
|
||||||
|
* @param workcaseProcess
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseProcessDTO> updateWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 删除工单处理过程
|
||||||
|
* @param workcaseProcess
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseProcessDTO> deleteWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取工单处理过程列表
|
||||||
|
* @param filter
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessList(TbWorkcaseProcessDTO filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取工单处理过程分页
|
||||||
|
* @param pageRequest
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseProcessDTO> getWorkcaseProcessPage(PageRequest<TbWorkcaseProcessDTO> pageRequest);
|
||||||
|
|
||||||
|
// ====================== 工单设备管理 ======================
|
||||||
|
/**
|
||||||
|
* @description 创建工单设备
|
||||||
|
* @param workcaseDevice
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDeviceDTO> createWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice);
|
||||||
|
/**
|
||||||
|
* @description 更新工单设备
|
||||||
|
* @param workcaseDevice
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDeviceDTO> updateWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice);
|
||||||
|
/**
|
||||||
|
* @description 删除工单设备
|
||||||
|
* @param workcaseDevice
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDeviceDTO> deleteWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice);
|
||||||
|
/**
|
||||||
|
* @description 获取工单设备列表
|
||||||
|
* @param filter
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDeviceList(TbWorkcaseDeviceDTO filter);
|
||||||
|
/**
|
||||||
|
* @description 获取工单设备分页
|
||||||
|
* @param pageRequest
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-19
|
||||||
|
*/
|
||||||
|
ResultDomain<TbWorkcaseDeviceDTO> getWorkcaseDevicePage(PageRequest<TbWorkcaseDeviceDTO> pageRequest);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -44,6 +44,10 @@
|
|||||||
<groupId>org.xyzh.common</groupId>
|
<groupId>org.xyzh.common</groupId>
|
||||||
<artifactId>common-utils</artifactId>
|
<artifactId>common-utils</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -2,6 +2,8 @@ package org.xyzh.common.dto;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@@ -41,4 +43,19 @@ public class BaseDTO implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "是否已删除", defaultValue = "false")
|
@Schema(description = "是否已删除", defaultValue = "false")
|
||||||
private Boolean deleted = false;
|
private Boolean deleted = false;
|
||||||
|
|
||||||
|
|
||||||
|
// =============== 下方为筛选字段,非数据库字段 ================
|
||||||
|
|
||||||
|
@Schema(description = "数量限制")
|
||||||
|
private Integer limit;
|
||||||
|
|
||||||
|
@Schema(description = "开始时间")
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
@Schema(description = "排序字段")
|
||||||
|
private List<OrderField> orderFields;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.xyzh.common.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "排序方式对象")
|
||||||
|
public class OrderField {
|
||||||
|
public static final String ASC = "ASC";
|
||||||
|
public static final String DESC = "DESC";
|
||||||
|
|
||||||
|
@Schema(description = "排序字段")
|
||||||
|
private String field;
|
||||||
|
|
||||||
|
@Schema(description = "排序方式")
|
||||||
|
private String order;
|
||||||
|
|
||||||
|
public OrderField(String field, String order) {
|
||||||
|
this.field = field;
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@ import lombok.Data;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.xyzh.common.dto.BaseDTO;
|
import org.xyzh.common.dto.BaseDTO;
|
||||||
import org.xyzh.common.utils.crypto.AesEncryptUtil;
|
import org.xyzh.common.utils.crypto.AesEncryptUtil;
|
||||||
import org.xyzh.common.utils.crypto.EncryptedStringTypeHandler;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@@ -33,7 +31,6 @@ public class TbSysUserDTO extends BaseDTO {
|
|||||||
@Schema(description = "邮箱")
|
@Schema(description = "邮箱")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@TableField(typeHandler = EncryptedStringTypeHandler.class)
|
|
||||||
@Schema(description = "手机(加密)")
|
@Schema(description = "手机(加密)")
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
||||||
|
|||||||
44
urbanLifelineServ/common/common-jdbc/pom.xml
Normal file
44
urbanLifelineServ/common/common-jdbc/pom.xml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.xyzh</groupId>
|
||||||
|
<artifactId>common</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-jdbc</artifactId>
|
||||||
|
<version>${urban-lifeline.version}</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>JDBC相关工具:MyBatis类型处理器</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- MyBatis -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- FastJson2 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2-extension-spring6</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- common-utils (用于 AesEncryptUtil) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-utils</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package org.xyzh.common.utils.crypto;
|
package org.xyzh.common.jdbc.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.xyzh.common.jdbc.handler.EncryptedStringTypeHandler;
|
||||||
|
import org.xyzh.common.utils.crypto.AesEncryptUtil;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package org.xyzh.common.utils.crypto;
|
package org.xyzh.common.jdbc.handler;
|
||||||
|
|
||||||
import org.apache.ibatis.type.BaseTypeHandler;
|
import org.apache.ibatis.type.BaseTypeHandler;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
import org.apache.ibatis.type.JdbcType;
|
||||||
import org.apache.ibatis.type.MappedTypes;
|
import org.apache.ibatis.type.MappedTypes;
|
||||||
|
import org.xyzh.common.utils.crypto.AesEncryptUtil;
|
||||||
|
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package org.xyzh.common.jdbc.handler;
|
||||||
|
|
||||||
|
import org.apache.ibatis.type.BaseTypeHandler;
|
||||||
|
import org.apache.ibatis.type.JdbcType;
|
||||||
|
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 通用枚举类型处理器,支持枚举类中定义 getName() 方法
|
||||||
|
* 将枚举的 name 属性(自定义字符串)存储到数据库
|
||||||
|
* @filename EnumNameTypeHandler.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
public class EnumNameTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {
|
||||||
|
|
||||||
|
private final Class<E> type;
|
||||||
|
|
||||||
|
public EnumNameTypeHandler(Class<E> type) {
|
||||||
|
if (type == null) {
|
||||||
|
throw new IllegalArgumentException("Type argument cannot be null");
|
||||||
|
}
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
|
||||||
|
String value = getEnumName(parameter);
|
||||||
|
ps.setString(i, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||||
|
String name = rs.getString(columnName);
|
||||||
|
return fromName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||||
|
String name = rs.getString(columnIndex);
|
||||||
|
return fromName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||||
|
String name = cs.getString(columnIndex);
|
||||||
|
return fromName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取枚举的 name 属性值
|
||||||
|
* 优先调用 getName() 方法,如果不存在则使用 name()
|
||||||
|
*/
|
||||||
|
private String getEnumName(E enumValue) {
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Method getNameMethod = type.getMethod("getName");
|
||||||
|
return (String) getNameMethod.invoke(enumValue);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return enumValue.name();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return enumValue.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 name 属性值查找枚举
|
||||||
|
* 优先匹配 getName(),如果不存在则匹配 name()
|
||||||
|
*/
|
||||||
|
private E fromName(String name) {
|
||||||
|
if (name == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
E[] enumConstants = type.getEnumConstants();
|
||||||
|
|
||||||
|
// 先尝试匹配 getName()
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Method getNameMethod = type.getMethod("getName");
|
||||||
|
for (E enumConstant : enumConstants) {
|
||||||
|
String enumName = (String) getNameMethod.invoke(enumConstant);
|
||||||
|
if (name.equals(enumName)) {
|
||||||
|
return enumConstant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// 没有 getName 方法,使用 name()
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 其他异常,使用 name()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回退到 name() 匹配
|
||||||
|
for (E enumConstant : enumConstants) {
|
||||||
|
if (name.equals(enumConstant.name())) {
|
||||||
|
return enumConstant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.xyzh.common.utils.json;
|
package org.xyzh.common.jdbc.handler;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
@@ -15,7 +15,7 @@ import java.sql.SQLException;
|
|||||||
* @description FastJSON2 JSONObject 类型处理器
|
* @description FastJSON2 JSONObject 类型处理器
|
||||||
* @filename FastJson2TypeHandler.java
|
* @filename FastJson2TypeHandler.java
|
||||||
* @author yslg
|
* @author yslg
|
||||||
* @copyright yslg
|
* @copyright xyzh
|
||||||
* @since 2025-12-09
|
* @since 2025-12-09
|
||||||
*/
|
*/
|
||||||
@MappedTypes({JSONObject.class})
|
@MappedTypes({JSONObject.class})
|
||||||
@@ -51,7 +51,6 @@ public class FastJson2TypeHandler extends BaseTypeHandler<JSONObject> {
|
|||||||
try {
|
try {
|
||||||
return JSON.parseObject(jsonString);
|
return JSON.parseObject(jsonString);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 如果解析失败,返回一个空的JSONObject
|
|
||||||
return new JSONObject();
|
return new JSONObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.xyzh.common.utils.json;
|
package org.xyzh.common.jdbc.handler;
|
||||||
|
|
||||||
import org.apache.ibatis.type.BaseTypeHandler;
|
import org.apache.ibatis.type.BaseTypeHandler;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
import org.apache.ibatis.type.JdbcType;
|
||||||
@@ -16,7 +16,7 @@ import java.util.List;
|
|||||||
* @description PostgreSQL VARCHAR数组类型处理器
|
* @description PostgreSQL VARCHAR数组类型处理器
|
||||||
* @filename StringArrayTypeHandler.java
|
* @filename StringArrayTypeHandler.java
|
||||||
* @author yslg
|
* @author yslg
|
||||||
* @copyright yslg
|
* @copyright xyzh
|
||||||
* @since 2025-12-15
|
* @since 2025-12-15
|
||||||
*/
|
*/
|
||||||
@MappedTypes({List.class})
|
@MappedTypes({List.class})
|
||||||
@@ -30,16 +30,6 @@
|
|||||||
<artifactId>poi-ooxml</artifactId>
|
<artifactId>poi-ooxml</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- MyBatis (用于类型处理器) -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mybatis</groupId>
|
|
||||||
<artifactId>mybatis</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.baomidou</groupId>
|
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- Spring Boot (用于加密工具) -->
|
<!-- Spring Boot (用于加密工具) -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
<module>common-auth</module>
|
<module>common-auth</module>
|
||||||
<module>common-redis</module>
|
<module>common-redis</module>
|
||||||
<module>common-utils</module>
|
<module>common-utils</module>
|
||||||
|
<module>common-jdbc</module>
|
||||||
<module>common-all</module>
|
<module>common-all</module>
|
||||||
<module>common-exception</module>
|
<module>common-exception</module>
|
||||||
</modules>
|
</modules>
|
||||||
@@ -65,6 +66,11 @@
|
|||||||
<artifactId>common-exception</artifactId>
|
<artifactId>common-exception</artifactId>
|
||||||
<version>${urban-lifeline.version}</version>
|
<version>${urban-lifeline.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-jdbc</artifactId>
|
||||||
|
<version>${urban-lifeline.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
</project>
|
</project>
|
||||||
@@ -195,6 +195,12 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- MyBatis-Plus 注解(用于 DTO 中的 @TableField 等注解) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-annotation</artifactId>
|
||||||
|
<version>${mybatis.plus.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 强制引入与 Spring Boot 3.x 匹配的 mybatis-spring 3.x -->
|
<!-- 强制引入与 Spring Boot 3.x 匹配的 mybatis-spring 3.x -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis</groupId>
|
<groupId>org.mybatis</groupId>
|
||||||
@@ -247,6 +253,16 @@
|
|||||||
<artifactId>api-log</artifactId>
|
<artifactId>api-log</artifactId>
|
||||||
<version>${urban-lifeline.version}</version>
|
<version>${urban-lifeline.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.apis</groupId>
|
||||||
|
<artifactId>api-ai</artifactId>
|
||||||
|
<version>${urban-lifeline.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.apis</groupId>
|
||||||
|
<artifactId>api-workcase</artifactId>
|
||||||
|
<version>${urban-lifeline.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Common 模块 -->
|
<!-- Common 模块 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -279,6 +295,11 @@
|
|||||||
<artifactId>common-exception</artifactId>
|
<artifactId>common-exception</artifactId>
|
||||||
<version>${urban-lifeline.version}</version>
|
<version>${urban-lifeline.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-jdbc</artifactId>
|
||||||
|
<version>${urban-lifeline.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 服务模块 -->
|
<!-- 服务模块 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.xyzh</groupId>
|
<groupId>org.xyzh</groupId>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.apache.dubbo.config.annotation.DubboReference;
|
|||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
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.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -16,6 +17,7 @@ import org.xyzh.common.core.page.PageRequest;
|
|||||||
import org.xyzh.common.dto.sys.TbGuestDTO;
|
import org.xyzh.common.dto.sys.TbGuestDTO;
|
||||||
import org.xyzh.common.utils.validation.ValidationUtils;
|
import org.xyzh.common.utils.validation.ValidationUtils;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,6 +65,11 @@ public class GuestController {
|
|||||||
return guestService.deleteGuest(userId);
|
return guestService.deleteGuest(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/wechat/{wechatId}")
|
||||||
|
public ResultDomain<TbGuestDTO> selectGuestByWechat(@PathVariable("wechatId") @NotBlank String wechatId){
|
||||||
|
return guestService.selectGuestByWechatId(wechatId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public ResultDomain<TbGuestDTO> listGuest(TbGuestDTO filter) {
|
public ResultDomain<TbGuestDTO> listGuest(TbGuestDTO filter) {
|
||||||
|
|||||||
@@ -50,6 +50,14 @@ public interface TbGuestMapper extends BaseMapper<TbGuestDTO>{
|
|||||||
*/
|
*/
|
||||||
TbGuestDTO selectGuestOne(TbGuestDTO guest);
|
TbGuestDTO selectGuestOne(TbGuestDTO guest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 根据微信id查询来客
|
||||||
|
* @param wechatId
|
||||||
|
* @author yslg
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
TbGuestDTO selectGuestByWechatId(String wechatId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 查询来客列表
|
* @description 查询来客列表
|
||||||
* @param guest 来客信息
|
* @param guest 来客信息
|
||||||
|
|||||||
@@ -49,21 +49,31 @@ public class GuestServiceImpl implements GuestService{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public ResultDomain<TbGuestDTO> deleteGuest(String userId) {
|
public ResultDomain<TbGuestDTO> deleteGuest(String userId) {
|
||||||
guestMapper.deleteGuest(userId);
|
int rows = guestMapper.deleteGuest(userId);
|
||||||
return ResultDomain.success("删除成功");
|
if (rows > 0) {
|
||||||
|
return ResultDomain.success("删除成功");
|
||||||
|
}
|
||||||
|
return ResultDomain.failure("删除失败,来客不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultDomain<TbGuestDTO> selectGuestList(TbGuestDTO guest) {
|
public ResultDomain<TbGuestDTO> selectGuestList(TbGuestDTO guest) {
|
||||||
guestMapper.selectGuestList(guest);
|
List<TbGuestDTO> list = guestMapper.selectGuestList(guest);
|
||||||
return ResultDomain.success("查询成功",guest);
|
return ResultDomain.success("查询成功", list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultDomain<TbGuestDTO> selectGuestOne(TbGuestDTO guest) {
|
public ResultDomain<TbGuestDTO> selectGuestOne(TbGuestDTO guest) {
|
||||||
guestMapper.selectGuestOne(guest);
|
TbGuestDTO selected = guestMapper.selectGuestOne(guest);
|
||||||
return ResultDomain.success("查询成功",guest);
|
return ResultDomain.success("查询成功",selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<TbGuestDTO> selectGuestByWechatId(String wechatId){
|
||||||
|
TbGuestDTO selected = guestMapper.selectGuestByWechatId(wechatId);
|
||||||
|
return ResultDomain.success("查询成功", selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
<result column="config_type" property="configType" jdbcType="VARCHAR"/>
|
<result column="config_type" property="configType" jdbcType="VARCHAR"/>
|
||||||
<result column="render_type" property="renderType" jdbcType="VARCHAR"/>
|
<result column="render_type" property="renderType" jdbcType="VARCHAR"/>
|
||||||
<result column="description" property="description" jdbcType="VARCHAR"/>
|
<result column="description" property="description" jdbcType="VARCHAR"/>
|
||||||
<result column="re" property="re" typeHandler="org.xyzh.common.utils.json.FastJson2TypeHandler"/>
|
<result column="re" property="re" typeHandler="org.xyzh.common.jdbc.handler.FastJson2TypeHandler"/>
|
||||||
<result column="options" property="options" typeHandler="org.xyzh.common.utils.json.FastJson2TypeHandler"/>
|
<result column="options" property="options" typeHandler="org.xyzh.common.jdbc.handler.FastJson2TypeHandler"/>
|
||||||
<result column="group" property="group" jdbcType="VARCHAR"/>
|
<result column="group" property="group" jdbcType="VARCHAR"/>
|
||||||
<result column="module_id" property="moduleId" jdbcType="VARCHAR"/>
|
<result column="module_id" property="moduleId" jdbcType="VARCHAR"/>
|
||||||
<result column="order_num" property="orderNum" jdbcType="INTEGER"/>
|
<result column="order_num" property="orderNum" jdbcType="INTEGER"/>
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
<result column="config_type" property="configType" jdbcType="VARCHAR"/>
|
<result column="config_type" property="configType" jdbcType="VARCHAR"/>
|
||||||
<result column="render_type" property="renderType" jdbcType="VARCHAR"/>
|
<result column="render_type" property="renderType" jdbcType="VARCHAR"/>
|
||||||
<result column="description" property="description" jdbcType="VARCHAR"/>
|
<result column="description" property="description" jdbcType="VARCHAR"/>
|
||||||
<result column="re" property="re" typeHandler="org.xyzh.common.utils.json.FastJson2TypeHandler"/>
|
<result column="re" property="re" typeHandler="org.xyzh.common.jdbc.handler.FastJson2TypeHandler"/>
|
||||||
<result column="options" property="options" typeHandler="org.xyzh.common.utils.json.FastJson2TypeHandler"/>
|
<result column="options" property="options" typeHandler="org.xyzh.common.jdbc.handler.FastJson2TypeHandler"/>
|
||||||
<result column="group" property="group" jdbcType="VARCHAR"/>
|
<result column="group" property="group" jdbcType="VARCHAR"/>
|
||||||
<result column="module_id" property="moduleId" jdbcType="VARCHAR"/>
|
<result column="module_id" property="moduleId" jdbcType="VARCHAR"/>
|
||||||
<result column="order_num" property="orderNum" jdbcType="INTEGER"/>
|
<result column="order_num" property="orderNum" jdbcType="INTEGER"/>
|
||||||
|
|||||||
@@ -74,11 +74,16 @@
|
|||||||
<if test="wechatId != null and wechatId != ''">
|
<if test="wechatId != null and wechatId != ''">
|
||||||
AND wechat_id = #{wechatId}
|
AND wechat_id = #{wechatId}
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
</where>
|
</where>
|
||||||
|
LIMIT 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectGuestByWechatId">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM sys.tb_guest
|
||||||
|
WHERE wechat_id = #{wechat_id}
|
||||||
|
LIMIT 1
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectGuestList" resultMap="BaseResultMap">
|
<select id="selectGuestList" resultMap="BaseResultMap">
|
||||||
SELECT <include refid="Base_Column_List"/>
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
|||||||
@@ -17,5 +17,47 @@
|
|||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.apis</groupId>
|
||||||
|
<artifactId>api-workcase</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>org.xyzh.apis</groupId>
|
||||||
|
<artifactId>api-ai</artifactId>
|
||||||
|
</dependency> -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-auth</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-utils</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xyzh.common</groupId>
|
||||||
|
<artifactId>common-exception</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.dubbo</groupId>
|
||||||
|
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package org.xyzh.workcase.config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.dubbo.config.annotation.DubboReference;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.xyzh.api.ai.dto.TbKnowledge;
|
||||||
|
import org.xyzh.api.ai.service.KnowledgeService;
|
||||||
|
import org.xyzh.common.core.domain.ResultDomain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 初始化客服系统必须的8个知识库,4个内部知识库,4个外部知识库,运行结束即销毁
|
||||||
|
* @filename KnowledgeInit.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class KnowledgeInit {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(KnowledgeInit.class);
|
||||||
|
|
||||||
|
private static final String SERVICE_WORKCASE = "workcase";
|
||||||
|
private static final String CATEGORY_INTERNAL = "internal";
|
||||||
|
private static final String CATEGORY_EXTERNAL = "external";
|
||||||
|
private static final String PERMISSION_PUBLIC = "PUBLIC";
|
||||||
|
|
||||||
|
@DubboReference(version = "1.0.0", group = "ai", timeout = 30000)
|
||||||
|
private KnowledgeService knowledgeService;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CommandLineRunner knowledgeInitRunner() {
|
||||||
|
return args -> {
|
||||||
|
logger.info("开始初始化客服系统知识库...");
|
||||||
|
|
||||||
|
List<KnowledgeConfig> configs = buildKnowledgeConfigs();
|
||||||
|
int successCount = 0;
|
||||||
|
int skipCount = 0;
|
||||||
|
|
||||||
|
for (KnowledgeConfig config : configs) {
|
||||||
|
if (checkKnowledgeExists(knowledgeService, config.title)) {
|
||||||
|
logger.info("知识库已存在,跳过: {}", config.title);
|
||||||
|
skipCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createKnowledge(knowledgeService, config)) {
|
||||||
|
successCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("客服系统知识库初始化完成: 成功创建{}个,跳过{}个", successCount, skipCount);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建8个知识库配置
|
||||||
|
*/
|
||||||
|
private List<KnowledgeConfig> buildKnowledgeConfigs() {
|
||||||
|
List<KnowledgeConfig> configs = new ArrayList<>();
|
||||||
|
|
||||||
|
// 4个内部知识库
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"内部-政策法规库",
|
||||||
|
"存储城市生命线相关政策法规、行业标准、规范文件",
|
||||||
|
CATEGORY_INTERNAL
|
||||||
|
));
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"内部-技术文档库",
|
||||||
|
"存储技术规范、操作手册、维护指南等技术文档",
|
||||||
|
CATEGORY_INTERNAL
|
||||||
|
));
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"内部-案例经验库",
|
||||||
|
"存储历史工单处理案例、经验总结、故障排查记录",
|
||||||
|
CATEGORY_INTERNAL
|
||||||
|
));
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"内部-培训资料库",
|
||||||
|
"存储员工培训材料、业务知识、常见问题解答",
|
||||||
|
CATEGORY_INTERNAL
|
||||||
|
));
|
||||||
|
|
||||||
|
// 4个外部知识库
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"外部-服务指南库",
|
||||||
|
"面向公众的服务办理指南、流程说明、所需材料",
|
||||||
|
CATEGORY_EXTERNAL
|
||||||
|
));
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"外部-常见问题库",
|
||||||
|
"公众常见咨询问题及标准答案,FAQ知识库",
|
||||||
|
CATEGORY_EXTERNAL
|
||||||
|
));
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"外部-公告通知库",
|
||||||
|
"政府公告、服务通知、停水停电通知等公开信息",
|
||||||
|
CATEGORY_EXTERNAL
|
||||||
|
));
|
||||||
|
configs.add(new KnowledgeConfig(
|
||||||
|
"外部-便民信息库",
|
||||||
|
"便民服务信息、联系方式、服务网点、办事地点等",
|
||||||
|
CATEGORY_EXTERNAL
|
||||||
|
));
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查知识库是否已存在
|
||||||
|
*/
|
||||||
|
private boolean checkKnowledgeExists(KnowledgeService knowledgeService, String title) {
|
||||||
|
TbKnowledge filter = new TbKnowledge();
|
||||||
|
filter.setTitle(title);
|
||||||
|
filter.setService(SERVICE_WORKCASE);
|
||||||
|
|
||||||
|
ResultDomain<TbKnowledge> result = knowledgeService.listKnowledges(filter);
|
||||||
|
if (result.getSuccess() && result.getDataList() != null && !result.getDataList().isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建知识库
|
||||||
|
*/
|
||||||
|
private boolean createKnowledge(KnowledgeService knowledgeService, KnowledgeConfig config) {
|
||||||
|
TbKnowledge knowledge = new TbKnowledge();
|
||||||
|
knowledge.setTitle(config.title);
|
||||||
|
knowledge.setDescription(config.description);
|
||||||
|
knowledge.setService(SERVICE_WORKCASE);
|
||||||
|
knowledge.setCategory(config.category);
|
||||||
|
knowledge.setDifyIndexingTechnique("high_quality");
|
||||||
|
knowledge.setRetrievalTopK(5);
|
||||||
|
knowledge.setRetrievalScoreThreshold(0.5);
|
||||||
|
knowledge.setRerankingEnable(1);
|
||||||
|
|
||||||
|
ResultDomain<TbKnowledge> result = knowledgeService.createKnowledge(
|
||||||
|
knowledge, PERMISSION_PUBLIC, null, null);
|
||||||
|
|
||||||
|
if (result.getSuccess()) {
|
||||||
|
logger.info("创建知识库成功: {} [{}]", config.title, config.category);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
logger.error("创建知识库失败: {} - {}", config.title, result.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 知识库配置内部类
|
||||||
|
*/
|
||||||
|
private static class KnowledgeConfig {
|
||||||
|
final String title;
|
||||||
|
final String description;
|
||||||
|
final String category;
|
||||||
|
|
||||||
|
KnowledgeConfig(String title, String description, String category) {
|
||||||
|
this.title = title;
|
||||||
|
this.description = description;
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.xyzh.workcase.enums;
|
||||||
|
|
||||||
|
public enum WorkcaseProcessAction {
|
||||||
|
|
||||||
|
INFO("info", "记录"),
|
||||||
|
ASSIGN("assign","指派"),
|
||||||
|
REDEPLOY("redeploy", "转派"),
|
||||||
|
REPEAL("repeal", "撤销"),
|
||||||
|
FINISH("finish", "完成");
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
WorkcaseProcessAction(String name, String description){
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
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.TbWorkcaseDeviceDTO;
|
||||||
|
import org.xyzh.common.core.page.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 工单设备文件数据访问层
|
||||||
|
* @filename TbWorkcaseDeviceMapper.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface TbWorkcaseDeviceMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入工单设备文件
|
||||||
|
*/
|
||||||
|
int insertWorkcaseDevice(TbWorkcaseDeviceDTO device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工单设备文件(只更新非null字段)
|
||||||
|
*/
|
||||||
|
int updateWorkcaseDevice(TbWorkcaseDeviceDTO device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除工单设备文件
|
||||||
|
*/
|
||||||
|
int deleteWorkcaseDevice(@Param("workcaseId") String workcaseId, @Param("fileId") String fileId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据工单ID和文件ID查询
|
||||||
|
*/
|
||||||
|
TbWorkcaseDeviceDTO selectWorkcaseDeviceById(@Param("workcaseId") String workcaseId, @Param("fileId") String fileId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询工单设备文件列表
|
||||||
|
*/
|
||||||
|
List<TbWorkcaseDeviceDTO> selectWorkcaseDeviceList(@Param("filter") TbWorkcaseDeviceDTO filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询工单设备文件
|
||||||
|
*/
|
||||||
|
List<TbWorkcaseDeviceDTO> selectWorkcaseDevicePage(@Param("filter") TbWorkcaseDeviceDTO filter, @Param("pageParam") PageParam pageParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计工单设备文件数量
|
||||||
|
*/
|
||||||
|
long countWorkcaseDevices(@Param("filter") TbWorkcaseDeviceDTO filter);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
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.TbWorkcaseDTO;
|
||||||
|
import org.xyzh.common.core.page.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 工单数据访问层
|
||||||
|
* @filename TbWorkcaseMapper.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface TbWorkcaseMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入工单
|
||||||
|
*/
|
||||||
|
int insertWorkcase(TbWorkcaseDTO workcase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工单(只更新非null字段)
|
||||||
|
*/
|
||||||
|
int updateWorkcase(TbWorkcaseDTO workcase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 逻辑删除工单
|
||||||
|
*/
|
||||||
|
int deleteWorkcase(TbWorkcaseDTO workcase);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询工单
|
||||||
|
*/
|
||||||
|
TbWorkcaseDTO selectWorkcaseById(@Param("workcaseId") String workcaseId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询工单列表
|
||||||
|
*/
|
||||||
|
List<TbWorkcaseDTO> selectWorkcaseList(@Param("filter") TbWorkcaseDTO filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询工单
|
||||||
|
*/
|
||||||
|
List<TbWorkcaseDTO> selectWorkcasePage(@Param("filter") TbWorkcaseDTO filter, @Param("pageParam") PageParam pageParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计工单数量
|
||||||
|
*/
|
||||||
|
long countWorkcases(@Param("filter") TbWorkcaseDTO filter);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
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.TbWorkcaseProcessDTO;
|
||||||
|
import org.xyzh.common.core.page.PageParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 工单过程数据访问层
|
||||||
|
* @filename TbWorkcaseProcessMapper.java
|
||||||
|
* @author yslg
|
||||||
|
* @copyright xyzh
|
||||||
|
* @since 2025-12-18
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface TbWorkcaseProcessMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入工单过程
|
||||||
|
*/
|
||||||
|
int insertWorkcaseProcess(TbWorkcaseProcessDTO process);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工单过程(只更新非null字段)
|
||||||
|
*/
|
||||||
|
int updateWorkcaseProcess(TbWorkcaseProcessDTO process);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除工单过程
|
||||||
|
*/
|
||||||
|
int deleteWorkcaseProcess(@Param("processId") String processId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID查询工单过程
|
||||||
|
*/
|
||||||
|
TbWorkcaseProcessDTO selectWorkcaseProcessById(@Param("processId") String processId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询工单过程列表
|
||||||
|
*/
|
||||||
|
List<TbWorkcaseProcessDTO> selectWorkcaseProcessList(@Param("filter") TbWorkcaseProcessDTO filter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询工单过程
|
||||||
|
*/
|
||||||
|
List<TbWorkcaseProcessDTO> selectWorkcaseProcessPage(@Param("filter") TbWorkcaseProcessDTO filter, @Param("pageParam") PageParam pageParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计工单过程数量
|
||||||
|
*/
|
||||||
|
long countWorkcaseProcesses(@Param("filter") TbWorkcaseProcessDTO filter);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.xyzh.workcase.service;
|
||||||
|
|
||||||
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<TbWorkcaseDTO> analyzeChat(String chatId) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<Boolean> commentChatMessage(TbChat filter, String messageId, String comment) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<TbChat> updateChat(TbChat chat) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<TbWordCloudDTO> updateWordCloud(TbWordCloudDTO wordCloud) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
package org.xyzh.workcase.service;
|
||||||
|
|
||||||
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
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 com.alibaba.fastjson2.JSON;
|
||||||
|
|
||||||
|
@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);
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<TbWorkcaseDTO> updateWorkcase(TbWorkcaseDTO workcase) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<TbWorkcaseDeviceDTO> updateWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultDomain<TbWorkcaseProcessDTO> updateWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
<?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.TbWorkcaseDeviceMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="org.xyzh.api.workcase.dto.TbWorkcaseDeviceDTO">
|
||||||
|
<id column="workcase_id" property="workcaseId" jdbcType="VARCHAR"/>
|
||||||
|
<id column="file_id" property="fileId" jdbcType="VARCHAR"/>
|
||||||
|
<result column="optsn" property="optsn" jdbcType="VARCHAR"/>
|
||||||
|
<result column="device" property="device" jdbcType="VARCHAR"/>
|
||||||
|
<result column="device_code" property="deviceCode" jdbcType="VARCHAR"/>
|
||||||
|
<result column="file_name" property="fileName" jdbcType="VARCHAR"/>
|
||||||
|
<result column="file_root_id" property="fileRootId" jdbcType="VARCHAR"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
workcase_id, file_id, optsn, device, device_code, file_name, file_root_id
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<insert id="insertWorkcaseDevice" parameterType="org.xyzh.api.workcase.dto.TbWorkcaseDeviceDTO">
|
||||||
|
INSERT INTO workcase.tb_workcase_device (
|
||||||
|
optsn, workcase_id, device, file_id, file_name
|
||||||
|
<if test="deviceCode != null">, device_code</if>
|
||||||
|
<if test="fileRootId != null">, file_root_id</if>
|
||||||
|
) VALUES (
|
||||||
|
#{optsn}, #{workcaseId}, #{device}, #{fileId}, #{fileName}
|
||||||
|
<if test="deviceCode != null">, #{deviceCode}</if>
|
||||||
|
<if test="fileRootId != null">, #{fileRootId}</if>
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateWorkcaseDevice" parameterType="org.xyzh.api.workcase.dto.TbWorkcaseDeviceDTO">
|
||||||
|
UPDATE workcase.tb_workcase_device
|
||||||
|
<set>
|
||||||
|
<if test="device != null and device != ''">device = #{device},</if>
|
||||||
|
<if test="deviceCode != null">device_code = #{deviceCode},</if>
|
||||||
|
<if test="fileName != null and fileName != ''">file_name = #{fileName},</if>
|
||||||
|
<if test="fileRootId != null">file_root_id = #{fileRootId},</if>
|
||||||
|
</set>
|
||||||
|
WHERE workcase_id = #{workcaseId} AND file_id = #{fileId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteWorkcaseDevice">
|
||||||
|
DELETE FROM workcase.tb_workcase_device
|
||||||
|
WHERE workcase_id = #{workcaseId} AND file_id = #{fileId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseDeviceById" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase_device
|
||||||
|
WHERE workcase_id = #{workcaseId} AND file_id = #{fileId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseDeviceList" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase_device
|
||||||
|
<where>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.device != null and filter.device != ''">
|
||||||
|
AND device LIKE CONCAT('%', #{filter.device}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.deviceCode != null and filter.deviceCode != ''">
|
||||||
|
AND device_code = #{filter.deviceCode}
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileId != null and filter.fileId != ''">
|
||||||
|
AND file_id = #{filter.fileId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileName != null and filter.fileName != ''">
|
||||||
|
AND file_name LIKE CONCAT('%', #{filter.fileName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileRootId != null and filter.fileRootId != ''">
|
||||||
|
AND file_root_id = #{filter.fileRootId}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY workcase_id, file_id
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseDevicePage" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase_device
|
||||||
|
<where>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.device != null and filter.device != ''">
|
||||||
|
AND device LIKE CONCAT('%', #{filter.device}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.deviceCode != null and filter.deviceCode != ''">
|
||||||
|
AND device_code = #{filter.deviceCode}
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileId != null and filter.fileId != ''">
|
||||||
|
AND file_id = #{filter.fileId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileName != null and filter.fileName != ''">
|
||||||
|
AND file_name LIKE CONCAT('%', #{filter.fileName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileRootId != null and filter.fileRootId != ''">
|
||||||
|
AND file_root_id = #{filter.fileRootId}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY workcase_id, file_id
|
||||||
|
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="countWorkcaseDevices" resultType="long">
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM workcase.tb_workcase_device
|
||||||
|
<where>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.device != null and filter.device != ''">
|
||||||
|
AND device LIKE CONCAT('%', #{filter.device}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.deviceCode != null and filter.deviceCode != ''">
|
||||||
|
AND device_code = #{filter.deviceCode}
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileId != null and filter.fileId != ''">
|
||||||
|
AND file_id = #{filter.fileId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileName != null and filter.fileName != ''">
|
||||||
|
AND file_name LIKE CONCAT('%', #{filter.fileName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.fileRootId != null and filter.fileRootId != ''">
|
||||||
|
AND file_root_id = #{filter.fileRootId}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
<?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.TbWorkcaseMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="org.xyzh.api.workcase.dto.TbWorkcaseDTO">
|
||||||
|
<id column="workcase_id" property="workcaseId" jdbcType="VARCHAR"/>
|
||||||
|
<result column="optsn" property="optsn" jdbcType="VARCHAR"/>
|
||||||
|
<result column="user_id" property="userId" jdbcType="VARCHAR"/>
|
||||||
|
<result column="username" property="username" jdbcType="VARCHAR"/>
|
||||||
|
<result column="phone" property="phone" jdbcType="VARCHAR"/>
|
||||||
|
<result column="type" property="type" jdbcType="VARCHAR"/>
|
||||||
|
<result column="device" property="device" jdbcType="VARCHAR"/>
|
||||||
|
<result column="device_code" property="deviceCode" jdbcType="VARCHAR"/>
|
||||||
|
<result column="imgs" property="imgs" jdbcType="ARRAY" typeHandler="org.xyzh.common.jdbc.handler.StringArrayTypeHandler"/>
|
||||||
|
<result column="emergency" property="emergency" jdbcType="VARCHAR"/>
|
||||||
|
<result column="status" property="status" jdbcType="VARCHAR"/>
|
||||||
|
<result column="processor" property="processor" jdbcType="VARCHAR"/>
|
||||||
|
<result column="creator" property="creator" jdbcType="VARCHAR"/>
|
||||||
|
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||||
|
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
|
||||||
|
<result column="delete_time" property="deleteTime" jdbcType="TIMESTAMP"/>
|
||||||
|
<result column="deleted" property="deleted" jdbcType="BOOLEAN"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
workcase_id, optsn, user_id, username, phone, type, device, device_code, imgs,
|
||||||
|
emergency, status, processor, creator, create_time, update_time, delete_time, deleted
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<insert id="insertWorkcase" parameterType="org.xyzh.api.workcase.dto.TbWorkcaseDTO">
|
||||||
|
INSERT INTO workcase.tb_workcase (
|
||||||
|
optsn, workcase_id, user_id, username, phone, type, device, device_code, creator
|
||||||
|
<if test="imgs != null">, imgs</if>
|
||||||
|
<if test="emergency != null">, emergency</if>
|
||||||
|
<if test="status != null">, status</if>
|
||||||
|
<if test="processor != null">, processor</if>
|
||||||
|
) VALUES (
|
||||||
|
#{optsn}, #{workcaseId}, #{userId}, #{username}, #{phone}, #{type}, #{device}, #{deviceCode}, #{creator}
|
||||||
|
<if test="imgs != null">, #{imgs, typeHandler=org.xyzh.common.jdbc.handler.StringArrayTypeHandler}</if>
|
||||||
|
<if test="emergency != null">, #{emergency}</if>
|
||||||
|
<if test="status != null">, #{status}</if>
|
||||||
|
<if test="processor != null">, #{processor}</if>
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateWorkcase" parameterType="org.xyzh.api.workcase.dto.TbWorkcaseDTO">
|
||||||
|
UPDATE workcase.tb_workcase
|
||||||
|
<set>
|
||||||
|
<if test="userId != null and userId != ''">user_id = #{userId},</if>
|
||||||
|
<if test="username != null and username != ''">username = #{username},</if>
|
||||||
|
<if test="phone != null and phone != ''">phone = #{phone},</if>
|
||||||
|
<if test="type != null and type != ''">type = #{type},</if>
|
||||||
|
<if test="device != null and device != ''">device = #{device},</if>
|
||||||
|
<if test="deviceCode != null and deviceCode != ''">device_code = #{deviceCode},</if>
|
||||||
|
<if test="imgs != null">imgs = #{imgs, typeHandler=org.xyzh.common.jdbc.handler.StringArrayTypeHandler},</if>
|
||||||
|
<if test="emergency != null and emergency != ''">emergency = #{emergency},</if>
|
||||||
|
<if test="status != null and status != ''">status = #{status},</if>
|
||||||
|
<if test="processor != null">processor = #{processor},</if>
|
||||||
|
update_time = now()
|
||||||
|
</set>
|
||||||
|
WHERE workcase_id = #{workcaseId} AND deleted = false
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="deleteWorkcase" parameterType="org.xyzh.api.workcase.dto.TbWorkcaseDTO">
|
||||||
|
UPDATE workcase.tb_workcase
|
||||||
|
SET deleted = true, delete_time = now()
|
||||||
|
WHERE workcase_id = #{workcaseId} AND deleted = false
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseById" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase
|
||||||
|
WHERE workcase_id = #{workcaseId} AND deleted = false
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseList" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase
|
||||||
|
<where>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.userId != null and filter.userId != ''">
|
||||||
|
AND user_id = #{filter.userId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.username != null and filter.username != ''">
|
||||||
|
AND username LIKE CONCAT('%', #{filter.username}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.phone != null and filter.phone != ''">
|
||||||
|
AND phone = #{filter.phone}
|
||||||
|
</if>
|
||||||
|
<if test="filter.type != null and filter.type != ''">
|
||||||
|
AND type = #{filter.type}
|
||||||
|
</if>
|
||||||
|
<if test="filter.device != null and filter.device != ''">
|
||||||
|
AND device LIKE CONCAT('%', #{filter.device}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.deviceCode != null and filter.deviceCode != ''">
|
||||||
|
AND device_code = #{filter.deviceCode}
|
||||||
|
</if>
|
||||||
|
<if test="filter.emergency != null and filter.emergency != ''">
|
||||||
|
AND emergency = #{filter.emergency}
|
||||||
|
</if>
|
||||||
|
<if test="filter.status != null and filter.status != ''">
|
||||||
|
AND status = #{filter.status}
|
||||||
|
</if>
|
||||||
|
<if test="filter.processor != null and filter.processor != ''">
|
||||||
|
AND processor = #{filter.processor}
|
||||||
|
</if>
|
||||||
|
AND deleted = false
|
||||||
|
</where>
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectWorkcasePage" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase
|
||||||
|
<where>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.userId != null and filter.userId != ''">
|
||||||
|
AND user_id = #{filter.userId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.username != null and filter.username != ''">
|
||||||
|
AND username LIKE CONCAT('%', #{filter.username}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.phone != null and filter.phone != ''">
|
||||||
|
AND phone = #{filter.phone}
|
||||||
|
</if>
|
||||||
|
<if test="filter.type != null and filter.type != ''">
|
||||||
|
AND type = #{filter.type}
|
||||||
|
</if>
|
||||||
|
<if test="filter.device != null and filter.device != ''">
|
||||||
|
AND device LIKE CONCAT('%', #{filter.device}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.deviceCode != null and filter.deviceCode != ''">
|
||||||
|
AND device_code = #{filter.deviceCode}
|
||||||
|
</if>
|
||||||
|
<if test="filter.emergency != null and filter.emergency != ''">
|
||||||
|
AND emergency = #{filter.emergency}
|
||||||
|
</if>
|
||||||
|
<if test="filter.status != null and filter.status != ''">
|
||||||
|
AND status = #{filter.status}
|
||||||
|
</if>
|
||||||
|
<if test="filter.processor != null and filter.processor != ''">
|
||||||
|
AND processor = #{filter.processor}
|
||||||
|
</if>
|
||||||
|
AND deleted = false
|
||||||
|
</where>
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="countWorkcases" resultType="long">
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM workcase.tb_workcase
|
||||||
|
<where>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.userId != null and filter.userId != ''">
|
||||||
|
AND user_id = #{filter.userId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.username != null and filter.username != ''">
|
||||||
|
AND username LIKE CONCAT('%', #{filter.username}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.phone != null and filter.phone != ''">
|
||||||
|
AND phone = #{filter.phone}
|
||||||
|
</if>
|
||||||
|
<if test="filter.type != null and filter.type != ''">
|
||||||
|
AND type = #{filter.type}
|
||||||
|
</if>
|
||||||
|
<if test="filter.device != null and filter.device != ''">
|
||||||
|
AND device LIKE CONCAT('%', #{filter.device}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="filter.deviceCode != null and filter.deviceCode != ''">
|
||||||
|
AND device_code = #{filter.deviceCode}
|
||||||
|
</if>
|
||||||
|
<if test="filter.emergency != null and filter.emergency != ''">
|
||||||
|
AND emergency = #{filter.emergency}
|
||||||
|
</if>
|
||||||
|
<if test="filter.status != null and filter.status != ''">
|
||||||
|
AND status = #{filter.status}
|
||||||
|
</if>
|
||||||
|
<if test="filter.processor != null and filter.processor != ''">
|
||||||
|
AND processor = #{filter.processor}
|
||||||
|
</if>
|
||||||
|
AND deleted = false
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
<?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.TbWorkcaseProcessMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="org.xyzh.api.workcase.dto.TbWorkcaseProcessDTO">
|
||||||
|
<id column="process_id" property="processId" jdbcType="VARCHAR"/>
|
||||||
|
<result column="optsn" property="optsn" jdbcType="VARCHAR"/>
|
||||||
|
<result column="workcase_id" property="workcaseId" jdbcType="VARCHAR"/>
|
||||||
|
<result column="action" property="action" jdbcType="VARCHAR"/>
|
||||||
|
<result column="message" property="message" jdbcType="VARCHAR"/>
|
||||||
|
<result column="files" property="files" jdbcType="ARRAY" typeHandler="org.xyzh.common.jdbc.handler.StringArrayTypeHandler"/>
|
||||||
|
<result column="processor" property="processor" jdbcType="VARCHAR"/>
|
||||||
|
<result column="remark" property="remark" jdbcType="VARCHAR"/>
|
||||||
|
<result column="creator" property="creator" jdbcType="VARCHAR"/>
|
||||||
|
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
process_id, optsn, workcase_id, action, message, files, processor, remark, creator, create_time
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<insert id="insertWorkcaseProcess" parameterType="org.xyzh.api.workcase.dto.TbWorkcaseProcessDTO">
|
||||||
|
INSERT INTO workcase.tb_workcase_process (
|
||||||
|
optsn, workcase_id, process_id, action, creator
|
||||||
|
<if test="message != null">, message</if>
|
||||||
|
<if test="files != null">, files</if>
|
||||||
|
<if test="processor != null">, processor</if>
|
||||||
|
<if test="remark != null">, remark</if>
|
||||||
|
) VALUES (
|
||||||
|
#{optsn}, #{workcaseId}, #{processId}, #{action}, #{creator}
|
||||||
|
<if test="message != null">, #{message}</if>
|
||||||
|
<if test="files != null">, #{files, typeHandler=org.xyzh.common.jdbc.handler.StringArrayTypeHandler}</if>
|
||||||
|
<if test="processor != null">, #{processor}</if>
|
||||||
|
<if test="remark != null">, #{remark}</if>
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="updateWorkcaseProcess" parameterType="org.xyzh.api.workcase.dto.TbWorkcaseProcessDTO">
|
||||||
|
UPDATE workcase.tb_workcase_process
|
||||||
|
<set>
|
||||||
|
<if test="action != null and action != ''">action = #{action},</if>
|
||||||
|
<if test="message != null">message = #{message},</if>
|
||||||
|
<if test="files != null">files = #{files, typeHandler=org.xyzh.common.jdbc.handler.StringArrayTypeHandler},</if>
|
||||||
|
<if test="processor != null">processor = #{processor},</if>
|
||||||
|
<if test="remark != null">remark = #{remark},</if>
|
||||||
|
</set>
|
||||||
|
WHERE process_id = #{processId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteWorkcaseProcess">
|
||||||
|
DELETE FROM workcase.tb_workcase_process
|
||||||
|
WHERE process_id = #{processId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseProcessById" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase_process
|
||||||
|
WHERE process_id = #{processId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseProcessList" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase_process
|
||||||
|
<where>
|
||||||
|
<if test="filter.processId != null and filter.processId != ''">
|
||||||
|
AND process_id = #{filter.processId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.action != null and filter.action != ''">
|
||||||
|
AND action = #{filter.action}
|
||||||
|
</if>
|
||||||
|
<if test="filter.processor != null and filter.processor != ''">
|
||||||
|
AND processor = #{filter.processor}
|
||||||
|
</if>
|
||||||
|
<if test="filter.creator != null and filter.creator != ''">
|
||||||
|
AND creator = #{filter.creator}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY create_time ASC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectWorkcaseProcessPage" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM workcase.tb_workcase_process
|
||||||
|
<where>
|
||||||
|
<if test="filter.processId != null and filter.processId != ''">
|
||||||
|
AND process_id = #{filter.processId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.action != null and filter.action != ''">
|
||||||
|
AND action = #{filter.action}
|
||||||
|
</if>
|
||||||
|
<if test="filter.processor != null and filter.processor != ''">
|
||||||
|
AND processor = #{filter.processor}
|
||||||
|
</if>
|
||||||
|
<if test="filter.creator != null and filter.creator != ''">
|
||||||
|
AND creator = #{filter.creator}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY create_time ASC
|
||||||
|
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="countWorkcaseProcesses" resultType="long">
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM workcase.tb_workcase_process
|
||||||
|
<where>
|
||||||
|
<if test="filter.processId != null and filter.processId != ''">
|
||||||
|
AND process_id = #{filter.processId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.workcaseId != null and filter.workcaseId != ''">
|
||||||
|
AND workcase_id = #{filter.workcaseId}
|
||||||
|
</if>
|
||||||
|
<if test="filter.action != null and filter.action != ''">
|
||||||
|
AND action = #{filter.action}
|
||||||
|
</if>
|
||||||
|
<if test="filter.processor != null and filter.processor != ''">
|
||||||
|
AND processor = #{filter.processor}
|
||||||
|
</if>
|
||||||
|
<if test="filter.creator != null and filter.creator != ''">
|
||||||
|
AND creator = #{filter.creator}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
12
urbanLifelineServ/workcase/工单流程.md
Normal file
12
urbanLifelineServ/workcase/工单流程.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# 小程序用户聊天和工单的产生逻辑
|
||||||
|
接口实现方式:
|
||||||
|
1. WorkcaseChatServiceImpl通过ai接口进行ai回复,对话人员是来客和ai
|
||||||
|
2. 当连续3次ai聊天后,询问是否转人工
|
||||||
|
3. 用户触发转人工(可能是一开始,就手动触发,没有聊天记录),跳转到微信客服的功能服务
|
||||||
|
4. 用户跳转前,必须创建工单
|
||||||
|
5. 同步工单到CRM
|
||||||
|
6. 将工单信息作为微信客服的欢迎语,进行放送,让来客和员工能看到工单的基本信息,从而实现让员工知道工单是哪一个
|
||||||
|
<!-- 员工可前往网页查看工单,和相关的聊天记录(ai和来客的对话)以及(员工和来客的对话) -->
|
||||||
|
7. 同步用户和员工在微信客服上的聊天记录,同步到tb_chat表里面,对话人员是来客和客服。(把ai替换成员工进行对话的续接)
|
||||||
|
8. 员工自己更新工单状态,如果在CRM更新工单状态会触发receiveWorkcaseFromCrm,如果在本系统更新工单会触发工单同步到CRM
|
||||||
|
9. 在工单是完成、撤销后,工单、对话进行总结,并更新词云
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
1. 不再自己构建知识库,使用dify的知识库
|
|
||||||
2. 服务的知识库表,只对文件进行重新上传才产生版本,对知识库内文档分段等修改不生成新的版本
|
|
||||||
Reference in New Issue
Block a user