docs: update task management design based on review

修正内容:
- InitUserTasks 粒度:改为创建 onboarding_status + 每日任务进度
- ReportTaskEvent:从内部 RPC 改为移动端 API POST /api/tasks/report-event
- InitUserTasksRequest 增加 star_id 字段
- 每日任务流程:补充用户注册 → InitUserTasks 步骤
- 展示收益流程:补充 failed 记录对用户不可见的说明
- 展示收益响应:补充 star_id 字段
- activity-admin 收益记录页面:支持查看 failed 记录和手动补发

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
zheng020 2026-04-08 19:01:45 +08:00
parent 770ca0e512
commit ceb0159290

View File

@ -78,7 +78,7 @@
| 展示收益发放 | 统一到次日 05:00 自动发放,支持手动领取 |
| 展示收益计算 | 由调用方galleryService计算后传入 |
| 每日任务 scope | 每个 (user_id, star_id) 各自独立 |
| InitUserTasks | 只打新用户标记,不预创建任务进度 |
| InitUserTasks | 创建 user_onboarding_status + 该 star_id 下的每日任务进度;新增粉丝身份时创建对应进度 |
| 重置日志 | 记录到 task_reset_log 表 |
| 旧字段处理 | is_first_login_bonus_claimed、has_friend_display_bonus 标记废弃 |
| 奖励发放失败 | 记录日志 + 本地重试 N 次(可配置),仍失败标记 failed |
@ -311,15 +311,18 @@ CREATE TABLE task_reset_log (
| 方法 | 路径 | 请求 | 说明 |
|------|------|------|------|
| GET | `/api/tasks/daily` | `star_id` | 获取每日任务列表及进度 |
| POST | `/api/tasks/report-event` | `{ event_type, star_id }` | 上报任务事件(如浏览展品、铸造等) |
| POST | `/api/tasks/daily/claim` | `{ task_key, star_id }` | 领取单个任务奖励 |
| POST | `/api/tasks/daily/claim-all` | `star_id` | 一键领取所有已完成任务奖励 |
**GET /api/tasks/daily 响应:**
```json
{
"star_id": 1,
"tasks": [
{
"task_key": "daily_login",
"star_id": 1,
"name": "每日首次登录",
"description": "每日首次登录 App",
"crystal_reward": 20,
@ -331,6 +334,24 @@ CREATE TABLE task_reset_log (
}
```
**POST /api/tasks/report-event 请求:**
```json
{
"event_type": "daily_browse_asset",
"star_id": 1
}
```
**POST /api/tasks/report-event 响应:**
```json
{
"success": true,
"task_key": "daily_browse_asset",
"task_completed": true,
"message": "任务完成"
}
```
#### 引导任务
| 方法 | 路径 | 请求 | 说明 |
@ -390,6 +411,7 @@ CREATE TABLE task_reset_log (
"items": [
{
"id": 123,
"star_id": 1,
"exhibition_id": 456,
"asset_id": 789,
"slot_id": 1,
@ -415,12 +437,9 @@ CREATE TABLE task_reset_log (
```protobuf
service TaskInternalService {
// 用户注册时调用,只打新用户标记
// 用户注册时调用,创建 onboarding_status + 该 star_id 下的每日任务进度
rpc InitUserTasks(InitUserTasksRequest) returns (InitUserTasksResponse);
// 任务事件上报
rpc ReportTaskEvent(ReportTaskEventRequest) returns (ReportTaskEventResponse);
// 展品到期完成galleryService 调用)
rpc OnExhibitionCompleted(OnExhibitionCompletedRequest) returns (OnExhibitionCompletedResponse);
}
@ -431,6 +450,7 @@ service TaskInternalService {
```protobuf
message InitUserTasksRequest {
int64 user_id = 1;
int64 star_id = 2; // 注册时选择的第一个 star_id
}
message InitUserTasksResponse {
@ -438,19 +458,6 @@ message InitUserTasksResponse {
bool success = 2;
}
message ReportTaskEventRequest {
int64 user_id = 1;
int64 star_id = 2;
string event_type = 3;
int64 timestamp = 4;
}
message ReportTaskEventResponse {
topfans.common.BaseResponse base = 1;
bool task_completed = 2;
string task_key = 3;
}
message OnExhibitionCompletedRequest {
int64 exhibition_id = 1;
int64 asset_id = 2;
@ -497,13 +504,16 @@ rpc AddExperience(AddExperienceRequest) returns (AddExperienceResponse);
### 5.1 每日任务流程
```
1. 用户登录 → 前端调用 GET /api/tasks/daily?star_id=xxx
2. 后端返回该用户的每日任务列表(含 status
3. 用户完成行为(如浏览展品)→ 前端调用 ReportTaskEvent
4. 后端自动标记任务完成status=completed
5. 用户点击"领取" → POST /api/tasks/daily/claim
6. 后端验证任务已完成 → 调用 userService.UpdateCrystalBalance → 调用 AddExperience → 更新状态为 claimed
7. 每日 05:00 Asia/Shanghai
1. 用户注册 → userService 调用 taskService.InitUserTasks
- 创建 user_onboarding_status新用户标记
- 创建该 star_id 下的每日任务进度记录status=pending
2. 用户登录 → 前端调用 GET /api/tasks/daily?star_id=xxx
3. 后端返回该用户的每日任务列表(含 status
4. 用户完成行为(如浏览展品)→ 前端调用 POST /api/tasks/report-event
5. 后端自动标记任务完成status=completed
6. 用户点击"领取" → POST /api/tasks/daily/claim
7. 后端验证任务已完成 → 调用 userService.UpdateCrystalBalance → 调用 AddExperience → 更新状态为 claimed
8. 每日 05:00 Asia/Shanghai
a. Advisory Lock 获取锁pg_advisory_lock(YYYYMMDD)
b. 查询 task_reset_log如今天已有记录则跳过
c. 所有非 pending 状态的记录恢复为 pending
@ -540,8 +550,10 @@ rpc AddExperience(AddExperienceRequest) returns (AddExperienceResponse);
b. 分批处理(每批 N 条,可配置)
c. 调用 userService.UpdateCrystalBalance 发放水晶
d. 成功则更新 status=claimed失败则重试 N 次
e. 仍失败则标记 status=failed
e. 仍失败则标记 status=failed(对用户不可见,运营可查)
5. 用户打开移动端 → GET /api/tasks/exhibition-revenue
- 前端只显示 claimable 和 claimed 状态的记录
- failed 记录对用户不可见
6. 用户点击领取 → POST /api/tasks/exhibition-revenue/claim
7. 后端调用 userService.UpdateCrystalBalance → 更新状态
```
@ -626,7 +638,7 @@ func (w *Worker) autoClaimExhibitionRevenue() {
| 引导任务进度 | `/tasks/onboarding-progress` | 查询各用户的引导任务完成情况 |
| 任务统计 | `/tasks/stats` | 任务完成率/领取率统计图表,支持 star_id、时间范围筛选 |
| 手动重置 | `/tasks/reset` | 手动触发每日任务重置 |
| 收益记录 | `/tasks/revenue` | 查看展示收益记录 |
| 收益记录 | `/tasks/revenue` | 查看展示收益记录(含 failed支持手动补发 |
**统计页面指标:**
- 每日任务:完成人数、领取人数、完成率、领取率