fix: improve UX and fix admin console display issues

Miniprogram:
- Add back buttons to all custom-nav pages
- Add debug/mock buttons (BLE connect, wear check, treatment)
  controlled by __DEV__ flag (hidden in prod)

Admin console:
- Fix log page using nonexistent fields (operator_type, target_type)
  now correctly reads admin_id/user_id/action/detail from API
- Fix subscription date fields (started_at→start_time, expired_at→expire_time)
- Wire up subscription detail/extend/renew action buttons
- Wire up device detail "查看完整日志" button
- Add "创建订阅" button to subscription toolbar
- Fix subscription status mapping (2=expired, 3=cancelled)

Docs:
- Add detailed architecture docs for server, miniprogram, admin console
这个提交包含在:
Guoguo
2026-04-28 18:32:26 -07:00
父节点 91d5937d8e
当前提交 c5f6033ccf
修改 30 个文件,包含 1509 行新增59 行删除
+48 -2
查看文件
@@ -1,5 +1,6 @@
var ble = require('../../services/ble')
var http = require('../../utils/request')
var config = require('../../config/env')
var app = getApp()
var SCAN_TIMEOUT = 15000
@@ -9,14 +10,24 @@ Page({
deviceId: '',
bindToken: '',
state: 'scanning',
error: ''
error: '',
devMode: false
},
onBack: function () {
wx.navigateBack({
fail: function () {
wx.reLaunch({ url: '/pages/index/index' })
}
})
},
onLoad: function (options) {
this.setData({ statusBarHeight: app.globalData.statusBarHeight })
this.setData({
deviceId: options.device_id || '',
bindToken: options.bind_token || ''
bindToken: options.bind_token || '',
devMode: config.__DEV__ || false
})
this.startBleConnect()
},
@@ -83,5 +94,40 @@ Page({
onRetry: function () {
ble.disconnect()
this.startBleConnect()
},
onMockConnect: function () {
var self = this
clearTimeout(this._scanTimer)
ble.stopScan()
self.setData({ state: 'binding' })
// Skip BLE bind, confirm directly with server
http.post('/api/v1/device/bind/confirm', {
device_id: self.data.deviceId,
bind_token: self.data.bindToken
}).then(function () {
self.setData({ state: 'done' })
wx.redirectTo({
url: '/pages/bind-success/bind-success?device_id=' + self.data.deviceId
})
}).catch(function (err) {
self.setData({ state: 'error', error: err.message || '模拟确认失败' })
})
},
onMockBindSuccess: function () {
var self = this
clearTimeout(this._scanTimer)
ble.stopScan()
http.post('/api/v1/device/bind/confirm', {
device_id: self.data.deviceId,
bind_token: self.data.bindToken
}).then(function () {
wx.redirectTo({
url: '/pages/bind-success/bind-success?device_id=' + self.data.deviceId
})
}).catch(function (err) {
self.setData({ state: 'error', error: err.message || '模拟确认失败' })
})
}
})
@@ -1,5 +1,6 @@
<view class="page">
<view class="page-header page-header-pink" style="padding-top: {{statusBarHeight + 24}}px;">
<view class="nav-back" bindtap="onBack"> 返回</view>
<view class="page-header-title">蓝牙连接</view>
<view class="page-header-subtitle">{{state === 'scanning' ? '正在搜索设备...' : state === 'connecting' ? '正在连接设备...' : state === 'binding' ? '正在绑定...' : '连接失败'}}</view>
</view>
@@ -26,5 +27,11 @@
<view class="found-name">{{error || '连接失败'}}</view>
<button class="retry-btn" bindtap="onRetry">重试</button>
</view>
<view class="debug-actions" wx:if="{{devMode}}">
<view class="debug-label">🔧 调试工具</view>
<button class="btn-secondary btn-sm" bindtap="onMockConnect">模拟连接成功</button>
<button class="btn-secondary btn-sm" bindtap="onMockBindSuccess">模拟绑定成功</button>
</view>
</view>
</view>