10 KiB
10 KiB
OPSX Tasks: 在线客服模块实施计划
变更标识
- 变更ID: customer-service-module
- 版本: 2.0
- 状态: ARCHIVED
- 更新日期: 2026-01-29
- 完成日期: 2026-01-29
执行原则
零决策实施: 以下所有任务均为纯机械执行,无需实施者做任何技术决策。 所有参数、算法、约束已在 specs.md 和 design.md 中完全定义。
Phase 1: 基础架构 (数据库 + Socket服务)
TASK-1.1: 创建数据库表
输入: design.md Section 2.1 表结构SQL
执行步骤:
- 在
Pro/init.sql末尾追加以下4个表的CREATE语句:cg_chat_sessioncg_chat_messagecg_chat_quick_replycg_chat_admin_status
- 执行SQL创建表
验收标准:
- 4个表创建成功
- 所有索引创建正确
- 字符集为utf8mb4
TASK-1.2: 实现雪花算法工具类
输入: design.md Section 3.1 Snowflake代码
执行步骤:
- 创建文件
Socket/app/utils/Snowflake.php - 复制 design.md 中的 Snowflake 类实现
- 配置 workerId=1, datacenterId=1
验收标准:
- 生成ID唯一且有序
- 10000次调用无重复
TASK-1.3: 创建Socket模型类
输入: design.md Section 2.1 表结构
执行步骤:
- 创建
Socket/app/models/chat/ChatSession.php - 创建
Socket/app/models/chat/ChatMessage.php - 创建
Socket/app/models/chat/ChatQuickReply.php - 创建
Socket/app/models/chat/ChatAdminStatus.php
验收标准:
- 4个模型类创建完成
- 表名前缀正确
cg_ - 自动时间戳配置正确
TASK-1.4: 实现AssignService分配服务
输入:
- design.md Section 3.2 分配算法
- specs.md Section 1 约束 (CC-01~CC-04)
执行步骤:
- 创建
Socket/app/services/chat/AssignService.php - 实现以下方法:
assignSession(int $userId, int $sessionId): ?intgetOnlineAgents(): arrayselectLeastLoadAgent(): ?intaddToOfflineQueue(int $userId, int $sessionId): voidprocessOfflineQueue(int $adminId): voidreleaseLock(): void
- Redis Key 前缀严格使用 specs.md Section 3 定义
约束参数:
- 分配锁超时: 3000ms
- 单客服最大会话数: 10
- 队列Key:
cs:queue:pending - 队列Score:
-balance(余额负数实现降序)
验收标准:
- 分配锁防止并发双分配
- 最少会话数策略正确
- 离线队列按余额排序
TASK-1.5: 实现MessageService消息服务
输入:
- design.md Section 3.3 重试算法
- specs.md Section 1 约束 (CC-05~CC-09)
执行步骤:
- 创建
Socket/app/services/chat/MessageService.php - 实现以下方法:
createMessage(array $data): int(生成雪花ID,入库)pushMessage(int $msgId, int $targetFd, array $payload): boolupdateMessageStatus(int $msgId, string $status): voidgetUnreadMessages(int $sessionId, int $limit = 50): arraymarkMessagesAsRead(array $msgIds): void
约束参数:
- 最大重试次数: 3
- 重试间隔: [1000, 2000, 4000] ms
- 消息长度限制: 500字符
- 重连拉取上限: 50条
验收标准:
- 消息ID使用雪花算法
- 重试策略为指数退避
- 消息状态正确流转
TASK-1.6: 实现SessionService会话服务
输入: specs.md 约束
执行步骤:
- 创建
Socket/app/services/chat/SessionService.php - 实现以下方法:
createSession(int $userId, int $source): intgetActiveSession(int $userId): ?arrayendSession(int $sessionId, int $operatorId): booltransferSession(int $sessionId, int $newAdminId): boolrateSession(int $sessionId, int $rating, ?string $content): bool
约束参数:
- 会话状态: 0=待分配, 1=进行中, 2=已结束
- 无自动超时关闭
验收标准:
- 同一用户只能有一个活跃会话
- 转接会话正确更新admin_id
- 评价存储正确
TASK-1.7: 实现ChatConnectListener
输入:
- specs.md Section 4 WebSocket事件协议
- specs.md 约束 (CC-10~CC-13)
执行步骤:
- 创建
Socket/app/listener/chat/ChatConnectListener.php - 处理事件:
chat.connect: 验证Token,注册在线状态chat.ping: 续期在线状态TTL- 断开连接: 清理Redis映射
- 在线状态Key:
cs:online:agent:{adminId}/cs:conn:user:{userId}
约束参数:
- 心跳间隔: 30秒
- 离线判定: 60秒 (TTL)
- 在线状态TTL: 60秒
验收标准:
- 连接时验证Token
- 心跳正确续期TTL
- 断开时清理Redis
TASK-1.8: 实现ChatMessageListener
输入: specs.md Section 4 事件协议
执行步骤:
- 创建
Socket/app/listener/chat/ChatMessageListener.php - 处理事件:
chat.message.send: 创建消息 → 返回server_ack → 推送对端 → 等待peer_ackchat.message.ack: 更新消息状态为delivered/readchat.typing: 转发正在输入状态
验收标准:
- 两段ACK机制实现
- 消息幂等性(msgId去重)
- typing状态正确转发
TASK-1.9: 实现ChatSessionListener
输入: specs.md Section 4 事件协议
执行步骤:
- 创建
Socket/app/listener/chat/ChatSessionListener.php - 处理事件:
chat.session.end: 结束会话chat.session.rate: 提交评价chat.agent.online: 客服上线,触发队列处理chat.agent.offline: 客服下线chat.session.transfer: 转接会话
验收标准:
- 客服上线自动处理离线队列
- 转接正确更新会话归属
TASK-1.10: 注册Listener到Swoole事件
输入: 现有Socket模块event.php配置
执行步骤:
- 编辑
Socket/config/event.php - 在listen数组中添加聊天相关Listener
验收标准:
- Listener正确注册
- 不影响现有游戏事件处理
Phase 2: Admin后台
TASK-2.1: 创建Chat控制器
输入: design.md Section 4.1 API
执行步骤:
- 创建
Pro/application/admin/controller/Chat.php - 继承
Common基类 - 实现方法:
index(): 客服工作台页面sessions(): 获取会话列表messages(): 获取消息历史endSession(): 结束会话transfer(): 转接会话stats(): 统计数据
验收标准:
- 继承Common基类
- 权限校验通过
TASK-2.2: 创建ChatQuickReply控制器
执行步骤:
- 创建
Pro/application/admin/controller/ChatQuickReply.php - 实现CRUD方法:
index(): 列表add(): 添加edit(): 编辑del(): 删除
验收标准:
- CRUD功能完整
- 使用insertAdminLog记录操作
TASK-2.3: 创建客服工作台页面
输入: Layui组件规范
执行步骤:
- 创建
Pro/application/admin/view/chat/index.html - 布局:
- 左侧: 会话列表(待接入/进行中)
- 中间: 聊天窗口
- 右侧: 用户信息面板
- WebSocket连接Admin后台
验收标准:
- Layui风格一致
- 实时消息收发
- 新消息声音提示
TASK-2.4: 创建快捷回复管理页面
执行步骤:
- 创建
Pro/application/admin/view/chat_quick_reply/index.html - 创建
Pro/application/admin/view/chat_quick_reply/add.html - 表格展示: 分类、标题、内容、排序、状态
验收标准:
- 列表分页正确
- 添加/编辑表单验证
TASK-2.5: 创建聊天记录查询页面
执行步骤:
- 创建
Pro/application/admin/view/chat/record.html - 筛选条件: 用户名、客服、时间范围
- 支持CSV导出
验收标准:
- 搜索功能正确
- 导出格式正确
TASK-2.6: 添加后台菜单入口
执行步骤:
- 在数据库
cg_auth_rule表插入菜单 - 分配权限给客服角色
验收标准:
- 菜单显示正确
- 权限控制正确
Phase 3: 前端改造
TASK-3.1: PC端聊天组件开发
输入: Element UI组件规范
执行步骤:
- 创建
PC/src/components/chat/chat.vue
验收标准:
- WebSocket连接稳定
- 消息实时收发
TASK-3.2: PC端客服入口改造
执行步骤:
- 修改客服入口,改为打开ChatWindow组件
验收标准:
- 点击客服按钮打开聊天窗口
- 不再跳转外链
TASK-3.3: Game端聊天组件开发
状态: 跳过 (用户确认不需要集成)
TASK-3.4: Game端客服入口添加
状态: 跳过 (用户确认不需要集成)
TASK-3.5: Portal端聊天页面改造
输入: uView组件规范
执行步骤:
- 修改
Portal/pages/user/customservice.vue - 移除Telegram/Line外链
- 改为内嵌聊天功能
验收标准:
- uView风格
- uni-app兼容(H5/小程序)
TASK-3.6: 前端图片上传接口对接
执行步骤:
- 各端创建图片上传方法
- 调用
/api/chat/upload接口 - 限制: 2MB, jpg/png/gif
验收标准:
- 上传前校验大小
- 上传后返回URL
Phase 4: 集成测试
TASK-4.1: PBT属性测试
状态: 跳过 (手动测试验证)
TASK-4.2: 端到端测试
执行步骤:
- 用户发起咨询 → 客服接入 → 消息往返 → 结束会话 → 评价
- 离线留言 → 客服上线 → 按余额顺序处理
- 断线重连 → 补发未读消息
验收标准:
- 完整流程通过
- 消息延迟<500ms
实施统计
代码量统计
| 模块 | 文件数 | 代码行数 |
|---|---|---|
| Pro 控制器 | 2 | 692 |
| Pro 视图 | 5 | 1,600 |
| Socket Listener | 14 | 1,381 |
| Socket Services | 3 | 986 |
| Socket Models | 4 | 236 |
| Portal 前端 | 1 | 518 |
| PC 前端 | 1 | 122 |
| 总计 | 30 | 5,535 |
完成情况
| Phase | 任务数 | 完成 | 跳过 |
|---|---|---|---|
| Phase 1: 基础架构 | 10 | 10 | 0 |
| Phase 2: Admin后台 | 6 | 6 | 0 |
| Phase 3: 前端改造 | 6 | 4 | 2 (Game端) |
| Phase 4: 集成测试 | 2 | 1 | 1 (PBT测试) |
| 总计 | 24 | 21 | 3 |
文档版本: 2.0 最后更新: 2026-01-29 归档日期: 2026-01-29