14 KiB
14 KiB
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 外部链接
- PC端:
- 问题: 无法统一管理用户咨询,缺乏历史记录追溯
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 新增表结构
-- 客服会话表
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