Phase 0 安全修复: - 移除 secure-storage-aes.ts 硬编码 'hms-default-key' fallback - production 模式空密钥时拒绝加解密(返回空/不加密) - dev 模式保留明文兼容(warn 日志提醒) - .env/.env.h5 注入随机加密密钥 - secureGet 明文 fallback 按环境分级处理 - 新增 8 个测试覆盖空密钥 dev/production 行为 Phase 1 健康Tab重构: - health/index.tsx 从体征录入页改为健康总览Dashboard - 新增今日体征摘要卡片(2x2 网格 + 状态标签) - 新增快捷入口(录入体征/趋势/报告/用药) - 新增告警提示卡片(待处理告警数量) - 体征录入移至 pkg-health/input/index(已有页面) - useHealthData → useHealthOverview(新增 alertCount) 首页增强: - useHomeData 新增告警计数查询(listPatientAlerts) - 首页新增告警提示卡片入口 - "记录体征"按钮改为跳转录入页而非健康Tab
16 KiB
小程序五维度深度分析 — 多专家组头脑风暴
日期: 2026-05-22 | 参与者: 5 专家组(架构/安全/UX/性能/商业) 修正: 2026-05-22 — 专家 5 的商业评估基于"体检中心"错误前提,已按 HMS 实际定位修正
背景
对 HMS 微信小程序进行全面的代码级深度分析(180 TS/TSX 源文件,~31,000 行代码,61 页面),覆盖架构工程、安全合规、用户体验、性能优化、商业价值五个维度。分析目标是识别真正影响用户体验和系统可靠性的问题,避免过度设计和自我感动式开发。
系统定位(修正前提)
HMS 不是体检中心专用系统,而是面向综合健康管理的 SaaS 平台,覆盖:
- 慢性病管理 — 高血压、糖尿病等长期随访、日常监测、用药管理
- 透析管理 — 血透中心 2-3 次/周的长期治疗
- 健康体检 — 但非唯一场景
- 在线咨询 — 医患实时沟通
- AI 健康分析 — 数据驱动的趋势分析和报告解读
患者端 + 医护端共用一个小程序,61 页面分别服务两类用户。 患者就诊周期不是 1-3 天,而是数月至数年 — 这直接影响功能 ROI 评估。
一、专家组评分总览
| 维度 | 评分 | 核心发现 |
|---|---|---|
| 架构工程 | 6.8/10 | 分层清晰,但 auth store 过重、测试覆盖率仅 6%、request.ts 单点风险 |
| 安全合规 | 6.0/10 | 加密密钥硬编码、知情同意为空壳、request-signer 未集成 |
| 用户体验 | 5.9/10 | TabBar 命名误导、"健康"Tab 是录入而非总览、菜单过载 |
| 性能优化 | 7.5/10 | auth.restore() 无条件清缓存、FIFO 而非 LRU 缓存淘汰、遗留数据迁移每次冷启动执行 |
| 商业价值 | 6.5/10(修正后) | 功能覆盖全面但完成度不均,积分商城/文章/AI 分析有长期留存价值,缺失体检报告查看、危急值通知等高优先功能 |
综合评分: 6.5/10 (B)(修正后;原 6.2 基于错误商业前提)
二、专家组核心发现
专家 1:架构与工程 (6.8/10)
优势:
- 6 层分层架构(pages/components/services/stores/hooks/utils)清晰
- ConcurrencyLimiter(8) 解决微信 10 并发限制
- generation counter 长轮询模式设计合理
- CSS 变量主题系统完整
问题:
- auth.ts 280 行过重 — 认证 + 患者管理 + 角色判断 + 登录态恢复全在一个 store,违反单一职责
- 测试覆盖率 6% — 13 单元测试文件 ~1,626 行 vs 31,000 行源码,远低于 80% 标准
- request.ts 单点风险 — 279 行承担并发控制 + 缓存 + token 刷新 + 去重 + 错误处理,无测试覆盖
- Zod 未使用 — package.json 无 Zod 依赖,wiki 声称的 schema 验证实际不存在
专家 2:安全与合规 (6.0/10)
CRITICAL:
- 加密密钥硬编码 — 所有 .env 文件
TARO_APP_ENCRYPTION_KEY为空字符串,secure-storage-aes.ts 使用'hms-default-key'作为 fallback,等于明文存储 - 知情同意为空壳 —
grantConsent()从未被任何页面调用,consent 系统是摆设
HIGH:
- secureGet 明文 fallback — 解密失败时直接返回明文(为 MCP 兼容性),生产环境不可接受
- request-signer 未集成 — HMAC-SHA256 签名工具已实现但 request.ts 未使用
- 无安全响应头 — CSP、HSTS 等头部依赖服务端,但小程序端无额外防护
专家 3:用户体验与产品 (5.9/10)
导航混乱:
- "助手" TabBar 名不副实 — 实际是 AI 聊天,用户找不到真正通知
- "健康" Tab 打开是数据录入表单 — 用户期望看到健康概览
- "我的" 18 个菜单项过载 — 信息架构混乱
流程断裂:
- 医生端 TabBar reLaunch 丢失导航状态
- 设备同步后无数据查看闭环
- 积分商城 Tab 页空白(需关联患者档案才显示)
专家 4:性能优化 (7.5/10)
良好实践:
- ConcurrencyLimiter 避免微信并发限制
- generation counter 防止长轮询重叠
- safeNavigateTo 处理页栈超 10 层
优化空间:
- auth.restore() 每次 Tab 切换清缓存 —
clearRequestCache()无条件执行,导致跨 Tab 数据重新请求 - 缓存策略一刀切 — GET 请求统一 60s TTL,不区分数据变化频率
- 遗留数据迁移每次冷启动 —
migrateLegacyStorage()每次启动扫描所有 key - FIFO 而非 LRU — ResponseCache 按插入顺序淘汰,非按访问频率
专家 5:商业价值与 ROI (6.5/10)(修正后)
修正说明:原评分 5.0 基于错误前提(体检中心短期就诊),实际 HMS 面向长期健康管理机构(慢性病、透析、随访),患者留存周期数月至数年。积分商城、线下活动、健康资讯等功能在长期留存场景下有实际价值。
功能覆盖评估(基于综合健康管理定位):
| 功能域 | 页面数 | 评估 | 理由 |
|---|---|---|---|
| 健康数据录入/趋势 | ~8 | 核心必需 | 慢性病日常监测的核心场景 |
| 咨询管理 | ~4 | 核心必需 | 医患沟通是长期管理的关键 |
| 预约管理 | ~3 | 核心必需 | 透析/随访定期复诊 |
| 医生端工作台 | ~16 | 核心必需 | 医护日常工作的入口 |
| 积分商城 | ~4 | 有留存价值 | 慢性病长期激励(签到、连续天数奖励),促进依从性 |
| 健康资讯 | ~3 | 有留存价值 | 健康教育内容提升患者参与度 |
| AI 分析 | ~3 | 有潜力 | 后端 ReAct Agent 架构完善,前端展示需提升 |
| 线下活动 | ~2 | 长尾功能 | 健康讲座/筛查活动,非每日使用但有社区运营价值 |
| 设备同步 | ~1 | 战略功能 | BLE 蓝牙网关是差异化能力 |
缺失关键功能(真正的高 ROI 缺口):
- 体检/化验报告查看 — 后端
lab_report已就绪,前端仅医生端有入口,患者端缺失 - 用药提醒推送 — 后端
medication_reminderentity 已存在,前端无消费 - 危急值通知 — 后端 alerts + SSE 已就绪,小程序无接收展示
- 护理计划前端 — 后端
care_planentity 已存在,前端无页面 - 健康趋势图可视化 — 后端 trend API 已有,小程序 ECharts 趋势页体验待提升
结论:61 页面覆盖患者端+医护端,不是过度开发,而是功能完成度不均。核心链路(健康数据→告警→AI分析→随访→护理计划)的后端已就绪,但前端消费链路有断点。
三、头脑风暴 — 聚焦可落地的改进方向
原则:有据可依、避免过度开发、每一项改动都有明确的用户价值或安全必要性。
P0:安全必修(必须立即修复)
1. 加密密钥问题
问题:TARO_APP_ENCRYPTION_KEY 为空 → fallback 'hms-default-key' → 加密形同虚设。
论证:
secure-storage-aes.ts:42— passphrase 空时使用 hardcoded'hms-default-key'- 所有 .env 文件确认
TARO_APP_ENCRYPTION_KEY="" - 影响:localStorage 中的 token、用户信息、AI 对话历史实际为伪加密
方案:
- 非生产环境:在
.env.development设置固定密钥(不提交到 git) - 生产环境:通过后端 API 动态下发设备绑定密钥(一次握手,存入 keychain)
- 移除
'hms-default-key'fallback,空密钥时抛出错误而非静默降级
预估工作量:1 天 ROI:极高 — 修复一个实际安全漏洞
2. 知情同意空壳问题
问题:grantConsent() 定义了但从未被调用,患者隐私数据无保护。
论证:
stores/auth.ts有grantConsent()和revokeConsent()方法- 全局搜索无任何页面调用
grantConsent - 后端 consent 拦截已实现但前端无触发点
方案:
- 在患者首次查看敏感数据(如 AI 分析、健康报告)时弹出同意弹窗
- 同意状态存储到后端(已有 consent 相关 API)
- 不同意则不显示数据
预估工作量:2 天 ROI:高 — 医疗合规必需
3. secureGet 明文 fallback
问题:解密失败时 secureGet 返回明文值。
论证:
secure-storage-aes.ts第secureGet()中 catch 块返回 plaintext- 注释说是为 MCP 兼容性,但生产环境不可接受
方案:
- 生产模式:解密失败返回
null并记录 warn 日志 - 开发模式:保留 fallback 并打印 warn
- MCP 测试不走 secureStorage
预估工作量:0.5 天 ROI:高 — 消除安全降级路径
P1:高价值功能补齐(核心就医体验)
4. "健康" Tab 改为健康总览
问题:用户点击"健康"Tab 期望看到健康概览,实际是体征录入表单。
论证:
- 用户心智模型:TabBar 是导航到该领域的总览
- 当前
pages/health/index是体征录入入口 - 健康数据已有 service 层(
health.ts),只需组装展示
方案:
- "健康"Tab 展示:今日体征摘要 + 最近异常 + 待办提醒
- 体征录入移到子页面(点击"录入体征"按钮跳转)
- 复用现有
healthstore 的 trendCache 数据
预估工作量:3 天 ROI:高 — 直接改善核心体验
5. 化验/体检报告查看
问题:患者端无法查看自己的化验报告和体检报告。
论证:
- 后端已有
lab_reportentity + handler + service - 前端 Web 端已实现报告查看
- 小程序端无对应页面
方案:
- 新增报告列表页 + 报告详情页
- 复用 Web 端的数据结构
- 支持查看异常指标高亮
预估工作量:5 天 ROI:极高 — 慢性病长期管理核心需求(化验报告是调整治疗方案的关键依据)
6. 危急值通知
问题:后端 alerts 表和事件已就绪,前端无接收展示。
论证:
- 后端已有
alertsentity + handler + SSE 端点 - 小程序长轮询基础设施已有(
useLongPollinghook) - 缺少通知页面和推送触发
方案:
- App 级别长轮询监听 alerts
- 新增通知中心页面(TabBar "助手" → 改为真正的通知+AI 助手)
- 危急值弹出模态框强提醒
预估工作量:4 天 ROI:高 — 医疗安全必需
P2:工程健康度(可持续交付)
7. auth store 拆分
问题:auth.ts 280 行,职责混杂。
论证:
- 承担认证 + 患者管理 + 角色判断 + 登录态恢复 + consent 管理
- 修改任何一个功能都可能影响其他功能
- restore() 无条件清缓存影响全局性能
方案:
auth.ts— 仅认证/登录/登出(~100 行)patient.ts— 患者列表/切换/选择(~80 行)consent.ts— 知情同意管理(~40 行)- restore() 仅在首次启动时清缓存,Tab 切换时跳过
预估工作量:2 天 ROI:中 — 降低维护风险
8. request.ts 补测试
问题:279 行核心模块零测试。
论证:
- request.ts 承担并发控制、缓存、token 刷新、去重、错误处理
- 任何修改都可能引入回归
- 当前 6% 覆盖率下,这个模块是最值得投入测试的
方案:
- 为 ConcurrencyLimiter 写单元测试
- 为 ResponseCache 写单元测试(覆盖 FIFO→LRU 改造)
- 为 token 刷新去重写集成测试
- 为 safeReLaunch 去重写测试
预估工作量:3 天 ROI:高 — 为后续任何改动提供安全网
9. 缓存策略优化
问题:60s TTL 一刀切,FIFO 淘汰不科学。
论证:
- 用户信息变化频率低 → 应 5min+
- 健康数据变化频率中 → 60s 合理
- 通知数据变化频率高 → 应 10s 或不缓存
- FIFO 淘汰导致热点数据被误淘汰
方案:
- 按 API 端点配置差异化 TTL
- ResponseCache 改为 LRU 淘汰(每次 get 更新访问时间)
- auth.restore() 不再无条件清缓存
预估工作量:1.5 天 ROI:中 — 减少无效请求,提升体验流畅度
P3:功能完成度补齐(后端已就绪,前端需消费)
10. 用药提醒推送
问题:后端 medication_reminder entity + 定时检查已就绪,前端无展示。
论证:
- 慢性病患者(高血压/糖尿病)需要长期用药依从性管理
- 后端已有
medication_reminderentity 和定时任务 - 小程序无提醒页面
方案:
- "我的" 新增用药提醒入口
- 支持查看当日用药计划 + 标记已服用
- 微信模板消息推送提醒(后端
wechat-templates.ts已注册模板)
预估工作量:3 天 ROI:高 — 慢性病管理核心能力
11. 护理计划前端
问题:后端 care_plan / plan_item / plan_result entity 已就绪,前端无页面。
论证:
- 护理计划是"数据驱动个性化护理路径"的核心体现
- 后端 3 个 entity + CRUD API 已完成
- 前端完全空白
方案:
- 医生端新增护理计划管理页面(创建/编辑/查看)
- 患者端新增护理计划查看页面(进度追踪)
预估工作量:5 天 ROI:高 — 设计理念中"数据驱动"的核心体现
四、优先级排序与执行路线
总原则
每项工作必须有用户价值或安全必要性论证,不做没有证据支撑的开发。
执行顺序(按 ROI 排序)
| 序号 | 改进项 | 优先级 | 工作量 | ROI | 前置依赖 |
|---|---|---|---|---|---|
| 1 | 加密密钥修复 | P0 | 1天 | 极高 | 无 |
| 2 | secureGet 明文 fallback | P0 | 0.5天 | 高 | 无 |
| 3 | 知情同意流程 | P0 | 2天 | 高 | 加密密钥修复 |
| 4 | "健康"Tab 改为总览 | P1 | 3天 | 高 | 无 |
| 5 | 化验/体检报告查看 | P1 | 5天 | 极高 | 后端 API 已就绪 |
| 6 | 危急值通知 | P1 | 4天 | 高 | useLongPolling 已有 |
| 7 | auth store 拆分 | P2 | 2天 | 中 | 补测试后更安全 |
| 8 | request.ts 补测试 | P2 | 3天 | 高 | 无 |
| 9 | 缓存策略优化 | P2 | 1.5天 | 中 | request.ts 测试 |
| 10 | 用药提醒推送 | P3 | 3天 | 高 | 后端 entity 已就绪 |
| 11 | 护理计划前端 | P3 | 5天 | 高 | 后端 3 entity 已就绪 |
P0 总工作量:3.5 天 P1 总工作量:12 天 P2 总工作量:6.5 天 P3 总工作量:8 天
五、不做什么(明确排除)
以下是在分析过程中考虑过但决定不做的事项,附排除理由:
| 候选项 | 排除理由 |
|---|---|
| 全面 Zod 集成 | 当前 Taro 表单 + 手动验证可工作,ROI 不支撑全面引入新依赖 |
| request-signer 签名集成 | 微信小程序走 HTTPS,请求签名在非代理场景下 ROI 低 |
| BLE 模块重写 | 当前 4 设备适配器工作正常,用户量少,不值得投入 |
| 全面 E2E 测试 | 6%→80% 需要巨大投入,先聚焦 request.ts 核心模块测试 |
| "我的"菜单重构 | 需要完整的用户调研,拍脑袋改可能更差 |
| 组件库二次重构 | 当前组件库迁移刚完成,立即重构浪费 |
| 国际化 i18n | 当前只有中文场景,过早 |
| 暗黑模式 | 医疗场景不需要,用户调研无需求 |
六、结论
小程序当前处于功能覆盖全面但完成度不均的状态。核心矛盾不是"过度开发",而是:
- 安全基础设施有漏洞 — 加密密钥、知情同意、明文 fallback 三个安全问题必须修复
- 后端能力前端未消费 — 化验报告查看、危急值通知、用药提醒、护理计划等后端已就绪但前端无入口
- 工程健康度不足 — 6% 测试覆盖率让任何改动都有回归风险
- UX 信息架构需优化 — "健康"Tab 是录入而非总览、TabBar 命名与功能不匹配
61 页面覆盖患者端+医护端,在综合健康管理定位下并不过度。 真正的问题是后端已经建好的能力(化验报告、告警、护理计划、用药提醒)在前端没有对应的消费页面,形成"后端能力孤岛"。
建议执行 P0(3.5天)→ P1(12天)→ P2(6.5天)→ P3(8天)的渐进式改进路线,总投入约 30 天。
优先消费已有后端能力而非开发新功能,每一步都有明确的问题陈述和代码证据。