docs: split tech docs into backend/patient/doctor, add prod roadmap, improve upload UI, fix report list for doctors, auto-start frontends in bat

This commit is contained in:
MingNian
2026-05-21 11:21:43 +08:00
parent 5d89dcceeb
commit 51c7c89ec5
5 changed files with 1570 additions and 1517 deletions

View File

@@ -0,0 +1,298 @@
# 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 | 患者前端技术文档