From 45b190ff028bb0df5015e73c1f264a71ed2c0ab9 Mon Sep 17 00:00:00 2001 From: lixiaolong <702156524@qq.com> Date: Wed, 5 Aug 2026 09:27:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(flow):=20=E4=BC=98=E5=8C=96=E6=9C=BA?= =?UTF-8?q?=E5=99=A8=E4=BA=BA=E8=AE=BE=E5=A4=87=E7=BB=91=E5=AE=9A=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将terminalId替换为robotId以统一机器人标识 - 实现机器人设备动态加载和选择功能 - 添加设备类型过滤和状态显示 - 重构设备注册页面为机器人设备管理界面 - 优化API调用参数传递方式 - 添加设备自动匹配和锁定机制 --- src/api/device/camera.js | 4 +- src/api/inspection/robot.js | 12 + src/store/modules/flow.js | 11 +- .../register/components/Camera/index.vue | 31 +- .../components/DexHand/LeftBottomHand.vue | 12 +- .../components/DexHand/LeftTopHand.vue | 14 +- .../register/components/DexHand/index.vue | 38 +- .../device/register/components/Head/index.vue | 10 +- .../register/components/Microphone/index.vue | 30 +- .../register/components/Speaker/index.vue | 10 +- src/views/device/register/index.vue | 538 +++++------------- src/views/device/robotManger/index.vue | 6 +- src/views/flow/components/TestRun.vue | 133 ++++- .../components/params/BasicNodeParams.vue | 119 +++- src/views/flow/config.js | 43 +- src/views/flow/index.vue | 83 ++- .../ManualTakeover/DirectionControl.vue | 14 +- .../components/ManualTakeover/RoboticArm.vue | 20 +- .../ManualTakeover/VoiceConversation.vue | 35 +- .../components/ManualTakeover/index.vue | 68 ++- src/views/is/project/evaluate/Run.vue | 6 +- src/views/test/configs/Run.vue | 6 +- src/views/test/configs/index.vue | 2 +- src/views/vi/testProject/evaluate/Run.vue | 6 +- 24 files changed, 675 insertions(+), 576 deletions(-) diff --git a/src/api/device/camera.js b/src/api/device/camera.js index 71781d4..c10a7be 100644 --- a/src/api/device/camera.js +++ b/src/api/device/camera.js @@ -1,9 +1,9 @@ import request from '@/utils/request' -export function getRgbStreamUrl(terminalId, deviceId) { +export function getRgbStreamUrl(robotId, deviceId) { return request({ url: '/api/edge/camera/rgb-stream-url', method: 'get', - params: { terminalId, deviceId } + params: { robotId, deviceId } }) } diff --git a/src/api/inspection/robot.js b/src/api/inspection/robot.js index a0a2e21..a1ee25b 100644 --- a/src/api/inspection/robot.js +++ b/src/api/inspection/robot.js @@ -38,6 +38,18 @@ export function getRobotDevices(id) { }) } +export function getRobotDevicesByRobotId(robotId, params = {}) { + return request({ + url: '/inspection/robot/devices', + method: 'get', + params: { + robotId, + onlineOnly: true, + ...params + } + }) +} + /** * 获取机器人地图 * @param {*} robotId diff --git a/src/store/modules/flow.js b/src/store/modules/flow.js index 287ae45..a78c228 100644 --- a/src/store/modules/flow.js +++ b/src/store/modules/flow.js @@ -2,20 +2,11 @@ import { defineStore } from 'pinia' export const useFlowStore = defineStore('flow', { state: () => ({ - disableForm: false, - deviceList: [] + disableForm: false }), actions: { updateDisableForm(value) { this.disableForm = value - }, - - async getDeviceList() { - const data = await new Promise((resolve, reject) => { - resolve( ['cam1', 'cam2', 'cam3', 'cam4']) - }) - this.deviceList = data - return data } } } diff --git a/src/views/device/register/components/Camera/index.vue b/src/views/device/register/components/Camera/index.vue index a7becbe..8e820bf 100644 --- a/src/views/device/register/components/Camera/index.vue +++ b/src/views/device/register/components/Camera/index.vue @@ -47,7 +47,7 @@ const props = defineProps({ type: String, default: null, }, - initialTerminalId: { + initialRobotId: { type: String, default: null, }, @@ -60,7 +60,7 @@ const data = reactive({ stereoModule: false, rgbCamera: false, }, - terminalId: null, + robotId: null, cameraId: null, type: 'camera', callbacks: {}, @@ -95,7 +95,7 @@ function getVideoRef(method) { } async function startDirectRgbStream() { - if (!data.terminalId || !data.cameraId || !colorVideo.value) return; + if (!data.robotId || !data.cameraId || !colorVideo.value) return; rgbStreamAbortController?.abort(); rgbStreamAbortController = null; const generation = ++rgbStreamGeneration; @@ -103,7 +103,7 @@ async function startDirectRgbStream() { rgbStreamRetryTimer = null; streamStatus.getRGBImageStream = 'connecting'; try { - const response = await getRgbStreamUrl(data.terminalId, data.cameraId); + const response = await getRgbStreamUrl(data.robotId, data.cameraId); if (generation !== rgbStreamGeneration || !data.form.rgbCamera) return; const relativeUrl = response.data; const baseUrl = import.meta.env.VITE_APP_BASE_API.replace(/\/$/, ''); @@ -342,11 +342,11 @@ function destroyMediaPlayer(method) { } function channelFor(method) { - return `edgeCameraServiceImpl/${method}/${data.terminalId}/${data.cameraId}`; + return `edgeCameraServiceImpl/${method}/${data.robotId}/${data.cameraId}`; } async function setSubscription(enabled, method, force = false) { - if (!socket || !data.terminalId || !data.cameraId) return; + if (!socket || !data.robotId || !data.cameraId) return; await nextTick(); const channel = channelFor(method); @@ -401,7 +401,7 @@ function scheduleRestart(method) { } function handleSocketOpen() { - if (data.form.stereoModule && data.terminalId && data.cameraId) { + if (data.form.stereoModule && data.robotId && data.cameraId) { destroyMediaPlayer('getDepthImageStream'); setSubscription(true, 'getDepthImageStream', true); } @@ -418,12 +418,12 @@ socket?.on('open', handleSocketOpen); socket?.on('close', handleSocketClose); watch(() => data.form.stereoModule, async (newVal) => { - if (!data.terminalId || !data.cameraId) return; + if (!data.robotId || !data.cameraId) return; await setSubscription(newVal, 'getDepthImageStream'); }); watch(() => data.form.rgbCamera, async (newVal) => { - if (!data.terminalId || !data.cameraId) return; + if (!data.robotId || !data.cameraId) return; if (newVal) { await nextTick(); await startDirectRgbStream(); @@ -436,10 +436,19 @@ watch( () => props.initialDeviceId || route.path.split('/')[3], async (deviceId) => { if (!deviceId) return; + const queryRobotId = props.initialRobotId || route.query.robotId; + const queryDeviceId = props.initialDeviceId || route.query.deviceId; + if (queryRobotId && queryDeviceId) { + data.cameraId = String(queryDeviceId); + data.robotId = String(queryRobotId); + if (data.form.stereoModule) await setSubscription(true, 'getDepthImageStream'); + if (data.form.rgbCamera) await startDirectRgbStream(); + return; + } try { const response = await getRegister(deviceId); data.cameraId = response.data.deviceCode; - data.terminalId = props.initialTerminalId || response.data.idDeDeviceTerminalConfig; + data.robotId = props.initialRobotId || response.data.idDeDeviceTerminalConfig; if (data.form.stereoModule) await setSubscription(true, 'getDepthImageStream'); if (data.form.rgbCamera) await startDirectRgbStream(); } catch (error) { @@ -455,7 +464,7 @@ onUnmounted(() => { stopDirectRgbStream(); ['getDepthImageStream'].forEach(method => { clearTimeout(retryTimers.get(method)); - if (data.terminalId && data.cameraId) { + if (data.robotId && data.cameraId) { const channel = channelFor(method); socket?.send({ type: 'channel_subscription', action: 'unsubscribe', channel }); if (data.callbacks[channel]) socket.off(channel, data.callbacks[channel]); diff --git a/src/views/device/register/components/DexHand/LeftBottomHand.vue b/src/views/device/register/components/DexHand/LeftBottomHand.vue index 27d3d37..302711f 100644 --- a/src/views/device/register/components/DexHand/LeftBottomHand.vue +++ b/src/views/device/register/components/DexHand/LeftBottomHand.vue @@ -17,7 +17,7 @@ import { inject } from 'vue'; const emit = defineEmits(['update:bottomSeriesData']); const socket = inject('ws'); const handCanvas = ref(null); -const terminalId = ref(''); // 待您修改 +const robotId = ref(''); // 待您修改 const deviceId = ref(''); // 待您修改 const frameData = ref({ count: 0, lastTime: 0 }); const isHandSeries = ref(false); @@ -29,7 +29,7 @@ const props = defineProps({ type: String, default: null, }, - initialTerminalId: { // 示例 prop,用于从弹窗接收 terminalId + initialRobotId: { // 示例 prop,用于从弹窗接收 robotId type: String, default: null, }, @@ -37,7 +37,7 @@ const props = defineProps({ // 2. 使用 watchEffect 来响应 props 和路由的变化 watchEffect(() => { - terminalId.value = props.initialTerminalId; + robotId.value = props.initialRobotId; deviceId.value = props.initialDeviceId; }); @@ -225,11 +225,11 @@ const sensorMap = [ // WebSocket 订阅 const subscribeSensorData = async (sub) => { - if (!socket || !terminalId.value || !deviceId.value) { - console.warn(`订阅失败: socket=${!!socket}, terminalId=${terminalId.value}, deviceId=${deviceId.value}`); + if (!socket || !robotId.value || !deviceId.value) { + console.warn(`订阅失败: socket=${!!socket}, robotId=${robotId.value}, deviceId=${deviceId.value}`); return; } - const channel = `edgeDexHandServiceImpl/getSensorDataStream/${terminalId.value}/${deviceId.value}`; + const channel = `edgeDexHandServiceImpl/getSensorDataStream/${robotId.value}/${deviceId.value}`; console.log(sub ? '订阅' : '取消订阅', channel); socket.send({ type: 'channel_subscription', diff --git a/src/views/device/register/components/DexHand/LeftTopHand.vue b/src/views/device/register/components/DexHand/LeftTopHand.vue index 5261e51..faeae7c 100644 --- a/src/views/device/register/components/DexHand/LeftTopHand.vue +++ b/src/views/device/register/components/DexHand/LeftTopHand.vue @@ -35,7 +35,7 @@ const handImage = ref(null); const containerRef = ref(null); // 新增:引用父容器 const defaultHandImageInfo = { width: 891, height: 981 }; const imageAspectRatio = defaultHandImageInfo.width / defaultHandImageInfo.height; -const terminalId = ref(''); +const robotId = ref(''); const deviceId = ref(''); // 1. 定义 props const props = defineProps({ @@ -43,7 +43,7 @@ const props = defineProps({ type: String, default: null, }, - initialTerminalId: { // 示例 prop,用于从弹窗接收 terminalId + initialRobotId: { // 示例 prop,用于从弹窗接收 robotId type: String, default: null, }, @@ -51,9 +51,9 @@ const props = defineProps({ // 2. 使用 watchEffect 来响应 props 和路由的变化 watchEffect(() => { - terminalId.value = props.initialTerminalId; + robotId.value = props.initialRobotId; deviceId.value = props.initialDeviceId; - console.log(deviceId.value, terminalId.value,props) + console.log(deviceId.value, robotId.value,props) }); const sliders = ref([ @@ -66,9 +66,9 @@ const sliders = ref([ ]); function updateSeriesData(value, i) { - console.log(deviceId.value, terminalId.value) + console.log(deviceId.value, robotId.value) loading.value = true; - setDexHandAngle({ deviceId: deviceId.value, terminalId: terminalId.value, value: value / 100, id: i }).then(() => { + setDexHandAngle({ deviceId: deviceId.value, robotId: robotId.value, value: value / 100, id: i }).then(() => { loading.value = false; updateToSeriesData(); }).catch(() => { @@ -131,7 +131,7 @@ const updateSliderPositions = () => { }; const updateToSeriesData = () => { - status({ deviceId: deviceId.value, terminalId: terminalId.value }).then((res) => { + status({ deviceId: deviceId.value, robotId: robotId.value }).then((res) => { const newTopSeriesData = res.data.handsList.map(item => item.force); emit('update:topSeriesData', newTopSeriesData); }); diff --git a/src/views/device/register/components/DexHand/index.vue b/src/views/device/register/components/DexHand/index.vue index fd33381..892ad7a 100644 --- a/src/views/device/register/components/DexHand/index.vue +++ b/src/views/device/register/components/DexHand/index.vue @@ -4,11 +4,11 @@