- 新增挑战列表、详情、加入/退出、进度上报等 REST 接口 - 定义 Challenge / ChallengeParticipant 数据模型与状态枚举 - 提供排行榜查询与用户排名计算 - 包含接口文档与数据库初始化脚本
6.3 KiB
6.3 KiB
挑战功能接口文档
所有接口均需携带
Authorization: Bearer <token>,鉴权方式与现有用户体系一致。 基础路径:/challenges
数据模型概述
Challenge
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string |
挑战唯一标识 |
title |
string |
挑战名称 |
image |
string |
挑战展示图 URL |
periodLabel |
string |
可选,展示周期文案(如「21 天计划」) |
durationLabel |
string |
必填,持续时间描述 |
requirementLabel |
string |
必填,参与要求文案 |
status |
"upcoming" | "ongoing" | "expired" |
由服务端根据时间自动计算 |
participantsCount |
number |
当前参与人数(仅统计 active 状态) |
rankingDescription |
string |
可选,排行榜说明 |
highlightTitle |
string |
高亮标题 |
highlightSubtitle |
string |
高亮副标题 |
ctaLabel |
string |
CTA 按钮文案 |
progress |
ChallengeProgress |
可选,仅当当前用户已加入时返回 |
isJoined |
boolean |
当前用户是否已加入 |
ChallengeProgress
| 字段 | 类型 | 说明 |
|---|---|---|
completed |
number |
已完成进度值 |
target |
number |
总目标值 |
remaining |
number |
剩余进度 |
badge |
string |
当前进度徽章文案 |
subtitle |
string |
可选,补充提示文案 |
RankingItem
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string |
用户 ID |
name |
string |
昵称 |
avatar |
string |
头像 URL |
metric |
string |
排行榜展示文案(如 5/21天) |
badge |
string |
可选,名次勋章(gold/silver/bronze) |
1. 获取挑战列表
- Method / Path:
GET /challenges - 描述:获取当前所有挑战(全局共享),按开始时间升序排序。
请求参数
无额外 query 参数。
响应示例
{
"code": 0,
"message": "获取挑战列表成功",
"data": [
{
"id": "f27c9a5d-8e53-4ba8-b8df-3c843f0241d2",
"title": "21 天核心燃脂计划",
"image": "https://cdn.example.com/challenges/core-21.png",
"periodLabel": "21 天",
"durationLabel": "持续 21 天",
"requirementLabel": "每日完成 1 次训练",
"status": "ongoing",
"startAt": "2024-03-01T00:00:00.000Z",
"endAt": "2024-03-21T23:59:59.000Z",
"participantsCount": 1287,
"rankingDescription": "坚持天数排行榜",
"highlightTitle": "一起塑造强壮核心",
"highlightSubtitle": "与全球用户共同挑战",
"ctaLabel": "立即加入挑战",
"progress": {
"completed": 5,
"target": 21,
"remaining": 16,
"badge": "已坚持 5天",
"subtitle": "还差 16天"
},
"isJoined": true
}
]
}
2. 获取挑战详情
- Method / Path:
GET /challenges/{id} - 描述:获取单个挑战的详细信息及排行榜。
路径参数
| 名称 | 必填 | 说明 |
|---|---|---|
id |
是 | 挑战 ID |
响应示例
{
"code": 0,
"message": "获取挑战详情成功",
"data": {
"id": "f27c9a5d-8e53-4ba8-b8df-3c843f0241d2",
"title": "21 天核心燃脂计划",
"image": "https://cdn.example.com/challenges/core-21.png",
"periodLabel": "21 天",
"durationLabel": "持续 21 天",
"requirementLabel": "每日完成 1 次训练",
"summary": "21 天集中强化腹部及核心肌群,帮助塑形与燃脂。",
"rankingDescription": "坚持天数排行榜",
"highlightTitle": "连赢 7 天即可获得限量徽章",
"highlightSubtitle": "邀请好友并肩作战",
"ctaLabel": "立即加入挑战",
"participantsCount": 1287,
"progress": {
"completed": 5,
"target": 21,
"remaining": 16,
"badge": "已坚持 5天",
"subtitle": "还差 16天"
},
"rankings": [
{
"id": "user-001",
"name": "Alexa",
"avatar": "https://cdn.example.com/users/user-001.png",
"metric": "15/21天",
"badge": "gold"
},
{
"id": "user-002",
"name": "Ella",
"avatar": null,
"metric": "13/21天",
"badge": "silver"
}
],
"userRank": 57
}
}
3. 加入挑战
- Method / Path:
POST /challenges/{id}/join - 描述:当前用户加入挑战。若已加入会返回冲突错误。
响应示例
{
"code": 0,
"message": "加入挑战成功",
"data": {
"completed": 0,
"target": 21,
"remaining": 21,
"badge": "已坚持 0天"
}
}
可能错误
404:挑战不存在400:挑战已过期409:用户已加入或已完成(需先退出再加入)
4. 退出挑战
- Method / Path:
POST /challenges/{id}/leave - 描述:用户退出挑战,之后不再计入排行榜。可重新加入恢复进度(将重置为 0)。
响应示例
{
"code": 0,
"message": "退出挑战成功",
"data": true
}
可能错误
404:用户尚未加入或挑战不存在
5. 上报挑战进度
- Method / Path:
POST /challenges/{id}/progress - 描述:用户完成一次进度上报。默认增量
1,也可传入自定义增量,服务端会控制不超过目标值。
请求体
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
increment |
number |
否 | 1 |
本次增加的进度值,必须大于等于 1 |
{
"increment": 2
}
响应示例
{
"code": 0,
"message": "进度更新成功",
"data": {
"completed": 7,
"target": 21,
"remaining": 14,
"badge": "已坚持 7天",
"subtitle": "还差 14天"
}
}
可能错误
404:挑战不存在或用户未加入400:挑战未开始 / 已过期 / 进度增量非法
错误码说明
code |
message |
场景 |
|---|---|---|
0 |
success/具体文案 |
请求成功 |
1 |
错误描述 | 业务异常,例如未加入、挑战已过期等 |
接入建议
- 列表接口可做缓存(例如 10 分钟),但需结合挑战状态实时变更。
- 排行榜为前 10 名,客户端可在详情页展示,并根据
userRank显示用户当前排名。 - 进度上报建议结合业务埋点,确保重复提交时可处理幂等性(服务端会封顶到目标值)。