CREATE SCHEMA IF NOT EXISTS workcase; -- 系统外部人员(来客)管理 用于给系统外人员创建id DROP TABLE IF EXISTS sys.tb_guest CASCADE; CREATE TABLE sys.tb_guest( optsn VARCHAR(50) NOT NULL, -- 流水号 user_id VARCHAR(50) NOT NULL, -- 来客ID name VARCHAR(50) NOT NULL, -- 姓名 phone VARCHAR(50) DEFAULT NULL, -- 电话 email VARCHAR(50) DEFAULT NULL, -- 邮箱 wechat_id VARCHAR(50) DEFAULT 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 (user_id), UNIQUE (wechat_id), UNIQUE (phone), UNIQUE (email) ); -- ========================================== -- IM聊天室 + Jitsi Meet 视频会议 表设计 -- ========================================== -- 1. 聊天室表(核心表) -- 一个工单对应一个聊天室,来客创建,客服人员可加入 DROP TABLE IF EXISTS workcase.tb_chat_room CASCADE; CREATE TABLE workcase.tb_chat_room( optsn VARCHAR(50) NOT NULL, -- 流水号 room_id VARCHAR(50) NOT NULL, -- 聊天室ID workcase_id VARCHAR(50) NOT NULL, -- 关联工单ID room_name VARCHAR(200) NOT NULL, -- 聊天室名称(如:工单#12345的客服支持) room_type VARCHAR(20) NOT NULL DEFAULT 'workcase', -- 聊天室类型:workcase-工单客服 status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态:active-活跃 closed-已关闭 archived-已归档 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同步) message_count INTEGER NOT NULL DEFAULT 0, -- 消息总数 last_message_time TIMESTAMPTZ DEFAULT NULL, -- 最后消息时间 last_message TEXT DEFAULT NULL, -- 最后一条消息内容(用于列表展示) closed_by VARCHAR(50) DEFAULT NULL, -- 关闭人 closed_time TIMESTAMPTZ 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 (room_id), UNIQUE (workcase_id), UNIQUE (optsn) ); CREATE INDEX idx_chat_room_guest ON workcase.tb_chat_room(guest_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聊天室表,一个工单对应一个聊天室'; -- 2. 聊天室成员表 -- 记录聊天室内的所有成员(来客+客服人员) DROP TABLE IF EXISTS workcase.tb_chat_room_member CASCADE; CREATE TABLE workcase.tb_chat_room_member( optsn VARCHAR(50) NOT NULL, -- 流水号 member_id VARCHAR(50) NOT NULL, -- 成员记录ID room_id VARCHAR(50) NOT NULL, -- 聊天室ID user_id VARCHAR(50) NOT NULL, -- 用户ID(来客ID或员工ID) user_type VARCHAR(20) NOT NULL, -- 用户类型:guest-来客 stuff-客服 ai-AI助手 user_name VARCHAR(100) NOT NULL, -- 用户名称 status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态:active-活跃 left-已离开 removed-被移除 unread_count INTEGER NOT NULL DEFAULT 0, -- 该成员的未读消息数 last_read_time TIMESTAMPTZ DEFAULT NULL, -- 最后阅读时间 last_read_msg_id VARCHAR(50) DEFAULT NULL, -- 最后阅读的消息ID join_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 加入时间 leave_time TIMESTAMPTZ DEFAULT NULL, -- 离开时间 creator VARCHAR(50) NOT NULL, -- 创建人 create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间 update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间 PRIMARY KEY (member_id), UNIQUE (room_id, user_id) ); CREATE INDEX idx_chat_member_room ON workcase.tb_chat_room_member(room_id, status); CREATE INDEX idx_chat_member_user ON workcase.tb_chat_room_member(user_id, user_type, status); COMMENT ON TABLE workcase.tb_chat_room_member IS '聊天室成员表,记录来客和客服人员'; -- 3. 聊天室消息表 -- 存储所有聊天消息(AI对话+人工客服对话) DROP TABLE IF EXISTS workcase.tb_chat_room_message CASCADE; CREATE TABLE workcase.tb_chat_room_message( optsn VARCHAR(50) NOT NULL, -- 流水号 message_id VARCHAR(50) NOT NULL, -- 消息ID room_id VARCHAR(50) NOT NULL, -- 聊天室ID sender_id VARCHAR(50) NOT NULL, -- 发送者ID sender_type VARCHAR(20) NOT NULL, -- 发送者类型:guest-来客 agent-客服 ai-AI助手 system-系统消息 sender_name VARCHAR(100) NOT NULL, -- 发送者名称 message_type VARCHAR(20) NOT NULL DEFAULT 'text', -- 消息类型:text-文本 image-图片 file-文件 voice-语音 video-视频 system-系统消息 meeting-会议通知 content TEXT NOT NULL, -- 消息内容 files VARCHAR(50)[] DEFAULT '{}', -- 附件文件ID数组(图片、文件、语音、视频等) content_extra JSONB DEFAULT NULL, -- 扩展内容(会议链接、引用信息等) reply_to_msg_id VARCHAR(50) DEFAULT NULL, -- 回复的消息ID(引用回复) is_ai_message BOOLEAN NOT NULL DEFAULT false, -- 是否AI消息(标记从ai.tb_chat同步的消息) ai_message_id VARCHAR(50) DEFAULT NULL, -- AI原始消息ID(用于追溯) status VARCHAR(20) NOT NULL DEFAULT 'sent', -- 状态:sending-发送中 sent-已发送 delivered-已送达 read-已读 failed-失败 recalled-已撤回 read_count INTEGER NOT NULL DEFAULT 0, -- 已读人数 send_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 发送时间 creator VARCHAR(50) NOT NULL, -- 创建人 create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间 update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间 PRIMARY KEY (message_id) ); CREATE INDEX idx_chat_msg_room ON workcase.tb_chat_room_message(room_id, send_time DESC); CREATE INDEX idx_chat_msg_sender ON workcase.tb_chat_room_message(sender_id, sender_type); CREATE INDEX idx_chat_msg_ai ON workcase.tb_chat_room_message(ai_message_id) WHERE ai_message_id IS NOT NULL; COMMENT ON TABLE workcase.tb_chat_room_message IS 'IM聊天消息表,包含AI对话和人工客服消息'; -- 4. 视频会议表(Jitsi Meet) -- 记录聊天室内创建的视频会议 DROP TABLE IF EXISTS workcase.tb_video_meeting CASCADE; CREATE TABLE workcase.tb_video_meeting( optsn VARCHAR(50) NOT NULL, -- 流水号 meeting_id VARCHAR(50) NOT NULL, -- 会议ID(也是Jitsi房间名) room_id VARCHAR(50) NOT NULL, -- 关联聊天室ID workcase_id VARCHAR(50) NOT NULL, -- 关联工单ID meeting_name VARCHAR(200) NOT NULL, -- 会议名称 meeting_password VARCHAR(50) DEFAULT NULL, -- 会议密码(可选) jwt_token TEXT DEFAULT NULL, -- JWT Token(用于身份验证) jitsi_room_name VARCHAR(200) NOT NULL, -- Jitsi房间名(格式:workcase_{workcase_id}_{timestamp}) jitsi_server_url VARCHAR(500) NOT NULL DEFAULT 'https://meet.jit.si', -- Jitsi服务器地址 status VARCHAR(20) NOT NULL DEFAULT 'scheduled', -- 状态:scheduled-已安排 ongoing-进行中 ended-已结束 cancelled-已取消 creator_id VARCHAR(50) NOT NULL, -- 创建者ID creator_type VARCHAR(20) NOT NULL, -- 创建者类型:guest-来客 agent-客服 creator_name VARCHAR(100) NOT NULL, -- 创建者名称 participant_count INTEGER NOT NULL DEFAULT 0, -- 参与人数 max_participants INTEGER DEFAULT 10, -- 最大参与人数 start_time TIMESTAMPTZ DEFAULT NULL, -- 实际开始时间 end_time TIMESTAMPTZ DEFAULT NULL, -- 实际结束时间 duration_seconds INTEGER DEFAULT 0, -- 会议时长(秒) iframe_url TEXT DEFAULT NULL, -- iframe嵌入URL(生成后存储) config JSONB DEFAULT NULL, -- Jitsi配置项(自定义配置) 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 (meeting_id), UNIQUE (jitsi_room_name) ); CREATE INDEX idx_meeting_room ON workcase.tb_video_meeting(room_id, status); CREATE INDEX idx_meeting_workcase ON workcase.tb_video_meeting(workcase_id, status); CREATE INDEX idx_meeting_time ON workcase.tb_video_meeting(create_time DESC); COMMENT ON TABLE workcase.tb_video_meeting IS 'Jitsi Meet视频会议表'; -- 5. 会议参与记录表(可选,用于审计和统计) DROP TABLE IF EXISTS workcase.tb_meeting_participant CASCADE; CREATE TABLE workcase.tb_meeting_participant( optsn VARCHAR(50) NOT NULL, -- 流水号 participant_id VARCHAR(50) NOT NULL, -- 参与记录ID meeting_id VARCHAR(50) NOT NULL, -- 会议ID user_id VARCHAR(50) NOT NULL, -- 用户ID user_type VARCHAR(20) NOT NULL, -- 用户类型:guest-来客 agent-客服 user_name VARCHAR(100) NOT NULL, -- 用户名称 join_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 加入时间 leave_time TIMESTAMPTZ DEFAULT NULL, -- 离开时间 duration_seconds INTEGER DEFAULT 0, -- 参与时长(秒) is_moderator BOOLEAN NOT NULL DEFAULT false, -- 是否主持人 join_method VARCHAR(20) DEFAULT 'web', -- 加入方式:web-网页 mobile-移动端 desktop-桌面端 device_info VARCHAR(200) DEFAULT NULL, -- 设备信息 create_time TIMESTAMPTZ NOT NULL DEFAULT now(), -- 创建时间 update_time TIMESTAMPTZ DEFAULT NULL, -- 更新时间 PRIMARY KEY (participant_id) ); CREATE INDEX idx_meeting_participant ON workcase.tb_meeting_participant(meeting_id, join_time); CREATE INDEX idx_participant_user ON workcase.tb_meeting_participant(user_id, user_type); COMMENT ON TABLE workcase.tb_meeting_participant IS '视频会议参与记录表'; -- 7. 会议转录记录表(音频转文字) DROP TABLE IF EXISTS workcase.tb_meeting_transcription CASCADE; CREATE TABLE workcase.tb_meeting_transcription( optsn VARCHAR(50) NOT NULL, -- 流水号 transcription_id VARCHAR(50) NOT NULL, -- 转录记录ID meeting_id VARCHAR(50) NOT NULL, -- 会议ID speaker_id VARCHAR(50) NOT NULL, -- 说话人ID speaker_name VARCHAR(100) NOT NULL, -- 说话人名称 speaker_type VARCHAR(20) NOT NULL, -- 说话人类型:guest-来客 agent-客服 content TEXT NOT NULL, -- 转录文本内容 content_raw TEXT DEFAULT NULL, -- 原始转录结果(含标点前) language VARCHAR(10) DEFAULT 'zh-CN', -- 语言:zh-CN en-US等 confidence NUMERIC(3,2) DEFAULT NULL, -- 识别置信度(0-1) speech_start_time TIMESTAMPTZ NOT NULL, -- 语音开始时间 speech_end_time TIMESTAMPTZ NOT NULL, -- 语音结束时间 duration_ms INTEGER NOT NULL, -- 语音时长(毫秒) audio_url VARCHAR(500) DEFAULT NULL, -- 音频片段URL(可选) segment_index INTEGER NOT NULL DEFAULT 0, -- 片段序号(按时间排序) is_final BOOLEAN NOT NULL DEFAULT true, -- 是否最终结果(实时转录会有中间结果) service_provider VARCHAR(50) DEFAULT 'xunfei', -- 服务提供商:xunfei aliyun tencent google 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, -- 当前工作量 total_served INTEGER NOT NULL DEFAULT 0, -- 累计服务次数 avg_response_time INTEGER DEFAULT NULL, -- 平均响应时间(秒) satisfaction_score NUMERIC(3,2) DEFAULT NULL, -- 满意度评分(0-5) 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 (user_id) ); 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; 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_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-工单 global-全局 source_id VARCHAR(50) DEFAULT NULL, -- 来源ID(room_id/workcase_id,NULL表示全局统计) 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, source_type, source_id, stat_date, category) -- 同一天同一来源同一分类的词唯一 ); CREATE INDEX idx_word_cloud_source ON workcase.tb_word_cloud(source_type, source_id, stat_date); CREATE INDEX idx_word_cloud_category ON workcase.tb_word_cloud(category, stat_date); COMMENT ON TABLE workcase.tb_word_cloud IS '词云统计表,记录聊天和工单中的关键词';