Files
hms/apps/miniprogram/native/pkg-veepoo/index.wxml
iven a86219c8a0 fix(mp): Veepoo M2 BLE 审计 C1-C5/H1-H6 全量修复
CRITICAL 修复:
- C1: 体温测量传 { switch: boolean } 参数 + 停止指令
- C2: uploadReadings 使用正确 NormalizedReading 类型替代 as any
- C3: navigatedRef 防重入避免 React 18 Strict Mode 双触发导航
- C4: WXML gauge 空闲态用 data 预计算值替代 findIndex+匿名函数
- C5: _onReady 清除 _authTimeout 防止 Timer 泄漏

HIGH 修复:
- H1: WXML 用 results[type] 替代未声明的 measureStates
- H2: handleConnect 添加 _connecting 防重入保护
- H4: 连接回调兼容 errno:0 / errCode:0 fallback
- H5: _formatValues 零值合法显示(!== undefined && !== null)

MEDIUM:
- Storage key 添加 hms: 命名空间前缀防冲突
2026-05-30 13:11:49 +08:00

134 lines
5.5 KiB
Plaintext

<!--
Veepoo M2 原生小程序页面 — 连接 + 测量
完全匹配 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-secondary" 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'}}">
<view class="measure-page">
<!-- 设备状态栏 -->
<view class="header">
<view class="header-device">
<view class="header-dot header-dot--on"></view>
<text class="header-name">{{deviceName}}</text>
<text wx:if="{{batteryLevel !== null}}" class="header-battery">{{batteryLevel}}%</text>
</view>
<text class="header-disconnect" bindtap="handleDisconnect">断开</text>
</view>
<!-- 指标选择器 — H1 修复:用 results[type] 替代 measureStates -->
<view class="selector">
<view
wx:for="{{measureTypes}}"
wx:key="type"
class="selector-item {{selectedType === item.type ? 'selector-item--active' : ''}} {{results[item.type] ? 'selector-item--done' : ''}}"
data-type="{{item.type}}"
bindtap="handleSelectType"
>
<text class="selector-icon" style="color: {{item.color}}">{{item.icon}}</text>
<text class="selector-label">{{item.label}}</text>
<view wx:if="{{results[item.type]}}" class="selector-check" style="background-color: {{item.color}}">✓</view>
</view>
</view>
<!-- 仪表盘区域 — C4 修复:用 data 中预计算的 selectedIcon/selectedColor -->
<view class="gauge">
<view class="gauge-circle">
<!-- 空闲 -->
<block wx:if="{{measurePhase === 'idle'}}">
<text class="gauge-icon" style="color: {{selectedColor}}">{{selectedIcon}}</text>
<text class="gauge-hint">点击下方按钮开始测量{{selectedLabel}}</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: #22C55E">{{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 wx:if="{{measurePhase === 'measuring' && measureProgress > 0}}" class="gauge-progress-bar">
<view class="gauge-progress-fill" style="width: {{measureProgress}}%"></view>
</view>
</view>
<!-- 免责声明 -->
<view class="disclaimer">
<text class="disclaimer-text">本数据由智能手环采集,仅供健康趋势参考,不作为医疗诊断依据</text>
</view>
<!-- 操作按钮 -->
<view class="actions">
<block wx:if="{{measurePhase === 'idle'}}">
<view class="btn-primary btn-large" bindtap="handleStartMeasure">开始测量{{selectedLabel}}</view>
</block>
<block wx:elif="{{measurePhase === 'measuring'}}">
<view class="btn-secondary btn-large" bindtap="handleCancelMeasure">停止测量</view>
</block>
<block wx:elif="{{measurePhase === 'success'}}">
<view class="actions-row">
<view class="btn-secondary" bindtap="handleResetResult">重新测量</view>
<view class="btn-primary" bindtap="handleBack">完成并返回</view>
</view>
</block>
<block wx:elif="{{measurePhase === 'error'}}">
<view class="btn-primary btn-large" bindtap="handleStartMeasure">重新测量</view>
</block>
</view>
</view>
</block>