0.0.0
This commit is contained in:
136
docs/02-数据模型.md
Normal file
136
docs/02-数据模型.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# 02 · 数据模型(云数据库)
|
||||
|
||||
云数据库为文档型(类 MongoDB)。共 4 个集合。约定:`_openid` 由云开发自动写入,作为归属与权限依据;时间统一存毫秒时间戳(Number)。
|
||||
|
||||
---
|
||||
|
||||
## 1. `users` — 用户
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `_id` | String | 自动 |
|
||||
| `_openid` | String | 微信 openid,唯一 |
|
||||
| `nickname` | String | 昵称,默认「铲屎官」 |
|
||||
| `avatar` | String | 云存储 fileID,可空 |
|
||||
| `walkCount` | Number | 累计遛狗次数(冗余,展示用) |
|
||||
| `joinedAt` | Number | 加入时间戳 |
|
||||
| `createdAt` | Number | 创建时间 |
|
||||
|
||||
> 「加入 92 天」由 `joinedAt` 客户端算;「遛狗 87 次」读 `walkCount`。
|
||||
|
||||
---
|
||||
|
||||
## 2. `dogs` — 狗狗
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `_id` | String | 狗狗 ID |
|
||||
| `_openid` | String | 归属用户 |
|
||||
| `name` | String | **必填**,名字 |
|
||||
| `breed` | String | **必填**,犬种(如「柯基」) |
|
||||
| `sizeLevel` | String | 体型档位:`xs`/`s`/`m`/`l`/`xl`,由犬种映射;未知犬种由用户手动选择 |
|
||||
| `baseStride` | Number | 档位基础步幅,单位米/步 |
|
||||
| `stride` | Number | 最终步幅,填体重时在 `baseStride` 上校准,封顶 ±15% |
|
||||
| `gender` | String | `male` / `female` / null |
|
||||
| `ageStage` | String | `puppy` / `adult` / `senior` / null |
|
||||
| `ageText` | String | 展示文案,如「成犬 3 岁」,可空 |
|
||||
| `weight` | Number | kg,可空(二次校准狗步) |
|
||||
| `avatar` | String | 云存储 fileID,可空 |
|
||||
| `stats` | Object | 累计统计(见下,冗余加速主页) |
|
||||
| `createdAt` | Number | 建档时间 |
|
||||
|
||||
**`stats` 内嵌对象**(每次遛狗结算时在云函数原子更新):
|
||||
|
||||
```js
|
||||
stats: {
|
||||
totalWalks: 87, // 总次数
|
||||
totalDistance: 142.0, // 总公里
|
||||
totalSteps: 0, // 总狗步(可选)
|
||||
currentStreak: 7, // 连续天数
|
||||
lastWalkDate: '2026-06-24', // 最近一次有效遛狗的日期(yyyy-mm-dd),算连续用
|
||||
}
|
||||
```
|
||||
|
||||
> 仅「名字 + 犬种」必填——降低首次门槛。`sizeLevel/baseStride/stride` 由 `utils/dogStep.js` 按「犬种 → 体型档位 → 步幅」计算;中华田园犬、串串、找不到的犬种必须让用户手动选体型档位。
|
||||
|
||||
---
|
||||
|
||||
## 3. `walks` — 遛狗记录
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `_id` | String | 记录 ID |
|
||||
| `_openid` | String | 归属用户 |
|
||||
| `dogIds` | Array<String> | 本次遛的狗(支持多狗一起遛) |
|
||||
| `startAt` | Number | 开始时间戳 |
|
||||
| `endAt` | Number | 结束时间戳 |
|
||||
| `duration` | Number | 净遛狗秒数(已扣暂停) |
|
||||
| `distance` | Number | 公里,未授权定位时为 null |
|
||||
| `dogStepsByDog` | Object | `{ [dogId]: steps }`,按每只狗的 `stride` 分别换算;未授权定位时为 null |
|
||||
| `pooped` | Boolean | 便便打卡 |
|
||||
| `weather` | String | `sunny`/`cloudy`/`rainy`,可空 |
|
||||
| `mood` | String | 状态标签,可空 |
|
||||
| `note` | String | 备注,可空 |
|
||||
| `photos` | Array<String> | 云存储 fileID,可空 |
|
||||
| `source` | String | `realtime` / `manual`,对应 PRD 的数据来源 |
|
||||
| `isManual` | Boolean | 是否手动补记;兼容展示判断,等价于 `source === 'manual'` |
|
||||
| `countsForRanking` | Boolean | 是否计入排行榜;补记恒为 `false` |
|
||||
| `walkDate` | String | `yyyy-mm-dd`,按本地时区,连续/分组用 |
|
||||
| `createdAt` | Number | 入库时间 |
|
||||
|
||||
> 成果卡所有补充字段(photos/weather/mood/note)全部选填,跳过也能保存。`dogStepsByDog` 仅用于拟人化展示;成就与未来排行榜只使用距离、时长、连续天数等客观量。
|
||||
|
||||
---
|
||||
|
||||
## 4. `dog_achievements` — 成就解锁记录
|
||||
|
||||
成就**按狗维度**(原型「成就墙 · 豆豆」)。成就定义不入库,固化在代码 `utils/achievements.js`(含 key、名称、描述、判定规则、图标)。本集合只存「某狗解锁了某成就」。
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `_id` | String | 自动 |
|
||||
| `_openid` | String | 归属用户 |
|
||||
| `dogId` | String | 狗狗 ID |
|
||||
| `achievementKey` | String | 成就标识,如 `week_streak` |
|
||||
| `unlockedAt` | Number | 解锁时间戳 |
|
||||
|
||||
唯一性:`(dogId, achievementKey)` 不重复解锁(云函数判定前先查重)。
|
||||
|
||||
**成就 key 参考**(来自原型):
|
||||
|
||||
| key | 名称 | 解锁条件 |
|
||||
|-----|------|---------|
|
||||
| `first_walk` | 首遛 | 第一次记录遛狗 |
|
||||
| `week_streak` | 一周不断 | 连续遛狗满 7 天 |
|
||||
| `month_streak` | 满月坚持 | 连续遛狗满 30 天 |
|
||||
| `rainy_warrior` | 雨天战士 | 雨天也坚持遛狗 |
|
||||
| `hundred_km` | 百里同行 | 累计满 100 公里 |
|
||||
| `early_bird` | 早起鸟 | 7 点前遛狗 10 次 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 索引
|
||||
|
||||
| 集合 | 索引字段 | 说明 |
|
||||
|------|---------|------|
|
||||
| `users` | `_openid`(唯一) | 登录查重 |
|
||||
| `dogs` | `_openid` | 列出我的狗 |
|
||||
| `walks` | `_openid` + `walkDate`(降序) | 历史列表、连续判定 |
|
||||
| `walks` | `dogIds`(多键) | 按狗查记录 |
|
||||
| `dog_achievements` | `dogId` + `achievementKey`(联合唯一) | 查重与成就墙 |
|
||||
|
||||
## 6. 数据库权限(安全规则)
|
||||
|
||||
全部集合设为 **「仅创建者可读写」**,写操作再经云函数二次校验。客户端只允许读自己的数据;统计累加、成就解锁等只能由云函数(管理员权限)写,防止刷量。
|
||||
|
||||
```json
|
||||
// 示例:walks 集合权限
|
||||
{
|
||||
"read": "doc._openid == auth.openid",
|
||||
"write": false // 客户端禁写,统一走云函数
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user