fix(mp): 数据监听器改为 onLoad 全局注册一次
重构原生页面: - 数据监听器和连接状态监听器在 onLoad 中全局注册一次 - _listenersRegistered 防止重复注册 - 连接流程不再注册监听器,只处理连接+认证 - 增加关键节点诊断日志(SDK函数类型、连接阶段、认证调用) - 连接回调简化为只匹配 connection:true 注意:需要清除 dist/ 后完整重建(dev 模式不监听 native/ 变更)
This commit is contained in:
@@ -2,10 +2,11 @@
|
||||
* Veepoo M2 原生小程序页面 — 连接 + 测量
|
||||
*
|
||||
* 完全脱离 Taro 框架,直接使用微信原生 API + Veepoo SDK。
|
||||
* 连接流程严格对齐官方 Demo:
|
||||
* scan → stopScan → connect(callback, 等待 connection:true)
|
||||
* → registerDataListener → delay 500ms → authenticate
|
||||
* → 轮询 deviceChipStatus → ready
|
||||
* 流程严格对齐官方 Demo:
|
||||
* onLoad 注册全局监听器
|
||||
* → scan → stopScan → connect(等待 connection:true)
|
||||
* → delay 500ms → authenticate
|
||||
* → SDK 事件(type=1) / Storage 轮询 → ready
|
||||
*/
|
||||
// eslint-disable-next-line no-undef
|
||||
const { veepooBle, veepooFeature, veepooLogger } = require('./libs/veepoo-sdk');
|
||||
@@ -79,6 +80,7 @@ Page({
|
||||
_connected: false,
|
||||
_eventChannel: null,
|
||||
_connecting: false,
|
||||
_listenersRegistered: false,
|
||||
|
||||
// ── 生命周期 ──
|
||||
|
||||
@@ -88,14 +90,13 @@ Page({
|
||||
// eslint-disable-next-line no-undef
|
||||
wx.setNavigationBarTitle({ title: 'M2 手环测量' });
|
||||
this._updateSelectedDisplay('heart_rate');
|
||||
// 诊断:确认 SDK 加载状态
|
||||
|
||||
// 在页面加载时一次性注册全局 SDK 监听器
|
||||
this._registerGlobalListeners();
|
||||
|
||||
// 诊断
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] SDK 加载状态:', {
|
||||
veepooBle: typeof veepooBle,
|
||||
veepooFeature: typeof veepooFeature,
|
||||
veepooLogger: typeof veepooLogger,
|
||||
scanFn: typeof veepooBle.veepooWeiXinSDKStartScanDeviceAndReceiveScanningDevice,
|
||||
});
|
||||
console.log('[veepoo-native] 页面已加载,全局监听器已注册');
|
||||
},
|
||||
|
||||
onUnload: function () {
|
||||
@@ -118,6 +119,41 @@ Page({
|
||||
}
|
||||
},
|
||||
|
||||
// ── 全局监听器(onLoad 注册一次) ──
|
||||
|
||||
_registerGlobalListeners: function () {
|
||||
if (this._listenersRegistered) return;
|
||||
this._listenersRegistered = true;
|
||||
var self = this;
|
||||
|
||||
// SDK 数据监听 — 接收所有解析后的事件(auth/measure/battery 等)
|
||||
veepooBle.veepooWeiXinSDKNotifyMonitorValueChange(function (data) {
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] SDK 数据事件:', JSON.stringify(data).substring(0, 500));
|
||||
self._handleSdkEvent(data);
|
||||
});
|
||||
|
||||
// BLE 连接状态变化
|
||||
veepooBle.veepooWeiXinSDKBLEConnectionStateChangeManager(function (res) {
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 连接状态变化:', JSON.stringify(res));
|
||||
if (!res.connected) {
|
||||
self._connected = false;
|
||||
self._connecting = false;
|
||||
self._cancelPendingMeasure();
|
||||
self.setData({ phase: 'disconnected' });
|
||||
}
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] SDK 函数类型:', {
|
||||
scanFn: typeof veepooBle.veepooWeiXinSDKStartScanDeviceAndReceiveScanningDevice,
|
||||
connectFn: typeof veepooBle.veepooWeiXinSDKBleConnectionServicesCharacteristicsNotifyManager,
|
||||
dataFn: typeof veepooBle.veepooWeiXinSDKNotifyMonitorValueChange,
|
||||
authFn: typeof veepooFeature.veepooBlePasswordCheckManager,
|
||||
});
|
||||
},
|
||||
|
||||
_updateSelectedDisplay: function (type) {
|
||||
var cfg = _findConfig(type);
|
||||
this.setData({
|
||||
@@ -129,10 +165,9 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
// ── 连接流程(严格对齐官方 Demo) ──
|
||||
// ── 连接流程 ──
|
||||
|
||||
handleConnect: function () {
|
||||
// H2 防重入
|
||||
if (this.data.phase !== 'idle' && this.data.phase !== 'error' && this.data.phase !== 'disconnected') return;
|
||||
if (this._connecting) return;
|
||||
this._connecting = true;
|
||||
@@ -149,8 +184,7 @@ Page({
|
||||
var name = (device.localName || device.name || '').toUpperCase();
|
||||
var deviceId = device.deviceId || device.mac || '';
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 扫描到:', name, deviceId, JSON.stringify(device).substring(0, 200));
|
||||
// 放宽匹配:包含 M2 / VPM / VEEPOO 均视为目标设备
|
||||
console.log('[veepoo-native] 扫描到:', name, deviceId);
|
||||
if (!self._scanFound && (name.indexOf('M2') !== -1 || name.indexOf('VPM') !== -1 || name.indexOf('VEEPOO') !== -1)) {
|
||||
self._scanFound = device;
|
||||
veepooBle.veepooWeiXinSDKStopSearchBleManager(function () {
|
||||
@@ -171,40 +205,35 @@ Page({
|
||||
_doConnect: function (device) {
|
||||
this.setData({ phase: 'connecting' });
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 连接设备:', device.deviceId || device.mac);
|
||||
console.log('[veepoo-native] 开始连接:', device.deviceId || device.mac);
|
||||
var self = this;
|
||||
|
||||
veepooBle.veepooWeiXinSDKBleConnectionServicesCharacteristicsNotifyManager(device, function (result) {
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 连接回调:', JSON.stringify(result));
|
||||
console.log('[veepoo-native] 连接阶段回调:', JSON.stringify(result).substring(0, 300));
|
||||
|
||||
// 只响应最终回调(connection:true),忽略中间阶段(services/characteristics/errno:0)
|
||||
// 只响应最终就绪回调(connection:true)
|
||||
if (result.connection === true) {
|
||||
self._connected = true;
|
||||
self._connecting = false;
|
||||
self.setData({
|
||||
deviceId: device.deviceId || device.mac || '',
|
||||
});
|
||||
|
||||
// 按 SDK 文档顺序:连接就绪 → 注册数据监听器 → 延迟 → 认证
|
||||
// wx.onBLECharacteristicValueChange 只支持一个回调,连接后注册避免被 SDK 内部覆盖
|
||||
self._registerListeners();
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 连接就绪,500ms 后发送认证');
|
||||
|
||||
setTimeout(function () {
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 调用 veepooBlePasswordCheckManager');
|
||||
veepooFeature.veepooBlePasswordCheckManager();
|
||||
self.setData({ phase: 'authenticating' });
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 认证指令已发送');
|
||||
}, 500);
|
||||
|
||||
// 双重检测:事件监听器(type=1)+ Storage 轮询兜底
|
||||
// Storage 轮询兜底
|
||||
self._authTimer = setInterval(function () {
|
||||
try {
|
||||
// eslint-disable-next-line no-undef
|
||||
var status = wx.getStorageSync('deviceChipStatus');
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 轮询 deviceChipStatus=', status);
|
||||
if (status === 'successfulVerification' || status === 'passTheVerification') {
|
||||
clearInterval(self._authTimer);
|
||||
self._authTimer = null;
|
||||
@@ -219,7 +248,7 @@ Page({
|
||||
self._authTimer = null;
|
||||
self._connecting = false;
|
||||
// eslint-disable-next-line no-undef
|
||||
console.error('[veepoo-native] 认证超时,deviceChipStatus=', wx.getStorageSync('deviceChipStatus'));
|
||||
console.error('[veepoo-native] 认证超时 deviceChipStatus=', wx.getStorageSync('deviceChipStatus'));
|
||||
self.setData({ phase: 'error', error: '设备认证超时,请重新连接' });
|
||||
}
|
||||
}, 8000);
|
||||
@@ -227,23 +256,7 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
_registerListeners: function () {
|
||||
var self = this;
|
||||
veepooBle.veepooWeiXinSDKNotifyMonitorValueChange(function (data) {
|
||||
self._handleSdkEvent(data);
|
||||
});
|
||||
veepooBle.veepooWeiXinSDKBLEConnectionStateChangeManager(function (res) {
|
||||
if (!res.connected) {
|
||||
self._connected = false;
|
||||
self._connecting = false;
|
||||
self._cancelPendingMeasure();
|
||||
self.setData({ phase: 'disconnected' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_onReady: function () {
|
||||
// C5 修复:清除 authTimeout 防止泄漏
|
||||
if (this._authTimeout) { clearTimeout(this._authTimeout); this._authTimeout = null; }
|
||||
this._connecting = false;
|
||||
// eslint-disable-next-line no-undef
|
||||
@@ -257,11 +270,11 @@ Page({
|
||||
_handleSdkEvent: function (data) {
|
||||
if (!data || data.type === undefined) return;
|
||||
var type = data.type;
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] SDK 事件: type=' + type, JSON.stringify(data).substring(0, 300));
|
||||
|
||||
if (type === SDK_EVENT_AUTH) {
|
||||
var password = (data.content || {}).VPDevicepassword;
|
||||
// eslint-disable-next-line no-undef
|
||||
console.log('[veepoo-native] 认证事件: VPDevicepassword=' + password);
|
||||
if (password === 'passTheVerification' || password === 'successfulVerification') {
|
||||
if (this._authTimer) { clearInterval(this._authTimer); this._authTimer = null; }
|
||||
if (this._authTimeout) { clearTimeout(this._authTimeout); this._authTimeout = null; }
|
||||
@@ -437,7 +450,6 @@ Page({
|
||||
return (values.systolic != null ? values.systolic : '--') + '/' + (values.diastolic != null ? values.diastolic : '--');
|
||||
}
|
||||
var v = Object.values(values)[0];
|
||||
// H5 修复:零值合法,仅 undefined/null 显示占位符
|
||||
return (v !== undefined && v !== null) ? String(v) : '--';
|
||||
},
|
||||
|
||||
@@ -486,7 +498,6 @@ Page({
|
||||
case 'blood_pressure':
|
||||
veepooFeature.veepooSendReadUniversalBloodPressureDataManager({ switch: on ? 'start' : 'stop' });
|
||||
break;
|
||||
// C1 修复:体温测量传 { switch: boolean } 参数,停止时也调用
|
||||
case 'temperature':
|
||||
veepooFeature.veepooSendTemperatureMeasurementSwitchManager({ switch: !!on });
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user