从 0 到 1 做一个猫咪健康记录小程序:架构设计、关键实现与后续规划
前言
这个项目最开始只是一个很朴素的想法:
能不能做一个专门记录猫咪日常健康情况的小程序?
一开始需求并不复杂,无非是想记一下猫咪有没有拉稀、呕吐、驱虫、看病、花了多少钱。但真正开始做之后会发现,这件事并不只是“做几个表单页面”那么简单。
如果希望它未来真的能长期使用,那它至少要解决几类问题:
- 记录要足够快,不能每次都像在填问卷
- 浏览要足够直观,能很快看到哪天发生了什么
- 消费要能分类统计,不然记了也很难回看
- 图片不能只是临时选一下,得能稳定保存
- 后续最好还能支持 AI 散记整理,而不是纯手工录入
- 数据最好能导出、备份、恢复,不然换手机或误删会很麻烦
所以这个项目逐渐从一个“记录 demo”,演化成了一个更完整的、本地优先的猫咪健康记录系统雏形。
一、项目目标
这个小程序当前主要围绕 4 个目标展开:
- 让猫咪日常事件记录足够轻量
- 让历史数据回看足够清晰
- 让消费记录具备分类和统计能力
- 让数据具备可备份、可恢复、可持续演进的能力
围绕这些目标,目前项目已经具备以下核心能力:
- 日历视图浏览
- 时间线浏览
- 单条记录新增 / 编辑 / 删除
- 消费分类与统计
- AI 散记拆分
- 图片本地持久化
- 数据备份与导入恢复
二、为什么选原生微信小程序
这个项目最终选择的是原生小程序开发,也就是:
- WXML
- WXSS
- JavaScript
没有额外上 Taro、uni-app 这类跨端框架,主要原因有三个:
1. 需求本身就是微信内场景
这个产品的主要使用场景就是在微信里随手打开、快速记录,所以直接使用小程序原生方案最顺。
2. 原生方案更容易理解平台边界
这个项目里涉及很多和平台强相关的能力:
wx.setStorageSyncFileSystemManagerwx.chooseMedia- 小程序页面 / 组件通信
wx.env.USER_DATA_PATH
用原生实现,能更直接理解小程序到底能做什么、不能做什么。
3. 对当前阶段来说,“可控”比“抽象”更重要
项目还处在快速迭代期,很多页面、状态和交互都在反复打磨。
这时候原生方案虽然写起来更细,但也意味着:
- 页面结构更透明
- 数据流更容易追
- 出问题时更容易定位
三、整体架构设计
这个项目的整体架构并不复杂,但有几个很重要的设计点。
1. 目录结构
miniprogram/
app.js
app.json
app.wxss
utils/
constants.js
db.js
util.js
ai.js
components/
calendar/
event-icon/
photo-picker/
timeline-item/
stat-card/
ec-canvas/
pages/
index/
record/
detail/
timeline/
settings/
backup/
2. 架构核心思想:页面只管用,底层细节交给适配层
我在这个项目里最看重的一件事,是尽量不让页面直接碰太多底层实现细节。
比如:
- 页面不直接操作 storage,而是调
utils/db.js - 页面不直接依赖某个 AI 服务,而是调
utils/ai.js
这样做的好处非常明显:
- 页面逻辑更干净
- 后续迁移云端更容易
- AI 接口切换时不用重写页面
这也是这个项目后面能持续扩功能,而不是越改越乱的关键。
四、页面与功能是怎么拆的
1. 首页:日历 + 类型筛选 + 当日记录
首页主要解决一个问题:
我今天想快速知道哪一天发生了什么。
所以首页不是“统计大屏”,而是一个很实用的组合:
- 上方是日历
- 中间是事件类型筛选
- 下方是当天记录列表
这套结构很适合高频查看。
图片展示占位
首页日历与筛选
2. 记录页:单条记录 + AI 散记
这是项目里交互最复杂的一页。
它有两种模式:
单条记录模式
用户直接选择事件类型,然后填写:
- 次数
- 金额
- 日期时间
- 备注
- 图片
AI 散记模式
用户直接输入一段自然语言,比如:
昨天晚上吐了两次,今天早上又拉稀,顺便去医院花了 200。
系统会先把这段内容解析成候选事件草稿,再让用户确认、修改后保存。
这部分的设计重点不是“做一个会聊天的智能体”,而是:
把杂乱输入整理成结构化事件对象。
这其实是一条典型的“结构化抽取”链路。
图片展示占位
记录页单条录入
AI散记模式
3. 时间线页:把记录变成可浏览的信息流
如果首页更偏“按天定位”,那么时间线页更偏“连续浏览”。
时间线页现在支持:
- 今日 / 本月切换
- 事件类型摘要筛选
- 趋势图
- 图标化时间线卡片
- 消费金额与消费类型展示
- 缩略图展示
时间线的意义在于,它让记录不是冷冰冰的数据,而是一条用户可以快速扫描的信息流。
图片展示占位
时间线列表、趋势图与类型统计
4. 详情页:从“看一条记录”升级到“看上下文”
详情页现在不只是把单条内容显示出来。
对于消费类记录,它会进一步显示:
- 消费类型
- 当日同类消费金额
- 当月同类消费金额
这意味着详情页已经不仅是查看页,而开始承担“局部决策信息”的作用。
图片展示占位
详情页
5. 设置页与备份页:把工具入口独立出来
设置页现在不再把所有工具都塞进去,而是做成了:
- 猫咪资料
- 工具入口
其中“数据备份”是一个单独的二级页。
这样做有两个好处:
- 设置首页保持轻量
- 备份能力可以持续扩展,不会把设置页越堆越厚
图片展示占位
设置页
数据备份页
五、几个关键实现
1. db.js:整个项目最核心的“数据中台”
如果要说当前项目最关键的代码文件,我会选:
miniprogram/utils/db.js
它统一承担了:
- 事件 CRUD
- 猫咪资料读写
- 消费分类管理
- 分类消费统计
- 备份导出
- 备份导入
- 最近备份元数据
页面层几乎都围绕它转。
这层的价值在于:
- 把 storage、文件系统、备份这些细节全部收口
- 页面只关心“我要什么数据”,不关心“数据怎么存”
这使得项目后续如果要迁移到云开发,会更有余地。
2. 本地图片持久化
这个项目里图片不是一个装饰项,而是真实记录的一部分。
所以不能只是拿一个临时路径显示一下,而要考虑:
- 临时文件会不会过期
- 删除记录时要不要同步删图片
- 备份时如何把图片一起带走
- 导入时如何恢复图片文件
这部分最终是通过:
wx.chooseMediaFileSystemManagerwx.env.USER_DATA_PATH
来完成的。
也正因为图片被纳入了正式数据流,这个项目才不是纯文本表单工具。
3. 消费分类系统
消费功能后面越做越像一个独立模块。
它现在支持:
- 默认分类
- 自定义分类
- 自定义图标
- 自定义分类删除
- 同类消费统计
这意味着“消费”已经不是简单的金额字段,而是有自己领域模型的一类记录。
从工程角度看,这是项目开始出现“子领域”的标志。
4. AI 散记:不是智能体,而是结构化抽取
很多时候一提到 AI,直觉上会想做一个 Agent。
但这个场景其实不需要先上复杂智能体。
它更适合做成:
文本 / 图片输入
-> 事件识别
-> 类型归类
-> 结构化候选对象
-> 用户确认
-> 落库
这也是为什么项目里专门做了 utils/ai.js 作为适配层:
- 当前可本地规则兜底
- 后续可接多模态模型
- 页面不依赖具体 AI 厂商
这个设计会比“直接把模型调用写进页面”稳很多。
5. 备份系统:从工具功能走向产品能力
备份这块一开始只是“能导出就行”,但后面逐渐发现,一个真正能用的备份系统至少要考虑:
- 文件导出
- 剪贴板复制
- 大文本剪贴板卡顿
- 资源文件一起备份
- 导入覆盖风险提醒
- 最近备份状态记录
现在这套实现里,备份已经不只是导出 JSON,而是:
- 结构化数据 + 资源资产统一打包
- 大体积时剪贴板降载
- 应用内固定
backups目录 - 应用内预览
- 导入恢复时重建文件资源
这一步让“备份”从附属功能,变成了真正的产品能力。
六、核心链路流程图
1. 普通记录链路
flowchart TD
A[选择事件类型] --> B[填写内容]
B --> C[构建事件对象]
C --> D[db.js 写入本地]
D --> E[首页/时间线/详情展示]
2. AI 散记链路
flowchart TD
A[输入散记和图片] --> B[ai.js 解析]
B --> C[生成候选事件]
C --> D[用户修正]
D --> E[批量写入 db.js]
E --> F[页面展示]
3. 备份链路
flowchart TD
A[点击导出备份] --> B[db.js 收集数据和资源]
B --> C[生成 JSON]
C --> D[写入应用内 backups 目录]
D --> E[记录最近备份元数据]
E --> F[复制剪贴板 / 预览 / 保存到系统文档]
七、目前这个项目最有价值的地方
如果只从“页面数量”看,这个项目并不算多大。
但它现在已经有几个很重要的产品和工程特征:
1. 本地优先,但不是写死在本地
虽然现在主要依赖本地存储,但接口已经在为后续迁移云端做准备。
2. 功能之间不是孤岛
消费、图片、AI、备份都已经和主数据流连在一起,而不是各做各的。
3. 已经有产品雏形,而不只是 demo 感
它已经具备:
- 核心记录能力
- 基础统计能力
- 工具链能力
- 数据生命周期能力
这几项凑在一起,已经很接近一个可持续演进的小产品了。
八、后续规划
如果后面还有时间和精力,我觉得最值得继续做的方向有几类。
1. 把备份真正做成“历史系统”
- 备份历史列表
- 每份备份显示大小、记录数、导出时间
- 支持删除旧备份
- 导入前显示“当前 vs 即将导入”的摘要对比
2. 把消费能力做深
- 分类统计页
- 分类占比图
- 月度消费趋势
- 预算和超支提醒
3. 把 AI 能力做强
- 接入真正的多模态模型
- 支持更强的时间理解
- 更聪明地把图片匹配到事件
4. 把记录体验进一步打磨
- 首页更丰富的日历标记
- 时间线按天分组
- 详情页显示“相似记录”或“最近同类记录”
5. 工程层面继续升级
- TypeScript 化
- 数据 schema 类型化
- 关键模块测试补齐
- 为云端迁移继续做接口解耦
九、结语
这个项目最开始只是想解决一个很具体的问题:
怎么更方便地记录猫咪的健康状态。
但随着功能一点点长出来,它也慢慢体现出一个很有意思的特点:
只要架构和边界一开始想清楚,一个小项目完全可以在不失控的前提下,持续长成功能更完整的产品。
现在它还不是一个完全成熟的产品,但已经具备了一个不错的基础:
- 有清晰的页面分工
- 有稳定的数据层
- 有可扩展的 AI 接口
- 有开始成型的备份体系
- 有继续打磨成完整产品的空间
如果后续继续往前推进,这个项目很有机会从“实用工具”长成一个更完整的、真正能长期陪伴使用的小型产品。
附:截图占位清单
你后面自己贴图时,可以优先补这些位置:
- 首页日历与筛选
- 单条记录录入页
- AI 散记页
- 时间线页
- 消费详情页
- 设置页
- 数据备份页
- 应用内备份预览