diff --git a/.gitignore b/.gitignore
index 12ab2e8a..52a3d422 100644
--- a/.gitignore
+++ b/.gitignore
@@ -199,4 +199,5 @@ cython_debug/
# PyPI configuration file
.pypirc
-江西城市生命线-可交互原型/frontend/node_modules/*
\ No newline at end of file
+江西城市生命线-可交互原型/frontend/node_modules/*
+THAI-Platform/*
\ No newline at end of file
diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableAI.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableAI.sql
index 6e5c68a0..38df93d9 100644
--- a/urbanLifelineServ/.bin/database/postgres/sql/createTableAI.sql
+++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableAI.sql
@@ -33,6 +33,7 @@ CREATE TABLE ai.tb_chat(
user_id VARCHAR(50) NOT NULL, -- 用户ID
user_type BOOLEAN NOT NULL DEFAULT true, -- 用户类型 true-系统内部人员 false-系统外部人员
title VARCHAR(500) NOT NULL, -- 对话标题
+ channel VARCHAR(50) DEFAULT 'agent' -- 对话渠道 agent、wechat
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
diff --git a/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql b/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql
index 6c7c7de8..6bc200d3 100644
--- a/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql
+++ b/urbanLifelineServ/.bin/database/postgres/sql/createTableWorkcase.sql
@@ -20,27 +20,93 @@ CREATE TABLE sys.tb_guest(
);
--- 客服对话记录,客服对话消息,包含ai、员工回答和来客提问
--- 直接使用ai.tb_chat和ai.tb_chat_message,user_type为false,表示该对话为来客对话
--- 这里,需要把在微信客服上的聊天同步到ai.tb_chat_message
+-- 客服对话记录,客服对话消息,包含ai、员工回答和来客提问,从ai.tb_chat同步ai对话时的数据
+-- 先是ai对话,后转人工
+
+
+
-- 工单表
DROP TABLE IF EXISTS workcase.tb_workcase CASCADE;
CREATE TABLE workcase.tb_workcase(
optsn VARCHAR(50) NOT NULL, -- 流水号
workcase_id VARCHAR(50) NOT NULL, -- 工单ID
+ chat_id VARCHAR(50) NOT NULL, -- 对话ID
user_id VARCHAR(50) NOT NULL, -- 来客ID
username VARCHAR(200) NOT NULL, -- 来客姓名
phone VARCHAR(20) 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-紧急
status VARCHAR(50) NOT NULL DEFAULT 'pending', -- 状态 pending-待处理 processing-处理中 done-已完成
processor VARCHAR(50) DEFAULT NULL, -- 处理人
+ creator VARCHAR(50) NOT NULL, -- 创建人
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
PRIMARY KEY (workcase_id),
+ UNIQUE (chat_id),
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) -- 同一天同一分类的词唯一
);
\ No newline at end of file
diff --git a/urbanLifelineServ/ai/pom.xml b/urbanLifelineServ/ai/pom.xml
index 370b25af..9dddd762 100644
--- a/urbanLifelineServ/ai/pom.xml
+++ b/urbanLifelineServ/ai/pom.xml
@@ -45,6 +45,10 @@
org.xyzh.common
common-utils
+
+ org.xyzh.common
+ common-jdbc
+
org.xyzh.common
common-exception
diff --git a/urbanLifelineServ/ai/src/main/resources/mapper/TbChatMessageMapper.xml b/urbanLifelineServ/ai/src/main/resources/mapper/TbChatMessageMapper.xml
index 1ffdadaf..9edc64e1 100644
--- a/urbanLifelineServ/ai/src/main/resources/mapper/TbChatMessageMapper.xml
+++ b/urbanLifelineServ/ai/src/main/resources/mapper/TbChatMessageMapper.xml
@@ -9,7 +9,7 @@
-
+
@@ -31,7 +31,7 @@
) VALUES (
#{optsn}, #{messageId}, #{chatId}, #{role}, #{content}
, #{difyMessageId}
- , #{files, typeHandler=org.xyzh.common.utils.json.StringArrayTypeHandler}
+ , #{files, typeHandler=org.xyzh.common.jdbc.handler.StringArrayTypeHandler}
, #{comment}
)
diff --git a/urbanLifelineServ/apis/api-system/src/main/java/org/xyzh/api/system/service/GuestService.java b/urbanLifelineServ/apis/api-system/src/main/java/org/xyzh/api/system/service/GuestService.java
index c5fbf206..d4301160 100644
--- a/urbanLifelineServ/apis/api-system/src/main/java/org/xyzh/api/system/service/GuestService.java
+++ b/urbanLifelineServ/apis/api-system/src/main/java/org/xyzh/api/system/service/GuestService.java
@@ -45,6 +45,14 @@ public interface GuestService {
*/
ResultDomain selectGuestOne(TbGuestDTO guest);
+ /**
+ * @description 根据微信id查询来客
+ * @param wechatId
+ * @author yslg
+ * @since 2025-12-18
+ */
+ ResultDomain selectGuestByWechatId(String wechatId);
+
/**
* @description 查询来客列表
* @param guest 来客信息
diff --git a/urbanLifelineServ/apis/api-workcase/pom.xml b/urbanLifelineServ/apis/api-workcase/pom.xml
index 5bcd75a9..d8c42550 100644
--- a/urbanLifelineServ/apis/api-workcase/pom.xml
+++ b/urbanLifelineServ/apis/api-workcase/pom.xml
@@ -9,7 +9,7 @@
1.0.0
- org.xyzh
+ org.xyzh.apis
api-workcase
1.0.0
@@ -18,4 +18,10 @@
21
+
+
+ org.xyzh.apis
+ api-ai
+
+
\ No newline at end of file
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/Main.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/Main.java
deleted file mode 100644
index f660b7a0..00000000
--- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/Main.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.xyzh;
-
-public class Main {
- public static void main(String[] args) {
- System.out.println("Hello world!");
- }
-}
\ No newline at end of file
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/WorkcaseService.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/WorkcaseService.java
deleted file mode 100644
index f9dd5fc1..00000000
--- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/WorkcaseService.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.xyzh.api.workcase;
-
-/**
- * 工单服务接口
- * 用于客服工单管理
- */
-public interface WorkcaseService {
-
-}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbConversationDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbConversationDTO.java
deleted file mode 100644
index c9c5d6e5..00000000
--- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbConversationDTO.java
+++ /dev/null
@@ -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 tags;
-
- @Schema(description = "会话元数据")
- private JsonNode metadata;
-}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbCustomerDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbCustomerDTO.java
deleted file mode 100644
index 76ebd840..00000000
--- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbCustomerDTO.java
+++ /dev/null
@@ -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 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;
-}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbTicketDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbTicketDTO.java
deleted file mode 100644
index cce7ab72..00000000
--- a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbTicketDTO.java
+++ /dev/null
@@ -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 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 tags;
-
- @Schema(description = "工单元数据")
- private JsonNode metadata;
-}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWordCloudDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWordCloudDTO.java
new file mode 100644
index 00000000..4e676176
--- /dev/null
+++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWordCloudDTO.java
@@ -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;
+
+}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseDTO.java
new file mode 100644
index 00000000..6f554d5a
--- /dev/null
+++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseDTO.java
@@ -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 imgs;
+
+ @Schema(description = "紧急程度 normal-普通 emergency-紧急")
+ private String emergency;
+
+ @Schema(description = "状态 pending-待处理 processing-处理中 done-已完成")
+ private String status;
+
+ @Schema(description = "处理人ID")
+ private String processor;
+
+}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseDeviceDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseDeviceDTO.java
new file mode 100644
index 00000000..8ef5930b
--- /dev/null
+++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseDeviceDTO.java
@@ -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;
+
+}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseProcessDTO.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseProcessDTO.java
new file mode 100644
index 00000000..c8b960c3
--- /dev/null
+++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/dto/TbWorkcaseProcessDTO.java
@@ -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 files;
+
+ @Schema(description = "处理人(指派、转派专属)")
+ private String processor;
+
+}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/WorkcaseChatService.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/WorkcaseChatService.java
new file mode 100644
index 00000000..84afce79
--- /dev/null
+++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/WorkcaseChatService.java
@@ -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 createChat(TbChat chat);
+
+ /**
+ * @description 更新聊天名称
+ * @param
+ * @author yslg
+ * @since 2025-12-18
+ */
+ ResultDomain updateChat(TbChat chat);
+
+ /**
+ * 获取聊天列表
+ * @param agentId 智能体ID
+ * @return 聊天列表
+ */
+ ResultDomain getChatList(TbChat filter);
+
+ /**
+ * 获取聊天分页
+ * @param pageRequest
+ * @return 聊天分页
+ */
+ ResultDomain getChatPage(PageRequest pageRequest);
+
+ // ========================= 聊天信息管理 ======================
+
+ /**
+ * 获取会话消息列表
+ * @param filter 会话过滤条件(包含agentId, chatId, userId, userType)
+ * @return 会话消息列表
+ */
+ ResultDomain getChatMessageList(TbChat filter);
+
+ // 用户转人工后,就不和智能体聊天了,在微信客服里聊天
+ /**
+ * 准备聊天数据(POST传递复杂参数)
+ * @param prepareData 对话准备数据(包含agentId, chatId, query, files, userId, userType)
+ * @return ResultDomain 返回sessionId
+ */
+ ResultDomain 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 stopChatMessageByTaskId(TbChat filter, String taskId);
+
+ /**
+ * 评价
+ * @param filter 会话过滤条件(包含agentId, chatId, userId, userType)
+ * @param messageId 消息ID
+ * @param comment 评价
+ * @return 评价结果
+ */
+ ResultDomain commentChatMessage(TbChat filter, String messageId, String comment);
+
+ // =============================== 对话分析 ==========================
+
+ /**
+ * 对话分析, 提取出工单相关的内容,这里有智能体调用等
+ * @param chatId 对话ID
+ * @return 对话分析结果
+ */
+ ResultDomain analyzeChat(String chatId);
+
+ // 对话总结
+ ResultDomain summaryChat(String chatId);
+
+
+
+ // =============================== 对话、工单等词云管理 ==========================
+
+ /**
+ * @description 添加词云
+ * @param wordCloud 词云对象
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain addWordCloud(TbWordCloudDTO wordCloud);
+
+ /**
+ * @description 更新词云
+ * @param wordCloud 词云对象
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain updateWordCloud(TbWordCloudDTO wordCloud);
+
+ /**
+ * @description 获取词云列表
+ * @param filter 词云过滤条件
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWordCloudList(TbWordCloudDTO filter);
+
+ /**
+ * @description 获取词云分页
+ * @param pageRequest 分页请求
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWordCloudPage(PageRequest pageRequest);
+
+}
diff --git a/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/WorkcaseService.java b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/WorkcaseService.java
new file mode 100644
index 00000000..868727c2
--- /dev/null
+++ b/urbanLifelineServ/apis/api-workcase/src/main/java/org/xyzh/api/workcase/service/WorkcaseService.java
@@ -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 createWorkcase(TbWorkcaseDTO workcase);
+ /**
+ * @description 更新工单
+ * @param workcase
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain updateWorkcase(TbWorkcaseDTO workcase);
+
+ /**
+ * @description 删除工单
+ * @param workcase
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain deleteWorkcase(TbWorkcaseDTO workcase);
+
+ /**
+ * @description 获取工单列表
+ * @param filter
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWorkcaseList(TbWorkcaseDTO filter);
+
+ /**
+ * @description 获取工单分页
+ * @param pageRequest
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWorkcasePage(PageRequest pageRequest);
+
+ /**
+ * @description 获取工单详情
+ * @param workcaseId
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWorkcaseById(String workcaseId);
+
+ // ====================== 同步到CRM和接收 ===================
+ /**
+ * @description 同步工单到CRM
+ * @param workcase
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain syncWorkcaseToCrm(TbWorkcaseDTO workcase);
+
+ /**
+ * @description 接收CRM的工单处理结果
+ * @param json
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain receiveWorkcaseFromCrm(JSON json);
+
+ // ====================== 工单处理过程 ======================
+ /**
+ * @description 创建工单处理过程
+ * @param workcaseProcess
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain createWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess);
+
+ /**
+ * @description 更新工单处理过程
+ * @param workcaseProcess
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain updateWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess);
+
+ /**
+ * @description 删除工单处理过程
+ * @param workcaseProcess
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain deleteWorkcaseProcess(TbWorkcaseProcessDTO workcaseProcess);
+
+ /**
+ * @description 获取工单处理过程列表
+ * @param filter
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWorkcaseProcessList(TbWorkcaseProcessDTO filter);
+
+ /**
+ * @description 获取工单处理过程分页
+ * @param pageRequest
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWorkcaseProcessPage(PageRequest pageRequest);
+
+ // ====================== 工单设备管理 ======================
+ /**
+ * @description 创建工单设备
+ * @param workcaseDevice
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain createWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice);
+ /**
+ * @description 更新工单设备
+ * @param workcaseDevice
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain updateWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice);
+ /**
+ * @description 删除工单设备
+ * @param workcaseDevice
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain deleteWorkcaseDevice(TbWorkcaseDeviceDTO workcaseDevice);
+ /**
+ * @description 获取工单设备列表
+ * @param filter
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWorkcaseDeviceList(TbWorkcaseDeviceDTO filter);
+ /**
+ * @description 获取工单设备分页
+ * @param pageRequest
+ * @author yslg
+ * @since 2025-12-19
+ */
+ ResultDomain getWorkcaseDevicePage(PageRequest pageRequest);
+
+
+}
diff --git a/urbanLifelineServ/common/common-all/pom.xml b/urbanLifelineServ/common/common-all/pom.xml
index 1b1138d0..77a04afa 100644
--- a/urbanLifelineServ/common/common-all/pom.xml
+++ b/urbanLifelineServ/common/common-all/pom.xml
@@ -44,6 +44,10 @@
org.xyzh.common
common-utils
+
+ org.xyzh.common
+ common-jdbc
+
\ No newline at end of file
diff --git a/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/BaseDTO.java b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/BaseDTO.java
index e8255364..65e207c8 100644
--- a/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/BaseDTO.java
+++ b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/BaseDTO.java
@@ -2,6 +2,8 @@ package org.xyzh.common.dto;
import java.io.Serializable;
import java.util.Date;
+import java.util.List;
+
import com.alibaba.fastjson2.annotation.JSONField;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -41,4 +43,19 @@ public class BaseDTO implements Serializable {
@Schema(description = "是否已删除", defaultValue = "false")
private Boolean deleted = false;
+
+
+ // =============== 下方为筛选字段,非数据库字段 ================
+
+ @Schema(description = "数量限制")
+ private Integer limit;
+
+ @Schema(description = "开始时间")
+ private Date startTime;
+
+ @Schema(description = "结束时间")
+ private Date endTime;
+
+ @Schema(description = "排序字段")
+ private List orderFields;
}
\ No newline at end of file
diff --git a/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/OrderField.java b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/OrderField.java
new file mode 100644
index 00000000..a9fc928a
--- /dev/null
+++ b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/OrderField.java
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java
index c1d48c22..558621e8 100644
--- a/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java
+++ b/urbanLifelineServ/common/common-dto/src/main/java/org/xyzh/common/dto/sys/TbSysUserDTO.java
@@ -4,8 +4,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.dto.BaseDTO;
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;
@@ -33,7 +31,6 @@ public class TbSysUserDTO extends BaseDTO {
@Schema(description = "邮箱")
private String email;
- @TableField(typeHandler = EncryptedStringTypeHandler.class)
@Schema(description = "手机(加密)")
private String phone;
diff --git a/urbanLifelineServ/common/common-jdbc/pom.xml b/urbanLifelineServ/common/common-jdbc/pom.xml
new file mode 100644
index 00000000..9385ac12
--- /dev/null
+++ b/urbanLifelineServ/common/common-jdbc/pom.xml
@@ -0,0 +1,44 @@
+
+
+ 4.0.0
+
+ org.xyzh
+ common
+ 1.0.0
+
+
+ org.xyzh.common
+ common-jdbc
+ ${urban-lifeline.version}
+ jar
+ JDBC相关工具:MyBatis类型处理器
+
+
+ 21
+ 21
+
+
+
+
+
+ org.mybatis
+ mybatis
+ provided
+
+
+
+
+ com.alibaba.fastjson2
+ fastjson2-extension-spring6
+
+
+
+
+ org.xyzh.common
+ common-utils
+ provided
+
+
+
diff --git a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/TypeHandlerConfig.java b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/config/TypeHandlerConfig.java
similarity index 88%
rename from urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/TypeHandlerConfig.java
rename to urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/config/TypeHandlerConfig.java
index e7ea3fc4..35dc0349 100644
--- a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/TypeHandlerConfig.java
+++ b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/config/TypeHandlerConfig.java
@@ -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.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
+import org.xyzh.common.jdbc.handler.EncryptedStringTypeHandler;
+import org.xyzh.common.utils.crypto.AesEncryptUtil;
import jakarta.annotation.PostConstruct;
diff --git a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/EncryptedStringTypeHandler.java b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/EncryptedStringTypeHandler.java
similarity index 96%
rename from urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/EncryptedStringTypeHandler.java
rename to urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/EncryptedStringTypeHandler.java
index 17b9b4f3..60a9b3ed 100644
--- a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/crypto/EncryptedStringTypeHandler.java
+++ b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/EncryptedStringTypeHandler.java
@@ -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.JdbcType;
import org.apache.ibatis.type.MappedTypes;
+import org.xyzh.common.utils.crypto.AesEncryptUtil;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
diff --git a/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/EnumNameTypeHandler.java b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/EnumNameTypeHandler.java
new file mode 100644
index 00000000..fd8226ec
--- /dev/null
+++ b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/EnumNameTypeHandler.java
@@ -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> extends BaseTypeHandler {
+
+ private final Class type;
+
+ public EnumNameTypeHandler(Class 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;
+ }
+}
diff --git a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/json/FastJson2TypeHandler.java b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/FastJson2TypeHandler.java
similarity index 93%
rename from urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/json/FastJson2TypeHandler.java
rename to urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/FastJson2TypeHandler.java
index 70801d89..b30ad91c 100644
--- a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/json/FastJson2TypeHandler.java
+++ b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/FastJson2TypeHandler.java
@@ -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.JSONObject;
@@ -15,7 +15,7 @@ import java.sql.SQLException;
* @description FastJSON2 JSONObject 类型处理器
* @filename FastJson2TypeHandler.java
* @author yslg
- * @copyright yslg
+ * @copyright xyzh
* @since 2025-12-09
*/
@MappedTypes({JSONObject.class})
@@ -51,7 +51,6 @@ public class FastJson2TypeHandler extends BaseTypeHandler {
try {
return JSON.parseObject(jsonString);
} catch (Exception e) {
- // 如果解析失败,返回一个空的JSONObject
return new JSONObject();
}
}
diff --git a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/json/StringArrayTypeHandler.java b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/StringArrayTypeHandler.java
similarity index 97%
rename from urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/json/StringArrayTypeHandler.java
rename to urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/StringArrayTypeHandler.java
index e868aaa9..f6659759 100644
--- a/urbanLifelineServ/common/common-utils/src/main/java/org/xyzh/common/utils/json/StringArrayTypeHandler.java
+++ b/urbanLifelineServ/common/common-jdbc/src/main/java/org/xyzh/common/jdbc/handler/StringArrayTypeHandler.java
@@ -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.JdbcType;
@@ -16,7 +16,7 @@ import java.util.List;
* @description PostgreSQL VARCHAR数组类型处理器
* @filename StringArrayTypeHandler.java
* @author yslg
- * @copyright yslg
+ * @copyright xyzh
* @since 2025-12-15
*/
@MappedTypes({List.class})
diff --git a/urbanLifelineServ/common/common-utils/pom.xml b/urbanLifelineServ/common/common-utils/pom.xml
index 9536c302..ad51b7d6 100644
--- a/urbanLifelineServ/common/common-utils/pom.xml
+++ b/urbanLifelineServ/common/common-utils/pom.xml
@@ -30,16 +30,6 @@
poi-ooxml
-
-
- org.mybatis
- mybatis
- provided
-
-
- com.baomidou
- mybatis-plus-boot-starter
-
org.springframework.boot
diff --git a/urbanLifelineServ/common/pom.xml b/urbanLifelineServ/common/pom.xml
index 6561405e..8bd0be38 100644
--- a/urbanLifelineServ/common/pom.xml
+++ b/urbanLifelineServ/common/pom.xml
@@ -19,6 +19,7 @@
common-auth
common-redis
common-utils
+ common-jdbc
common-all
common-exception
@@ -65,6 +66,11 @@
common-exception
${urban-lifeline.version}
+
+ org.xyzh.common
+ common-jdbc
+ ${urban-lifeline.version}
+
\ No newline at end of file
diff --git a/urbanLifelineServ/pom.xml b/urbanLifelineServ/pom.xml
index 1facc96d..cd9ed4da 100644
--- a/urbanLifelineServ/pom.xml
+++ b/urbanLifelineServ/pom.xml
@@ -195,6 +195,12 @@
+
+
+ com.baomidou
+ mybatis-plus-annotation
+ ${mybatis.plus.version}
+
org.mybatis
@@ -247,6 +253,16 @@
api-log
${urban-lifeline.version}
+
+ org.xyzh.apis
+ api-ai
+ ${urban-lifeline.version}
+
+
+ org.xyzh.apis
+ api-workcase
+ ${urban-lifeline.version}
+
@@ -279,6 +295,11 @@
common-exception
${urban-lifeline.version}
+
+ org.xyzh.common
+ common-jdbc
+ ${urban-lifeline.version}
+
org.xyzh
diff --git a/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java b/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java
index 17f791d9..d16ad6cd 100644
--- a/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java
+++ b/urbanLifelineServ/system/src/main/java/org/xyzh/system/controller/GuestController.java
@@ -6,6 +6,7 @@ import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -16,6 +17,7 @@ import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.sys.TbGuestDTO;
import org.xyzh.common.utils.validation.ValidationUtils;
+import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
/**
@@ -63,6 +65,11 @@ public class GuestController {
return guestService.deleteGuest(userId);
}
+ @GetMapping("/wechat/{wechatId}")
+ public ResultDomain selectGuestByWechat(@PathVariable("wechatId") @NotBlank String wechatId){
+ return guestService.selectGuestByWechatId(wechatId);
+ }
+
@GetMapping("/list")
public ResultDomain listGuest(TbGuestDTO filter) {
diff --git a/urbanLifelineServ/system/src/main/java/org/xyzh/system/mapper/user/TbGuestMapper.java b/urbanLifelineServ/system/src/main/java/org/xyzh/system/mapper/user/TbGuestMapper.java
index ae979b84..79b36b4c 100644
--- a/urbanLifelineServ/system/src/main/java/org/xyzh/system/mapper/user/TbGuestMapper.java
+++ b/urbanLifelineServ/system/src/main/java/org/xyzh/system/mapper/user/TbGuestMapper.java
@@ -50,6 +50,14 @@ public interface TbGuestMapper extends BaseMapper{
*/
TbGuestDTO selectGuestOne(TbGuestDTO guest);
+ /**
+ * @description 根据微信id查询来客
+ * @param wechatId
+ * @author yslg
+ * @since 2025-12-18
+ */
+ TbGuestDTO selectGuestByWechatId(String wechatId);
+
/**
* @description 查询来客列表
* @param guest 来客信息
diff --git a/urbanLifelineServ/system/src/main/java/org/xyzh/system/service/impl/GuestServiceImpl.java b/urbanLifelineServ/system/src/main/java/org/xyzh/system/service/impl/GuestServiceImpl.java
index d62b503e..50fcf4f9 100644
--- a/urbanLifelineServ/system/src/main/java/org/xyzh/system/service/impl/GuestServiceImpl.java
+++ b/urbanLifelineServ/system/src/main/java/org/xyzh/system/service/impl/GuestServiceImpl.java
@@ -49,21 +49,31 @@ public class GuestServiceImpl implements GuestService{
}
@Override
+ @Transactional
public ResultDomain deleteGuest(String userId) {
- guestMapper.deleteGuest(userId);
- return ResultDomain.success("删除成功");
+ int rows = guestMapper.deleteGuest(userId);
+ if (rows > 0) {
+ return ResultDomain.success("删除成功");
+ }
+ return ResultDomain.failure("删除失败,来客不存在");
}
@Override
public ResultDomain selectGuestList(TbGuestDTO guest) {
- guestMapper.selectGuestList(guest);
- return ResultDomain.success("查询成功",guest);
+ List list = guestMapper.selectGuestList(guest);
+ return ResultDomain.success("查询成功", list);
}
@Override
public ResultDomain selectGuestOne(TbGuestDTO guest) {
- guestMapper.selectGuestOne(guest);
- return ResultDomain.success("查询成功",guest);
+ TbGuestDTO selected = guestMapper.selectGuestOne(guest);
+ return ResultDomain.success("查询成功",selected);
+ }
+
+ @Override
+ public ResultDomain selectGuestByWechatId(String wechatId){
+ TbGuestDTO selected = guestMapper.selectGuestByWechatId(wechatId);
+ return ResultDomain.success("查询成功", selected);
}
@Override
diff --git a/urbanLifelineServ/system/src/main/resources/mapper/config/TbSysConfigMapper.xml b/urbanLifelineServ/system/src/main/resources/mapper/config/TbSysConfigMapper.xml
index c4795284..cd938752 100644
--- a/urbanLifelineServ/system/src/main/resources/mapper/config/TbSysConfigMapper.xml
+++ b/urbanLifelineServ/system/src/main/resources/mapper/config/TbSysConfigMapper.xml
@@ -11,8 +11,8 @@
-
-
+
+
@@ -37,8 +37,8 @@
-
-
+
+
diff --git a/urbanLifelineServ/system/src/main/resources/mapper/user/TbGuestMapper.xml b/urbanLifelineServ/system/src/main/resources/mapper/user/TbGuestMapper.xml
index 035602b2..b312b249 100644
--- a/urbanLifelineServ/system/src/main/resources/mapper/user/TbGuestMapper.xml
+++ b/urbanLifelineServ/system/src/main/resources/mapper/user/TbGuestMapper.xml
@@ -74,11 +74,16 @@
AND wechat_id = #{wechatId}
-
-
+ LIMIT 1
+