- iconMap 抽离为 utils/iconRegistry.tsx(单一真相源),补齐 10 个后端 seed 使用但前端缺失的图标 - MainLayout import 从 28 个图标减少到 6 个(仅保留布局专用图标) - routeTitleFallback 从 26 条精简到 10 条(仅保留动态参数路由 + 无后端菜单的静态路由) - 后端菜单已覆盖的 16 条标题映射移除(由 getTitleFromMenus 从后端数据获取) - wiki 关键数字更新:迁移 146、权限码 132
16 KiB
16 KiB
HMS 健康管理平台 — 知识库
Health Management System (HMS) — 面向体检中心/医疗机构的综合健康管理平台。从 ERP 底座分叉,继承身份权限/工作流/消息/配置等基础能力,
erp-health原生模块承载医疗业务。
关键数字
最后更新: 2026-05-15 | 数据截止: feat/media-library-banner 分支
| 指标 | 值 |
|---|---|
| Rust crate | 17 个(erp-core + 5 基础业务 + erp-health + erp-ai + erp-dialysis + erp-plugin + 7 插件/原型) |
| Rust 源文件 | 649 个 |
| 数据库表 | 30 基础表 + 49 健康业务表 + 9 AI 表 + 3 媒体库/轮播图表 |
| 数据库迁移 | 146 个(最新 m20260515_000146) |
| 后端路由 | 260+ 个(11 公开 + 14 FHIR + 2 网关 + ~240 受保护) |
| 核心模块 | 5 基础 (auth/config/workflow/message/plugin) + 3 业务 (health + ai + dialysis) |
| erp-health 实体 | 57 个 Entity(31 handler / 36 service / 21 DTO,189 文件) |
| erp-ai 实体 | 9 个 Entity(45 文件,4 AI Provider) |
| Web 前端 | 332 个 TS/TSX 文件(29 活跃路由 + 6 冻结路由,52 API 模块) |
| 微信小程序 | Taro 4.2 + React 18,163 个 TS/TSX 文件 / 66 页面 / 4 TabBar + 医生端分包 |
| 前端单元测试 | 88 个测试文件(472 Web 断言 + 39 MP 断言)+ 13 E2E spec(124 断言) |
| 后端测试 | 943 个函数(762 同步 + 181 异步),79 个文件含内联测试 |
| 事件系统 | 31 事件类型(health 模块内)/ 23 幂等消费者 / Outbox + LISTEN/NOTIFY |
| 权限码 | 132 个(health 59 + auth 17 + ai 9 + workflow 8 + dialysis 6 + plugin 2 + config 13 + message 5 + Copilot 5) |
| 生产 unwrap | 24 处(从 514 降至 24),全为安全解包 |
| utoipa 注解 | 88 个文件含注解 |
| Clippy | 全 workspace 0 警告(2026-05-07 清零) |
| 依赖版本 | 全部最新主版本线(Rust edition 2024) |
| API 文档 | http://localhost:3000/api/docs/openapi.json |
| Git 提交 | 800+ 次 |
| 系统分析评分 | 6.9/10 (B)(六维度全面均衡分析,2026-05-11) |
| 审计状态 | V1: 83% → V2: 85%,P0 安全修复已完成,V2 CRITICAL 全清零 |
| 角色测试 | R01-R05 全角色验证完成,86.5% 通过率,5 个 BUG 已修复;小程序 MP 多角色 96.2% 通过率 |
| Design Token | 11 级字号(含 --tk-font-display)+ 4 结构 token,68 SCSS 文件全面接入,关怀模式 CSS 变量级联自动生效 |
| 长者模式 | 58/58 页面 100% 覆盖 |
| UI 合规审计 | T40: 60 页面全覆盖(PASS 24 / PASS_WITH_ISSUES 36 / NEEDS_WORK 0),HIGH×2 + MEDIUM×6 + LOW×67 全部修复,评分 95/100 |
| 项目阶段 | 功能完善(媒体库+轮播图+文章编辑器上线,6 模块冻结待解冻) |
症状导航
| 症状 | 先查 | 再查 | 常见根因 |
|---|---|---|---|
| API 返回 403 | 权限码检查 | wasm-plugin 权限系统 | 权限码不匹配 / 缺少 .list 权限 |
| API 返回 500 无日志 | erp-core 错误链 | 后端 tracing 输出 | AppError::Internal 静默 |
| 数据库连接失败 | infrastructure | PostgreSQL 服务状态 | 服务未启动 / 环境变量未设置 |
| 前端 401 刷新时 | frontend auth store | API client token 刷新 | token 过期未主动刷新 |
| 迁移执行失败 | database | PostgreSQL 日志 | 表冲突 / 唯一索引 + 软删除 / 缺失迁移文件 |
| 端口被占用 | infrastructure dev.ps1 | 端口 5174-5189 进程 | 残留 Vite 进程 |
| 预约创建 400 doctor_id is required | erp-health 预约并发控制 | AppointmentList.tsx | 医生字段为必填(后端 CAS 要求) |
| 预约超额 | erp-health 排班并发 | appointment CAS 操作 | 并发控制未走原子 CAS |
| 患者创建 422 birth_date trailing input | frontend 日期序列化 | DatePicker dayjs 对象 | 未格式化为 YYYY-MM-DD 字符串 |
| 跨租户数据泄漏 | architecture 多租户策略 | database tenant_id | 查询缺少 tenant_id 过滤 |
| 小程序页面空白 | miniprogram defineConstants | process.env 未替换 |
编译时未注入环境变量 |
小程序登录失败 btoa is not defined |
miniprogram secure-storage | Web API 不可用 | 使用 Taro.arrayBufferToBase64 替代 |
| 微信登录 500 | database wechat_users 表结构 | Entity 字段与表不匹配 | 补 created_by/updated_by/version 列 |
| 迁移文件缺失报错 | database 迁移注册 | migration/src/lib.rs | 已应用的迁移文件被删除,需创建 stub |
MCP 连接失败 split error |
miniprogram MCP 联调 | project.config.json | 未开启 automationAudits |
| MCP mp_screenshot 超时 | miniprogram MCP 联调 | automator 已知 bug | 用 page_getElement 替代截图 |
| MCP 导航后跳回登录页 | miniprogram MCP 联调 §6.4 | storage 被清空 | 明文 token 写入后立即 reLaunch |
| MCP token 注入后仍 401 | miniprogram MCP 联调 §6.1 | 用了生产构建 | dev 构建(NODE_ENV=development)+ 空密钥 |
| MCP App 级命令全部超时 | miniprogram MCP 联调 §6.2 | 多 DevTools 实例冲突 | taskkill /F /IM wechatdevtools.exe 后重开 |
| MCP CLI 报"需要重新登录" | miniprogram MCP 联调 §6.2 | DevTools 未扫码 | 在 DevTools 中先扫码登录 |
| 积分商城 Tab 页空白 | miniprogram 待优化 | 未关联患者档案 | 需增加降级 UI 引导建档 |
| MCP 批量审计页面栈溢出 | miniprogram MCP 联调 §6.6 | navigateTo 超 10 层 |
改用 reLaunch 逐页测试 |
| 告警管理按钮不显示 | frontend 权限码拼写 | AlertList.tsx | health.alert.manage → health.alerts.manage(缺 s) |
| 小程序晚间血压丢失 | miniprogram 体征录入 | indicator_type 映射 | 已修复: 新增 blood_pressure_evening 类型,录入页+日常监测页+后端+测试全覆盖 |
| 咨询页长轮询 CPU 飙升 | miniprogram §5 审查 | longPoll delay=0 递归 | 已修复: 成功路径加 3s 间隔 + 连续失败上限 50 次 |
| 小程序 DevTools 卡死(所有 API ERR_SSL_PROTOCOL_ERROR) | miniprogram request.ts | process.env.NODE_ENV === 'production' 时 http→https 自动转换 |
已修复: 移除 getHeaders 中自动 http→https 升级,URL 以 .env 为唯一来源 |
| 小程序 Tab 切换卡死(并发请求阻塞 30s) | miniprogram request.ts | getHeaders() 中 await tryRefreshToken() 预检查 |
已修复: 移除 getHeaders 中的同步 Token 刷新预检查,仅依赖 401 重试路径 |
| 小程序患者端登录后卡死(Tab 切换频繁卡死) | miniprogram §5 审查 | 并发请求超微信 10 限制排队 + 长轮询重叠 + 防重入缺失 | 已修复: 全局并发限制 MAX_CONCURRENT=8 + generation counter 长轮询 + loadingRef 防重入 |
| 小程序咨询页闭会话崩溃(pollingRef is not defined) | miniprogram 审计第二轮 | generation counter 重构后 loadData 残留 pollingRef 引用 | 已修复: 移除 loadData 中 pollingRef.current = false 残余行 |
| 小程序深层页面导航失败(页栈超 10 层) | miniprogram navigate.ts | navigateTo 超微信 10 层限制 |
已修复: 新增 safeNavigateTo,栈≥9 自动降级为 redirectTo |
| 小程序登录卡死(getPhoneNumber 无响应) | miniprogram login 页 | DevTools 中 openType='getPhoneNumber' 不弹窗 |
已修复: dev 模式新增"开发模式快速登录"按钮绕过手机号授权 |
| 轮播图图片 500 | erp-health banner_handler | 媒体文件不在磁盘上 | 测试数据问题,生产环境不影响 |
| 设备同步内存无限增长 | miniprogram §5 审查 | BLE 模块单例 + readings 无上限 | 已修复: useRef 懒初始化 + MAX_LIVE_READINGS=200 |
| 医生端日期选择器不可用 | miniprogram §5 审查 | 原生 <input type='date'> |
已修复: 替换为 <Picker mode='date'> |
| 透析记录列表过滤不准 | miniprogram §5 审查 | 客户端过滤代替服务端过滤 | 已修复: 传 status 参数给后端 |
| 告警详情加载失败 | miniprogram §5 审查 | 列表加载 100 条客户端过滤 | 已修复: 新增 getAlert(id) 单条查询 |
| AI 分析 SSE 无 UI 入口 | erp-health AI 分析 | 前端未调用 | 4 个 SSE 端点无管理界面触发 |
| AI 分析返回对话式回复 | erp-ai prompt 模板 | 迁移 000123 | system_prompt 未加非对话指令 / 数据为空 |
| AI 分析结果显示原始 JSON | erp-ai 缓存回放 | replay_cached |
迁移 000123 前的嵌套 JSON bug,前端 extractPlainText 兼容 |
| AI 分析输出全空(SSE content="") | erp-ai qwen3 thinking | strip_think_block |
qwen3 流式 API content 为空,改非流式 + 剥离 think 块 |
Ollama 内存不足 memory layout |
infrastructure Ollama 配置 | OLLAMA_CONTEXT_LENGTH |
默认 262144 导致 35GB KV cache,设为 4096 |
| Ollama 暴露到局域网 | infrastructure Ollama 安全 | OLLAMA_HOST |
默认 0.0.0.0,必须设 127.0.0.1 |
| AI 趋势/报告分析 500 模板渲染失败 | erp-ai Handlebars 模板 | anomalies.length |
.length 不是有效 Handlebars 语法,改为 {{#if anomalies}} |
| AI 分析 400 缺少数据 | 后端预校验 | handler 层 | 化验报告 items 为空 / 趋势数据 metrics 为空 |
| 患者创建空名称成功 | erp-health patient_handler | name.trim().is_empty() |
已修复: 后端添加空名称校验返回 Validation 错误 |
| 仪表盘统计 500 | erp-health stats_handler | 单个查询异常导致整接口崩溃 | 已修复: 容错处理,单个查询失败返回零值 |
| FHIR 端点全部 404 | erp-server main.rs | 路由注册在 /fhir 非 /api/v1/fhir |
已修复: 移到 /api/v1/fhir |
| 冻结模块 API 可绕过 | erp-server frozen_module | 后端无拦截中间件 | 已修复: 新增 frozen_module_middleware |
| 积分端点 403 权限码错 | erp-health points_handler | 患者端用了 health.health-data.list |
已修复: 改为 health.points.list |
| MCP 审计大量 LOGIN_REDIRECT | miniprogram §6.8 审计脚本 | 测试用户密码配置错误 | 已修复: 所有测试用户密码均为 Admin@2026(不是 Test@2026) |
| 小程序访客轮播图不显示 | miniprogram 访客首页 | TARO_APP_DEFAULT_TENANT_ID 未配置 |
已修复: .env 添加默认 tenant_id,空字符串时跳过 API 调用 |
| 小程序轮播图图片 404 | erp-health 公开端点 | Axum 路由参数 :id → {id} 语法变更 + URL 拼接缺失 /api/v1 |
已修复: 路由改用 {banner_id},新增 /public/banner-image/{id} 图片服务端点 |
| 前端媒体库图片 401 | frontend MediaLibrary | /uploads 路径需要 JWT 认证 |
已修复: 新增 resolveMediaUrl() 工具函数自动拼接 ?token=,Vite 代理 /uploads |
后端启动 panic "Path segments must not start with :" |
erp-health module.rs | Axum v0.8+ 路由参数语法变更 | 路由定义使用 {param} 而非 :param |
模块导航
基础层(继承自 ERP 底座)
- erp-core — 错误体系 · 事件总线 · 模块 trait · 共享类型
- architecture — 架构决策 · 设计原则 · 技术选型
业务层(继承自 ERP 底座)
- erp-auth — 用户/角色/权限/组织/部门/岗位 · JWT · RBAC · 行级数据权限
- erp-config — 字典/菜单/设置/编号规则/主题/语言
- erp-workflow — BPMN 解析 · Token 驱动 · 任务分配
- erp-message — 消息 CRUD · 模板 · 订阅 · 通知面板
- erp-plugin — WASM 运行时 · 动态表 · 热更新(HMS 保留但非主要扩展方式)
核心业务层(HMS 专属)
- erp-health — 患者管理 · 健康数据 · 预约排班 · 随访管理 · 咨询管理 · 内容管理 · 媒体库 · 轮播图管理 · 积分商城 · 透析管理 · 线下活动 · 日常监测 · 告警系统(原生 Rust 模块,57 实体 / 31 handler / 36 service,已实现)
- erp-ai — AI 智能分析 · 化验单解读 · 趋势分析 · 报告摘要(原生 Rust 模块,9 实体 / 45 文件 / 4 AI Provider,Phase 1 MVP)
组装层
- erp-server — Axum 入口 · AppState · 7+ 模块注册 · 后台任务 · 优雅关闭
患者端
- miniprogram — 微信小程序 · Taro 4.2 · 微信登录 · 手机绑定 · 健康数据查看
基础设施
- infrastructure — 连接信息 · 环境变量 · 一键启动 (单一真相源)
- database — SeaORM 迁移 · 多租户表结构(145 迁移)
- frontend — React 19 SPA · 健康管理页面(29 活跃路由 + 6 冻结 + 工作台组件)
- testing — 验证清单 · 测试分布 · 性能基准
核心架构问答
为什么 erp-health 用原生模块而非 WASM 插件? 医疗业务需要 18 强类型实体、自定义 API(趋势分析/统计报表)、文件上传(化验单/体检报告)、未来 AI 集成,超出 WASM 插件能力范围。详见 erp-health。
模块间如何通信? erp-core EventBus 发布/订阅 DomainEvent。erp-health 发布 patient.created、appointment.confirmed 等事件,订阅 workflow.task.completed 等。详见 architecture。
多租户怎么隔离? 共享数据库 + tenant_id 列过滤,中间件从 JWT 注入。详见 database architecture。
患者/医护与 erp-auth 的关系? 账号走 users 表,erp-health 通过 user_id 外键关联扩展字段(科室、职称、档案等)。患者可先建档后绑定账号。
文档索引
| 类型 | 位置 |
|---|---|
| 健康模块设计规格 | docs/superpowers/specs/2026-04-23-health-management-module-design.md(已归档到 archive/superpowers-completed/) |
| AI 模块设计规格 | docs/superpowers/specs/2026-04-25-erp-ai-module-design.md |
| 内容管理设计规格 | docs/superpowers/specs/2026-04-26-content-management-design.md |
| 媒体库+轮播图设计规格 | docs/superpowers/specs/2026-05-10-media-library-banner-design.md |
| Copilot 基因化设计 | docs/superpowers/specs/2026-05-11-copilot-gene-design.md |
| 六维度全面均衡分析 | docs/superpowers/specs/2026-05-11-system-comprehensive-analysis-design.md(6.9/10 B,六维度评估) |
| PII 加密扩展规格 | docs/superpowers/specs/2026-04-26-pii-encryption-expansion-design.md |
| 设计规格(活跃) | docs/superpowers/specs/ (32 份) |
| 实施计划(活跃) | docs/superpowers/plans/ (30 份) |
| UI/UX 重构设计规格 | docs/superpowers/specs/2026-04-28-ui-ux-overhaul-design.md |
| UI/UX 重构实施计划 | docs/superpowers/plans/2026-04-28-ui-ux-overhaul-plan.md |
| 全系统审计报告(V1) | docs/archive/audits-v1/08-audit-report-2026-04-30.md(已归档) |
| 全系统审计报告(V2) | docs/audits/v2/13-final-report.md(85% 总体完成度,P0 安全修复已完成) |
| 讨论记录 | docs/discussions/ (41 份) |
| 事件注册表 | docs/event-registry.md |
| 角色测试计划(全量) | docs/qa/role-test-plans/ (R01-R05) |
| 角色测试结果 | docs/qa/role-test-results/ (R01 100% / R02 100% / R03 90.9% / R04 90.0% / R05 72.7% → 修复后待复测) |
| 协作规则 | CLAUDE.md |
| 插件制作指南 | .claude/skills/plugin-development/SKILL.md |
| 归档 | |
| 早期 CRM/插件设计 | docs/archive/superpowers-early/ (13 份,4月13-20日早期迭代) |
| 已完成设计/计划 | docs/archive/superpowers-completed/ (28 份,已实施完成) |
| V1 审计报告 | docs/archive/audits-v1/ (13 份,已被 V2 取代) |
| 早期讨论/测试报告 | docs/archive/discussions-early/ + docs/archive/test-reports-early/ |