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:
298
frontend-patient/技术文档-患者前端.md
Normal file
298
frontend-patient/技术文档-患者前端.md
Normal 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 | 患者前端技术文档
|
||||
Reference in New Issue
Block a user