Explorar o código

设计文档:在线小游戏作为任务类型的处理方案(方案B-2:category+minigameCode)

Sisyphus hai 6 meses
pai
achega
564b8ef6f4
Modificáronse 1 ficheiros con 188 adicións e 0 borrados
  1. 188 0
      docs/plans/2026-04-17-minigame-as-task-type-design.md

+ 188 - 0
docs/plans/2026-04-17-minigame-as-task-type-design.md

@@ -0,0 +1,188 @@
+# 在线小游戏作为任务类型的设计方案
+
+## 1. 需求背景
+
+当前项目中:
+- **MiniGame系统**:独立的小游戏模块(舒尔特方格、猜数字1a2b、数独),通过MiniGameController/MiniGameService管理,完成时调用积分计算
+- **Task系统**:独立的任务模块,通过TaskController/TaskService管理,任务完成时计算积分
+- **共同点**:都使用PointsLog记录积分变动,更新孩子的totalPoints
+
+**需求**:将在线小游戏作为任务分类的一种形式("小游戏类"),统一到任务系统中管理
+
+## 2. 选定方案
+
+### 方案B-2:task_type类型区分
+
+| 设计点 | 选择 |
+|--------|------|
+| 字段添加 | 新增minigameCode字段 |
+| category值 | 小游戏类 |
+| 积分计算 | 使用MiniGame规则(现有MiniGameService逻辑)|
+
+## 3. 数据库设计
+
+### 3.1 Tasks表变更
+
+```sql
+-- 添加minigameCode字段
+ALTER TABLE tasks ADD COLUMN minigame_code VARCHAR(50) DEFAULT NULL COMMENT '小游戏代码: schulte/1a2b/sudoku';
+
+-- 添加索引
+CREATE INDEX idx_tasks_minigame ON tasks(minigame_code) WHERE minigame_code IS NOT NULL;
+```
+
+### 3.2 字段说明
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| category | String | '小游戏类' |
+| minigameCode | String | 小游戏代码,category='小游戏类'时必填 |
+| points | Integer | 基准积分,为空时使用MiniGame.defaultPoints |
+| status | String | pending/completed/canceled |
+| completedAt | Date | 完成时间 |
+
+## 4. API设计
+
+### 4.1 创建小游戏任务
+
+```
+POST /api/tasks
+{
+  "title": "完成舒尔特方格",
+  "category": "小游戏类",
+  "minigameCode": "schulte",
+  "childId": 2,
+  "deadline": "2026-04-20T18:00:00",
+  "points": 5,  // 可选,为空时使用MiniGame.defaultPoints
+  "needReview": 0
+}
+```
+
+### 4.2 获取小游戏列表(创建任务时选择)
+
+```
+POST /api/mini-game/list
+```
+
+### 4.3 完成小游戏任务
+
+```
+POST /api/tasks/{id}/complete
+{
+  "childId": 2,
+  "completionTime": 45,  // 完成时间(秒)
+  "score": 80  // 得分,可选
+}
+```
+
+## 5. 业务流程
+
+### 5.1 创建流程
+
+```
+家长选择"小游戏类" ↓
+可选小游戏列表(舒尔特方格/猜数字/数独) ↓
+选择具体小游戏 ↓
+设置任务名称、截止时间 ↓
+保存任务(category='小游戏类',minigameCode='schulte')
+```
+
+### 5.2 完成流程
+
+```
+孩子完成任务 ↓
+校验任务存在且属于该孩子 ↓
+判断category='小游戏类' ↓
+调用MiniGameService.completeGame()计算积分 ↓
+更新任务状态为completed ↓
+记录PointsLog(类型: earn) ↓
+更新孩子总积分
+```
+
+## 6. 核心代码变更
+
+### 6.1 Task实体(Task.java)
+
+```java
+// 新增字段
+private String minigameCode;  // 小游戏代码: schulte/1a2b/sudoku
+```
+
+### 6.2 TaskService变更
+
+```java
+// createTask方法中增加校验
+if ("小游戏类".equals(category) && minigameCode == null) {
+    throw new BusinessException("小游戏类任务必须选择具体游戏");
+}
+
+// completeTask方法中小游戏任务处理
+if ("小游戏类".equals(task.getCategory())) {
+    // 调用MiniGameService计算积分
+    Map<String, Object> result = miniGameService.completeGame(
+        childId, 
+        task.getMinigameCode(), 
+        completionTime, 
+        score
+    );
+    pointsEarned = (Integer) result.get("pointsEarned");
+}
+```
+
+### 6.3 TaskController增加小游戏任务相关接口
+
+```java
+// 获取可选择的小游戏列表(创建任务时使用)
+@PostMapping("/minigame-options")
+public Result<List<MiniGame>> getMinigameOptions()
+```
+
+## 7. 前端变更
+
+### 7.1 创建任务页面
+
+- category选择器增加"小游戏类"选项
+- 选择"小游戏类"后,弹出小游戏选择列表
+- 选择具体游戏后自动填充任务名称
+
+### 7.2 小游戏页面
+
+- 任务列表中的小游戏任务,点击进入小游戏页面
+- 完成小游戏后自动调用任务完成接口
+
+## 8. 测试用例
+
+| 用例ID | 描述 | 预期结果 |
+|--------|------|----------|
+| MINITASK-001 | 家长创建小游戏任务 | 任务创建成功,category='小游戏类' |
+| MINITASK-002 | 孩子完成小游戏任务 | 积分按MiniGame规则计算 |
+| MINITASK-003 | 小游戏任务记录到任务历史 | 历史中可查询 |
+| MINITASK-004 | 积分记录到PointsLog | 积分流水正确 |
+
+## 9. 实施计划
+
+| 序号 | 任务 | 预估工作量 |
+|------|------|----------|
+| 1 | 数据库迁移脚本 | 0.5h |
+| 2 | Task实体添加字段 | 0.5h |
+| 3 | TaskService逻辑变更 | 2h |
+| 4 | TaskController API变更 | 1h |
+| 5 | 前端创建任务页面 | 2h |
+| 6 | 前端任务列表/详情页 | 1h |
+| 7 | 测试验证 | 1h |
+
+**总计**: 约8小时
+
+## 10. 待确认事项
+
+- [x] 方案选择
+- [x] 字段添加方式
+- [x] category值确定
+- [x] 积分计算方式
+- [ ] 启动实施?
+
+---
+
+**设计日期**: 2026-04-17
+**设计人**: Sisyphus
+**状态**: 待用户确认后启动实施