feat: implement P0 security and reliability improvements

- bcrypt password hashing with auto-migration from SHA-256
- BLE command retry (3 attempts, 500ms delay, skip on disconnect)
- BLE auto-reconnect with service re-discovery on disconnect
- Treatment page disconnect/reconnect event handling
- Token refresh endpoint with 3-day grace period
- Client-side token auto-refresh when <24h remaining
- Single treatment record detail API with ownership check
这个提交包含在:
Guoguo
2026-04-28 18:12:30 -07:00
父节点 88adee7743
当前提交 91d5937d8e
修改 10 个文件,包含 307 行新增32 行删除
+43
查看文件
@@ -33,9 +33,15 @@ Page({
this._onStatus = this.onStatus.bind(this)
this._onComplete = this.onComplete.bind(this)
this._onException = this.onException.bind(this)
this._onDisconnect = this.onDisconnect.bind(this)
this._onReconnect = this.onReconnect.bind(this)
this._onReconnectFailed = this.onReconnectFailed.bind(this)
ble.on('status', this._onStatus)
ble.on('treatment_complete', this._onComplete)
ble.on('exception', this._onException)
ble.on('disconnected', this._onDisconnect)
ble.on('reconnected', this._onReconnect)
ble.on('reconnect_failed', this._onReconnectFailed)
this.startLocalTimer()
this.syncCommands()
},
@@ -44,6 +50,9 @@ Page({
if (this._onStatus) ble.off('status', this._onStatus)
if (this._onComplete) ble.off('treatment_complete', this._onComplete)
if (this._onException) ble.off('exception', this._onException)
if (this._onDisconnect) ble.off('disconnected', this._onDisconnect)
if (this._onReconnect) ble.off('reconnected', this._onReconnect)
if (this._onReconnectFailed) ble.off('reconnect_failed', this._onReconnectFailed)
if (this._localTimer) clearInterval(this._localTimer)
},
@@ -131,6 +140,40 @@ Page({
})
},
onDisconnect: function () {
this.setData({ paused: true })
wx.showToast({
title: '设备连接断开,正在重连...',
icon: 'none',
duration: 3000
})
},
onReconnect: function () {
this.setData({ paused: false })
wx.showToast({
title: '设备已重新连接',
icon: 'success',
duration: 2000
})
},
onReconnectFailed: function () {
var self = this
if (this._localTimer) {
clearInterval(this._localTimer)
this._localTimer = null
}
wx.showModal({
title: '连接丢失',
content: '设备蓝牙连接已断开,无法恢复。本次护理数据将保存。',
showCancel: false,
complete: function () {
self.finishAsComplete()
}
})
},
onStop: function () {
var self = this
wx.showModal({