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