封装控制设备 初始哈 xbox显示 优化

This commit is contained in:
mmc
2026-05-20 09:25:58 +08:00
parent 64682d9ef5
commit e7234ce63e
4 changed files with 212 additions and 12 deletions

View File

@@ -0,0 +1,185 @@
// src/components/device/deviceController.js
import { message } from 'antd';
import { wsManager } from '../WebSocketManager.ts';
import { getControlRight, getJurisdiction } from '../../api/device.ts';
import envConfig from '../../../env';
export default class DeviceController {
constructor(userInfo, messageApi) {
this.userInfo = userInfo;
this.messageApi = messageApi;
this.wsUrl = envConfig.WS_URL || 'wss://ri.satabot.com/ws/';
// 状态
this.connectedDeviceSn = null;
this.requestDeviceId = '';
this.isControlled = false;
this.isRequestControl = false;
this.hasControlRight = false;
this.wsDeviceInfo = {};
this.wsStatus = 'disconnected';
// 回调
this.onDeviceInfoUpdate = null;
this.onControlStatusChange = null;
this.onWsStatusChange = null;
this.onPermissionRequest = null;
// 绑定 this
this.handleWsMessage = this.handleWsMessage.bind(this);
this.getControl = this.getControl.bind(this);
this.connectDevice = this.connectDevice.bind(this);
this.sendPermissionRequest = this.sendPermissionRequest.bind(this);
}
// 初始化监听
init() {
wsManager.onMessage(this.handleWsMessage);
wsManager.onStatusChange((status) => {
this.wsStatus = status;
if (this.onWsStatusChange) this.onWsStatusChange(status);
});
}
// 销毁
destroy() {
wsManager.close();
}
// 获取设备控制权限
async getControl(serialnum) {
try {
const data = { platform: 'web', deviceId: serialnum };
const res = await getJurisdiction(data);
const ok = res?.code === 200 && res?.data?.remoteControl === true;
this.isControlled = ok;
if (this.onControlStatusChange) this.onControlStatusChange(ok);
} catch (err) {
this.isControlled = false;
if (this.onControlStatusChange) this.onControlStatusChange(false);
}
}
// 连接设备 WebSocket
async connectDevice(device) {
if (!device) return;
const sn = device.serialNumber || device.device_sn;
wsManager.close();
this.connectedDeviceSn = null;
this.wsDeviceInfo = {};
try {
const res = await getControlRight({
userName: this.userInfo.username,
sourceType: 1,
token: this.userInfo.token,
});
if (res?.code === 200) {
this.hasControlRight = true;
wsManager.connect(sn, this.wsUrl);
this.connectedDeviceSn = sn;
await this.getControl(sn);
} else {
this.hasControlRight = false;
this.messageApi.warning('其他端正在控制');
}
} catch (err) {
this.messageApi.error('权限校验失败');
}
}
// 发送权限请求
sendPermissionRequest(data, type) {
const wsData = {
type,
switchResult: data,
token: this.userInfo.token,
deviceId:
type === 'switchPermission'
? this.connectedDeviceSn
: this.requestDeviceId,
userName: this.userInfo.username,
};
wsManager.send(wsData);
}
// 处理外部请求控制
requestControl() {
if (this.isRequestControl || !this.hasControlRight) {
if (!this.hasControlRight) this.messageApi.warning('当前网页端无控制权限');
return;
}
this.isRequestControl = true;
this.messageApi.loading({
key: 'control',
content: '权限请求中...',
duration: 0,
});
this.sendPermissionRequest(true, 'switchPermission');
}
// 处理 WebSocket 消息
handleWsMessage(msg) {
switch (msg.type) {
case 'deviceInfo':
const data = {};
msg.data.forEach((item) => (data[item.name] = item.value));
this.wsDeviceInfo = data;
if (this.onDeviceInfoUpdate) this.onDeviceInfoUpdate(data);
break;
case 'AUTH':
if (msg.isAuth) this.getControl(this.connectedDeviceSn);
break;
case 'switchResult':
this.messageApi.success({
content: '权限获取成功',
key: 'control',
duration: 2,
});
this.isRequestControl = false;
this.isControlled = true;
if (this.onControlStatusChange) this.onControlStatusChange(true);
break;
case 'switchPermission':
const platform = (msg.platform || '').toLowerCase().trim();
if (!msg.platform || platform === 'web') return;
this.requestDeviceId = msg.deviceId;
if (this.onPermissionRequest) {
this.onPermissionRequest({
title: '权限请求',
content: `${msg.platform} 请求控制 ${msg.deviceId}`,
});
}
break;
case 'detectionReport':
if (msg.data?.deviceId !== this.connectedDeviceSn) return;
const { isSecure, obstacle } = msg.data;
if (isSecure) return;
const type = obstacle?.type;
const distance = (obstacle?.distance || 0).toFixed(2);
const types = { 0: '未知', 1: '人', 2: '车辆', 3: '围栏', 4: '坑洞', 5: '草丛' };
this.messageApi.warning({
key: 'obstacle-warning',
content: `检测到 ${types[type] ?? '未知物'},距离 ${distance}m`,
duration: 3,
});
break;
}
}
// 发送游戏手柄指令
sendGamepad(state) {
if (!this.isControlled || !this.connectedDeviceSn) return;
wsManager.send({
type: 'gamepad',
deviceId: this.connectedDeviceSn,
data: { axes: state.axes, buttons: state.buttons },
});
}
}