feat: treating page monitors fitting/run_state and handles safety events
- Listen for 'fitting' event: detect skin detachment, pause on loss, resume on re-attach - Listen for 'run_state' event: detect device fault (0xFF) and IDLE completion (0x00) - Low battery warnings: toast at <=10%, force stop at <=5% - Guard finishAsComplete against double-completion - Proper cleanup of all new event listeners on unload
这个提交包含在:
@@ -17,6 +17,8 @@ Page({
|
|||||||
completed: false,
|
completed: false,
|
||||||
startedAt: 0,
|
startedAt: 0,
|
||||||
regionText: '全区域',
|
regionText: '全区域',
|
||||||
|
fittingLost: false,
|
||||||
|
deviceFault: false
|
||||||
},
|
},
|
||||||
|
|
||||||
_getRegionText: function (regionMask) {
|
_getRegionText: function (regionMask) {
|
||||||
@@ -44,15 +46,18 @@ Page({
|
|||||||
regionText: this._getRegionText(regions)
|
regionText: this._getRegionText(regions)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this._sessionId = 'SESS_' + Date.now()
|
||||||
|
|
||||||
this._onStatus = this.onStatus.bind(this)
|
this._onStatus = this.onStatus.bind(this)
|
||||||
|
this._onBattery = this.onBattery.bind(this)
|
||||||
this._onComplete = this.onComplete.bind(this)
|
this._onComplete = this.onComplete.bind(this)
|
||||||
this._onException = this.onException.bind(this)
|
this._onException = this.onException.bind(this)
|
||||||
this._onDisconnect = this.onDisconnect.bind(this)
|
this._onDisconnect = this.onDisconnect.bind(this)
|
||||||
this._onReconnect = this.onReconnect.bind(this)
|
this._onReconnect = this.onReconnect.bind(this)
|
||||||
this._onReconnectFailed = this.onReconnectFailed.bind(this)
|
this._onReconnectFailed = this.onReconnectFailed.bind(this)
|
||||||
this._sessionId = 'SESS_' + Date.now()
|
this._onFitting = this.onFitting.bind(this)
|
||||||
|
this._onRunState = this.onRunState.bind(this)
|
||||||
|
|
||||||
this._onBattery = this.onBattery.bind(this)
|
|
||||||
ble.on('status', this._onStatus)
|
ble.on('status', this._onStatus)
|
||||||
ble.on('battery', this._onBattery)
|
ble.on('battery', this._onBattery)
|
||||||
ble.on('treatment_complete', this._onComplete)
|
ble.on('treatment_complete', this._onComplete)
|
||||||
@@ -60,6 +65,9 @@ Page({
|
|||||||
ble.on('disconnected', this._onDisconnect)
|
ble.on('disconnected', this._onDisconnect)
|
||||||
ble.on('reconnected', this._onReconnect)
|
ble.on('reconnected', this._onReconnect)
|
||||||
ble.on('reconnect_failed', this._onReconnectFailed)
|
ble.on('reconnect_failed', this._onReconnectFailed)
|
||||||
|
ble.on('fitting', this._onFitting)
|
||||||
|
ble.on('run_state', this._onRunState)
|
||||||
|
|
||||||
this.startLocalTimer()
|
this.startLocalTimer()
|
||||||
this.syncCommands()
|
this.syncCommands()
|
||||||
this.syncTreatmentStart()
|
this.syncTreatmentStart()
|
||||||
@@ -73,7 +81,42 @@ Page({
|
|||||||
if (this._onDisconnect) ble.off('disconnected', this._onDisconnect)
|
if (this._onDisconnect) ble.off('disconnected', this._onDisconnect)
|
||||||
if (this._onReconnect) ble.off('reconnected', this._onReconnect)
|
if (this._onReconnect) ble.off('reconnected', this._onReconnect)
|
||||||
if (this._onReconnectFailed) ble.off('reconnect_failed', this._onReconnectFailed)
|
if (this._onReconnectFailed) ble.off('reconnect_failed', this._onReconnectFailed)
|
||||||
|
if (this._onFitting) ble.off('fitting', this._onFitting)
|
||||||
|
if (this._onRunState) ble.off('run_state', this._onRunState)
|
||||||
if (this._localTimer) clearInterval(this._localTimer)
|
if (this._localTimer) clearInterval(this._localTimer)
|
||||||
|
if (this._fittingTimer) clearTimeout(this._fittingTimer)
|
||||||
|
},
|
||||||
|
|
||||||
|
onFitting: function (data) {
|
||||||
|
if (this.data.completed) return
|
||||||
|
if (data.fitting === 0 && !this.data.fittingLost) {
|
||||||
|
this.setData({ fittingLost: true, paused: true })
|
||||||
|
wx.showToast({ title: '检测到离肤,请重新佩戴设备', icon: 'none', duration: 3000 })
|
||||||
|
} else if (data.fitting === 1 && this.data.fittingLost) {
|
||||||
|
this.setData({ fittingLost: false, paused: false })
|
||||||
|
wx.showToast({ title: '已重新贴合,继续使用', icon: 'success', duration: 2000 })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onRunState: function (data) {
|
||||||
|
if (this.data.completed) return
|
||||||
|
console.log('[TREAT] run_state:', data.run_state)
|
||||||
|
|
||||||
|
if (data.run_state === 0xFF) {
|
||||||
|
this.setData({ deviceFault: true })
|
||||||
|
var self = this
|
||||||
|
wx.showModal({
|
||||||
|
title: '设备故障',
|
||||||
|
content: '设备上报故障,已自动停止。',
|
||||||
|
showCancel: false,
|
||||||
|
complete: function () { self.finishAsComplete() }
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.run_state === 0x00 && !this.data.paused && !this.data.fittingLost) {
|
||||||
|
this.finishAsComplete()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
startLocalTimer: function () {
|
startLocalTimer: function () {
|
||||||
@@ -83,6 +126,23 @@ Page({
|
|||||||
var elapsed = Date.now() - self.data.startedAt
|
var elapsed = Date.now() - self.data.startedAt
|
||||||
var remaining = Math.max(0, self.data.duration - elapsed)
|
var remaining = Math.max(0, self.data.duration - elapsed)
|
||||||
self.updateProgress(remaining)
|
self.updateProgress(remaining)
|
||||||
|
|
||||||
|
if (self.data.battery > 0 && self.data.battery <= 5) {
|
||||||
|
clearInterval(timer)
|
||||||
|
wx.showModal({
|
||||||
|
title: '电量过低',
|
||||||
|
content: '设备电量不足5%,已自动停止。请及时充电。',
|
||||||
|
showCancel: false,
|
||||||
|
complete: function () { self.finishAsComplete() }
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.data.battery > 0 && self.data.battery <= 10 && !self._lowBatteryWarned) {
|
||||||
|
self._lowBatteryWarned = true
|
||||||
|
wx.showToast({ title: '电量低,请及时充电', icon: 'none', duration: 3000 })
|
||||||
|
}
|
||||||
|
|
||||||
if (remaining <= 0) {
|
if (remaining <= 0) {
|
||||||
clearInterval(timer)
|
clearInterval(timer)
|
||||||
self.finishAsComplete()
|
self.finishAsComplete()
|
||||||
@@ -179,6 +239,7 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
finishAsComplete: function () {
|
finishAsComplete: function () {
|
||||||
|
if (this.data.completed) return
|
||||||
var elapsed = Math.min(this.data.duration, Date.now() - this.data.startedAt)
|
var elapsed = Math.min(this.data.duration, Date.now() - this.data.startedAt)
|
||||||
this.syncTreatmentEnd(elapsed)
|
this.syncTreatmentEnd(elapsed)
|
||||||
this.onComplete({
|
this.onComplete({
|
||||||
@@ -254,6 +315,5 @@ Page({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户