- 连接认证成功后自动依次测量心率→血氧→血压→体温→压力 - 列表式进度UI展示每项指标状态(等待/测量中/完成/跳过) - 总进度条百分比实时更新 - 测量完成后保存结果并显示'查看结果并返回'按钮 - 支持取消自动测量,已测得的数据不丢失 - 修复仪表盘中心区域缺少背景色导致数值与底色混淆不可见
216 lines
9.7 KiB
Plaintext
216 lines
9.7 KiB
Plaintext
<!--
|
|
Veepoo M2 原生小程序页面 — 连接 + 测量
|
|
设计原型: docs/design/veepoo-measure-prototype.html
|
|
完全匹配 SDK 官方 Demo 流程,不依赖 Taro
|
|
-->
|
|
|
|
<!-- ═══ 未连接 / 错误 / 断开 ═══ -->
|
|
<block wx:if="{{phase === 'idle' || phase === 'error' || phase === 'disconnected'}}">
|
|
<view class="connect-screen">
|
|
<view class="connect-anim">
|
|
<view class="connect-ring"></view>
|
|
<view class="connect-center">
|
|
<text class="connect-bt">BT</text>
|
|
</view>
|
|
</view>
|
|
<text class="connect-title">M2 手环健康测量</text>
|
|
<text class="connect-hint">请确保手环已开机且蓝牙已开启</text>
|
|
|
|
<view wx:if="{{error}}" class="connect-error">
|
|
<text class="connect-error-text">{{error}}</text>
|
|
</view>
|
|
|
|
<view class="connect-btn-wrap">
|
|
<view class="btn-primary" bindtap="handleConnect">
|
|
{{phase === 'error' ? '重新连接' : phase === 'disconnected' ? '重新连接' : '连接 M2 手环'}}
|
|
</view>
|
|
</view>
|
|
|
|
<view wx:if="{{hasResults}}" class="connect-back">
|
|
<view class="btn-text" bindtap="handleBack">查看测量结果并返回</view>
|
|
</view>
|
|
</view>
|
|
</block>
|
|
|
|
<!-- ═══ 连接中(扫描/连接/认证) ═══ -->
|
|
<block wx:elif="{{phase === 'scanning' || phase === 'connecting' || phase === 'authenticating'}}">
|
|
<view class="connect-screen">
|
|
<view class="connect-anim">
|
|
<view class="connect-ring connect-ring--active"></view>
|
|
<view class="connect-center">
|
|
<text class="connect-bt">BT</text>
|
|
</view>
|
|
</view>
|
|
<text class="connect-title">
|
|
{{phase === 'scanning' ? '正在搜索 M2 手环...' : phase === 'connecting' ? '正在连接...' : '正在认证...'}}
|
|
</text>
|
|
<text class="connect-hint">请确保手环已开机且靠近手机</text>
|
|
</view>
|
|
</block>
|
|
|
|
<!-- ═══ 自动测量中 / 自动测量完成 ═══ -->
|
|
<block wx:elif="{{phase === 'ready' && (autoMeasuring || autoMeasureDone)}}">
|
|
<view class="measure-page">
|
|
<!-- 设备状态栏 -->
|
|
<view class="device-bar">
|
|
<view class="device-bar__left">
|
|
<view class="device-bar__dot"></view>
|
|
<text class="device-bar__name">{{deviceName}}</text>
|
|
<text wx:if="{{batteryLevel !== null}}" class="device-bar__battery">{{batteryLevel}}%</text>
|
|
</view>
|
|
<view wx:if="{{autoMeasuring}}" class="device-bar__disconnect" bindtap="handleCancelAutoMeasure">取消</view>
|
|
</view>
|
|
|
|
<view class="auto-measure">
|
|
<!-- 标题 -->
|
|
<view class="auto-measure__header">
|
|
<text class="auto-measure__title">{{autoMeasureDone ? '✓ 测量完成!' : '正在自动测量...'}}</text>
|
|
<text wx:if="{{!autoMeasureDone}}" class="auto-measure__subtitle">请保持手环佩戴,无需任何操作</text>
|
|
</view>
|
|
|
|
<!-- 指标列表 -->
|
|
<view class="auto-measure__list">
|
|
<view
|
|
wx:for="{{measureTypes}}"
|
|
wx:key="type"
|
|
class="auto-item {{autoMeasureStatus[item.type] === 'done' ? 'auto-item--done' : autoMeasureStatus[item.type] === 'measuring' ? 'auto-item--active' : autoMeasureStatus[item.type] === 'error' ? 'auto-item--error' : ''}}"
|
|
>
|
|
<view class="auto-item__left">
|
|
<view class="auto-item__icon-wrap" style="background: {{autoMeasureStatus[item.type] === 'done' ? item.color : autoMeasureStatus[item.type] === 'error' ? '#ccc' : item.color}}">
|
|
<text class="auto-item__icon">{{autoMeasureStatus[item.type] === 'done' ? '✓' : autoMeasureStatus[item.type] === 'error' ? '✕' : item.icon}}</text>
|
|
</view>
|
|
<text class="auto-item__label">{{item.label}}</text>
|
|
</view>
|
|
<view class="auto-item__right">
|
|
<block wx:if="{{autoMeasureStatus[item.type] === 'done'}}">
|
|
<text class="auto-item__value" style="color: {{item.color}}">{{autoMeasureValues[item.type]}}</text>
|
|
<text wx:if="{{item.unit}}" class="auto-item__unit">{{item.unit}}</text>
|
|
</block>
|
|
<text wx:elif="{{autoMeasureStatus[item.type] === 'measuring'}}" class="auto-item__status auto-item__status--active">测量中...</text>
|
|
<text wx:elif="{{autoMeasureStatus[item.type] === 'error'}}" class="auto-item__status auto-item__status--error">已跳过</text>
|
|
<text wx:else class="auto-item__status">等待中</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 进度条 -->
|
|
<view class="auto-progress">
|
|
<view class="auto-progress__bar">
|
|
<view class="auto-progress__fill" style="width: {{autoMeasureProgress}}%"></view>
|
|
</view>
|
|
<text class="auto-progress__text">{{autoMeasureProgress}}%</text>
|
|
</view>
|
|
|
|
<!-- 免责声明 -->
|
|
<view class="disclaimer">
|
|
<text class="disclaimer__text">测量数据仅供参考,不作为医学诊断依据。如有不适请及时就医。</text>
|
|
</view>
|
|
|
|
<!-- 操作按钮 -->
|
|
<view class="actions">
|
|
<block wx:if="{{autoMeasureDone}}">
|
|
<view class="btn btn--primary" bindtap="handleBack">查看结果并返回</view>
|
|
</block>
|
|
<block wx:elif="{{autoMeasuring}}">
|
|
<view class="btn btn--text" bindtap="handleCancelAutoMeasure">取消自动测量</view>
|
|
</block>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</block>
|
|
|
|
<!-- ═══ 就绪 + 手动测量 ═══ -->
|
|
<block wx:elif="{{phase === 'ready'}}">
|
|
<view class="measure-page">
|
|
<!-- 设备状态栏 -->
|
|
<view class="device-bar">
|
|
<view class="device-bar__left">
|
|
<view class="device-bar__dot"></view>
|
|
<text class="device-bar__name">{{deviceName}}</text>
|
|
<text wx:if="{{batteryLevel !== null}}" class="device-bar__battery">{{batteryLevel}}%</text>
|
|
</view>
|
|
<view class="device-bar__disconnect" bindtap="handleDisconnect">断开</view>
|
|
</view>
|
|
|
|
<!-- 指标选择器 — 药丸式 -->
|
|
<scroll-view class="selector" scroll-x enhanced show-scrollbar="{{false}}">
|
|
<view
|
|
wx:for="{{measureTypes}}"
|
|
wx:key="type"
|
|
class="selector__pill {{selectedType === item.type ? 'selector__pill--active' : ''}} {{results[item.type] ? 'selector__pill--done' : ''}}"
|
|
data-type="{{item.type}}"
|
|
bindtap="handleSelectType"
|
|
>
|
|
<view class="selector__icon-wrap" style="background: {{item.color}}">
|
|
<text class="selector__icon">{{item.icon}}</text>
|
|
</view>
|
|
<text class="selector__label">{{item.label}}</text>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 仪表盘区域 -->
|
|
<view class="gauge-section">
|
|
<view class="gauge {{measurePhase === 'measuring' ? 'gauge--measuring' : ''}}">
|
|
<!-- SVG 圆环 -->
|
|
<view class="gauge__ring-wrap">
|
|
<view class="gauge__ring-bg"></view>
|
|
<view class="gauge__ring-progress" style="background: conic-gradient({{selectedColor}} {{measureProgress * 3.6}}deg, #E8E2DC 0deg);"></view>
|
|
<view class="gauge__center">
|
|
<!-- 空闲 -->
|
|
<block wx:if="{{measurePhase === 'idle'}}">
|
|
<text class="gauge__icon-lg" style="color: {{selectedColor}}">{{selectedIcon}}</text>
|
|
<text class="gauge__hint">点击下方按钮开始</text>
|
|
</block>
|
|
<!-- 测量中 -->
|
|
<block wx:elif="{{measurePhase === 'measuring'}}">
|
|
<text wx:if="{{measureDisplayValue}}" class="gauge__value" style="color: {{selectedColor}}">{{measureDisplayValue}}</text>
|
|
<text wx:else class="gauge__loading">测量中...</text>
|
|
<text wx:if="{{measureDisplayValue}}" class="gauge__unit">{{selectedUnit}}</text>
|
|
</block>
|
|
<!-- 成功 -->
|
|
<block wx:elif="{{measurePhase === 'success'}}">
|
|
<text class="gauge__value" style="color: {{selectedColor}}">{{measureDisplayValue}}</text>
|
|
<text class="gauge__unit">{{selectedUnit}}</text>
|
|
</block>
|
|
<!-- 错误 -->
|
|
<block wx:elif="{{measurePhase === 'error'}}">
|
|
<text class="gauge__err">!</text>
|
|
<text class="gauge__err-text">{{measureError}}</text>
|
|
</block>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 进度条 -->
|
|
<view wx:if="{{measurePhase === 'measuring' && measureProgress > 0}}" class="progress-bar">
|
|
<view class="progress-bar__fill" style="width: {{measureProgress}}%; background: {{selectedColor}};"></view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 免责声明 -->
|
|
<view class="disclaimer">
|
|
<text class="disclaimer__text">测量数据仅供参考,不作为医学诊断依据。如有不适请及时就医。</text>
|
|
</view>
|
|
|
|
<!-- 操作按钮 -->
|
|
<view class="actions">
|
|
<block wx:if="{{measurePhase === 'idle'}}">
|
|
<view class="btn btn--primary" style="background: {{selectedColor}}; box-shadow: 0 4px 16px rgba(0,0,0,0.15);" bindtap="handleStartMeasure">
|
|
开始测量{{selectedLabel}}
|
|
</view>
|
|
</block>
|
|
<block wx:elif="{{measurePhase === 'measuring'}}">
|
|
<view class="btn btn--secondary" bindtap="handleCancelMeasure">停止测量</view>
|
|
<view class="btn btn--text" bindtap="handleBack">完成并查看结果</view>
|
|
</block>
|
|
<block wx:elif="{{measurePhase === 'success'}}">
|
|
<view class="btn btn--primary" style="background: {{selectedColor}}; box-shadow: 0 4px 16px rgba(0,0,0,0.15);" bindtap="handleResetResult">重新测量</view>
|
|
<view class="btn btn--secondary" bindtap="handleBack">完成并查看结果</view>
|
|
</block>
|
|
<block wx:elif="{{measurePhase === 'error'}}">
|
|
<view class="btn btn--primary" style="background: {{selectedColor}}; box-shadow: 0 4px 16px rgba(0,0,0,0.15);" bindtap="handleStartMeasure">重新测量</view>
|
|
</block>
|
|
</view>
|
|
</view>
|
|
</block>
|