背景与动机
家庭囤货是常态,但管理不善就会变成「买完忘、过期扔、重复买」的死循环。冷藏室里冻了一年的肉、柜子深处过期的调味料,是每个家庭都会遇到的场景。
市面上已有的保质期管理工具大多是 SaaS 模式,需要注册账号、连接云端。但这类工具的核心场景是个人或家庭内部使用,为了记几个日期去搭一套后端,不仅成本高,还有隐私顾虑。有没有更轻量的办法?
答案是:纯本地微信小程序,零服务器成本。
功能设计
商品录入
- 扫码录入:使用
wx.scanCode扫描商品条码,自动获取条码编号 - 手动回填:当扫码无法获取完整信息时,用户自行填写品名、分类、购入日期、保质期
库存看板
以列表或卡片形式展示所有商品,支持两种排序维度:
- 按过期时间:即将过期的排最前
- 按分类:同类商品聚合展示
到期提醒
- 首页看板高亮标记:即将过期(黄色)和已过期(红色)
- 小程序启动时自动检查:通过
App.onShow或页面onLoad遍历所有商品,计算过期状态并展示汇总提示
条码识别演进
当前版本扫码后只拿到条码编号,需要用户手动补充品名。商业版计划接入 LLM 识别方案:拍摄商品包装 → OCR 提取文字 → LLM 结构化输出(品名、品牌、保质期),一步完成录入。
技术实现
数据模型
商品是核心实体,字段设计如下:
| 字段 | 类型 | 说明 |
|---|---|---|
code | string | 条码编号 (EAN-13) |
name | string | 商品名称 |
category | string | 分类(食品、日用品等) |
quantity | number | 数量 |
purchaseDate | string | 购入日期 (YYYY-MM-DD) |
expiryDate | string | 过期日期 (YYYY-MM-DD) |
notes | string | 备注 |
分类采用预置 + 自定义模式。预置分类包括:食品、饮品、调味品、日用品、个人护理、药品、其他。
数据持久化方案
这是整个项目最核心的技术决策。
约束条件:零云服务、零服务器成本、用户无感、数据不能轻易丢失。
微信小程序的两种本地存储
| 存储方式 | 限制 | 清理缓存时 | 清理全部数据时 |
|---|---|---|---|
wx.setStorageSync | 总上限 10MB,单 key 1MB | ❌ 丢失 | ❌ 丢失 |
文件系统 (wx.env.USER_DATA_PATH) | 总上限 200MB | ✅ 保留 | ❌ 丢失 |
关键区别在于:用户最常见的操作是「清理缓存」(清 Storage),而文件系统的数据不受影响。「清理全部数据」才同时清除两者,但这是用户主动销毁数据的操作,任何本地 App 都无法避免。
方案:双写冗余 + 自动恢复
写入路径 用户可见性
────────────────────────────────────────────
A. wx.setStorageSync 不可见(沙盒内)
B. wx.env.USER_DATA_PATH 不可见(沙盒内)
流程:
┌──────────────────────────────────────┐
│ 启动小程序 │
│ ↓ │
│ wx.getStorageSync 读取主数据 │
│ ↓ │
│ ┌── 数据存在?──┐ │
│ │ 是 │ 否 │
│ ↓ ↓ │
│ 正常使用 从文件系统恢复 │
│ (自动,用户无感) │
│ ↓ │
│ 写入 Storage │
└──────────────────────────────────────┘
每次数据变更 → 同时写入 Storage + 文件系统
这套方案下,用户完全不感知备份和恢复的存在。最常见的「清理缓存」场景数据不会丢失,零云成本,代码量也不大。
扫码录入流程
用户点击「扫码」 → wx.scanCode() → 拿到条码编号
↓
本地数据库查询(getStorageSync)
↓
存在该商品 → 自动填充名称等信息 → 用户确认 → 存入
不存在该商品 → 跳转手动填写页面
「本地数据库」是一个简单的 JSON 数组,存储所有已录入的商品记录。日常所有读写操作都走 Storage,写操作结束后再同步一份到文件系统。
对于商业版的 LLM 自动识别,流程扩展为:
拍照 → wx.chooseImage() → OCR 提取包装文字 → LLM prompt
↓
结构化输出 { name, brand, category, expiryDays }
↓
结合当前日期计算出 expiryDate → 写入本地数据
到期提醒机制
纯本地方案无法推送系统通知栏消息(微信小程序不存在 createLocalNotification 这类 API)。提醒完全在应用内完成:
- 首页展示:列表根据当前日期动态计算每件商品的状态。
Math.ceil((expiryDate - today) / day)<= 7 天标黄,<= 0 天标红,按过期时间升序排列。 - 启动检查:在
App.onShow中遍历数据,通过wx.showModal或自定义弹窗汇总提示即将过期的商品数量。
更主动的推送需依赖微信「订阅消息」能力,但这需要服务端下发通知,超出了纯本地方案的范围。
关于「家庭共享」的取舍
最初设想过多设备共享数据。但微信小程序生态下,不存在纯客户端的两用户数据交换机制。没有中转服务器,A 手机的数据无法直接同步到 B 手机。
替代方案是通过导出 JSON → 微信发送文件 → 导入,实现半自动的"共享"。如果选择不对用户暴露文件细节,也可以接受「多人各自管理自己的数据」—— 一个家庭共用一台手机的微信小程序即可。
付费版规划
免费版满足个人本地使用。付费版通过一次性购买或订阅解锁两项核心能力:
云同步与家庭共享
基于微信云开发的基础套餐(19.9 元/月),实现多设备数据同步。
数据模型升级:引入 familyId 字段,同一家庭的所有成员读写同一份数据。
建家流程:用户 A 建家 → 生成邀请码 → 用户 B 输入邀请码加入 → 两人的 familyId 绑定一致。云端安全规则按 familyId 鉴权,而非 _openid,保证家庭成员间互相同步。
同步策略:用户端始终先读本地缓存保证秒开,后台静默同步云端变更。网络不可用时降级为纯本地模式,不影响正常使用。
LLM / OCR 商品识别
接入微信云开发的 AI 能力或第三方大模型 API,替代手动录入。
流程:
拍照 → wx.chooseImage() → 图片上传 → OCR 提取包装文字
↓
LLM 结构化输出:{ name: "海天酱油", brand: "海天",
category: "调味品", expiryDays: 540 }
↓
结合购入日期自动算出 expiryDate → 填入表单,用户确认后保存
一个家庭首次录入某商品后,识别结果存入云端商品库。同家庭的其他成员下次录入同一商品时直接回填,无需重复调用模型。
成本估算
付费版依赖云端实现数据同步,主要备选方案有两个。
方案一:微信云开发(19.9 元/月起)
微信云开发是微信小程序深度集成的云服务,小程序端可直接通过 wx.cloud.database() 调用,无需额外配置域名。
其计费模式为基础套餐 + 按量付费,不存在纯按量选项:
| 资源 | 套餐配额 |
|---|---|
| 调用次数 | 20 万次/月 |
| 容量 | 2GB |
| 云函数外网出流量 | 2GB |
| 云函数资源使用量 | 10 万 GBs |
| QPS | 500 |
| 价格 | 19.9 元/月 |
超出套餐配额的部分按量计费:0.5 元/万次调用、0.1 元/GB/天容量。
方案二:腾讯云通用 Serverless(按量计费)
如果脱离微信云开发,使用通用的腾讯云 Serverless 组件自行搭建后端,各组件独立计费:
| 组件 | 免费额度 / 月 | 超出后按量价 |
|---|---|---|
| SCF 云函数 | 400 万次调用 + 40 万 GBs | 1.33 元/百万次 + 0.000111 元/GBs |
| API 网关 | 100 万次请求 | 0.13 元/万次 |
| 对象存储 COS | 50GB 存储 + 10GB CDN | 0.099 元/GB/月 |
| 云数据库 MongoDB | 无免费额度 | 最低约 30 元/月起 |
方案对比
| 微信云开发 | 通用 Serverless | |
|---|---|---|
| 小程序调用 | 直连,无需域名 | 需通过 API 网关转发 |
| 数据库费用 | 含在套餐内 | 单独计费 ≈ 30 元/月 |
| 纯按量模式 | 不支持 | 支持(数据库除外) |
| 最低月成本 | 19.9 元 | ≈ 30-50 元 |
通用 Serverless 的 SCF 和 API 网关虽然有慷慨的免费额度,但云数据库没有免费层。对于"多用户云端同步"这个场景,数据库是刚性需求,无法绕过。微信云开发的套餐把数据库费用打包在内,反而更划算。
单用户资源消耗估算
按正常家庭使用习惯:
| 行为 | 频次 | 月调用次数 |
|---|---|---|
| 打开小程序拉取数据 | 3 次/天 | 90 次 |
| 录入/编辑商品 | 1 次/天 | 30 次 |
| 删除/整理 | 2 次/周 | 8 次 |
| 合计 | ~128 次/月 |
单用户存储占用约 50KB(假设 50-100 件商品,不含图片)。
多用户规模测算(基于微信云开发)
| 活跃用户 | 套餐数 | 月套餐费 | 超额费(估) | 总成本 / 月 | 每用户成本 |
|---|---|---|---|---|---|
| < 1,000 | 1 套 | 19.9 元 | ≈ 0 元 | ~20 元 | < 0.02 元 |
| 5,000 | 1 套 | 19.9 元 | ≈ 20 元 | ~40 元 | 0.008 元 |
| 10,000 | 1 套 | 19.9 元 | ≈ 50 元 | ~70 元 | 0.007 元 |
| 50,000 | 1 套 | 19.9 元 | ≈ 400 元 | ~420 元 | 0.008 元 |
单套餐 20 万次调用配额对几千用户绰绰有余。达到 5 万用户时超额费开始显著上升,届时可升配或加购资源包。
定价与盈利空间
付费版若定价 1 元/月 或 6 元买断,按 5% 免费→付费转化率计算:
| 用户总数 | 付费用户 | 月收入(1 元/月) | 月成本 | 月利润 |
|---|---|---|---|---|
| 10,000 | 500 | 500 元 | ~70 元 | ~430 元 |
| 50,000 | 2,500 | 2,500 元 | ~420 元 | ~2,080 元 |
从几千用户开始即可实现正向收益。全部依赖微信原生能力或腾讯云 Serverless 组件,无需自建任何服务器。
总结
这个项目展示了如何仅用微信小程序原生能力,零服务器成本构建一个实用工具。从技术角度看,值得关注的点:
- 利用文件系统做冗余存储,是纯本地方案应对数据丢失的有效手段
- 微信小程序 Storage + FileSystem 足够承载个人工具的全部数据需求
- 纯客户端意味着零运维、零成本、零隐私顾虑
- 理解微信生态的 API 边界才能做出务实的技术决策
后续迭代方向:LLM 识别条码自动填充、条码库共建(本地积累商品信息)、数据导出分享给家人。