# cangku **Repository Path**: WMCC/cangku ## Basic Information - **Project Name**: cangku - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-26 - **Last Updated**: 2026-07-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 家有库存 🍎 > 让家里的食品、药品、护肤品、日用品**有迹可循**——记录在哪、还剩多少、什么时候过期。临期前主动用微信推送提醒,不再让一瓶酸奶悄悄过期,不再因为忘了家里有什么而重复购买。 一个轻量的微信小程序,给注重生活管理的家庭用。 --- ## 为什么做这个 家庭日常会囤积大量物品。常见的三个痛点: 1. **不知道家里还有没有** —— 出门又买了一瓶生抽,回来才发现柜子里还有两瓶 2. **忘了东西放在哪** —— 那盒维生素到底是放在药箱还是茶几抽屉? 3. **食品/药品悄悄过期** —— 牛奶过期一周才发现;婴儿奶粉开罐 6 周后才想起 市面上的同类工具要么太重(要装 App、要注册账号、要付费会员),要么不解决最关键的"临期提醒"——而微信小程序刚好可以做到:**随手打开、按 openid 自动隔离个人数据、用微信订阅消息主动触达**。 ## 能做什么(V1 已交付) - 📦 **录入物品**:名称 / 分类 / 数量 / 存放位置 / 备注(30 秒搞定一条) - 📅 **保质期管理**:直接填到期日,或填"生产日期 + 18 个月"自动算(用真实的 `setMonth` / `setFullYear`,不是 ×30 天的粗算) - 🔔 **临期主动提醒**:每天上午 09:00 自动扫描,临期物品通过微信订阅消息推送 - 🏷️ **分类管理**:内置 9 个常用分类(食品/生鲜冷冻/调味品/零食饮料/药品/护肤美妆/日用清洁/母婴用品/其他),可自定义新增、拖拽排序 - 🔍 **搜索 + 筛选 + 排序**:按分类、状态(全部/临期/过期/无保质期)、关键词 - 🌗 **白天 / 夜晚 双主题**:手动切换,记住偏好 - 📊 **首页概览**:健康库存环形图、临期/过期 KPI 双卡、分类分布条形图 ## 截图与原型 完整可交互的视觉原型在 `prototype/index.html`,用浏览器直接打开即可。本项目所有 page/component 的视觉都严格按照该原型 1:1 实现到小程序——原型既是设计稿也是开发基准。 ## 技术选型 | 层级 | 选型 | 为什么 | |---|---|---| | 前端框架 | 微信小程序原生(wxml / wxss / js) | 最稳,性能好,不引入额外构建工具 | | 后端 | 微信云开发(CloudBase Serverless) | 免运维、免备案;个人主体即可;数据自动按 openid 隔离 | | 数据库 | 云数据库(文档型 NoSQL,4 张集合) | 前端直连 + 权限规则;零业务代码实现租户隔离 | | 文件存储 | 云存储(V1 暂未启用图片上传,V2 接入) | — | | 推送 | 微信订阅消息(一次性) | 微信原生通道;用配额累积机制消化"一次授权 = 一次发送"限制 | | 定时任务 | 云函数定时触发器(Cron `0 0 9 * * *`) | 每日 09:00 自动扫描临期物品 | | 单元测试 | Jest(仅核心日期工具) | `utils/date.js` 100% 覆盖;其余靠手测 + 真机走查 | ## 项目结构 ``` kucun/ ├── miniprogram/ # 小程序前端 │ ├── pages/ # 6 个页面:首页 / 库存 / 物品详情 / 新增编辑 / 分类 / 我的 │ ├── components/ # 5 个组件:物品卡 / 步进器 / 分类胶囊 / 状态徽标 / 空态 │ ├── services/ # 集合层(items / categories / users / remind) │ ├── utils/ # date / cloud / theme 三个纯工具 │ ├── store/ # 全局状态(getApp().globalData) │ └── constants/ # 系统分类、状态枚举、订阅模板 ID │ ├── cloudfunctions/ # 云函数(部署到云开发) │ ├── login/ # 首登 upsert users │ ├── sendRemind/ # 单条推送 + 写日志 │ └── checkExpiry/ # 每日 09:00 cron 扫描 + 派发 │ ├── tests/utils/ # Jest 单元测试 ├── prototype/ # 浏览器可打开的交互原型(视觉基准) └── docs/superpowers/ # 设计文档与 runbook ├── specs/ # V1 实现规格(10 条关键决策) ├── plans/ # 30 任务实现计划 └── runbooks/ # 云开发部署 + V1 验收清单 ``` ## 怎么运行 / 上线 > 项目 V1 代码已落地,但首次部署需要在**微信公众平台 + 开发者工具**做一些手工配置(运营卡点,无法自动化)。完整步骤在 `docs/superpowers/runbooks/cloud-setup.md`,下面是骨架。 ### 1. 准备账号 & 工具 - 安装 [微信开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html) - 到 [微信公众平台](https://mp.weixin.qq.com) 注册个人小程序,拿到 **AppID** ### 2. 开通云开发 - 开发者工具 → 云开发 → 开通环境(选免费试用配额) - 记下 **环境 ID**(形如 `kucun-prod-xxxx`) ### 3. 填占位 替换 3 个 `TOUCHME_REPLACE_*` 占位: | 文件 | 字段 | 内容 | |---|---|---| | `project.config.json` | `appid` | 注册拿到的 AppID | | `miniprogram/constants/env.js` | `CLOUD_ENV` | 云环境 ID | | `miniprogram/constants/template.js` | `TEMPLATE_ID` | 订阅消息模板 ID(见下一步) | ### 4. 建库 + 配权限 + 建索引 按 runbook 第 3–5 节: - 创建 4 张集合:`users` / `categories` / `items` / `reminder_logs` - 每张集合权限选「**仅创建者可读写**」 - 建 4 个联合索引(用于列表查询与每日扫描) ### 5. 申请订阅消息模板 公众平台 → 功能 → 订阅消息 → 申请模板,字段顺序: | 字段 | 类型 | 用途 | |---|---|---| | `thing1` | thing(≤20 字) | 物品名 | | `date2` | date | 到期日 | | `thing3` | thing(≤20 字) | 温馨提示 | 审核通过后填回 `template.js`。 ### 6. 部署云函数 开发者工具 → cloudfunctions 目录右键各云函数 → 「上传并部署:云端安装依赖」。 为 `sendRemind` / `checkExpiry` 在云开发后台 → 函数配置 → 环境变量 设置: - `TEMPLATE_ID` = 上一步拿到的 ID - `MAX_BATCH` = `500` `checkExpiry` 的定时触发器已写在 `config.json`(cron `0 0 9 * * * *`),部署即生效。 ### 7. 跑测试 + 走查 ```bash npm install # 装 jest npm test # 应该看到 97/97 PASS(含 utils/date.js 28 case 主逻辑 + services 47 case + cloudfunctions/status.js 9 case + 12 case V1.1 补丁;utils 与 status.js 覆盖率 100/100/100/100) ``` 按 `docs/superpowers/runbooks/v1-acceptance.md` 的 20 条 E2E 清单真机走一遍——通过即可提审上线。 ## 一些不那么显然的设计取舍 读源码前如果先理解这几点,会少很多疑问: - **`items.status` 不入库**:「正常 / 临期 / 过期」的状态由前端 `utils/date.js#getStatus(item, advance)` 实时计算。原因:状态会随今日时间漂移,存了反而要每天重算一遍同步。 - **系统 9 个分类是前端常量**:写在 `miniprogram/constants/categories.js`,不入数据库。`categories` 集合只存用户自定义分类。 - **提醒时段固定 09:00**:用一个全局 cron 服务所有用户。让用户自定义时段意味着每个时段一个 cron + 过滤逻辑,V1 不值得。 - **`subscribeQuota` 配额展示给用户看**:微信的"一次性订阅消息"限制无法绕开,所以把游戏规则告诉用户——「我的」页明示「剩余推送额度:N 条」并提供「主动授权」按钮主动补充。 - **暗黑模式只本地存储**:用 `wx.setStorageSync`,不入库。设备切换会丢偏好,但省一次 DB 请求 + 简化登录链路。可接受。 - **保质期月份用真 `setMonth`**:避免 12 个月 = 360 天的常见 bug,闰年 2/29 + 1 年也会被正确折到 2/28。 - **物品图片 V1 不做**:家庭库存场景"快录入"比"好看"重要;推到 V2 时一并接入图片识别。 ## 当前状态 - ✅ **V1 代码已完成**(30 个任务,69 个源文件) - ✅ **核心工具单测覆盖 100%**(`utils/date.js`) - ✅ **2 个 final review Important 已修** - ⏳ **首次部署待人工**:3 处 `TOUCHME_REPLACE_*` 占位 + 公众平台手工步骤 - 📝 **11 条 Minor 待办**:记录在 `.sdd/progress.md`,可推 V1.1 处理 ## 路线图 - **V1(MVP,当前)**:物品 CRUD、保质期、订阅消息推送、默认 + 自定义分类、首页概览 - **V2**:图片上传 + 拍照识别生产日期、回收站(基于 V1 已预留的软删字段)、统计图表增强 - **V3**:家庭多人共享库存、购物清单联动、数据导出、微信群提醒 ## 成本 | 阶段 | 费用 | |---|---| | 开发期 + 测试 | **0 元**(云开发免费试用配额) | | 上线后日常运营 | **19.9 元 / 月**(云开发基础套餐,含 20 万次调用/月) | 按 100 个家庭用户估算:月调用约 6 万次,远低于套餐额度,**正常用量不会产生超额**。 ## 文档地图 - `requirements.md` — 完整 PRD,含用户故事与验收标准 - `architecture.md` — 技术架构详细方案(数据库 / 云函数 / 订阅消息 / 部署) - `docs/superpowers/specs/2026-06-25-v1-implementation-design.md` — V1 实现规格(10 条关键决策) - `docs/superpowers/plans/2026-06-25-kucun-v1.md` — 30 任务实现计划 - `docs/superpowers/runbooks/cloud-setup.md` — 部署 runbook - `docs/superpowers/runbooks/v1-acceptance.md` — V1 验收 checklist(20 项) - `prototype/README.md` — 原型说明(含视觉风格升级日志) - `CLAUDE.md` — 给 AI 编程助手的项目导览 ## License 待补。