# OPSX Proposal: 在线客服模块集成 ## 变更标识 - **变更ID**: customer-service-module - **创建日期**: 2026-01-28 - **状态**: SPEC_COMPLETE --- ## 1. 上下文 (Context) ### 1.1 用户需求 在OG Live Gaming Platform的admin后台集成在线客服模块,将PC端和移动端(Game/Portal)的客服功能从外链跳转改为内置实时聊天,所有用户消息统一转发到后台由客服人员回复。 ### 1.2 现有实现 - **当前方案**: 外链跳转第三方客服平台 - PC端: `PC/src/components/updateService/update-service.vue` - 通过 `webconfig.customerLink` 跳转 - Portal端: `Portal/pages/user/customservice.vue` - 支持 Telegram/Line 外部链接 - **问题**: 无法统一管理用户咨询,缺乏历史记录追溯 ### 1.3 技术环境 | 组件 | 技术栈 | 版本 | |------|--------|------| | 后端主服务 | ThinkPHP | 5.x | | WebSocket服务 | ThinkPHP + Swoole | 6.x | | PC前端 | Vue.js + Element UI | 2.x | | Game前端 | Vue.js + Vant | 3.x | | Portal前端 | uni-app + uView | - | | 数据库 | MySQL | 5.7 | | 缓存 | Redis | 5.x | --- ## 2. 约束集合 (Constraint Sets) ### 2.1 硬约束 (Hard Constraints) - 不可违反 | ID | 约束 | 来源 | 影响 | |----|------|------|------| | HC-01 | 必须使用现有Socket服务(ThinkPHP 6.x + Swoole)作为WebSocket通信基础 | 架构一致性 | 不能引入新的WebSocket服务 | | HC-02 | 数据库表必须使用 `cg_` 前缀 | `application/database.php:23` | 表名规范 | | HC-03 | Admin后台控制器必须继承 `Common` 基类 | `application/admin/controller/Common.php` | 权限控制 | | HC-04 | 前端API请求必须通过现有封装的HTTP客户端 | 各端API封装 | 接口一致性 | | HC-05 | 用户认证必须复用现有Session/Token机制 | 安全性 | 不能引入新认证体系 | ### 2.2 软约束 (Soft Constraints) - 建议遵循 | ID | 约束 | 来源 | 建议 | |----|------|------|------| | SC-01 | Admin后台UI应使用Layui框架 | 现有后台风格 | 保持视觉一致性 | | SC-02 | WebSocket事件应遵循现有listener模式 | `Socket/app/listener/` | 代码组织一致 | | SC-03 | 前端组件命名应遵循各端现有规范 | 代码风格 | PascalCase组件名 | | SC-04 | 日志记录应使用现有 `insertAdminLog()` 函数 | `application/helper.php` | 审计追踪 | ### 2.3 依赖约束 (Dependencies) | ID | 依赖项 | 类型 | 说明 | |----|--------|------|------| | DC-01 | cg_user 表 | 数据 | 用户信息关联 | | DC-02 | cg_admin 表 | 数据 | 客服人员账号 | | DC-03 | Redis | 基础设施 | 在线状态、会话分配 | | DC-04 | Socket服务 | 服务 | 实时消息推送 | --- ## 3. 需求规格 (Requirements) ### 3.1 功能需求 #### REQ-01: 后台客服工作台 **场景**: 客服人员登录admin后台,进入客服模块 **验收标准**: - [ ] 显示待接入会话列表(按等待时间排序) - [ ] 显示当前处理中的会话列表 - [ ] 支持同时处理多个会话(标签页切换) - [ ] 实时显示新消息通知(声音+视觉提示) - [ ] 显示用户基本信息(用户名、余额、来源端) #### REQ-02: 会话自动分配 **场景**: 用户发起客服咨询 **验收标准**: - [ ] 系统自动将用户分配给当前会话数最少的在线客服 - [ ] 客服离线时,消息进入待分配队列 - [ ] 支持会话转接给其他在线客服 - [ ] 记录会话分配历史 #### REQ-03: 实时消息通信 **场景**: 用户与客服进行对话 **验收标准**: - [ ] 支持文字消息发送/接收 - [ ] 支持图片消息发送/接收(上传+预览) - [ ] 消息实时推送(延迟<500ms) - [ ] 显示消息发送状态(发送中/已送达/已读) - [ ] 支持消息时间戳显示 #### REQ-04: 离线消息 **场景**: 用户发送消息时客服全部离线,或客服回复时用户已离线 **验收标准**: - [ ] 离线消息持久化存储 - [ ] 用户/客服上线后自动推送未读消息 - [ ] 显示未读消息数量角标 #### REQ-05: 快捷回复 **场景**: 客服需要快速回复常见问题 **验收标准**: - [ ] 支持预设快捷回复语管理(增删改) - [ ] 支持快捷回复分类 - [ ] 一键插入快捷回复内容 #### REQ-06: 聊天记录查询 **场景**: 客服或管理员需要查看历史对话 **验收标准**: - [ ] 支持按用户名搜索 - [ ] 支持按时间范围筛选 - [ ] 支持按客服人员筛选 - [ ] 支持导出聊天记录 #### REQ-07: 用户信息展示 **场景**: 客服处理会话时需要了解用户背景 **验收标准**: - [ ] 显示用户账号、昵称 - [ ] 显示用户余额 - [ ] 显示用户来源(PC/Game/Portal) - [ ] 显示用户上级代理信息 - [ ] 显示用户最近下注记录(可选) #### REQ-08: 会话评价 **场景**: 用户结束咨询后对服务进行评价 **验收标准**: - [ ] 会话结束后弹出评价窗口 - [ ] 支持1-5星评分 - [ ] 支持文字评价(可选) - [ ] 后台可查看评价统计 #### REQ-09: 前端客服入口改造 **场景**: 用户在PC/Game/Portal端点击客服按钮 **验收标准**: - [ ] PC端: 替换外链跳转为内嵌聊天窗口 - [ ] Game端: 添加客服聊天组件 - [ ] Portal端: 替换外链页面为聊天页面 - [ ] 三端UI风格与各自设计语言一致 --- ## 4. 数据库设计 ### 4.1 新增表结构 ```sql -- 客服会话表 CREATE TABLE `cg_chat_session` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `user_id` int(10) unsigned NOT NULL COMMENT '用户ID', `admin_id` int(10) unsigned DEFAULT NULL COMMENT '客服ID', `source` tinyint(1) NOT NULL DEFAULT '1' COMMENT '来源: 1=PC 2=Game 3=Portal', `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态: 0=待分配 1=进行中 2=已结束', `rating` tinyint(1) DEFAULT NULL COMMENT '评分: 1-5', `rating_content` varchar(500) DEFAULT NULL COMMENT '评价内容', `create_time` int(10) unsigned NOT NULL, `update_time` int(10) unsigned NOT NULL, `end_time` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), KEY `admin_id` (`admin_id`), KEY `status` (`status`), KEY `create_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客服会话表'; -- 聊天消息表 CREATE TABLE `cg_chat_message` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `session_id` int(10) unsigned NOT NULL COMMENT '会话ID', `sender_type` tinyint(1) NOT NULL COMMENT '发送者类型: 1=用户 2=客服', `sender_id` int(10) unsigned NOT NULL COMMENT '发送者ID', `msg_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '消息类型: 1=文字 2=图片', `content` text NOT NULL COMMENT '消息内容', `is_read` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已读', `create_time` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `session_id` (`session_id`), KEY `sender_type` (`sender_type`), KEY `is_read` (`is_read`), KEY `create_time` (`create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='聊天消息表'; -- 快捷回复表 CREATE TABLE `cg_chat_quick_reply` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `category` varchar(50) DEFAULT NULL COMMENT '分类', `title` varchar(100) NOT NULL COMMENT '标题', `content` text NOT NULL COMMENT '内容', `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序', `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态', `create_time` int(10) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `category` (`category`), KEY `status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快捷回复表'; -- 客服在线状态表 (Redis辅助) CREATE TABLE `cg_chat_admin_status` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `admin_id` int(10) unsigned NOT NULL COMMENT '客服ID', `is_online` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否在线', `current_sessions` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '当前会话数', `max_sessions` int(10) unsigned NOT NULL DEFAULT '10' COMMENT '最大会话数', `last_active_time` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `admin_id` (`admin_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客服状态表'; ``` --- ## 5. 技术方案 ### 5.1 架构图 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ PC端 │ │ Game端 │ │ Portal端 │ │ (Vue 2.x) │ │ (Vue 3.x) │ │ (uni-app) │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ └────────────────┼────────────────┘ │ WebSocket ▼ ┌─────────────────┐ │ Socket服务 │ │ (TP6 + Swoole) │ │ │ │ 新增listener: │ │ - ChatConnect │ │ - ChatMessage │ │ - ChatSession │ └────────┬────────┘ │ ┌─────────────┼─────────────┐ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ MySQL │ │ Redis │ │ 文件存储 │ │ 消息持久化│ │ 在线状态 │ │ 图片上传 │ └──────────┘ └──────────┘ └──────────┘ │ ▼ ┌─────────────────┐ │ Admin后台 │ │ (TP5 + Layui) │ │ │ │ 新增模块: │ │ - Chat控制器 │ │ - 客服工作台 │ │ - 快捷回复管理 │ │ - 聊天记录查询 │ └─────────────────┘ ``` ### 5.2 WebSocket事件设计 | 事件名 | 方向 | 说明 | |--------|------|------| | `chat.connect` | Client→Server | 用户/客服建立聊天连接 | | `chat.message` | 双向 | 发送/接收消息 | | `chat.typing` | 双向 | 正在输入状态 | | `chat.read` | Client→Server | 消息已读回执 | | `chat.session.new` | Server→Admin | 新会话通知 | | `chat.session.assign` | Server→Admin | 会话分配通知 | | `chat.session.transfer` | Admin→Server | 会话转接 | | `chat.session.end` | 双向 | 会话结束 | | `chat.admin.online` | Admin→Server | 客服上线 | | `chat.admin.offline` | Admin→Server | 客服下线 | ### 5.3 文件变更清单 #### Pro模块 (Admin后台) ``` application/admin/controller/ ├── Chat.php # 新增 - 客服工作台控制器 ├── ChatRecord.php # 新增 - 聊天记录控制器 └── ChatQuickReply.php # 新增 - 快捷回复管理控制器 application/admin/view/ ├── chat/ │ ├── index.html # 新增 - 客服工作台页面 │ └── record.html # 新增 - 聊天记录页面 └── chat_quick_reply/ ├── index.html # 新增 - 快捷回复列表 └── add.html # 新增 - 添加快捷回复 application/admin/view/index/index.html # 修改 - 添加客服菜单入口 ``` #### Socket模块 ``` app/listener/chat/ ├── ChatConnect.php # 新增 - 聊天连接处理 ├── ChatMessage.php # 新增 - 消息处理 └── ChatSession.php # 新增 - 会话管理 app/services/chat/ ├── ChatService.php # 新增 - 聊天核心服务 ├── SessionService.php # 新增 - 会话分配服务 └── MessageService.php # 新增 - 消息存储服务 app/models/chat/ ├── ChatSession.php # 新增 - 会话模型 ├── ChatMessage.php # 新增 - 消息模型 └── ChatQuickReply.php # 新增 - 快捷回复模型 ``` #### PC端 ``` src/components/chat/ ├── ChatWindow.vue # 新增 - 聊天窗口组件 ├── ChatMessage.vue # 新增 - 消息气泡组件 └── ChatInput.vue # 新增 - 输入框组件 src/components/updateService/ └── update-service.vue # 修改 - 改为打开聊天窗口 ``` #### Game端 ``` src/components/chat/ ├── ChatWindow.vue # 新增 - 聊天窗口组件 ├── ChatMessage.vue # 新增 - 消息气泡组件 └── ChatInput.vue # 新增 - 输入框组件 src/components/ └── HallNav.vue # 修改 - 添加客服入口 ``` #### Portal端 ``` pages/user/ └── customservice.vue # 修改 - 改为聊天页面 components/chat/ ├── ChatWindow.vue # 新增 - 聊天窗口组件 └── ChatMessage.vue # 新增 - 消息组件 ``` --- ## 6. 风险评估 | 风险 | 等级 | 缓解措施 | |------|------|----------| | WebSocket连接数过多导致服务压力 | 中 | 实现连接池、心跳检测、自动断开空闲连接 | | 消息丢失 | 中 | 消息持久化优先、ACK确认机制 | | 图片上传占用存储 | 低 | 图片压缩、定期清理、可配置存储路径 | | 客服全部离线时用户体验 | 低 | 显示离线提示、支持留言 | --- ## 7. 成功判据 (Success Criteria) - [ ] 用户可在PC/Game/Portal三端发起客服咨询 - [ ] 客服可在Admin后台实时接收和回复消息 - [ ] 消息延迟 < 500ms - [ ] 支持文字和图片消息 - [ ] 离线消息可正常存储和推送 - [ ] 会话自动分配正常工作 - [ ] 聊天记录可查询和导出 - [ ] 快捷回复功能正常 - [ ] 会话评价功能正常 --- ## 8. 实施阶段建议 ### Phase 1: 基础架构 - 数据库表创建 - Socket服务聊天事件监听器 - 基础消息收发功能 ### Phase 2: Admin后台 - 客服工作台UI - 会话管理 - 快捷回复管理 ### Phase 3: 前端改造 - PC端聊天组件 - Game端聊天组件 - Portal端聊天页面 ### Phase 4: 增强功能 - 离线消息 - 会话评价 - 聊天记录查询导出 --- *文档版本: 1.0* *最后更新: 2026-01-28*