- 升级 HaveADrink SDK 从 1.0.16 到 1.0.17 版本 - 新增 GetAchievements API 接口及相关数据类型定义 - 添加 17 个成就定义,包括打卡次数、连续打卡、标准杯累计、酒类探索等类别 - 实现成就解锁逻辑计算,支持 category_records 类型成就判断 - 创建成就徽章对接文档,定义接口格式和存储建议 - 在用户资料页面集成成就展示功能,优化图标匹配逻辑
128 lines
5.5 KiB
Markdown
128 lines
5.5 KiB
Markdown
# 成就徽章体系 - 后端对接文档
|
||
|
||
> 前端已将成就体系从 5 个扩充到 17 个,本文档供后端对齐成就定义、解锁判定与接口返回格式。
|
||
> 前端本地已实现完整兜底计算,后端接口未就绪或返回为空时不影响前端展示。
|
||
|
||
---
|
||
|
||
## 一、成就清单(共 17 个)
|
||
|
||
### 1. 打卡次数类(total_records)
|
||
|
||
| id | 名称 | 描述 | 解锁条件 |
|
||
|----|------|------|----------|
|
||
| first_checkin | 初来乍到 | 完成第一次打卡,开启你的饮酒记录之旅 | 累计打卡 ≥ 1 次 |
|
||
| records_10 | 小有心得 | 累计打卡10次,记录已成习惯 | 累计打卡 ≥ 10 次 |
|
||
| records_50 | 记录老手 | 累计打卡50次,每一杯都有迹可循 | 累计打卡 ≥ 50 次 |
|
||
| records_100 | 酒档宗师 | 累计打卡100次,个人酒档初具规模 | 累计打卡 ≥ 100 次 |
|
||
|
||
### 2. 连续打卡类(streak_days)
|
||
|
||
| id | 名称 | 描述 | 解锁条件 |
|
||
|----|------|------|----------|
|
||
| streak_7 | 七日之约 | 连续打卡7天,一周不落 | 连续打卡 ≥ 7 天 |
|
||
| streak_30 | 签到王者 | 连续打卡30天,自律的记录者 | 连续打卡 ≥ 30 天 |
|
||
| streak_100 | 百日坚持 | 连续打卡100天,毅力惊人 | 连续打卡 ≥ 100 天 |
|
||
|
||
### 3. 标准杯累计类(total_standard_cups)
|
||
|
||
| id | 名称 | 描述 | 解锁条件 |
|
||
|----|------|------|----------|
|
||
| cups_10 | 微醺初体验 | 累计饮用10标准杯 | 累计标准杯 ≥ 10 |
|
||
| cups_50 | 五十杯之路 | 累计饮用50标准杯,微醺是最好的状态 | 累计标准杯 ≥ 50 |
|
||
| hundred_cups | 百杯不醉 | 累计饮用100标准杯 | 累计标准杯 ≥ 100 |
|
||
| cups_300 | 海量传说 | 累计饮用300标准杯,记得理性饮酒哦 | 累计标准杯 ≥ 300 |
|
||
|
||
### 4. 酒类探索类(category_variety)
|
||
|
||
| id | 名称 | 描述 | 解锁条件 |
|
||
|----|------|------|----------|
|
||
| variety_3 | 探索起步 | 尝试过3种不同类型的酒 | 酒类品种数 ≥ 3 |
|
||
| tasting_master | 品鉴师 | 尝试过5种以上不同类型的酒 | 酒类品种数 ≥ 5 |
|
||
| variety_8 | 酒类百科 | 尝试过8种以上不同类型的酒,尝遍百味 | 酒类品种数 ≥ 8 |
|
||
|
||
### 5. 单一酒类深耕类(category_records)
|
||
|
||
| id | 名称 | 描述 | 解锁条件 |
|
||
|----|------|------|----------|
|
||
| baijiu_master | 白酒达人 | 白酒累计打卡20次 | category=baijiu,打卡 ≥ 20 次 |
|
||
| beer_master | 啤酒之王 | 啤酒累计打卡20次,冰爽永不停 | category=beer,打卡 ≥ 20 次 |
|
||
| wine_master | 红酒绅士 | 红酒累计打卡20次,品味微酸的美好 | category=wine,打卡 ≥ 20 次 |
|
||
|
||
---
|
||
|
||
## 二、条件类型说明
|
||
|
||
| type | 说明 | value 含义 | 附加字段 |
|
||
|------|------|-----------|----------|
|
||
| total_records | 总打卡次数 | 次数 | 无 |
|
||
| streak_days | 连续打卡天数 | 天数 | 无 |
|
||
| total_standard_cups | 累计标准杯 | 杯数 | 无 |
|
||
| category_variety | 尝试过的酒类品种数 | 品种数 | 无 |
|
||
| category_records | 某酒类打卡次数 | 次数 | `category`(baijiu / beer / wine,后续可扩展其他酒类) |
|
||
|
||
**判定规则统一为 `>=`**(达到阈值即解锁,解锁后不回退)。
|
||
|
||
---
|
||
|
||
## 三、接口要求
|
||
|
||
### 3.1 GET /achievements 响应格式
|
||
|
||
```json
|
||
{
|
||
"achievements": [
|
||
{
|
||
"id": "first_checkin",
|
||
"name": "初来乍到",
|
||
"desc": "完成第一次打卡,开启你的饮酒记录之旅",
|
||
"unlocked": true,
|
||
"unlockedAt": "2026-08-10T20:00:00.000Z",
|
||
"condition": { "type": "total_records", "value": 1 },
|
||
"progress": 1.0
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**字段约定:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|------|------|:---:|------|
|
||
| id | string | 是 | 成就ID,必须与本文档清单一致 |
|
||
| name / desc | string | 是 | 名称与描述,与清单保持一致 |
|
||
| unlocked | boolean | 是 | 是否已解锁 |
|
||
| unlockedAt | string/null | 否 | 解锁时间,ISO 8601 |
|
||
| condition | object | 是 | 与清单一致;category_records 需带 category |
|
||
| progress | number | 否 | 进度 0~1(当前值/目标值,封顶 1) |
|
||
| icon | string | 否 | **后端无需返回有效图标**,前端忽略该字段,统一使用本地预置图标 |
|
||
|
||
### 3.2 注意事项
|
||
|
||
1. **必须返回全量 17 条**(含未解锁的),前端按列表顺序渲染成就墙;不要只返回已解锁项
|
||
2. **icon 字段可不返回**:后端返回的图片路径前端不会使用,图标由前端本地控制
|
||
3. **progress 计算**:`min(当前累计值 / value, 1)`;category_records 按对应酒类的打卡次数计算
|
||
4. **解锁检测时机**:建议在创建打卡记录后异步触发(避免阻塞主流程),比对全部成就条件并写入解锁记录
|
||
5. **幂等**:同一成就解锁只记录一次,`unlocked_at` 以首次解锁时间为准
|
||
6. **id 兼容**:前端取值顺序为 `achievement_id || id`,两者返回其一即可
|
||
|
||
### 3.3 存储建议
|
||
|
||
```sql
|
||
CREATE TABLE user_achievements (
|
||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||
user_id VARCHAR(32) NOT NULL,
|
||
achievement_id VARCHAR(32) NOT NULL,
|
||
unlocked_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
UNIQUE INDEX idx_user_achievement (user_id, achievement_id)
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 四、前端兜底策略(供后端了解)
|
||
|
||
- 接口失败或返回空数组时,前端用本地统计(totalRecords / totalCups / streak / categoryVariety)对照上述条件自行计算解锁状态
|
||
- 本地计算 `category_records` 类成就依赖 `stats.categoryRecords`(各酒类打卡次数映射),统计接口若能返回该字段可提升兜底准确度
|
||
- 因此后端即使暂未实现,前端也不会报错,只是解锁以本地统计为准
|