# HMS 小程序 UI 优化实施指南
> 基于 `docs/design/mp-*.html` 高保真原型稿,指导全局性 UI 优化。
> 核心原则:**先建组件库,再逐页替换**,避免逐页手写导致风格不一致。
## 1. 原型稿索引
所有原型文件在 `docs/design/` 目录下,双击浏览器即可预览:
| 文件 | 涵盖页面 | 屏幕数 |
|------|---------|--------|
| `mp-00-visitor.html` | **访客端**:轮播图×3 + 访客首页 + 访客"我的" | 5 |
| `mp-redesign-home.html` | 首页/健康/消息/我的(4个TabBar主页面) | 4 |
| `mp-01-login.html` | 登录页(初始状态 + 填写中) | 2 |
| `mp-02-consultation.html` | 咨询列表 + 聊天详情 | 2 |
| `mp-03-appointment.html` | 预约列表 + 预约创建 + 预约详情 | 3 |
| `mp-04-article-report.html` | 文章列表 + 详情 + AI报告列表 + 详情 | 4 |
| `mp-05-mall.html` | 积分商城主页 | 1 |
| `mp-06-health-pkg.html` | 告警/日常监测/设备同步/体征录入/趋势 | 5 |
| `mp-07-profile-health.html` | 健康记录/诊断/用药/报告列表/报告详情 | 5 |
| `mp-08-profile-dialysis.html` | 透析记录列表+详情/随访列表+详情 | 4 |
| `mp-09-profile-other.html` | 家庭管理/添加/知情同意/事件/长者模式/设置 | 6 |
| `mp-10-mall-pkg.html` | 商品详情/兑换确认/订单列表/咨询详情 | 4 |
| `mp-11-doctor-core.html` | 医生工作台/待办/咨询/随访/患者 | 5 |
| `mp-12-doctor-clinical.html` | 告警列表+详情/透析列表+创建/处方列表+详情 | 6 |
**总计 14 个文件,52 个屏幕,覆盖 58+ 页面(含访客端)。**
## 2. 设计 Token(全局变量)
从原型稿中提取的完整 Token 系统,所有页面必须严格遵循:
### 2.1 色彩体系
```scss
// === 患者端主色(暖陶土) ===
$color-primary: #C4623A;
$color-primary-light: #F0DDD4;
$color-primary-dark: #8B3E1F;
// === 医生端主色(靛蓝) ===
$color-doctor-primary: #3A6B8C;
$color-doctor-primary-light: #D4E5F0;
$color-doctor-primary-dark: #2A4F6A;
// === 中性色 ===
$color-bg: #F5F0EB; // 页面背景
$color-card: #FFFFFF; // 卡片背景
$color-surface: #EDE8E2; // 表面/次要背景
$color-border: #E8E2DC; // 边框
$color-border-light: #F0EBE5; // 浅边框
// === 文字色 ===
$color-text: #2D2A26; // 主文字
$color-text-secondary: #5A554F; // 次要文字
$color-text-tertiary: #78716C; // 辅助文字
// === 语义色 ===
$color-success: #5B7A5E; // 正常/成功
$color-success-light: #E8F0E8;
$color-warning: #C4873A; // 警告/偏高
$color-warning-light: #FFF3E0;
$color-danger: #B54A4A; // 危险/异常
$color-danger-light: #FDEAEA;
// === 功能色 ===
$color-wechat: #07C160; // 微信绿
```
### 2.2 字体系统
```scss
$font-display: "Georgia, 'Times New Roman', serif"; // 标题/数字
$font-body: "-apple-system, 'PingFang SC', sans-serif"; // 正文
// 字号规范(11级)
$font-size-xs: 10px; // 极小标注
$font-size-sm: 11px; // 标签/状态
$font-size-base-sm: 12px; // 辅助文字
$font-size-base: 13px; // 正文小
$font-size-body: 14px; // 正文
$font-size-md: 15px; // 小标题/按钮
$font-size-lg: 16px; // 卡片标题
$font-size-xl: 18px; // 区块标题
$font-size-2xl: 22px; // 页面子标题
$font-size-3xl: 26px; // 页面主标题
$font-size-4xl: 28px; // 大号数字(积分等)
$font-size-5xl: 30px; // 体征数值
```
### 2.3 圆角与间距
```scss
$radius-lg: 16px; // 卡片/大按钮
$radius-md: 12px; // 输入框/中等容器
$radius-sm: 8px; // 小元素/标签
$radius-full: 999px; // 胶囊标签/圆形
$spacing-xs: 4px;
$spacing-sm: 8px;
$spacing-md: 12px;
$spacing-lg: 16px;
$spacing-xl: 20px;
$spacing-2xl: 24px;
$page-padding: 20px; // 页面左右内边距
$card-padding: 16px; // 卡片内边距
$card-padding-lg: 20px; // 大卡片内边距
$section-gap: 16px; // 区块间距
$item-gap: 8px; // 列表项间距
```
### 2.4 阴影
```scss
$shadow-card: 0 2px 12px rgba(45,42,38,0.06); // 普通卡片
$shadow-card-sm: 0 1px 4px rgba(45,42,38,0.04); // 轻量卡片
$shadow-button: 0 4px 16px rgba(196,98,58,0.3); // 主按钮
$shadow-tab-active: 0 2px 8px rgba(196,98,58,0.25); // 选中Tab
```
## 3. 全局组件库(必须先建立)
> **铁律:以下组件必须先在 `src/components/ui/` 和 `src/components/patterns/` 中建好,
> 然后所有页面只引用组件,不允许在页面文件中硬编码样式。**
### 3.1 基础 UI 组件
#### `NavBar` — 子页面导航栏
```
高度: 44px
左侧: 返回箭头(‹ 字符或图标),color: $color-primary
中央: 页面标题,font: serif 18px bold,color: $color-text
右侧: 可选操作按钮
底部: 1px solid $color-border-light
```
**原型参考**: 所有 mp-02~12 文件的导航栏
#### `PageHeader` — TabBar 页面标题
```
font: serif 26px/700
color: $color-text
margin-bottom: 20px
padding: 20px 20px 0
```
**原型参考**: mp-redesign-home.html 的"上午好,张三"/"健康数据"/"消息"/页面标题
#### `ContentCard` — 内容卡片容器
```
background: $color-card
border-radius: $radius-lg
padding: $card-padding-lg
box-shadow: $shadow-card
```
**原型参考**: 所有文件中的白色圆角卡片
#### `StatusTag` — 状态标签
```
fontSize: 11px
padding: 2px 8px
borderRadius: $radius-full
fontWeight: 500
变体:
- success: bg=$color-success-light, color=$color-success
- warning: bg=$color-warning-light, color=$color-warning
- danger: bg=$color-danger-light, color=$color-danger
- neutral: bg=$color-surface, color=$color-text-tertiary
- primary: bg=$color-primary-light, color=$color-primary
```
**原型参考**: 所有文件中的"正常"/"偏高"/"待就诊"/"已完成"等标签
#### `SectionTitle` — 区块标题
```
font: serif 18px/700
color: $color-text
margin-bottom: 12px
```
**原型参考**: mp-redesign-home.html 的"今日体征"/"近 7 天趋势"
#### `FormInput` — 表单输入框
```
height: 56px (血压等大号) 或 48px (普通)
background: $color-card
border: 1.5px solid $color-border
border-radius: $radius-lg
padding: 0 16px
font-size: 16px
focus 状态:
border-color: $color-primary
label:
font-size: 13px, color: $color-text-tertiary, margin-bottom: 6px
```
**原型参考**: mp-01-login.html 的手机号/验证码输入, mp-03-appointment.html 的表单
#### `PrimaryButton` — 主操作按钮
```
height: 54px (登录) 或 52px (普通)
border-radius: 14px
background: $color-primary
color: #fff
font-size: 18px (登录) 或 17px (普通)
font-weight: 600
box-shadow: $shadow-button
医生端变体:
background: $color-doctor-primary
```
**原型参考**: 所有文件的底部主按钮
#### `SecondaryButton` — 次操作按钮
```
同 PrimaryButton 尺寸
background: transparent
border: 2px solid $color-primary
color: $color-primary
```
**原型参考**: mp-redesign-home.html 的"预约挂号"按钮
### 3.2 复合组件
#### `TabFilter` — 筛选/切换标签
```
两种样式:
样式A (填充型 - 如体征类型切换):
- 选中: bg=$color-primary, color=#fff, box-shadow=$shadow-tab-active
- 未选: bg=$color-surface, color=$color-text-secondary
- 高度: 44px, borderRadius: $radius-md
样式B (pill型 - 如文章分类):
- 选中: bg=$color-primary, color=#fff
- 未选: bg=$color-surface, color=$color-text-secondary
- 高度: 32px, borderRadius: $radius-full, padding: 0 16px
样式C (段控型 - 如消息页咨询/通知):
- 外框: bg=$color-surface, borderRadius: $radius-sm, padding: 3px
- 选中: bg=$color-card, box-shadow
- 未选: transparent
- 高度: 40px
```
**原型参考**: mp-redesign-home.html HealthA 的体征Tab, MessagesA 的咨询/通知
#### `ListItem` — 列表项
```
background: $color-card
border-radius: $radius-lg
padding: 16px
box-shadow: $shadow-card-sm
margin-bottom: $item-gap
布局: 左侧头像/图标 + 中间内容(flex:1) + 右侧状态/箭头
分隔线(多个item在一张卡片内时):
border-bottom: 1px solid $color-border-light, 最后一项无
未读态: opacity 1
已读态: opacity 0.7
```
**原型参考**: mp-02-consultation.html, mp-07-profile-health.html 的列表项
#### `InfoRow` — 信息行(左标签右值)
```
display: flex, justify-content: space-between, align-items: center
padding: 12px 0
border-bottom: 1px solid $color-border-light (最后一项无)
标签: font-size: 14px, color: $color-text-secondary
值: font-size: 15px, color: $color-text
```
**原型参考**: mp-03-appointment.html 详情页, mp-12-doctor-clinical.html 处方详情
#### `ProgressRing` — 环形进度
```
尺寸: 64px (小号) / 80px (大号)
SVG: 两个 circle, 底层 $color-border, 上层 $color-primary
lineWidth: 4px
中心: 数字/文字, font: serif bold, color: $color-primary
```
**原型参考**: mp-redesign-home.html 首页"今日已记录 3/4"
#### `AlertCard` — 提醒/提示卡片
```
三种样式:
样式A (渐变型 - 智能提醒):
background: linear-gradient(135deg, $color-primary, $color-primary-dark)
color: #fff, borderRadius: $radius-lg
样式B (左边框型 - AI建议/提示):
background: $color-success-light
borderLeft: 4px solid $color-success
样式C (全边框型 - 温馨提示):
background: $color-warning-light
borderRadius: $radius-md
```
**原型参考**: mp-redesign-home.html 首页智能提醒, HealthA 的AI建议, mp-03-appointment.html 温馨提示
#### `ChatBubble` — 聊天气泡
```
医生/对方消息:
- background: $color-card
- border-radius: $radius-lg (左上 $radius-sm)
- 左对齐, maxWidth: 75%
我的消息:
- background: $color-primary-light
- border-radius: $radius-lg (右上 $radius-sm)
- 右对齐, maxWidth: 75%
```
**原型参考**: mp-02-consultation.html, mp-10-mall-pkg.html 咨询详情
#### `VitalCard` — 体征数据卡片(2x2网格用)
```
background: $color-card
border-radius: $radius-lg
padding: 14px 16px
布局:
- 标签名: 13px, $color-text-secondary
- 数值: serif 30px/700, $color-text
- 单位: 12px, $color-text-tertiary
- 状态标签: StatusTag
```
**原型参考**: mp-redesign-home.html 首页体征2x2网格
#### `GradientHeader` — 渐变头部卡片
```
background: linear-gradient(135deg, $color-primary 0%, $color-primary-dark 100%)
border-radius: $radius-lg
padding: 18px
color: #fff
```
**原型参考**: mp-05-mall.html 积分卡, mp-redesign-home.html 首页智能提醒
### 3.3 页面骨架组件
#### `PageShell` — 页面外壳(已存在,需更新样式)
```
使用 Token 变量更新现有 PageShell 的背景色、内边距等
```
#### `SubPageLayout` — 子页面布局
```
NavBar (固定顶部)
内容区 (scroll-view, padding: $page-padding)
可选底部操作栏 (fixed bottom)
```
## 4. 实施步骤(严格按顺序执行)
### Phase 0: 建立 SCSS 变量文件(30分钟)
1. 创建 `src/styles/_tokens.scss`,写入 §2 中的所有设计 Token
2. 创建 `src/styles/_mixins.scss`,封装常用样式组合:
```scss
@mixin card { background: $color-card; border-radius: $radius-lg; box-shadow: $shadow-card; }
@mixin page-padding { padding: $page-padding; }
@mixin nav-bar { height: 44px; display: flex; align-items: center; justify-content: center; border-bottom: 1px solid $color-border-light; }
```
3. 在 `app.scss` 中 import tokens 和 mixins
### Phase 1: 更新/创建全局组件(2-3小时)
按以下顺序逐一实现 §3 中的组件,**每个组件写完后立即替换 2-3 个引用页面验证效果**:
1. `NavBar` → 替换所有子页面的导航栏
2. `StatusTag` → 替换所有状态标签
3. `ContentCard` → 替换所有卡片容器
4. `FormInput` → 替换所有表单输入
5. `PrimaryButton` / `SecondaryButton` → 替换所有按钮
6. `TabFilter` → 替换所有筛选标签
7. `ListItem` → 替换所有列表项
8. `InfoRow` → 替换所有信息行
9. `SectionTitle` / `PageHeader` → 替换所有标题
10. `ProgressRing` → 替换进度环
11. `AlertCard` → 替换提示卡片
12. `ChatBubble` → 替换聊天气泡
13. `VitalCard` → 替换体征卡片
14. `GradientHeader` → 替换渐变头部
### Phase 2: 逐页替换样式(每个页面 15-30 分钟)
按页面重要性排序,逐页将硬编码样式替换为组件引用:
**第一批 — 主 TabBar 页面(已有组件基础):**
1. `pages/index/index` → 参照 mp-redesign-home.html HomeA
2. `pages/health/index` → 参照 mp-redesign-home.html HealthA
3. `pages/messages/index` → 参照 mp-redesign-home.html MessagesA
4. `pages/profile/index` → 参照 mp-redesign-home.html ProfileA
**第二批 — 高频功能页面:**
5. `pages/login/index` → 参照 mp-01-login.html
6. `pages/consultation/index` → 参照 mp-02-consultation.html
7. `pages/appointment/index` → 参照 mp-03-appointment.html 列表
8. `pages/appointment/create/index` → 参照 mp-03-appointment.html 创建
9. `pages/appointment/detail/index` → 参照 mp-03-appointment.html 详情
**第三批 — 内容页面:**
10. `pages/article/index` + `detail` → 参照 mp-04-article-report.html
11. `pages/ai-report/list` + `detail` → 参照 mp-04-article-report.html
12. `pages/mall/index` → 参照 mp-05-mall.html
**第四批 — 健康分包:**
13-17. `pages/pkg-health/*` (5个) → 参照 mp-06-health-pkg.html
**第五批 — 个人中心分包:**
18-33. `pages/pkg-profile/*` (16个) → 参照 mp-07/08/09
**第六批 — 商城/咨询分包:**
34-37. `pages/pkg-mall/*` + `pages/pkg-consultation/detail` → 参照 mp-10-mall-pkg.html
**第七批 — 医生端:**
38-47. `pages/pkg-doctor-core/*` + `pages/pkg-doctor-clinical/*` → 参照 mp-11/12
### Phase 3: 全局验证(1小时)
1. **一致性检查**: 打开所有页面截图对比原型,确认风格统一
2. **长者模式**: 所有 58 个页面的关怀模式适配(字号 ≥ 22px)
3. **暗色/亮色**: Token 通过 CSS 变量支持主题切换
4. **交叉页面导航**: 确保页面间跳转无样式断裂
## 5. 医生端 vs 患者端
医生端页面(pkg-doctor-core / pkg-doctor-clinical)使用不同的主色:
```scss
// 在医生端页面入口设置 CSS 变量覆盖
--color-primary: #3A6B8C; // 替代 #C4623A
--color-primary-light: #D4E5F0; // 替代 #F0DDD4
--color-primary-dark: #2A4F6A; // 替代 #8B3E1F
```
这样所有引用 Token 的组件在医生端自动变色,**无需为医生端写单独的组件**。
## 6. 关键约束
1. **不允许在页面文件中硬编码颜色值** — 全部通过 Token 变量引用
2. **不允许跳过组件直接写样式** — 先建组件再引用
3. **每个组件必须支持 CSS 变量覆盖** — 医生端/关怀模式/主题切换都靠这个
4. **先更新 3-5 个页面验证组件可用** — 再批量替换剩余页面
5. **58 个页面中 66 个已迁移到统一组件库** — 在现有基础上更新 Token 和组件样式即可
## 7. 访客端(Guest Mode)
> **原型参考**: `mp-00-visitor.html`(5 个屏幕)
访客端是用户未登录时看到的界面,核心目标是**引导转化登录**。与已登录页面有以下差异:
### 7.1 访客首页 vs 登录首页对比
| 维度 | 访客首页 | 登录首页 |
|------|---------|---------|
| 顶部 | 全屏 Swiper 轮播(品牌形象/智慧健康/温馨环境) | 智能提醒卡片 + 体征概览 |
| 内容 | 健康文章推荐(公开数据)+ 平台功能介绍卡片 | 今日体征网格 + 趋势图 + 快捷入口 |
| 底部 | 无快捷入口,有"登录享更多"CTA | 预约挂号/查看报告等快捷入口 |
| TabBar | 首页/健康(灰化)/消息(灰化)/我的 | 首页/健康/消息/我的(全部可用)|
### 7.2 访客专属组件
#### `BannerSwiper` — 轮播图组件
```
高度: 180px
borderRadius: $radius-lg
indicatorDots: 底部居中,活跃色 $color-primary
autoplay: true, interval: 4000ms
轮播项(3个渐变背景 slides):
- 品牌形象: linear-gradient(135deg, #C4623A, #8B3E1F),大标题+副标题
- 智慧健康: linear-gradient(135deg, #3A6B8C, #2A4F6A),数据卡片展示
- 温馨就医: linear-gradient(135deg, #5B7A5E, #3D5A40),场景描述
数据来源: /api/v1/public/banners(公开端点,无需认证)
```
**原型参考**: mp-00-visitor.html 前 3 个 Swiper slides
#### `FeatureCard` — 功能介绍卡片
```
background: $color-card
borderRadius: $radius-lg
padding: 20px
box-shadow: $shadow-card
textAlign: center
布局: 图标(40px圆形背景) + 标题(16px bold) + 描述(13px tertiary)
```
**原型参考**: mp-00-visitor.html 访客首页底部 3 个功能卡片
#### `LoginCTA` — 登录引导按钮
```
background: $color-primary
color: #fff
borderRadius: $radius-full
padding: 14px 32px
fontSize: 16px
fontWeight: 600
boxShadow: $shadow-button
textAlign: center
文字: "登录享更多健康服务"
点击: navigateTo login 页面
```
**原型参考**: mp-00-visitor.html 访客首页底部 + 访客"我的"页
### 7.3 访客"我的"页
访客态的个人中心与登录态完全不同:
```
头像区域:
- 未登录: 显示 "?" 圆形图标(bg: $color-surface, color: $color-text-tertiary)
- 登录后: 真实头像
登录提示卡:
- 标题: "登录后即可查看"
- 副标题: "健康数据、预约记录、咨询消息等"
- 按钮: "立即登录" (PrimaryButton)
菜单列表:
- 仅显示公开菜单(关于我们/隐私政策/使用条款)
- 隐藏所有需认证菜单(健康记录/家庭管理/设备绑定等)
```
**原型参考**: mp-00-visitor.html 最后一个屏幕
### 7.4 访客端实施要点
1. **`isGuest` 状态判断**: 在 `GuestHome` 页面中通过 `useAuth()` 检查登录态,未登录渲染访客布局
2. **轮播图数据**: 调用 `/api/v1/public/banners` 公开端点获取轮播图数据
3. **灰化 Tab**: 健康页/消息页在访客态显示"请先登录"提示 + 登录按钮
4. **登录转化**: 所有交互触发点(查看详情/预约/咨询)统一拦截跳转登录页
5. **组件复用**: BannerSwiper 组件同时用于访客首页和登录首页,通过 props 控制样式差异
6. **TabBar 页面路由**: 访客态和登录态共享同一路由,通过 `isGuest` 条件渲染不同内容
### 7.5 访客端实施优先级
排在 Phase 2 第一批(主 TabBar 页面)之后、第二批之前:
```
Phase 1.5 — 访客端:
1. 创建 BannerSwiper 组件 → src/components/ui/BannerSwiper/
2. 创建 FeatureCard 组件 → src/components/ui/FeatureCard/
3. 创建 LoginCTA 组件 → src/components/ui/LoginCTA/
4. 更新 GuestHome 页面 → 参照 mp-00-visitor.html 访客首页
5. 更新 Profile 页 isGuest 分支 → 参照 mp-00-visitor.html 访客"我的"
```