189 lines
4.7 KiB
JavaScript
189 lines
4.7 KiB
JavaScript
/**
|
||
* 设备详情页 - 实时数据(纯视图)
|
||
*
|
||
* 连接与上报全部由应用级网关(gateway)承担,本页仅:
|
||
* - 订阅网关快照,实时展示该设备的 hex 原始帧与统计
|
||
* - 提供”启用网关采集”开关(单 enabled,开启即停其他设备)
|
||
* - 手动补传离线缓存 / 清空
|
||
*/
|
||
const { gateway } = require('../../../services/gateway.js');
|
||
const storage = require('../../../utils/storage.js');
|
||
|
||
const app = getApp();
|
||
|
||
Page({
|
||
data: {
|
||
device: null,
|
||
enabled: false,
|
||
|
||
// 网关快照(该设备是否为当前采集对象)
|
||
isActive: false,
|
||
activeSn: '',
|
||
running: false,
|
||
bleConnected: false,
|
||
mqttConnected: false,
|
||
phaseText: '未启用',
|
||
lastError: null,
|
||
|
||
// 数据列表与统计
|
||
dataList: [],
|
||
stats: { received: 0, uploaded: 0, failed: 0 },
|
||
offlineCount: 0,
|
||
},
|
||
|
||
onLoad(options) {
|
||
const sn = options.sn;
|
||
if (!sn) {
|
||
wx.showToast({ title: '设备信息缺失', icon: 'none' });
|
||
setTimeout(() => wx.navigateBack(), 500);
|
||
return;
|
||
}
|
||
|
||
// 从全局或存储获取设备信息
|
||
let device = app.globalData.currentDevice;
|
||
if (!device || device.serialNumber !== sn) {
|
||
device = storage.getDevice(sn);
|
||
}
|
||
if (!device) {
|
||
wx.showToast({ title: '设备不存在', icon: 'none' });
|
||
setTimeout(() => wx.navigateBack(), 500);
|
||
return;
|
||
}
|
||
|
||
this.sn = sn;
|
||
this.setData({
|
||
device,
|
||
enabled: !!device.enabled,
|
||
});
|
||
},
|
||
|
||
onShow() {
|
||
// 订阅网关,实时渲染
|
||
if (!this._unsub) {
|
||
this._unsub = gateway.subscribe((snap) => this._apply(snap));
|
||
}
|
||
this._apply(gateway.getSnapshot());
|
||
|
||
// 本设备已启用时,确保网关在采集(幂等)
|
||
if (this.data.device && this.data.device.enabled) {
|
||
gateway.ensureStarted();
|
||
}
|
||
},
|
||
|
||
onHide() {
|
||
this._unsubscribe();
|
||
},
|
||
|
||
onUnload() {
|
||
this._unsubscribe();
|
||
},
|
||
|
||
_unsubscribe() {
|
||
if (this._unsub) {
|
||
this._unsub();
|
||
this._unsub = null;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 应用网关快照到页面
|
||
*/
|
||
_apply(snap) {
|
||
const dev = this.data.device;
|
||
const isActive = !!(snap.device && dev && snap.device.serialNumber === dev.serialNumber);
|
||
|
||
this.setData({
|
||
isActive,
|
||
activeSn: snap.device ? snap.device.serialNumber : '',
|
||
bleConnected: isActive && snap.bleConnected,
|
||
mqttConnected: isActive && snap.mqttConnected,
|
||
running: isActive && snap.phase === 'running',
|
||
phaseText: snap.phaseText,
|
||
lastError: isActive ? snap.lastError : null,
|
||
dataList: isActive ? snap.dataList : [],
|
||
stats: isActive ? snap.stats : { received: 0, uploaded: 0, failed: 0 },
|
||
offlineCount: snap.offlineCount,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 启用/停用网关采集(单 enabled)
|
||
*/
|
||
async handleEnableToggle(e) {
|
||
const enabled = e.detail.value;
|
||
const device = this.data.device;
|
||
if (!device) return;
|
||
|
||
if (enabled) {
|
||
// 本设备成为唯一启用,并立即启动采集
|
||
storage.activateDevice(device.serialNumber);
|
||
this.setData({
|
||
enabled: true,
|
||
device: { ...device, enabled: true },
|
||
});
|
||
const target = storage.getDevice(device.serialNumber);
|
||
gateway.start(target || { ...device, enabled: true });
|
||
} else {
|
||
storage.deactivateDevice(device.serialNumber);
|
||
this.setData({
|
||
enabled: false,
|
||
device: { ...device, enabled: false },
|
||
});
|
||
// 停用后若无其他启用设备,网关停止
|
||
await gateway.ensureStarted();
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 发送命令 - 跳转命令管理页
|
||
*/
|
||
handleSendCommand() {
|
||
const device = this.data.device;
|
||
if (!device) return;
|
||
|
||
wx.navigateTo({
|
||
url: `/pages/device/command/command?sn=${device.serialNumber}`,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 手动补传离线缓存
|
||
*/
|
||
async handleFlushOffline() {
|
||
const { offlineCount } = this.data;
|
||
if (!this.data.mqttConnected) {
|
||
wx.showToast({ title: 'MQTT 未连接', icon: 'none' });
|
||
return;
|
||
}
|
||
if (offlineCount === 0) {
|
||
wx.showToast({ title: '暂无离线数据', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
wx.showLoading({ title: '上传中...', mask: true });
|
||
const before = gateway.getSnapshot().offlineCount;
|
||
await gateway.flushOffline();
|
||
wx.hideLoading();
|
||
const after = gateway.getSnapshot().offlineCount;
|
||
wx.showToast({
|
||
title: `已上传 ${before - after} 条`,
|
||
icon: 'none',
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 清空展示数据
|
||
*/
|
||
handleClearData() {
|
||
wx.showModal({
|
||
title: '清空数据',
|
||
content: '确定清空当前实时数据与统计吗?(不影响离线缓存)',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
gateway.clearHistory();
|
||
}
|
||
},
|
||
});
|
||
},
|
||
});
|