5.4 KiB
5.4 KiB
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 内嵌对象(每次遛狗结算时在云函数原子更新):
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. 数据库权限(安全规则)
全部集合设为 「仅创建者可读写」,写操作再经云函数二次校验。客户端只允许读自己的数据;统计累加、成就解锁等只能由云函数(管理员权限)写,防止刷量。
// 示例:walks 集合权限
{
"read": "doc._openid == auth.openid",
"write": false // 客户端禁写,统一走云函数
}