# 设备同步页面 设计规格
> 来源: mp-device-sync-redesign.html | 平台: 小程序(患者端) | 页面数: 7 | 生成: 2026-05-23
## 页面索引
| 页面 | 截图 | 路由 |
|------|------|------|
| 空闲态 |  | pages/pkg-health/device-sync/index |
| 扫描中 |  | pages/pkg-health/device-sync/index |
| 设备列表 |  | pages/pkg-health/device-sync/index |
| 连接中 |  | pages/pkg-health/device-sync/index |
| 已连接 |  | pages/pkg-health/device-sync/index |
| 同步完成 |  | pages/pkg-health/device-sync/index |
| 错误状态 |  | pages/pkg-health/device-sync/index |
## 一、Token 映射
| 原型值 | 项目 Token | 状态 |
|--------|-----------|------|
| T.pri (#C4623A) | --tk-pri | ✅ |
| T.priL (#F0DDD4) | --tk-pri-l | ✅ |
| T.priD (#8B3E1F) | --tk-pri-d | ✅ |
| T.bg (#F5F0EB) | $bg SCSS 变量 | ⚠️ 无 CSS Token,直接用 $bg |
| T.card (#FFFFFF) | --tk-card-bg ($card) | ✅ |
| T.surface (#EDE8E2) | --tk-card-bg (≈) | ⚠️ 近似,用 $surface-alt SCSS 变量 |
| T.tx (#2D2A26) | $tx SCSS 变量 | ⚠️ 无 CSS Token,直接用 $tx |
| T.tx2 (#5A554F) | $tx2 SCSS 变量 | ⚠️ 无 CSS Token,直接用 $tx2 |
| T.tx3 (#78716C) | --tk-text-secondary ($tx3) | ✅ |
| T.bd (#E8E2DC) | $bd SCSS 变量 | ⚠️ 无 CSS Token,直接用 $bd |
| T.bdL (#F0EBE5) | $bd-l SCSS 变量 | ⚠️ 无 CSS Token |
| T.acc (#5B7A5E) | $acc SCSS 变量 | ⚠️ 无 CSS Token |
| T.accL (#E8F0E8) | $acc-l SCSS 变量 | ⚠️ 无 CSS Token |
| T.wrn (#C4873A) | $wrn SCSS 变量 | ⚠️ 无 CSS Token |
| T.wrnL (#FFF3E0) | $wrn-l SCSS 变量 | ⚠️ 无 CSS Token |
| T.dan (#B54A4A) | $dan SCSS 变量 | ⚠️ 无 CSS Token |
| T.danL (#FDEAEA) | $dan-l SCSS 变量 | ⚠️ 无 CSS Token |
| T.r (16) | --tk-card-radius ($r) | ✅ |
| T.rSm (12) | $r-sm SCSS 变量 | ⚠️ 无 CSS Token |
| T.rXs (8) | $r-xs SCSS 变量 | ⚠️ 无 CSS Token |
| T.serif (Georgia...) | 字体栈 | ❌ 不映射,直接硬编码 |
| T.sans (-apple-system...) | 字体栈 | ❌ 不映射,直接硬编码 |
> 状态标记: ✅ confirmed 直接使用 | ⚠️ pending 需 SCSS 变量 | ❌ unmatched 需硬编码
## 二、页面结构
### 1. 空闲态(idle)

布局层级(从上到下):
- **NavBar** — 深色主色背景,标题"设备同步"
- **Hero 区域** — 主色渐变背景(135deg pri→priD),包含:
- 蓝牙图标(72px 圆形,半透明白底)
- 标题"智能设备同步"(serif 22px 700)
- 副标题(14px 0.75 白色透明度)
- **支持设备** — 三列标签(心率手环/血压计/血糖仪),每个含 SVG 图标
- **上次同步卡片** — ContentCard 样式,左侧绿色勾选图标 + 时间 + 右侧数据量 badge
- **待上传提示** — 黄色背景警告条($wrnL),三角感叹号图标
- **扫描按钮** — 全宽主色按钮,蓝牙图标 + "扫描附近设备"
### 2. 扫描中(scanning)

布局层级:
- **NavBar** — 同上
- **居中脉冲区域**:
- 三层脉冲圆环(CSS animation: pulse-ring),外层→中层→内层递进
- 中心 80px 圆形蓝牙图标($priL 底色)
- **标题** — serif 20px "正在搜索设备..."
- **副文本** — 14px $tx3 提示文字
- **进度条** — 180px 宽,渐变填充 $priL→$pri
- **计时文字** — 12px "已用时 6 秒"
### 3. 设备列表(found)

布局层级:
- **NavBar** — 同上
- **结果头部** — 左侧"发现 N 台设备"标题 + 右侧"重新扫描"链接(含刷新图标)
- **设备卡片列表**(×3)— 每张卡片含:
- 左:44px 圆角方块图标($priL 底色 + 蓝牙 SVG)
- 中:设备名(16px 600)+ 适配器类型(12px $tx3)
- 右:信号强度条(4 级竖条) + 箭头
- **未发现设备提示** — 虚线边框卡片,搜索图标 + 提示文字
### 4. 连接中(connecting)

布局层级:
- **NavBar** — 同上
- **居中动画区域**:
- 100px 旋转环(border-top-color: $pri,CSS animation: connect-spin)
- 60px 中心圆形蓝牙图标
- **标题** — serif 18px "正在连接 {设备名}"
- **副文本** — "正在进行蓝牙配对..."
- **步骤指示器** — 三点一线:发现设备(✓) → 连接中(●脉冲) → 同步数据(○)
### 5. 已连接(connected)

布局层级:
- **NavBar** — 同上
- **连接状态卡片** — 绿色渐变背景(acc→#4A6B4E),蓝牙图标 + 设备名 + "实时" badge
- **最新读数高亮卡片** — 大卡片(r=16 圆角 + shadow),含:
- 52px 心形图标
- 类型+时间小字
- 数值(serif 36px 700)+ 单位
- **历史读数列表** — 标题 + 表格行(类型/数值/时间),每行 12px 分隔线
- **采集计数** — 居中小字
- **操作按钮行** — 左侧全宽"上传数据"主色按钮 + 右侧 52px 红色断开按钮
### 6. 同步完成(done)

布局层级:
- **NavBar** — 同上
- **居中成功区域**:
- 80px 绿色圆形勾选图标
- 标题"同步完成"(serif 24px 700)
- 副文本"数据已安全上传至健康管理平台"
- **三列统计卡片** — 上传条数(5)/数据类型(3)/成功率(100%)
- **完成按钮** — 全宽主色按钮
### 7. 错误状态(error)

布局层级:
- **NavBar** — 同上
- **居中错误区域**:
- 80px 红色圆形叉号图标
- 标题"连接失败"(serif 22px 700)
- 错误描述文字
- **错误详情卡片** — 含错误码/设备/时间三行键值对
- **重试按钮** — 全宽主色按钮,含刷新图标
- **返回按钮** — 描边按钮
## 三、组件映射
| 原型元素 | 推荐组件 | 来源 | 备注 |
|----------|---------|------|------|
| 页面外壳 | PageShell | @components/ui/PageShell | padding="none",NavBar 自带 |
| 连接状态卡片 | ContentCard | @components/ui/ContentCard | variant="elevated",绿色渐变背景自定义 |
| 成功结果卡片 | ContentCard | @components/ui/ContentCard | variant="elevated",居中布局 |
| 错误详情卡片 | ContentCard | @components/ui/ContentCard | variant="outlined" |
| 扫描按钮/上传按钮 | PrimaryButton | @components/ui/PrimaryButton | size="large",full width |
| 断开连接按钮 | — | 自定义 | 红色小方块图标按钮 |
| 返回按钮 | SecondaryButton | @components/ui/SecondaryButton | — |
| 设备类型标签 | — | 自定义 DeviceTypeTag | 小图标+文字,$bdL 边框 |
| 信号强度 | — | 自定义 SignalBars | 4 级竖条 |
| 上次同步信息 | ListItem | @components/ui/ListItem | leftIcon + title + subtitle + extra |
| 历史读数行 | InfoRow | @components/ui/InfoRow | label + value + last |
| 待上传警告 | AlertCard | @components/ui/AlertCard | variant="bordered",黄色 |
> ⚠️ **需新建**: SignalBars — 4 级竖条信号强度指示器(20 行以内小组件)
> ⚠️ **需新建**: DeviceTypeTag — 设备类型标签(图标+文字,已非常简单,可直接内联)
## 四、交互规格
| 元素 | 交互 | 触发 | 反馈 | 备注 |
|------|------|------|------|------|
| 扫描按钮 | 调用 handleScan | onClick | 按钮变灰+loading,状态→scanning | 触发 BLE 扫描 |
| 设备卡片 | 调用 handleConnect | onClick | 状态→connecting,显示旋转动画 | 传递选中的 BLEDevice |
| 重新扫描链接 | 调用 handleScan | onClick | 同扫描按钮 | 刷新设备列表 |
| 上传数据按钮 | 调用 handleSync | onClick | 状态→syncing → done/error | 上传采集数据到后端 |
| 断开连接按钮 | 调用 handleDisconnect | onClick | 断开 BLE,状态→idle | 清空 liveReadings |
| 完成按钮 | handleDisconnect + navigateBack | onClick | 返回上一页 | 如果 returnTo=input 则回填 Storage |
| 重试按钮 | handleScan | onClick | 重新扫描 | 从 error 恢复 |
| 返回按钮 | Taro.navigateBack | onClick | 返回上一页 | 错误状态 |
| 实时数据面板 | 被动更新 | BLE 通知 | 新数据插入列表顶部,数值动画 | useBLEManager hook 驱动 |
## 五、状态变体
- **idle**: 默认状态,展示 Hero + 设备类型 + 上次同步 + 扫描按钮
- **scanning**: 脉冲动画 + 进度条 + 计时,不可操作(无按钮)
- **found**: 设备列表 + 重新扫描链接,点击设备进入 connecting
- **connecting**: 旋转环动画 + 步骤指示器,不可操作
- **connected**: 绿色连接状态卡 + 实时数据面板 + 上传/断开按钮
- **done**: 成功图标 + 统计卡片 + 完成按钮
- **error**: 错误图标 + 错误详情 + 重试/返回按钮
- **syncing**: 复用 scanning 的加载态样式,文字改为"正在上传数据..."
## 六、样式清单
### 关键样式参数
```
/* Hero 渐变 */
background: linear-gradient(135deg, $pri 0%, $pri-d 100%)
padding: 32px 20px 28px
/* 脉冲圆环 */
animation: pulse-ring 2s ease-out infinite
三层: 140px / 110px / 80px (center)
/* 旋转环 */
animation: connect-spin 1s linear infinite
border-top-color: $pri
/* 最新读数数值 */
font-family: $serif; font-size: 36px; font-weight: 700
/* 连接状态卡片渐变 */
background: linear-gradient(135deg, $acc 0%, #4A6B4E 100%)
/* 信号条 */
4 根竖条: height [4, 7, 10, 13]px, width: 3px, gap: 2px
活跃色: $acc, 非活跃: $bd
/* 主按钮 */
background: $pri; border-radius: $r-sm; padding: 16px;
box-shadow: 0 4px 16px rgba(196, 98, 58, 0.3)
```
### 字号映射
| 原型字号 | Token | 用途 |
|---------|-------|------|
| 36px | 超大数值,直接用 serif bold | 最新读数数值 |
| 28px | --tk-font-h1 | 统计卡片数值 |
| 24px | — | 成功/错误标题 |
| 22px | --tk-font-h2 | Hero 标题、连接中标题 |
| 20px | — | 历史读数数值 |
| 18px | --tk-font-body-lg | NavBar 标题、按钮文字 |
| 17px | — | 主按钮文字 |
| 16px | --tk-font-body | 设备名、按钮文字 |
| 15px | — | 完成页副文本 |
| 14px | --tk-font-body-sm | 副文本、描述、列表类型 |
| 13px | --tk-font-cap | 标签文字、小字 |
| 12px | — | 时间、提示 |
---
> 此规格由 design-handoff skill 自动生成。LLM 实施时请:
> 1. 先阅读截图建立视觉印象
> 2. 按 Token 映射表使用项目 Token(✅ 标记的直接用,⚠️ 用 SCSS 变量)
> 3. 优先使用"组件映射"中列出的已有组件
> 4. 参考"交互规格"实现对应的交互逻辑
> 5. "需新建"的组件参考截图和布局描述从头实现