Files
Pet3/docs/01-架构设计.md
2026-06-25 18:24:29 +08:00

6.7 KiB
Raw Permalink Blame History

01 · 架构设计

1. 技术选型理由

原生小程序 + 云开发,因为:

  • 云开发是微信官方为原生小程序量身打造,集成度最高、免运维、免自建鉴权。
  • 汪圈 V1 是单机闭环无跨端App / H5 / 支付宝)需求,原生比 Taro / uni-app 更直接。
  • 云函数里 cloud.getWXContext().OPENID 直接拿到可信用户标识,省掉整套登录鉴权后端。

2. 整体架构

┌─────────────────────────────────────────────┐
│              微信小程序客户端                  │
│  pages/ (12屏)  ·  components/  ·  utils/      │
│            globalData + 事件总线               │
└───────────────────┬─────────────────────────┘
                     │ wx.cloud.callFunction
        ┌────────────┴────────────┐
        ▼                         ▼
┌───────────────┐         ┌───────────────┐
│   云函数        │         │  云数据库       │
│ login          │◄───────►│ users          │
│ dogManage      │         │ dogs           │
│ walkSave       │         │ walks          │
│ walkManual     │         │ dog_achievements│
│ getDogDetail   │         └───────────────┘
│ getHistory     │
└───────────────┘                 │
        │                         ▼
        ▼                  ┌───────────────┐
   成就判定/统计累加         │  云存储         │
                          │ 头像/照片/分享图 │
                          └───────────────┘

核心原则:写操作 + 敏感计算全部走云函数,客户端只读(或经云函数读聚合结果)。连续天数、成就解锁、补记规则等绝不在客户端算。

3. 工程目录结构

Pet3/
├── cloudfunctions/              # 云函数Node.js
│   ├── login/                   # 登录 + 首次建用户
│   │   ├── index.js
│   │   └── package.json
│   ├── dogManage/               # 狗狗增改查
│   ├── walkSave/                # 保存遛狗 + 触发统计/成就
│   ├── walkManual/              # 手动补记
│   ├── getDogDetail/            # 狗狗主页聚合数据
│   └── getHistory/              # 历史/记录 Tab 列表聚合
│
├── miniprogram/
│   ├── app.js                   # 初始化 wx.cloud、globalData
│   ├── app.json                 # 路由、tabBar、分包
│   ├── app.wxss                 # 全局样式 + 设计 token
│   ├── pages/
│   │   ├── login/               # 0a 登录
│   │   ├── dog-edit/            # 0b 建档/编辑(复用)
│   │   ├── home/                # 1  我的tab
│   │   ├── walking/             # 2/2b 遛狗中(含暂停态)
│   │   ├── summary/             # 3  成果卡
│   │   ├── dog-detail/          # 4  狗狗主页
│   │   ├── history/             # 5  遛狗历史
│   │   ├── records/             # 6/6b 记录tab含空状态
│   │   └── achievements/        # 7  完整成就页
│   ├── components/
│   │   ├── dog-card/            # 狗狗卡片
│   │   ├── walk-row/            # 历史/记录行
│   │   ├── stat-grid/           # 统计三宫格
│   │   ├── achievement-medal/   # 成就勋章(解锁/锁定)
│   │   ├── multi-dog-sheet/     # 0c 多狗选择弹层
│   │   └── manual-add-sheet/    # 补记弹层
│   ├── utils/
│   │   ├── cloud.js             # callFunction 统一封装 + 错误处理
│   │   ├── format.js            # 时长/距离/日期格式化
│   │   ├── dogStep.js           # 狗步换算(体型档位/步幅/体重校准)
│   │   └── store.js             # 全局状态 + 订阅
│   └── images/                  # 本地图标/占位图
│
├── docs/                        # 设计文档(本目录)
├── wangquan-prototype.html      # 交互原型
└── project.config.json

4. 全局状态store

不引入重型状态库。miniprogram/utils/store.js 维护:

const store = {
  userInfo: null,        // { openid, nickname, avatar, joinedAt, walkCount }
  dogs: [],              // 当前用户的狗狗列表
  currentDogId: null,    // 默认/上次选中的狗
  walkSession: null,     // 进行中的遛狗会话(见下)
};

遛狗会话walkSession 是 V1 最关键的运行时状态,需支持小程序退到后台后恢复:

walkSession = {
  dogIds: ['xxx'],       // 本次遛的狗(支持多狗)
  startAt: 1719230000000,
  pausedTotal: 0,        // 累计暂停时长(ms),结算时扣除
  pausedAt: null,        // 当前暂停起点null=进行中
  pooped: false,         // 便便打卡
  locationEnabled: false, // 是否获得定位授权
  distanceMeters: null,   // GPS 累计距离;未授权为 null
  lastLocation: null,     // 最近一次有效定位点,用于增量累计距离
  status: 'walking' | 'paused',
}

落地策略:会话写入 wx.setStorageSync('walkSession')App onShow 时恢复,避免锁屏/切后台丢失计时。计时基于 startAt 与当前时间差实时计算,不依赖 setInterval 累加(后台被冻结也不丢)。定位为可选增强:获得授权时累计 GPS 距离并换算狗步;未授权时 distanceMeters / dogStepsByDognull,界面隐藏距离与狗步,闭环仍成立。

5. 设计 Token迁移自原型

原型 CSS 变量直接转为 app.wxss 全局变量,保证视觉一致:

Token 用途
--bg #F2EDE6 页面背景
--surface #FBF8F3 卡片
--ink #2E2A24 主文字
--ink-2 #6E665B 次文字
--accent #E8A04B 主色(按钮/FAB
--accent-deep #C77E2E 主色深
--success #6B8E5A 遛狗中
--warn #D98A4E 暂停态
--danger #C25A4E 结束/二次确认

小程序 WXSS 支持 CSS 变量,可直接 var(--accent)。不引第三方组件库,全部基础 UI按钮、卡片、chip、toggle、勋章等按原型纯手写为 components/ 下的可复用组件。