This commit is contained in:
2025-12-22 11:06:48 +08:00
parent 6c1aa13498
commit 1f37db80d8
12 changed files with 548 additions and 29 deletions

View File

@@ -37,10 +37,7 @@ CREATE TABLE workcase.tb_chat_room(
guest_id VARCHAR(50) NOT NULL, -- 来客ID创建者
guest_name VARCHAR(100) NOT NULL, -- 来客姓名
ai_session_id VARCHAR(50) DEFAULT NULL, -- AI对话会话ID从ai.tb_chat同步
current_agent_id VARCHAR(50) DEFAULT NULL, -- 当前负责客服ID
agent_count INTEGER NOT NULL DEFAULT 0, -- 已加入的客服人数
message_count INTEGER NOT NULL DEFAULT 0, -- 消息总数
unread_count INTEGER NOT NULL DEFAULT 0, -- 未读消息数(客服端)
last_message_time TIMESTAMPTZ DEFAULT NULL, -- 最后消息时间
last_message TEXT DEFAULT NULL, -- 最后一条消息内容(用于列表展示)
closed_by VARCHAR(50) DEFAULT NULL, -- 关闭人
@@ -55,7 +52,6 @@ CREATE TABLE workcase.tb_chat_room(
UNIQUE (optsn)
);
CREATE INDEX idx_chat_room_guest ON workcase.tb_chat_room(guest_id, status);
CREATE INDEX idx_chat_room_agent ON workcase.tb_chat_room(current_agent_id, status);
CREATE INDEX idx_chat_room_time ON workcase.tb_chat_room(last_message_time DESC);
COMMENT ON TABLE workcase.tb_chat_room IS 'IM聊天室表一个工单对应一个聊天室';
@@ -196,10 +192,21 @@ CREATE TABLE workcase.tb_meeting_transcription(
segment_index INTEGER NOT NULL DEFAULT 0, -- 片段序号(按时间排序)
is_final BOOLEAN NOT NULL DEFAULT true, -- 是否最终结果(实时转录会有中间结果)
service_provider VARCHAR(50) DEFAULT 'xunfei', -- 服务提供商xunfei aliyun tencent google
agent_id VARCHAR(50) NOT NULL, -- 客服ID关联sys用户ID
agent_name VARCHAR(100) NOT NULL, -- 客服姓名
agent_code VARCHAR(50) DEFAULT NULL, -- 客服工号
status VARCHAR(20) NOT NULL DEFAULT 'online', -- 状态online-在线 busy-忙碌 offline-离线
create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间
PRIMARY KEY (transcription_id)
);
CREATE INDEX idx_transcription_meeting ON workcase.tb_meeting_transcription(meeting_id, segment_index);
COMMENT ON TABLE workcase.tb_meeting_transcription IS '会议转录记录表,用于保存视频会议的语音转文字内容';
-- 8. 员工配置表
-- 用于控制哪些人员可以在聊天室里接待来客
DROP TABLE IF EXISTS workcase.tb_customer_service CASCADE;
CREATE TABLE workcase.tb_customer_service(
optsn VARCHAR(50) NOT NULL, -- 流水号
user_id VARCHAR(50) NOT NULL, -- 员工ID关联sys用户ID
username VARCHAR(100) NOT NULL, -- 员工姓名
user_code VARCHAR(50) DEFAULT NULL, -- 员工工号
status VARCHAR(20) NOT NULL DEFAULT 'offline', -- 状态online-在线 busy-忙碌 offline-离线
skill_tags VARCHAR(50)[] DEFAULT '{}', -- 技能标签(如:电力、燃气、水务)
max_concurrent INTEGER NOT NULL DEFAULT 5, -- 最大并发接待数
current_workload INTEGER NOT NULL DEFAULT 0, -- 当前工作量
@@ -211,10 +218,10 @@ CREATE TABLE workcase.tb_meeting_transcription(
update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间
delete_time TIMESTAMPTZ DEFAULT NULL, -- 删除时间
deleted BOOLEAN NOT NULL DEFAULT false, -- 是否删除
PRIMARY KEY (agent_id)
PRIMARY KEY (user_id)
);
CREATE INDEX idx_agent_status ON workcase.tb_customer_service(status, current_workload);
COMMENT ON TABLE workcase.tb_customer_service IS '客服人员配置表';
CREATE INDEX idx_customer_service_status ON workcase.tb_customer_service(status, current_workload);
COMMENT ON TABLE workcase.tb_customer_service IS '员工配置表,用于控制哪些人员可以在聊天室接待来客';
-- 工单表
DROP TABLE IF EXISTS workcase.tb_workcase CASCADE;

View File

@@ -0,0 +1,49 @@
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 TbCustomerServiceDTO.java
* @author cascade
* @copyright xyzh
* @since 2025-12-22
*/
@Data
@Schema(description = "客服人员配置表对象")
public class TbCustomerServiceDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "员工ID关联sys用户ID")
private String userId;
@Schema(description = "员工姓名")
private String username;
@Schema(description = "员工工号")
private String userCode;
@Schema(description = "状态online-在线 busy-忙碌 offline-离线")
private String status;
@Schema(description = "技能标签")
private List<String> skillTags;
@Schema(description = "最大并发接待数")
private Integer maxConcurrent;
@Schema(description = "当前工作量")
private Integer currentWorkload;
@Schema(description = "累计服务次数")
private Integer totalServed;
@Schema(description = "平均响应时间(秒)")
private Integer avgResponseTime;
@Schema(description = "满意度评分0-5")
private Double satisfactionScore;
}

View File

@@ -0,0 +1,51 @@
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 TbMeetingParticipantDTO.java
* @author cascade
* @copyright xyzh
* @since 2025-12-22
*/
@Data
@Schema(description = "会议参与记录表对象")
public class TbMeetingParticipantDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "参与记录ID")
private String participantId;
@Schema(description = "会议ID")
private String meetingId;
@Schema(description = "用户ID")
private String userId;
@Schema(description = "用户类型guest-来客 agent-客服")
private String userType;
@Schema(description = "用户名称")
private String userName;
@Schema(description = "加入时间")
private String joinTime;
@Schema(description = "离开时间")
private String leaveTime;
@Schema(description = "参与时长(秒)")
private Integer durationSeconds;
@Schema(description = "是否主持人")
private Boolean isModerator;
@Schema(description = "加入方式web-网页 mobile-移动端 desktop-桌面端")
private String joinMethod;
@Schema(description = "设备信息")
private String deviceInfo;
}

View File

@@ -0,0 +1,76 @@
package org.xyzh.api.workcase.dto;
import com.alibaba.fastjson2.JSONObject;
import org.xyzh.common.dto.BaseDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* @description 视频会议表数据对象DTO
* @filename TbVideoMeetingDTO.java
* @author cascade
* @copyright xyzh
* @since 2025-12-22
*/
@Data
@Schema(description = "视频会议表对象")
public class TbVideoMeetingDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@Schema(description = "会议ID")
private String meetingId;
@Schema(description = "关联聊天室ID")
private String roomId;
@Schema(description = "关联工单ID")
private String workcaseId;
@Schema(description = "会议名称")
private String meetingName;
@Schema(description = "会议密码")
private String meetingPassword;
@Schema(description = "JWT Token")
private String jwtToken;
@Schema(description = "Jitsi房间名")
private String jitsiRoomName;
@Schema(description = "Jitsi服务器地址")
private String jitsiServerUrl;
@Schema(description = "状态scheduled-已安排 ongoing-进行中 ended-已结束 cancelled-已取消")
private String status;
@Schema(description = "创建者ID")
private String creatorId;
@Schema(description = "创建者类型guest-来客 agent-客服")
private String creatorType;
@Schema(description = "创建者名称")
private String creatorName;
@Schema(description = "参与人数")
private Integer participantCount;
@Schema(description = "最大参与人数")
private Integer maxParticipants;
@Schema(description = "实际开始时间")
private String actualStartTime;
@Schema(description = "实际结束时间")
private String actualEndTime;
@Schema(description = "会议时长(秒)")
private Integer durationSeconds;
@Schema(description = "iframe嵌入URL")
private String iframeUrl;
@Schema(description = "Jitsi配置项")
private JSONObject config;
}

View File

@@ -0,0 +1,60 @@
package org.xyzh.api.workcase.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.xyzh.common.vo.BaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
/**
* 客服人员配置VO
* 用于前端展示客服人员信息
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "客服人员配置VO")
public class CustomerServiceVO extends BaseVO {
private static final long serialVersionUID = 1L;
@Schema(description = "员工ID关联sys用户ID")
private String userId;
@Schema(description = "员工姓名")
private String username;
@Schema(description = "员工工号")
private String userCode;
@Schema(description = "员工头像")
private String avatar;
@Schema(description = "状态online-在线 busy-忙碌 offline-离线")
private String status;
@Schema(description = "状态名称")
private String statusName;
@Schema(description = "技能标签")
private List<String> skillTags;
@Schema(description = "最大并发接待数")
private Integer maxConcurrent;
@Schema(description = "当前工作量")
private Integer currentWorkload;
@Schema(description = "累计服务次数")
private Integer totalServed;
@Schema(description = "平均响应时间(秒)")
private Integer avgResponseTime;
@Schema(description = "平均响应时间(格式化)")
private String avgResponseTimeFormatted;
@Schema(description = "满意度评分0-5")
private Double satisfactionScore;
@Schema(description = "是否可接待(工作量未满)")
private Boolean isAvailable;
}

View File

@@ -199,23 +199,8 @@ device_info -- 设备信息
**用途**:管理有客服权限的员工
```sql
agent_id -- 客服ID关联sys用户ID
agent_name -- 客服姓名
agent_code -- 客服工号
status -- 状态online busy offline
skill_tags -- 技能标签(如:电力、燃气、水务)
max_concurrent -- 最大并发接待数
current_workload -- 当前工作量
total_served -- 累计服务次数
avg_response_time -- 平均响应时间(秒)
satisfaction_score -- 满意度评分0-5
```
**业务规则**
- 用于客服负载均衡
- 技能标签用于智能分配
- 实时更新工作量
user_id
username
---
#### 7. **tb_word_cloud** - 词云统计表(已有)