title, updated, status, tags
| title |
updated |
status |
tags |
| Web 前端 |
2026-04-28 |
stable |
| frontend |
| react |
| antd |
| vite |
| spa |
|
Web 前端
从 index 导航。关联: erp-server infrastructure erp-health
1. 设计决策
- 组件库优先 — Ant Design 6,不自造轮子
- 状态集中 — Zustand 管理全局状态(5 个 store)
- API 层分离 — HTTP 调用封装到
src/api/(含 health/ 和 ai/ 子目录),组件不直接 fetch
- 代理开发 — Vite 代理
/api 到后端 3000 端口
- HashRouter — 不需要服务端 fallback 配置,部署更稳健
- 懒加载 — 除 Login 外所有页面使用
lazy() 按需加载
版本(以实际 package.json 为准)
React 19.2.4 / Ant Design 6.3.5 / React Router 7.14.0 / Zustand 5.0.12 / Vite 8.0.4 / TypeScript 6.0.2
2. UI 规范
SaaS 后台布局
经典 SaaS 后台管理布局(响应式,支持移动端):
UI 规则
- 使用 Ant Design 组件库,不自造轮子
- 中文优先,所有文案通过 i18n key 引用
- 支持 4 套主题切换:信任蓝 / 温润东方 / 深邃夜色 / 翡翠清雅
- 侧边栏按模块分组:基础模块 / 行业模块
- 表单验证使用 Ant Design Form 的 validateRules
2.1 多主题系统(4 套内置主题)
自 2026-04-28 起采用多主题架构。用户可在顶栏主题切换器中选择偏好主题,选择持久化到 localStorage。
4 套主题视觉人格
| 主题 |
主色 |
背景 |
圆角 |
性格 |
| 信任蓝 (blue) |
#2563EB |
#F8FAFC 冷灰 |
10/12/6px |
专业·企业 |
| 温润东方 (warm) |
#C4623A |
#F5F0EB 暖米 |
12/16/8px |
温润·人文 |
| 深邃夜色 (dark) |
#60A5FA |
#0F172A 深蓝黑 |
10/12/6px |
护眼·专注 |
| 翡翠清雅 (emerald) |
#5B7A5E |
#F4F7F4 浅绿灰 |
10/14/8px |
清新·健康 |
技术架构
- CSS 变量层 —
:root 默认为 blue,[data-theme='xxx'] 覆盖全部视觉 token(apps/web/src/index.css)
- Ant Design 动态主题 —
ConfigProvider 的 theme prop 按 ThemeName 选择不同配置(apps/web/src/App.tsx)
- Zustand 持久化 —
useAppStore().theme + localStorage('hms-theme')(apps/web/src/stores/app.ts)
- 暗色检测 —
useThemeMode() hook 从 store 读取,不再比对色值(apps/web/src/hooks/useThemeMode.ts)
温润东方风详细 Token(与小程序端共享)
小程序端源文件:apps/miniprogram/src/styles/variables.scss + mixins.scss
| 角色 |
CSS 变量 |
色值 |
| 主色 |
--erp-primary |
#C4623A |
| 背景 |
--erp-bg-page |
#F5F0EB |
| 容器 |
--erp-bg-container |
#FFFFFF |
| 主文字 |
--erp-text-primary |
#2D2A26 |
| 次文字 |
--erp-text-secondary |
#7A756E |
| 边框 |
--erp-border |
#E8E2DC |
| 成功 |
--erp-success |
#5B7A5E |
| 警告 |
--erp-warning |
#C4873A |
| 错误 |
--erp-error |
#B54A4A |
禁止事项
- 禁止紫色渐变、禁止 emoji 作图标
- 禁止左侧彩色边框卡片标示状态(改用 tag 标签)
- 禁止无意义的渐变背景
- 禁止装饰性 icon 遍地配
3. 关键文件 + 数据流
核心文件
| 文件 |
职责 |
apps/web/src/main.tsx |
React 入口 |
apps/web/src/App.tsx |
路由定义 + Ant Design 动态主题(4 套) |
apps/web/src/layouts/MainLayout.tsx |
SaaS 后台管理布局 + ThemeSwitcher 集成 |
apps/web/src/stores/ |
4 个 Zustand store |
apps/web/src/components/ThemeSwitcher.tsx |
主题选择下拉面板 |
apps/web/src/hooks/useThemeMode.ts |
暗色模式检测(从 store 读取) |
apps/web/src/api/ |
28 个 API 服务文件(含 7 个健康模块 API) |
apps/web/vite.config.ts |
Vite 配置 + API 代理 |
微信小程序(患者端)是独立前端项目,详见 miniprogram
路由结构
公开: /login
受保护(MainLayout 包裹):
| 路径 |
页面 |
/ |
首页 |
/users, /roles, /organizations |
用户/角色/组织管理 |
/workflow |
工作流 |
/messages |
消息中心 |
/settings |
系统设置 |
/plugins/admin, /plugins/market |
插件管理/市场 |
/plugins/:pluginId/:entityName |
插件 CRUD(动态生成) |
| `/plugins/:pluginId/tabs |
tree |
健康管理路由(22 条):
| 路径 |
页面 |
/health/patients |
患者列表 |
/health/patients/:id |
患者详情(5 个标签页:基本信息/体征/化验/健康档案/随访) |
/health/patient-tags |
患者标签管理 |
/health/doctors |
医护管理 |
/health/schedules |
排班管理(含日历视图) |
/health/appointments |
预约管理(含状态流转) |
/health/follow-up-tasks |
随访任务列表 |
/health/follow-up-records |
随访记录 |
/health/consultations |
咨询会话列表 |
/health/consultations/:id |
咨询详情(含消息 + 导出) |
/health/articles |
文章管理列表 |
/health/article-editor |
文章编辑器(富文本) |
/health/article-categories |
文章分类管理 |
/health/article-tags |
文章标签管理 |
/health/points-rules |
积分规则管理 |
/health/points-products |
积分商品管理 |
/health/points-orders |
积分订单列表 |
/health/statistics |
统计概览(透析/化验/预约/体征上报率) |
/health/offline-events |
线下活动管理 |
/health/ai-analysis |
AI 分析历史 |
/health/ai-prompts |
AI Prompt 管理 |
/health/ai-usage |
AI 用量统计 |
健康模块共享组件(11 个)
| 组件 |
用途 |
StatusTag |
预约/随访/咨询状态标签(含单元测试) |
PatientSelect |
患者搜索选择器(远程搜索) |
DoctorSelect |
医护搜索选择器(远程搜索) |
CalendarView |
排班日历视图 |
ExportButton |
咨询记录导出按钮 |
VitalSignsChart |
多指标趋势图:概览卡片条(5 指标 sparkline) + 点击展开详情折线图 |
VitalSignsTab |
患者详情-体征标签页 |
LabReportsTab |
患者详情-化验报告标签页 |
HealthRecordsTab |
患者详情-健康档案标签页 |
FollowUpTab |
患者详情-随访标签页 |
ImagePreview |
图片预览组件 |
集成契约
| 方向 |
模块 |
接口 |
触发时机 |
| 调用 → |
erp-server |
/api/v1/* REST |
所有数据操作 |
| 调用 → |
erp-server |
ws://localhost:3000/ws/* |
WebSocket |
| 消费 ← |
插件系统 |
plugin.toml schema |
动态生成插件页面 |
| 调用 → |
erp-health |
/api/v1/health/* |
健康模块所有数据操作 |
4. 代码逻辑
状态管理(5 个 Zustand Store)
| Store |
状态 |
app.ts |
theme(blue/warm/dark/emerald), sidebarCollapsed, localStorage 持久化 |
auth.ts |
user, isAuthenticated, localStorage 持久化 |
health.ts |
患者/医生姓名缓存与批量解析 |
message.ts |
unreadCount, recentMessages, SSE 实时推送连接, 请求去重 |
plugin.ts |
plugins 列表, 动态菜单, schema 缓存, 请求去重 |
健康模块 API 文件(10 个)
| 文件 |
覆盖端点 |
patients.ts |
患者 CRUD + 标签 + 健康摘要 + 家庭成员 |
doctors.ts |
医护档案 CRUD |
appointments.ts |
预约 CRUD + 状态流转 |
healthData.ts |
体征/化验/健康档案/趋势 |
followUp.ts |
随访任务 + 记录 |
consultations.ts |
咨询会话 + 消息 + 导出 |
articles.ts |
健康文章 |
points.ts |
积分系统 |
deviceReadings.ts |
设备数据采集 |
alerts.ts |
健康预警 |
前端单元测试(5 个)
| 文件 |
测试内容 |
constants/health.test.ts |
健康常量定义验证 |
hooks/useThemeMode.test.ts |
暗色模式 hook |
hooks/useDebouncedValue.test.ts |
防抖 hook |
pages/health/components/StatusTag.test.tsx |
状态标签渲染 |
utils/exprEvaluator.test.ts |
表达式求值 |
插件页面系统
插件通过 plugin.toml schema 声明页面,前端根据 schema 动态生成:
PluginCRUDPage — 标准列表+表单
PluginTabsPage — 标签页切换
PluginTreePage — 树形展示
PluginGraphPage — 关系图谱
PluginKanbanPage — 看板视图
PluginDashboardPage — 仪表盘
⚡ 不变量: 插件菜单由 plugin.ts store 从 API 动态获取,不硬编码
⚡ 不变量: API client 在请求前 30s 检查 token 过期,提前刷新避免 401
⚡ 不变量: DatePicker 返回 dayjs 对象,提交前必须 .format('YYYY-MM-DD') 转字符串
代理配置
5. 活跃问题 + 陷阱
⚠️ Ant Design 6 废弃 destroyOnClose,应使用 destroyOnHidden
⚠️ Ant Design 6 废弃 API 警告(valueStyle/Spin tip/trailColor)已在历史版本中修复
⚠️ antd.setScaleParam 强制回流 64ms — antd 内部问题,无法直接修复
历史教训
- DatePicker 提交 dayjs 对象而非字符串 → 后端 422
birth_date trailing input — 必须调用 .format('YYYY-MM-DD')
- 预约表单医护字段标为可选但后端必填 → 400
doctor_id is required — 医护为必填(CAS 排班需要)
- 趋势图后端 DTO
Vec<(NaiveDate, f64)> 序列化为 JSON 数组 [[date, value]] 而非对象 [{date, value}] → 改用 Vec<DataPoint> 修复;前端 extractData 需同时处理 ApiResponse 包装和裸数组两种响应格式
IndicatorTimeseriesResp 返回 { indicator, data: [...] } 包装对象,不是裸数组 — Array.isArray(res) 为 false,必须从 res.data 取值
6. 变更记录
| 日期 |
变更 |
| 2026-04-28 |
UI/UX 重构 Phase 5(小程序端 8 项优化):首页健康资讯+空状态引导、Hub sparkline bar+打卡合并、日常监测 3 分组折叠+异常高亮、预约时段灰显、咨询消息日期分组+图片预览、医护异常横幅+搜索、趋势图骨架屏 |
| 2026-04-28 |
UI/UX 重构 Phase 4:4 个表单 Modal→DrawerForm(患者 4 分组/预约 3 分组+排班校验/随访 2 分组/积分商品 2 分组) |
| 2026-04-28 |
UI/UX 重构 Phase 3:10 个列表页统一迁移至 PageContainer + usePaginatedData + EntityName + 共享格式化工具,移除手动 isDark 处理 |
| 2026-04-28 |
UI/UX 重构 Phase 2:仪表盘角色自适应(useDashboardRole + DoctorDashboard/NurseDashboard/AdminDashboard/OperatorDashboard),删除快捷入口/积分排行/最近活动旧区块 |
| 2026-04-28 |
UI/UX 重构 Phase 1:提取 6 个共享组件(PageContainer/EntityName/FilterBar/DrawerForm/FilterBar + dayjs/format 工具),12 个文件 dayjs 导入统一 |
| 2026-04-28 |
多主题系统:4 套主题(blue/warm/dark/emerald)+ CSS 变量 + Ant Design 动态主题 + ThemeSwitcher + useThemeMode 修复 |
| 2026-04-26 |
全面更新:22 条健康路由(+12 内容/积分/统计/活动/AI)、11 个共享组件、77 个 TSX 文件 |
| 2026-04-26 |
从 CLAUDE.md 迁移:UI 布局规范(§8) |
| 2026-04-26 |
VitalSignsChart 重设计:概览卡片条 + 点击展开详情图,5 指标独立 Y 轴 |
| 2026-04-25 |
全面更新:10 条健康路由、12 个共享组件、7 个健康 API 文件、3 个单元测试 |
| 2026-04-24 |
添加小程序交叉引用 |
| 2026-04-23 |
重构为 5 节结构,更新为当前完整前端状态 |