舟家康册 · 家庭健康档案系统 — 交接说明
最后更新:2026-10-30 交接对象:后续接手本项目的开发者或 AI 助手
1. 项目概览
定位:家庭健康信息管理系统。目标是把一家人的健康信息(体检、就医报告、日常血压血糖、孩子身高体重、既往病史)统一采集、归档、检索、分析,并支持就医前的病情整理。
当前阶段:MVP 高保真交互原型,已完成线上部署。核心可用功能是儿童身高体重的采集、整理与趋势可视化,其余模块(健康档案、成员管理、就医准备)已完成界面与交互,数据为演示数据。
线上地址:https://zjia.pages.dev
2. 当前状态速览
| 维度 | 状态 | 说明 |
|---|---|---|
| 原型完成度 | ✅ 5 个页面全部完成 | 交互闭环,含增删改查、导入、导出、打印 |
| 线上部署 | ✅ 已部署 | Cloudflare Pages 项目 zjia |
| 真实数据 | ⚠️ 部分 | 仅儿童身高体重 170 条为真实;其他为编造演示数据 |
| 访问保护 | ❌ 未完成 | Cloudflare Access 未启用,站点当前公开可访问 |
| 后端 | ❌ 无 | 纯前端 + localStorage,api.js 为桩函数 |
| 多端同步 | ❌ 无 | 数据绑定单个浏览器,换设备即空 |
3. 目录结构
D:\Backup\Downloads\PRIV\FamilyHealth\
├── family-health-v2\ ← 当前项目(线上部署的就是这个目录)
│ ├── index.html # 家庭总览:成员卡片、成长快照、提醒、动态
│ ├── growth.html # 成长记录:曲线图、记录表、导入/导出
│ ├── archive.html # 健康档案:材料登记、检索、数据提取
│ ├── members.html # 成员管理:基本信息、过敏史、既往病史
│ ├── report.html # 就医准备:生成就诊摘要、复制、打印
│ ├── styles.css # 设计系统(CSS 变量 + 组件样式 + 响应式)
│ ├── icons.js # 内联 SVG 图标注册表(Lucide 风格)
│ ├── mock.js # 种子数据(members/growthRecords/docs/reminders/whoRefs)
│ ├── store.js # 数据层:localStorage 读写
│ ├── api.js # 服务桩层(每个函数标注目标 HTTP 端点)
│ ├── app.js # 公共运行时:toast、modal、日期格式化
│ ├── charts.js # SVG 图表引擎:生长曲线 + 迷你趋势线
│ └── assets\app-icon.jpg # 应用图标(舟形心 + 绿十字,2048×2048)
│
├── main.py / database.py ← 旧版 Flask 后端(v1,已弃用,未参与本次部署)
├── growth.db ← 旧版 SQLite 数据库(164 条身高体重)
├── _export_records.json ← 从 growth.db 导出的原始记录(数据来源档案)
└── templates\ ← 旧版前端页面(已弃用)
说明:family-health-v2\ 目录本身就是完整的可部署产物,无构建步骤、无依赖、无外部 CDN,双击 index.html 即可离线运行。
4. 技术架构
4.1 技术选型
纯静态 HTML + CSS + 原生 JS(ES5 写法),零依赖、零构建。
选此方案的原因:原型阶段优先「打开即用、离线可用、易于分发给非技术用户查看」,避免构建工具链带来的维护成本。若后续要工程化,建议迁到 Vite + React,但现在不要为了"现代化"而重构。
4.2 分层结构
页面 HTML(视图层)
↓ 调用
api.js(服务层,async 桩函数,模拟网络延迟)
↓ 调用
store.js(数据层,读写 localStorage)
↓ 首次读取时
mock.js(种子数据)
公共运行时 app.js(toast / modal / 日期格式化)与 charts.js(SVG 绘图)被各页面复用。icons.js 提供 <i data-icon="xxx"> 的内联 SVG 渲染。
4.3 关键机制
- 数据持久化:
localStorage键名fh2.v1。首次加载时用mock.js播种,之后一直读写用户数据,不会被后续修改的mock.js覆盖。 - 重置演示数据:页面按钮可清空 localStorage 回到种子状态。
- API 交接契约雏形:
api.js里每个函数头部都注释了目标端点,例如: GET /api/growth/:memberIdPOST /api/growth/import-previewPOST /api/growth/importPOST /api/documents/:id/extract
将来接真实后端时,逐个替换这些桩函数即可,视图层无需改动。
5. 数据模型
顶层结构(Store.state):
{
members: [...], // 家庭成员
growthRecords: [...], // 身高体重记录
docs: [...], // 归档材料
reminders: [...], // 复诊/体检提醒
whoRefs: {...} // WHO 生长曲线参考带
}
5.1 members
{ id: 'm1', name: '可舟', role: '儿子', gender: '男',
birth: '2020-07-15', blood: 'O',
allergies: ['尘螨', '芒果(口腔过敏综合征)'],
conditions: [ { year: '2025', name: '龋齿 2 颗', note: '已涂氟处理' } ],
history: '按计划完成疫苗接种;3 岁起每年幼儿园体检' }
角色顺序:m1 儿子 / m2 爸爸 / m3 妈妈 / m4 奶奶。
5.2 growthRecords
{ id: 'g162', memberId: 'm1', date: '2026-06-11',
height: 123.2, weight: null, head: null, note: '' }
height / weight 允许为 null(只有身高或只有体重的单次测量)。体重统一以 kg 存储,导入时自动从「斤」换算(1 斤 = 0.5 kg)。
5.3 docs
{ id: 'd1', memberId: 'm1', title: '2024 年度幼儿园体检报告',
type: '体检报告', // 体检报告|诊断证明|检验单|影像报告|处方|疫苗记录
docDate: '2024-04-18',
source: '纸质扫描', // 纸质扫描|手机拍照|电子版
location: '书房文件柜 A-2', // 实体存放位置
status: '已归档', // 已归档|待录入
extracted: [ { label: '身高', value: '112.5 cm', target: 'growth' } ],
content: [ { label: '血红蛋白', value: '128 g/L' } ] } // 可选,完整 OCR 文本
extracted[].target 取值:growth / bp / glucose / history / vaccine / medication / note,表示该字段提取后应归档到哪个数据域。
5.4 reminders
{ id: 'r1', memberId: 'm1', title: '六周岁儿保体检',
due: '2026-08-30', kind: '儿保体检', level: 'soon' } // soon|later
5.5 whoRefs
heightBoy / weightBoy,各含 months / p3 / p50 / p97 数组(0–84 月龄,每 3 月一点)。
⚠️ 目前只有男孩的参考数据,女孩曲线未实现——这是已知缺口,见第 9 节。
6. 数据真实性说明(重要,勿误判)
交接时务必清楚:项目里的数据不是全部真实的。
6.1 真实数据(来源:growth.db / _export_records.json)
- 儿童身高体重共 170 条(原 164 条去重后 + 用户补录 6 条)
- 孩子姓名「可舟」、出生日期
2020-07-15、出生身高 51cm / 体重 4.0kg - 时间跨度:出生至 2026-08-23
6.2 编造的演示数据(无任何真实来源)
- 成员「林建国(爸爸)」「沈雅(妈妈)」「周秀兰(奶奶)」及其全部出生日期、血型
- 爸爸的高血压 1 级、氨氯地平用药、自测血压值、2022 年戒烟史
- 妈妈的青霉素过敏、甲状腺结节
- 奶奶的 2 型糖尿病、二甲双胍用药
- 一共 12 份归档材料(
docs)与 5 条提醒(reminders)全部虚构 - 孩子除身高体重外的过敏史、龋齿、上呼吸道感染等病史条目
处理原则:接入真实使用前,必须把这些演示数据全部替换为真实信息。当前它们仅用于展示界面效果。
6.3 公开参考标准
whoRefs 为 WHO 儿童生长标准百分位带的近似值,属公开数据。
7. 本地运行与开发
7.1 运行
直接双击 family-health-v2\index.html。无需服务器、无需联网。
7.2 开发约定
- 改动前先读设计契约:
C:\Users\YMCC\AppData\Local\Temp\fh2-contract\design-contract.md(临时目录,可能已被清理;若已丢失,以styles.css为准) - 所有颜色/间距/圆角必须用
styles.css里的 CSS 变量,不要写死色值 - 新增页面需保持导航(5 项
data-nav)、脚本引入顺序(icons.js→mock.js→store.js→api.js→app.js→charts.js→ 页面脚本)一致 - 图标统一走
icons.js注册表,不引入外部图标库
7.3 导入数据格式(已支持智能识别)
在「成长记录」页粘贴任意格式,解析器兼容:
- 日期:
20260628/2026-06-28/2026/6/28/2026年6月28日 - 分隔:空格、逗号、制表符、分号,混用亦可
- 列序不限,数值可带单位(
cm/厘米/斤/kg/公斤) - 只有身高或只有体重的行也能导入
- 导入时同日记录自动互补合并,完全重复自动跳过
实现见 api.js 的 parseImport 与 importGrowth。
8. 云端部署(Cloudflare Pages)
8.1 部署信息
| 项 | 值 |
|---|---|
| 账号 | Biixxiid@gmail.com's Account |
| Account ID | 9c851f02481c07d1290607abc1107a9f |
| Pages 项目 | zjia |
| 生产地址 | https://zjia.pages.dev |
| 绑定域名 | zjia.pages.dev(无其他自定义域名) |
| 账号下已有项目 | zjia、zm-shu、zm-py、zm-eng、zm-kebiao |
| Workers 子域 | biixxiid |
8.2 认证方式
使用本机 wrangler 的 OAuth 授权(账号已登录),凭据位置:
C:\Users\YMCC\AppData\Roaming\xdg.config\.wrangler\config\default.toml
- Access Token 有效期约 1 小时,wrangler 会自动用
refresh_token续期 - 授权范围含
pages:write、workers:write、zone:read、d1:write等 - 不含 Access(Zero Trust)权限,所以无法通过 API 配置访问保护
8.3 重新部署命令
本机 node/npm 不在系统 PATH 中,且 wrangler 4.x 要求 Node ≥ 22。当前可用的 Node 22 是临时下载的:
C:\Users\YMCC\AppData\Local\Temp\node22\node.exe (v22.23.4)
⚠️ 该目录在系统临时区,可能被清理。若已消失,需重新下载 Node 22 或改用其他方式。
wrangler 缓存位置:
C:\Users\YMCC\AppData\Local\npm-cache\_npx\32026684e21afda6\node_modules\.bin\wrangler.cmd (v4.156.0)
部署命令(PowerShell):
$env:PATH = "$env:LOCALAPPDATA\Temp\node22;" + $env:PATH
$w = "$env:LOCALAPPDATA\npm-cache\_npx\32026684e21afda6\node_modules\.bin\wrangler.cmd"
& $w pages deploy "d:\Backup\Downloads\PRIV\FamilyHealth\family-health-v2" `
--project-name=zjia --branch=main --commit-dirty=true
注意:该命令需写入 AppData\Roaming\xdg.config\.wrangler(沙箱外)且需访问 api.cloudflare.com,在受限沙箱中会失败,需直接以系统权限执行。
8.4 部署内容
13 个文件全部推送(5 个 HTML + 7 个 JS/CSS + 1 个图标)。无需构建、无需 wrangler.toml,属于 Pages 的静态资源直传模式。
9. 未完成事项与待办
9.1 优先级 P0:访问保护(安全)
现状:站点公开可访问,任何人拿到网址即可看到真实身高体重数据,https://zjia.pages.dev/mock.js 可直接下载。
API 报错证据:
403 access.api.error.not_enabled: Access is not enabled.
Visit the Access dashboard and click the 'Enable Access' button.
方案 A(用户手动,最快):
- 打开 https://one.dash.cloudflare.com/ → 启用 Zero Trust(免费,需设置 team 域名)
- Access → Applications → Add self-hosted
- 域名填
zjia.pages.dev - Policy 设为
Allow,条件Emails填biixxiid@gmail.com - 同时把
https://*.zjia.pages.dev的通配也覆盖(预览部署也需保护)
方案 B(提供 Token 后由 AI 配置):需要一个具备以下权限的 API Token:
Access: Organizations, Identity Providers, and Groups — EditAccess: Apps and Policies — Edit
方案 C(临时下线):直接删除 Pages 项目,随时可重新部署。
9.2 优先级 P1:数据层升级
| 问题 | 影响 | 建议 |
|---|---|---|
| 数据只存浏览器 localStorage | 换设备/清缓存即丢失 | 接后端 + 数据库 |
| 本地与云端数据不同步 | 线上站点是种子数据,你在本地浏览器里的改动不会同步上去 | 同上 |
| 无数据导出兜底 | 有丢失风险 | 建议先加「导出全部数据为 JSON」按钮 |
关键认知(务必理解,否则会误判):localStorage 按源(origin)隔离。本地 file:// 与线上 https://zjia.pages.dev 是两个不同源,数据不会自动迁移。想让线上带你的数据,必须把数据写进种子文件后重新部署,或接入后端。
9.3 优先级 P2:功能缺口
- WHO 女孩生长曲线缺失:
whoRefs只有heightBoy/weightBoy。若要支持女孩,需补heightGirl/weightGirl - 血压、血糖数据结构未定义:
growthRecords只涵盖身高/体重/头围。血压、血糖在docs[].extracted里只是文本,没有独立数据结构,无法做趋势图 - 档案模块无真实文件上传:
docs只记录元信息(标题、类型、存放位置),没有附件实体存储 - OCR 提取为模拟:
archive.html的「提取数据」用预置extracted数组模拟,非真实 OCR - 无后端:所有
api.js函数是桩函数
10. 已知问题与技术债
api.js用 ES5 写法(var+function),与项目整体风格一致但可读性偏低。改造时注意不要只改一半。- JSON 内联在
mock.js中,文件已 23KB。数据量继续增长应拆成独立 JSON 文件按需 fetch。 _export_records.json与growth.db是历史遗留,当前代码不读取它们,仅作数据来源档案保留,勿删。- 旧版 Flask 项目(
main.py/database.py/templates/)已完全弃用,如确认不再需要可清理。 - 设计契约文件在系统临时目录,可能已丢失。若需长期维护,建议把契约内容并入
styles.css顶部注释或项目内DESIGN.md。
11. 后续路线建议
按「由易到难」原则,建议顺序:
第一步|守住数据 1. 启用 Cloudflare Access,止住隐私泄露 2. 加「导出/导入全部数据 JSON」按钮,给用户兜底能力
第二步|补齐 MVP
3. 补 WHO 女孩曲线(数据结构已就绪,只需加数据)
4. 为血压、血糖定义独立数据结构与趋势图(复用 charts.js)
第三步|去演示化 5. 清空所有编造成员与病史,接入真实家庭数据 6. 真实文件上传(可用 Cloudflare R2 存原始材料)
第四步|接后端
7. 按 api.js 已标注的端点实现服务,数据落 D1 / Supabase
8. 用户体系 + 多设备同步
12. 快速上手指引(给下一位接手者)
- 先读
styles.css顶部注释,理解设计系统与色值变量 - 再读
store.js(1.8KB)和api.js的函数签名注释,理解数据流 - 打开
growth.html作为参照页面,它包含了最完整的交互模式(图表切换、表格分页、增删改查、导入弹窗) - 改任何页面之前,先确认 5 个页面的导航结构(
data-nav)与脚本引入顺序 - 部署前用
node --check校验所有 JS 语法;静态走查清单见历史记录(nav 一致性、图标、链接、重复 ID、外部资源)
本文档由 AI 助手在部署完成后生成,作为项目状态快照。若与代码实际不符,以代码为准。