猫咪健康记录小程序

46 阅读10分钟

从 0 到 1 做一个猫咪健康记录小程序:架构设计、关键实现与后续规划

前言

这个项目最开始只是一个很朴素的想法:

能不能做一个专门记录猫咪日常健康情况的小程序?

一开始需求并不复杂,无非是想记一下猫咪有没有拉稀、呕吐、驱虫、看病、花了多少钱。但真正开始做之后会发现,这件事并不只是“做几个表单页面”那么简单。
如果希望它未来真的能长期使用,那它至少要解决几类问题:

  • 记录要足够快,不能每次都像在填问卷
  • 浏览要足够直观,能很快看到哪天发生了什么
  • 消费要能分类统计,不然记了也很难回看
  • 图片不能只是临时选一下,得能稳定保存
  • 后续最好还能支持 AI 散记整理,而不是纯手工录入
  • 数据最好能导出、备份、恢复,不然换手机或误删会很麻烦

所以这个项目逐渐从一个“记录 demo”,演化成了一个更完整的、本地优先的猫咪健康记录系统雏形


一、项目目标

这个小程序当前主要围绕 4 个目标展开:

  1. 让猫咪日常事件记录足够轻量
  2. 让历史数据回看足够清晰
  3. 让消费记录具备分类和统计能力
  4. 让数据具备可备份、可恢复、可持续演进的能力

围绕这些目标,目前项目已经具备以下核心能力:

  • 日历视图浏览
  • 时间线浏览
  • 单条记录新增 / 编辑 / 删除
  • 消费分类与统计
  • AI 散记拆分
  • 图片本地持久化
  • 数据备份与导入恢复

二、为什么选原生微信小程序

这个项目最终选择的是原生小程序开发,也就是:

  • WXML
  • WXSS
  • JavaScript

没有额外上 Taro、uni-app 这类跨端框架,主要原因有三个:

1. 需求本身就是微信内场景

这个产品的主要使用场景就是在微信里随手打开、快速记录,所以直接使用小程序原生方案最顺。

2. 原生方案更容易理解平台边界

这个项目里涉及很多和平台强相关的能力:

  • wx.setStorageSync
  • FileSystemManager
  • wx.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. 首页:日历 + 类型筛选 + 当日记录

首页主要解决一个问题:

我今天想快速知道哪一天发生了什么。

所以首页不是“统计大屏”,而是一个很实用的组合:

  • 上方是日历
  • 中间是事件类型筛选
  • 下方是当天记录列表

这套结构很适合高频查看。

图片展示占位

首页日历与筛选

微信图片_20260426192312_20851_4.png


2. 记录页:单条记录 + AI 散记

这是项目里交互最复杂的一页。

它有两种模式:

单条记录模式

用户直接选择事件类型,然后填写:

  • 次数
  • 金额
  • 日期时间
  • 备注
  • 图片
AI 散记模式

用户直接输入一段自然语言,比如:

昨天晚上吐了两次,今天早上又拉稀,顺便去医院花了 200。

系统会先把这段内容解析成候选事件草稿,再让用户确认、修改后保存。

这部分的设计重点不是“做一个会聊天的智能体”,而是:

把杂乱输入整理成结构化事件对象。

这其实是一条典型的“结构化抽取”链路。

图片展示占位

记录页单条录入

微信图片_20260426192315_20853_4.png

AI散记模式

微信图片_20260426192758_20854_4.png

微信图片_20260426192759_20855_4.png


3. 时间线页:把记录变成可浏览的信息流

如果首页更偏“按天定位”,那么时间线页更偏“连续浏览”。

时间线页现在支持:

  • 今日 / 本月切换
  • 事件类型摘要筛选
  • 趋势图
  • 图标化时间线卡片
  • 消费金额与消费类型展示
  • 缩略图展示

时间线的意义在于,它让记录不是冷冰冰的数据,而是一条用户可以快速扫描的信息流。

图片展示占位

时间线列表、趋势图与类型统计

微信图片_20260426192314_20852_4.png


4. 详情页:从“看一条记录”升级到“看上下文”

详情页现在不只是把单条内容显示出来。

对于消费类记录,它会进一步显示:

  • 消费类型
  • 当日同类消费金额
  • 当月同类消费金额

这意味着详情页已经不仅是查看页,而开始承担“局部决策信息”的作用。

图片展示占位

详情页

微信图片_20260426192315_20853_4.png


5. 设置页与备份页:把工具入口独立出来

设置页现在不再把所有工具都塞进去,而是做成了:

  • 猫咪资料
  • 工具入口

其中“数据备份”是一个单独的二级页。

这样做有两个好处:

  1. 设置首页保持轻量
  2. 备份能力可以持续扩展,不会把设置页越堆越厚

图片展示占位

设置页

微信图片_20260426193106_20857_4.jpg

数据备份页

微信图片_20260426192300_20850_4.jpg


五、几个关键实现

1. db.js:整个项目最核心的“数据中台”

如果要说当前项目最关键的代码文件,我会选:

miniprogram/utils/db.js

它统一承担了:

  • 事件 CRUD
  • 猫咪资料读写
  • 消费分类管理
  • 分类消费统计
  • 备份导出
  • 备份导入
  • 最近备份元数据

页面层几乎都围绕它转。

这层的价值在于:

  • 把 storage、文件系统、备份这些细节全部收口
  • 页面只关心“我要什么数据”,不关心“数据怎么存”

这使得项目后续如果要迁移到云开发,会更有余地。


2. 本地图片持久化

这个项目里图片不是一个装饰项,而是真实记录的一部分。

所以不能只是拿一个临时路径显示一下,而要考虑:

  • 临时文件会不会过期
  • 删除记录时要不要同步删图片
  • 备份时如何把图片一起带走
  • 导入时如何恢复图片文件

这部分最终是通过:

  • wx.chooseMedia
  • FileSystemManager
  • wx.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 接口
  • 有开始成型的备份体系
  • 有继续打磨成完整产品的空间

如果后续继续往前推进,这个项目很有机会从“实用工具”长成一个更完整的、真正能长期陪伴使用的小型产品。


附:截图占位清单

你后面自己贴图时,可以优先补这些位置:

  1. 首页日历与筛选
  2. 单条记录录入页
  3. AI 散记页
  4. 时间线页
  5. 消费详情页
  6. 设置页
  7. 数据备份页
  8. 应用内备份预览