# HealthManager 患者前端 — 技术文档 > 移动端 H5 应用,患者用手机浏览器打开。 --- ## 目录 1. [技术选型](#1-技术选型) 2. [文件结构](#2-文件结构) 3. [关键文件详解](#3-关键文件详解) 4. [页面详解](#4-页面详解) 5. [状态管理](#5-状态管理) 6. [API 调用方式](#6-api-调用方式) 7. [常见问题 FAQ](#7-常见问题-faq) --- ## 1. 技术选型 | 库 | 版本 | 做什么 | |----|------|--------| | React | 19 | UI 框架 | | TypeScript | 6 | 类型安全 | | Vite | 8 | 构建工具 | | Zustand | 5 | 状态管理 | | React Router | 7 | 路由(页面跳转) | | ECharts | 6 | 图表(趋势图、饼图) | | Framer Motion | 12 | 动画 | | dayjs | 2 | 日期处理 | --- ## 2. 文件结构 ``` src/ ├── main.tsx ← React 应用入口 ├── App.tsx ← 根组件,渲染路由 ├── router/ │ ├── index.tsx ← URL 和页面的映射关系 │ └── AuthGuard.tsx ← 路由守卫:没登录→跳登录页 ├── stores/ │ ├── auth.store.ts ← 认证状态:用户、令牌、登录/登出 │ └── notification.store.ts ← 通知状态 ├── services/ │ ├── api-client.ts ← 底层 HTTP 请求(封装 fetch) │ ├── auth.service.ts ← 登录/注册/资料 API │ ├── health.service.ts ← 健康数据 API │ ├── medication.service.ts ← 药物 API │ ├── consultation.service.ts ← 咨询 API │ ├── report.service.ts ← 报告 API │ ├── followup.service.ts ← 随访 API │ ├── notification.service.ts ← 通知 API │ ├── exercise-diet.service.ts← 运动饮食 API │ └── device.service.ts ← 设备 API ├── types/ │ ├── user.ts, health.ts, medication.ts, consultation.ts │ ├── report.ts, followup.ts, notification.ts, device.ts │ ├── calendar.ts, exercise-diet.ts │ └── index.ts ← 统一导出 ├── utils/ │ ├── format.ts ← 日期/数字格式化 │ ├── validator.ts ← 手机号/验证码格式校验 │ └── constants.ts ← 常量(测量类型、健康贴士等) ├── hooks/ │ ├── useAuth.ts ← 获取认证状态 │ └── useCountdown.ts ← 验证码倒计时 ├── components/ │ ├── common/ │ │ ├── Button.tsx ← 按钮(支持 loading 状态) │ │ ├── Card.tsx ← 卡片容器 │ │ ├── Badge.tsx ← 角标(红点/数字) │ │ ├── Input.tsx ← 输入框(带标签+错误提示) │ │ ├── Toast.tsx ← 轻提示 │ │ └── Empty.tsx ← 空状态占位 │ ├── layout/ │ │ ├── AppLayout.tsx ← 主布局:TabBar + 内容区 │ │ ├── StackLayout.tsx ← 子页面布局:返回按钮 + 内容区 │ │ ├── TabBar.tsx ← 底部导航栏(首页/健康/服务/我的) │ │ └── PageHeader.tsx ← 页面标题栏 │ └── charts/ │ ├── LineChart.tsx ← ECharts 折线图 │ ├── BarChart.tsx ← ECharts 柱状图 │ └── PieChart.tsx ← ECharts 饼图 └── pages/ ├── auth/ │ ├── LoginPage.tsx ← 登录页 │ └── RegisterPage.tsx ← 注册页 ├── home/ │ ├── HomePage.tsx ← 仪表盘首页 │ └── DeviceBindingPage.tsx ← 设备绑定 ├── health/ ← 健康模块 ├── medication/ ← 用药模块 ├── services/ ← 服务模块(问诊/报告/随访) ├── exercise-diet/ ← 运动饮食 ├── profile/ ← 个人中心 └── notifications/ ← 通知 ``` --- ## 3. 关键文件详解 ### 3.1 `services/api-client.ts` — HTTP 请求客户端 **所有前端 API 调用的基础**,封装了原生 `fetch`。 **核心逻辑**: 1. 公开接口(login/register/send-sms/refresh)**不附加** Authorization 头 2. 其他请求自动从 localStorage 读取 JWT 令牌,加到 `Authorization: Bearer xxx` 3. 发送 HTTP 请求到 `http://localhost:5000` 4. 如果返回 401(未认证)→ 清除 localStorage,跳转登录页 5. 把服务器返回的 JSON 统一包装成 `{ code, data, message }` **四个方法**:`get`、`post`、`put`、`del` ### 3.2 `services/auth.service.ts` — 认证服务 | 函数 | 做的事 | |------|--------| | `login(phone, smsCode)` | 调 `POST /api/auth/login` → 返回 `{token, user}` | | `register(phone, smsCode, name)` | 调 `POST /api/auth/register` | | `getProfile()` | 调 `GET /api/auth/me` → 更新 localStorage 中的用户资料 | | `updateProfile(data)` | 调 `PUT /api/auth/me` → 更新姓名/性别/身高/体重/病史 | | `logout()` | 清除 localStorage 的 `hrt_auth` | ### 3.3 `services/health.service.ts` — 健康数据服务 | 函数 | API | 说明 | |------|-----|------| | `getRecords({type, startDate, endDate})` | `GET /health-records` | 查记录列表 | | `addRecord(record)` | `POST /health-records` | 添加记录。自动把 value 转成 JSON 字符串 | | `getLatestStats()` | `GET /health-records?days=7` | 拉取 7 天数据,客户端计算各类型的均值和趋势 | | `getTrendData(type, days)` | `GET /health-records?type=&days=` | 趋势图数据 | **Value 解析逻辑**:`parseValue()` 根据 type 解析 JSON: - `blood_pressure` → `{systolic, diastolic}` 对象 - 其他类型 → `{value}` 中的数字 ### 3.4 `services/medication.service.ts` — 用药服务 | 函数 | API | 说明 | |------|-----|------| | `getMedications()` | `GET /medications` | 药物列表 | | `addMedication(data)` | `POST /medications` | 添加药物 | | `markTaken(medicationId, slot)` | `POST /medications/{id}/take` | 打卡 | | `getAdherence(medicationId)` | `GET /medications/{id}/adherence` | 依从率 | ### 3.5 `services/consultation.service.ts` — 咨询 | 函数 | API | 说明 | |------|-----|------| | `getDoctors()` | `GET /consultations/doctors` | 可接诊医生列表 | | `getConsultation(doctorId)` | `GET /consultations` | 查与某医生的活跃咨询 | | `startConsultation(doctorId)` | `POST /consultations` | 发起新咨询 | | `sendMessage(consultationId, text)` | `POST /consultations/{id}/messages` | 发送消息 | | `getDoctorReply(consultationId)` | `GET /consultations/{id}/messages` | 拉取最新消息,找医生的回复 | ### 3.6 `stores/auth.store.ts` — 认证状态 **状态数据**:`user`, `token`, `isAuthenticated` **操作方法**: - `login(phone, code)` → 调 API → 保存 token → 再拉完整用户资料 - `register(phone, code, name)` → 同上 - `logout()` → 清除所有数据 - `updateProfile(data)` → 只更新内存中的用户对象 **持久化**:Zustand `persist` 中间件 → `localStorage` 的 `hrt_auth` 键。刷新页面不丢登录状态。 ### 3.7 `router/index.tsx` — 路由 分为三类: 1. **公开路由**(无需登录):`/login`、`/register` 2. **Tab 路由**(需登录,底部导航栏):`/home`、`/health`、`/services`、`/profile` 3. **Stack 路由**(需登录,有返回按钮):所有子页面如 `/health/records/add`、`/services/consultation/chat/:doctorId` 等 `AuthGuard` 组件包裹在需要登录的路由外,未登录自动跳 `/login`。 --- ## 4. 页面详解 ### 登录页 `LoginPage.tsx` - 输入手机号 + 短信验证码 - 点"获取验证码" → 60 秒倒计时 - 验证码任意输入(演示版) - 成功后跳首页 ### 首页 `HomePage.tsx` - **健康概览卡片**(蓝色渐变):最新血压 + 心率,异常值变色 - **快捷操作**(6 个):测血压、记用药、在线问诊、报告解读、健康日历、运动饮食 - **健康小贴士**:随机展示,点击换下一条 - **通知角标**:未读通知红点 ### 健康中心 `HealthHubPage.tsx` 6 种测量类型卡片 → 点击进记录列表 → 点"+ 录入" → 填数值 → 保存 ### 趋势图 `TrendChartPage.tsx` - ECharts 折线图,可选 7/14/30/90 天 - 血压同时显示收缩压+舒张压两条线,140 警戒线 ### 药物管理 - **列表**:分"进行中/已结束"Tab - **添加**:选常用药或手动输入,设剂量、频次(每日1~3次)、服药时间点 - **详情**:依从率饼图,近30天服药记录 ### 在线问诊 - **医生列表**:按科室筛选 → 点医生 → 进聊天 - **聊天**:对话气泡,自动滚底 - 发送后 1.5 秒模拟医生回复(演示版) ### 报告管理 - **上传**:填标题 → 选类别 → 点虚线框选图片 → 提交 - **列表**:分状态 Tab 查看 - **详情**:查看解读结果 ### 个人中心 `ProfilePage.tsx` - 用户信息卡片(点击进入编辑) - 身体数据展示 - 菜单:用药、通知、设备、设置、关于 - 退出登录 ### 编辑资料 `EditProfilePage.tsx` 可修改:姓名、性别、生日、身高(cm)、体重(kg)、病史(顿号分隔) --- ## 5. 状态管理 | Store | 存储键 | 持久化 | 内容 | |-------|--------|--------|------| | `auth.store` | `hrt_auth` | ✓ localStorage | user, token, isAuthenticated | | `notification.store` | — | ✗ 内存 | notifications[], unreadCount | 通知不持久化——每次打开应用重新从服务器拉取。 --- ## 6. API 调用方式 ``` 前端 services → api-client.ts → fetch() → http://localhost:5000 → 后端 Controller ``` - 所有 API 请求经过 `api-client.ts` 统一处理 - 自动带 JWT 令牌(公开接口除外) - 401 自动清除登录态并跳转登录页 - 响应统一为 `{ code, data, message }` 格式 --- ## 7. 常见问题 FAQ ### Q1: 前端怎么调后端 API? 前端 `services/` 下的每个 service 文件封装了一类 API 调用。底层都通过 `api-client.ts` 发 HTTP 请求到 `http://localhost:5000`。 ### Q2: 怎么测这个前端? ```bash cd frontend-patient npm run dev # 浏览器打开 http://localhost:5173 # F12 → 左上角 📱 图标 → 选 iPhone 12 Pro 模拟手机 ``` ### Q3: 演示账号是什么? 手机号 `13800138000`,验证码随便填(1234 就行)。 ### Q4: 为什么某些页面打开是空白的? 打开 F12 看 Console 有没有红色报错。最常见原因: - 后端没启动(`ERR_CONNECTION_REFUSED`) - 令牌过期(401 Unauthorized)→ 清 localStorage 重新登录 ### Q5: 怎么改颜色/样式? 全局 CSS 变量在 `src/assets/styles/variables.css`: - 主色 `--color-primary: #1E6BFF` - 背景 `--color-bg: #F2F5FA` - 改一个地方,全局生效 --- > 文档版本:v1.0 | 最后更新:2026-05-20 | 患者前端技术文档