362 lines
7.9 KiB
JavaScript
362 lines
7.9 KiB
JavaScript
/**
|
||
* 命令发送页面
|
||
*/
|
||
const { commandManager } = require('../../../services/command-manager.js');
|
||
const { gateway } = require('../../../services/gateway.js');
|
||
const storage = require('../../../utils/storage.js');
|
||
|
||
const app = getApp();
|
||
|
||
Page({
|
||
data: {
|
||
device: null,
|
||
activeTab: 0,
|
||
tabs: ['预设命令', '自定义', '发送历史'],
|
||
|
||
// 预设命令
|
||
commands: [],
|
||
|
||
// 自定义输入
|
||
customHex: '',
|
||
customName: '',
|
||
|
||
// 发送历史
|
||
history: [],
|
||
|
||
// BLE连接状态
|
||
bleConnected: false,
|
||
|
||
// 编辑弹窗
|
||
showEditModal: false,
|
||
editMode: 'add', // 'add' 或 'edit'
|
||
editCommand: null,
|
||
editName: '',
|
||
editHex: '',
|
||
},
|
||
|
||
onLoad(options) {
|
||
const sn = options.sn;
|
||
if (!sn) {
|
||
wx.showToast({ title: '设备信息缺失', icon: 'none' });
|
||
setTimeout(() => wx.navigateBack(), 500);
|
||
return;
|
||
}
|
||
|
||
// 获取设备信息
|
||
let device = storage.getDevice(sn);
|
||
if (!device) {
|
||
wx.showToast({ title: '设备不存在', icon: 'none' });
|
||
setTimeout(() => wx.navigateBack(), 500);
|
||
return;
|
||
}
|
||
|
||
this.setData({ device });
|
||
this.loadCommands();
|
||
this.loadHistory();
|
||
this.checkConnectionStatus();
|
||
},
|
||
|
||
onShow() {
|
||
// 订阅网关状态
|
||
if (!this._unsub) {
|
||
this._unsub = gateway.subscribe(() => this.checkConnectionStatus());
|
||
}
|
||
this.checkConnectionStatus();
|
||
},
|
||
|
||
onHide() {
|
||
if (this._unsub) {
|
||
this._unsub();
|
||
this._unsub = null;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 加载预设命令
|
||
*/
|
||
loadCommands() {
|
||
const commands = commandManager.getCommands(this.data.device.serialNumber);
|
||
this.setData({ commands });
|
||
},
|
||
|
||
/**
|
||
* 加载发送历史
|
||
*/
|
||
loadHistory() {
|
||
const history = commandManager.getHistory(this.data.device.serialNumber);
|
||
// 格式化时间
|
||
const formattedHistory = history.map(item => ({
|
||
...item,
|
||
sendTime: this._formatTime(item.sendTime),
|
||
}));
|
||
this.setData({ history: formattedHistory });
|
||
},
|
||
|
||
/**
|
||
* 检查连接状态
|
||
*/
|
||
checkConnectionStatus() {
|
||
const snap = gateway.getSnapshot();
|
||
const isActive = snap.device && snap.device.serialNumber === this.data.device.serialNumber;
|
||
|
||
this.setData({
|
||
bleConnected: isActive && snap.bleConnected,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 切换 Tab
|
||
*/
|
||
switchTab(e) {
|
||
const index = e.currentTarget.dataset.index;
|
||
this.setData({ activeTab: index });
|
||
|
||
// 切换到历史 tab 时重新加载
|
||
if (index === 2) {
|
||
this.loadHistory();
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 输入自定义命令
|
||
*/
|
||
onCustomHexInput(e) {
|
||
this.setData({ customHex: e.detail.value.toUpperCase() });
|
||
},
|
||
|
||
/**
|
||
* 输入命令名称
|
||
*/
|
||
onCustomNameInput(e) {
|
||
this.setData({ customName: e.detail.value });
|
||
},
|
||
|
||
/**
|
||
* 发送自定义命令
|
||
*/
|
||
async handleSendCustom() {
|
||
const { customHex, customName, device } = this.data;
|
||
|
||
if (!customHex) {
|
||
wx.showToast({ title: '请输入命令', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
await this._sendCommand(customHex, customName || '自定义命令');
|
||
},
|
||
|
||
/**
|
||
* 选择预设命令
|
||
*/
|
||
async handleSelectCommand(e) {
|
||
const index = e.currentTarget.dataset.index;
|
||
const command = this.data.commands[index];
|
||
if (!command) return;
|
||
|
||
await this._sendCommand(command.hex, command.name, command.id);
|
||
},
|
||
|
||
/**
|
||
* 发送命令(核心方法,固定使用BLE)
|
||
*/
|
||
async _sendCommand(hex, name, commandId) {
|
||
const { device, bleConnected } = this.data;
|
||
|
||
// 检查BLE连接状态
|
||
if (!bleConnected) {
|
||
wx.showToast({ title: 'BLE 未连接,请先连接设备', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
wx.showLoading({ title: '发送中...', mask: true });
|
||
|
||
try {
|
||
// 固定使用BLE方式发送
|
||
await commandManager.sendCommand(hex, 'BLE', device, { name });
|
||
|
||
// 更新命令使用次数
|
||
if (commandId) {
|
||
commandManager.incrementUseCount(commandId);
|
||
}
|
||
|
||
wx.hideLoading();
|
||
wx.showToast({ title: '发送成功', icon: 'success' });
|
||
|
||
// 刷新历史
|
||
this.loadHistory();
|
||
} catch (err) {
|
||
wx.hideLoading();
|
||
wx.showToast({
|
||
title: err.message || '发送失败',
|
||
icon: 'none',
|
||
});
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 显示添加命令弹窗
|
||
*/
|
||
handleAddCommand() {
|
||
this.setData({
|
||
showEditModal: true,
|
||
editMode: 'add',
|
||
editCommand: null,
|
||
editName: '',
|
||
editHex: '',
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 编辑命令
|
||
*/
|
||
handleEditCommand(e) {
|
||
const index = e.currentTarget.dataset.index;
|
||
const command = this.data.commands[index];
|
||
if (!command) return;
|
||
|
||
this.setData({
|
||
showEditModal: true,
|
||
editMode: 'edit',
|
||
editCommand: command,
|
||
editName: command.name,
|
||
editHex: command.hex,
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 取消编辑
|
||
*/
|
||
handleCancelEdit() {
|
||
this.setData({
|
||
showEditModal: false,
|
||
editCommand: null,
|
||
editName: '',
|
||
editHex: '',
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 阻止事件冒泡(空方法)
|
||
*/
|
||
stopPropagation() {
|
||
// 阻止事件冒泡,什么都不做
|
||
},
|
||
|
||
/**
|
||
* 编辑命令输入
|
||
*/
|
||
onEditNameInput(e) {
|
||
this.setData({ editName: e.detail.value });
|
||
},
|
||
|
||
onEditHexInput(e) {
|
||
this.setData({ editHex: e.detail.value.toUpperCase() });
|
||
},
|
||
|
||
/**
|
||
* 删除命令
|
||
*/
|
||
handleSaveCommand() {
|
||
const { editMode, editName, editHex, device, editCommand } = this.data;
|
||
|
||
if (!editName || editName.trim() === '') {
|
||
wx.showToast({ title: '请输入命令名称', icon: 'none' });
|
||
return;
|
||
}
|
||
if (!editHex || editHex.trim() === '') {
|
||
wx.showToast({ title: '请输入命令', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
// 验证命令格式
|
||
const hex = editHex.replace(/\s+/g, '').toUpperCase();
|
||
if (!/^[0-9A-F]+$/.test(hex) || hex.length % 2 !== 0) {
|
||
wx.showToast({ title: '命令格式错误', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
const command = {
|
||
name: editName.trim(),
|
||
hex: hex,
|
||
deviceId: device.serialNumber,
|
||
};
|
||
|
||
if (editMode === 'add') {
|
||
const success = commandManager.addCommand(command);
|
||
if (!success) {
|
||
wx.showToast({ title: '命令名称已存在', icon: 'none' });
|
||
return;
|
||
}
|
||
wx.showToast({ title: '添加成功', icon: 'success' });
|
||
} else {
|
||
// 编辑模式
|
||
if (!editCommand || !editCommand.id) {
|
||
wx.showToast({ title: '编辑失败', icon: 'none' });
|
||
return;
|
||
}
|
||
command.id = editCommand.id;
|
||
commandManager.updateCommand(command);
|
||
wx.showToast({ title: '修改成功', icon: 'success' });
|
||
}
|
||
|
||
this.setData({
|
||
showEditModal: false,
|
||
editCommand: null,
|
||
editName: '',
|
||
editHex: '',
|
||
});
|
||
this.loadCommands();
|
||
},
|
||
|
||
|
||
/**
|
||
* 删除命令
|
||
*/
|
||
handleDeleteCommand(e) {
|
||
const index = e.currentTarget.dataset.index;
|
||
const command = this.data.commands[index];
|
||
if (!command) return;
|
||
|
||
wx.showModal({
|
||
title: '删除命令',
|
||
content: `确定删除命令 "${command.name}" 吗?`,
|
||
confirmColor: '#ff4d4f',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
commandManager.removeCommand(command.id);
|
||
this.loadCommands();
|
||
wx.showToast({ title: '已删除', icon: 'success' });
|
||
}
|
||
},
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 清空发送历史
|
||
*/
|
||
handleClearHistory() {
|
||
wx.showModal({
|
||
title: '清空历史',
|
||
content: '确定清空今天的发送历史吗?',
|
||
confirmColor: '#ff4d4f',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
commandManager.clearHistory();
|
||
this.loadHistory();
|
||
wx.showToast({ title: '已清空', icon: 'success' });
|
||
}
|
||
},
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 格式化时间
|
||
*/
|
||
_formatTime(timestamp) {
|
||
const date = new Date(timestamp);
|
||
const h = date.getHours().toString().padStart(2, '0');
|
||
const m = date.getMinutes().toString().padStart(2, '0');
|
||
const s = date.getSeconds().toString().padStart(2, '0');
|
||
return `${h}:${m}:${s}`;
|
||
},
|
||
}); |