家庭日用品追踪小程序 · 开发过程技术文档

项目代号:耗品记(household-consumable-tracker)
文档版本:v1.0 | 整理日期:2026-08-07
适用读者:开发者、维护者、产品评审

家庭日用品追踪小程序

---

1. 文档说明

本技术文档用于完整记录「家庭日用品追踪小程序」从立项到当前版本(完全纯本地)的架构设计、功能实现与关键开发决策,重点沉淀开发过程中踩过的坑、做过的架构取舍,便于后续维护与知识传递。

本文内容基于源码(7 个页面 + 3 个工具模块 + 全局配置)与开发过程记录整理,关键结论均可在 overview.md.workbuddy/memory/ 中找到对应时间线。

文档结构

  1. 项目背景与目标
  2. 产品功能概览
  3. 技术架构
  4. 核心模块设计与实现
  5. 开发历程与关键技术决策(按时间线)
  6. 当前架构状态与权衡
  7. 踩坑与经验总结
  8. 后续优化建议
  9. 附录:文件清单与验证命令

2. 项目背景与目标

2.1 痛点

家庭日用品(纸巾、洗洁精、牙膏、调料等)属于「低单价、高频消耗、易忘记补货」的品类。用户通常在「用完了才发现没买」时才补,缺乏:

2.2 目标

做一个轻量、零门槛、纯本地的家庭耗品记账与管理工具:

2.3 产品定位决策


3. 产品功能概览

页面(tab) 文件 核心功能
物品(首页) pages/index 物品列表(分类筛选/搜索/排序/卡片/紧凑双视图)、顶部数据概览、快速记录使用、即将过期专区、提醒横幅
添加 pages/add 新增/编辑物品(消耗品/耐用品两类、常见日用品预设库、分类色)
详情 pages/detail 物品完整信息、使用记录时间线、补货记录、补货/使用/编辑/删除、分享卡片(Canvas 长图)
分析 pages/analysis 在用物品实时分析 + 历史消耗统计(支出排行条形图按分类着色)
提醒 pages/reminder 库存预警 + 过期提醒列表、提醒开关/时间/星期设置、补货阈值/提前天数/过期提醒天数滑块、采购清单长图分享
盘点 pages/checkin 每周盘点:逐项填剩余量、实时算期间消耗、差异提示、覆盖式保存
我的 pages/mine 数据清空、隐私政策入口、关于

数据层(utils/storage.js)、工具层(utils/util.js / utils/card.js)被所有页面复用,是项目的「单一数据源」。


4. 技术架构

4.1 整体架构(纯本地)

┌─────────────────────────────────────────────┐
│              微信小程序前端(7 个页面)          │
│   index / add / detail / analysis / reminder   │
│        / checkin / mine                        │
└───────────────┬───────────────────────────────┘
                │  require('../../utils/storage.js')
┌───────────────┴───────────────────────────────┐
│  数据层  utils/storage.js(纯本地存储)          │
│  工具层  utils/util.js(日期/数值/ID/颜色)       │
│         utils/card.js(Canvas 卡片绘制)         │
└───────────────┬───────────────────────────────┘
                │  wx.setStorageSync / getStorageSync
┌───────────────┴───────────────────────────────┐
│   本地 Storage(用户手机,无任何云端依赖)         │
│   hct_items / hct_history / hct_settings /      │
│   hct_checkins                                  │
└───────────────────────────────────────────────┘

关键事实(2026-08-03 起):项目无任何云端依赖——没有云函数、没有云数据库、没有微信订阅消息、没有账号系统。所有逻辑在客户端完成。

4.2 目录结构

household-consumable-tracker/
├── app.js / app.json / app.wxss      # 全局逻辑、配置、样式令牌
├── project.config.json               # 已移除 cloudfunctionRoot
├── pages/                            # 7 个页面,每页 .js/.json/.wxml/.wxss
├── utils/
│   ├── storage.js                    # 数据存储层(单一数据源)
│   ├── util.js                       # 通用工具
│   └── card.js                       # Canvas 卡片绘制
├── tab-icons/                        # 4 个 tab 的选中/未选中图标
└── overview.md                       # 修复与变更总览

4.3 数据模型(storage 层)

存储键(见 storage.js 顶部常量):

Key 内容
hct_items 在用物品数组(含使用/补货记录、实时分析)
hct_history 已消耗完的物品(保留用于分析)
hct_settings 提醒/阈值/过期天数等配置
hct_checkins 每周盘点记录(剩余量快照 + 期间消耗)

Item 结构(核心字段):

{
  id, name, category, unit,
  itemType: 'consumable' | 'durable',     // 消耗品 / 耐用品
  totalQuantity, remainingQuantity, price,
  purchaseDate, expireDate,
  status: 'active' | 'consumed',
  usageRecords: [{ time, quantity, note }],
  restockRecords: [{ date, quantity, price }],
  consumedTime, analysis
}

Settings(DEFAULT_SETTINGS)lowStockThreshold(0.2)、repurchaseDays(7)、expireLeadDays(14)、notifyEnablednotifyFreq(固定 weekly)、notifyTime('20:00')、notifyWeekday(0=周日)、lastBannerDismissDatelastLocalAlertDate

设计要点:所有写入都经过 round() 数值兜底,避免 NaN 写入 storage;页面读取 item 时 JSON.parse(JSON.stringify(raw)) 深拷贝,防止污染 storage 原始引用。

4.4 页面与路由

4.5 工具层


5. 核心模块设计与实现

5.1 物品生命周期管理

5.2 消耗分析算法(耐用品 vs 消耗品)

analyze() 是核心,对两类物品采用不同口径(见 storage.js):

5.3 补货预测(三级回退)

predictPurchase() 按数据质量依次回退,保证尽量有值:

  1. 盘点快照(最准):用最近两次盘点的间隔与消耗量算日均。
  2. 使用记录:回退到「使用总量 ÷ 购买至今时长」(避免短间隔放大)。
  3. 历史同名均值:同名下已消耗物品的 dailyUsage 均值。
    最终输出 daysLeftneedBuy(剩余 ≤ repurchaseDays 触发)。

5.4 每周盘点系统

5.5 提醒系统(纯本地,不依赖微信)

三种表现(均只在打开小程序时可见):

  1. 首页横幅 shouldShowBanner:盘点日过点 或 存在紧急待办(优先级 1)时显示;lastBannerDismissDate 当天不再弹。
  2. 提醒 tab 本地弹窗:打开提醒 tab 且 shouldNotifyToday() 为真时 wx.showModal「有 N 件物品即将用完」,lastLocalAlertDate 每天最多一次。
  3. 提醒 tab 列表:库存预警(low_stock)+ 过期提醒(expire),按优先级排序。

触发判定 shouldNotifyToday():仅当 notifyEnabled 且当天为 notifyWeekday 且已过 notifyTime 才为真。过期提醒getExpiringItems(leadDays) 实现,按剩余天数升序,文案三态(剩X天/今天到期/已过期X天)。

5.6 分享卡片(Canvas)


6. 开发历程与关键技术决策(时间线)

以下每个决策点都对应 overview.md 的具体修复记录,本文做归纳与归因。

6.1 初版与上线(2026-07-22 ~ 07-23)

6.2 隐私授权方案踩坑与回退(07-29)

6.3 过期提醒改为应用内(07-29)

6.4 微信订阅消息推送的尝试与最终移除(重点)

6.5 代码审查与 Bug 修复(2026-08-01)

对全量代码静态审查(node --check 全通过,无语法错),定位并修复 10 个问题(2 P1 + 6 P2 + 2 P3)

P1 功能性 Bug

  1. 分析页「支出排行」条形图颜色全灰:computeSummary 的聚合缺 category 字段,导致 catColor 取 undefined 回落灰色。修复后条形图按物品实际分类着色。
  2. 提醒页抢跑 markNotifiedToday 挡掉微信推送:reminder.js onShow 在 shouldNotifyToday() 为真时立即 markNotifiedToday(),与 app.js 微信推送共用 lastNotifyDate,导致用户先切提醒 tab 后 app.js 跳过推送。引入独立 lastLocalAlertDate 去重键解决。

P2 代码质量/死代码/兼容
3. 删除 cloud.jsgetMiniCode 死代码 + cloudfunctions/getQRCode/ 目录。
4. 删除 storage.js 未调用的 getAnalysisSummary/saveCheckin/getCheckinStats 兼容旧接口。
5. checkin.wxmlshow-scrollbar="false"(字符串)改 {{false}}(布尔)。
6. detail.wxml 的 8 位 hex(#RRGGBBAA) 改 hexToRgba() 兼容老基础库。
7. mine.wxml 删除冗余「用户协议」入口。

P3 优化
8. util.round() 加 NaN/null 兜底(返回 0)。
9. checkin.js 历史盘点 stats 不再按当前 itemType 快照过滤,避免物品改类型后历史条目丢失。

6.6 运行期日志报错修复


7. 当前架构状态与权衡

7.1 架构状态(2026-08-03 起)

小程序 = 完全纯本地、无任何云端依赖

7.2 已失去的能力(权衡)

7.3 仍保留的能力


8. 踩坑与经验总结

  1. 微信隐私授权:不要自研组件去「抢」系统授权弹窗,在 __usePrivacyCheck__: true 下,系统弹窗才是权威路径,逐页组件会导致每 tab 重弹且授权不落库。
  2. 微信订阅消息限制App.onShow 是唯一客户端触发点,一次性订阅授权 7 天/一次,无法在 App 关闭时定时下发。需要真·到点推送必须上云函数定时触发器。
  3. Canvas 兼容性:老基础库不支持 8 位 hex 与内置 roundRect,统一用 hexToRgba() + 自写 roundRect();长图 dpr 手动封顶避免 canvas 尺寸超限。
  4. 数据模型:页面读取 item 要深拷贝,防止污染 storage 原始对象;旧数据可能缺 analysis,读取时主动 analyze() 兜底。
  5. 数值安全:所有出入 storage 的数值经 round() 兜底 NaN,避免脏数据污染统计。
  6. 静态审查价值node --check + Grep 残留引用 是低成本高收益的「伪编译」手段,能在无真机环境下拦住大部分引用类回归。
  7. 过渡态清理:移除大功能(如微信推送)时,要连字段、函数、云函数、配置、孤立样式一起清,并用 grep 验证零残留,否则会留下隐蔽的运行时报错与体积浪费。

9. 后续优化建议

方向 建议 备注
数据导出/备份 增加「导出 JSON / 导入」功能,弥补纯本地无云同步的易丢风险 用户换机/清缓存即丢失
定时提醒 若确需「到点推送」,评估云函数定时触发器 + 订阅授权引导流程 复杂度高,需重新引入云端
多家庭/共享 当前无账号体系,天然单机;共享需引入云同步 + 家庭关系 见 MEMORY 历史方案,从未实现
可视化升级 分析页环形图(WXML 不支持内联 SVG,可改用 Canvas) 当前用进度条零兼容风险
埋点分析 纯本地无后端,留存/崩溃需去 MP「数据分析-访问分析」看平台自带数据 无需自建
组件库 如需 100% 微信原生组件观感,可单独引入 weui-miniprogram 当前未引入以降低构建风险

附录 A:关键文件清单

文件 职责
app.js 全局初始化(storage.init),无推送逻辑
app.json 页面/tabBar/隐私开关配置
app.wxss 微信原生卡片分区风样式令牌
utils/storage.js 数据存储层(单一数据源,含分析/预测/盘点/提醒)
utils/util.js 日期/数值/ID/颜色工具
utils/card.js Canvas 卡片绘制(采购清单/资产卡)
pages/index/index.js 首页:列表/筛选/搜索/排序/横幅/过期专区
pages/analysis/analysis.js 消耗分析(条形图按分类着色)
pages/reminder/reminder.js 提醒中心(列表/设置/本地弹窗/分享长图)
pages/checkin/checkin.js 每周盘点(剩余量/差异/覆盖保存)
pages/detail/detail.js 详情(使用/补货/编辑/删除/分享卡片)
pages/add/add.js 新增/编辑(预设库/分类色)
pages/mine/mine.js 我的(数据清空/隐私)

注:移除云函数后若开发者工具仍报 sendSubMsg/index.js ENOENT,需关闭并重开项目清除云函数注册缓存。

微信搜一搜 © iBitBetter