From 815f8d3cde35ea12c50e68b07f98212394897ab1 Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Tue, 25 Aug 2026 10:25:40 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/error/401.vue | 82 - src/views/error/404.vue | 227 -- .../flow/components/ActionQueueSingleRun.vue | 281 -- src/views/flow/components/Aside.vue | 251 -- .../flow/components/FormItemRecursive.vue | 242 -- .../flow/components/LoopIterationResults.vue | 217 -- src/views/flow/components/NodeState.vue | 202 -- src/views/flow/components/NodeTitle.vue | 338 -- src/views/flow/components/OuterNode.vue | 50 - src/views/flow/components/ParamsDrawer.vue | 161 - .../components/RuntimeAssignmentsEditor.vue | 411 --- .../flow/components/RuntimeParamsEditor.vue | 122 - .../components/SubFlowExecutionResults.vue | 173 - .../flow/components/TaskExecutionLog.vue | 889 ----- src/views/flow/components/TestRun.vue | 319 -- .../components/params/ActionQueueParams.vue | 585 ---- .../components/params/BasicNodeParams.vue | 598 ---- .../flow/components/params/CodeNodeParams.vue | 501 --- .../components/params/DeviceUniversal.vue | 521 --- .../flow/components/params/EndParams.vue | 158 - .../flow/components/params/HttpNodeParams.vue | 704 ---- .../components/params/ImageAnalysisParams.vue | 431 --- .../components/params/MediaAnalysisParams.vue | 567 ---- .../components/params/RecognizeNodeParams.vue | 387 --- .../params/RobotExecutionTarget.vue | 120 - .../components/params/SdAgentNodeParams.vue | 390 --- .../flow/components/params/StartParams.vue | 233 -- .../flow/components/params/SubFlowParams.vue | 291 -- .../components/params/SwitchNodeParams.vue | 413 --- src/views/flow/components/params/useQuote.js | 43 - src/views/flow/composables/useFlowEvents.js | 27 - src/views/flow/config.js | 897 ----- src/views/flow/icon/audio.svg | 1 - src/views/flow/icon/awaken.svg | 1 - src/views/flow/icon/camera.svg | 1 - src/views/flow/icon/dialogue.svg | 1 - src/views/flow/icon/end.svg | 1 - src/views/flow/icon/expression.svg | 1 - src/views/flow/icon/group.svg | 3 - src/views/flow/icon/loop.svg | 1 - src/views/flow/icon/microphone.svg | 4 - src/views/flow/icon/plan.svg | 1 - src/views/flow/icon/sleep.svg | 1 - src/views/flow/icon/start.svg | 6 - src/views/flow/icon/stopLoop.svg | 1 - src/views/flow/icon/switch.svg | 7 - src/views/flow/icon/touch.svg | 1 - src/views/flow/icon/video.svg | 3 - src/views/flow/index.vue | 2994 ----------------- src/views/flow/nodes/common/endNode.vue | 24 - .../flow/nodes/common/selectAreaNode.vue | 128 - src/views/flow/nodes/common/serviceNode.vue | 169 - src/views/flow/nodes/common/startNode.vue | 101 - src/views/flow/nodes/function/actionQueue.vue | 25 - src/views/flow/nodes/function/codeNode.vue | 146 - src/views/flow/nodes/function/currentLoop.vue | 262 -- .../flow/nodes/function/deviceUniversal.vue | 146 - src/views/flow/nodes/function/httpNode.vue | 146 - src/views/flow/nodes/function/loop.vue | 265 -- src/views/flow/nodes/function/recognize.vue | 130 - src/views/flow/nodes/function/sdAgent.vue | 130 - src/views/flow/nodes/function/sleep.vue | 129 - src/views/flow/nodes/function/stopLoop.vue | 205 -- src/views/flow/nodes/function/subEnd.vue | 19 - src/views/flow/nodes/function/subFlow.vue | 97 - src/views/flow/nodes/function/subStart.vue | 19 - src/views/flow/nodes/function/switch.vue | 319 -- src/views/flow/vue-flow/FlowEdge.vue | 95 - src/views/flow/vue-flow/FlowNode.vue | 419 --- src/views/flow/vue-flow/adapter.js | 990 ------ src/views/inspection/alarm/index.vue | 452 --- src/views/inspection/cockpit/canvasUtils.js | 620 ---- .../inspection/cockpit/components/Header.vue | 161 - .../ManualTakeover/DirectionControl.vue | 325 -- .../components/ManualTakeover/RoboticArm.vue | 419 --- .../ManualTakeover/VoiceConversation.vue | 1125 ------- .../components/ManualTakeover/index.vue | 622 ---- .../cockpit/components/MapCanvas.vue | 527 --- .../cockpit/components/MapOverview.vue | 433 --- .../inspection/cockpit/components/Monitor.vue | 209 -- .../cockpit/components/UrdfView.vue | 292 -- src/views/inspection/cockpit/index.vue | 50 - src/views/inspection/point/index.vue | 419 --- src/views/inspection/runTask/index.vue | 824 ----- src/views/inspection/runTask/task-log.vue | 469 --- src/views/inspection/runTask/task-steps.vue | 117 - src/views/inspection/task/index.vue | 404 --- src/views/intelligenceTest/car/index.vue | 304 -- .../intelligenceTest/mobilePhone/index.vue | 321 -- .../intelligenceTest/runningTask/index.vue | 885 ----- .../intelligenceTest/runningTask/task-log.vue | 641 ---- .../runningTask/task-steps.vue | 117 - .../intelligenceTest/taskManage/index.vue | 376 --- src/views/intelligenceTest/testCase/index.vue | 344 -- src/views/login.vue | 239 -- src/views/monitor/cache/index.vue | 132 - src/views/monitor/cache/list.vue | 246 -- src/views/monitor/druid/index.vue | 13 - src/views/monitor/job/detail.vue | 217 -- src/views/monitor/job/index.vue | 435 --- src/views/monitor/job/log.vue | 251 -- src/views/monitor/logininfor/index.vue | 233 -- src/views/monitor/online/index.vue | 109 - src/views/monitor/operlog/detail.vue | 152 - src/views/monitor/operlog/index.vue | 262 -- src/views/monitor/server/index.vue | 187 - src/views/redirect/index.vue | 14 - src/views/register.vue | 219 -- src/views/resource/device/index.vue | 104 - src/views/resource/map/index.vue | 189 -- src/views/resource/robot/index.vue | 339 -- src/views/resource/terminal/index.vue | 75 - src/views/system/config/index.vue | 316 -- src/views/system/dept/index.vue | 334 -- src/views/system/dict/data.vue | 362 -- src/views/system/dict/detail.vue | 202 -- src/views/system/dict/index.vue | 346 -- src/views/system/file/index.vue | 350 -- src/views/system/group/index.vue | 289 -- src/views/system/menu/index.vue | 508 --- src/views/system/notice/ReadUsers.vue | 118 - src/views/system/notice/index.vue | 306 -- src/views/system/post/index.vue | 287 -- src/views/system/role/authUser.vue | 179 - src/views/system/role/index.vue | 584 ---- src/views/system/role/selectUser.vue | 144 - src/views/system/user/authRole.vue | 123 - src/views/system/user/index.vue | 459 --- src/views/system/user/profile/index.vue | 94 - src/views/system/user/profile/resetPwd.vue | 60 - src/views/system/user/profile/userAvatar.vue | 180 - src/views/system/user/profile/userInfo.vue | 67 - src/views/system/user/view.vue | 175 - src/views/system/vehOper/index.vue | 349 -- src/views/tool/build/CodeTypeDialog.vue | 71 - src/views/tool/build/DraggableItem.vue | 68 - src/views/tool/build/IconsDialog.vue | 115 - src/views/tool/build/RightPanel.vue | 906 ----- src/views/tool/build/TreeNodeDialog.vue | 93 - src/views/tool/build/index.vue | 660 ---- src/views/tool/gen/basicInfoForm.vue | 48 - src/views/tool/gen/createTable.vue | 46 - src/views/tool/gen/editTable.vue | 212 -- src/views/tool/gen/genInfoForm.vue | 328 -- src/views/tool/gen/importTable.vue | 126 - src/views/tool/gen/index.vue | 309 -- src/views/tool/swagger/index.vue | 9 - 147 files changed, 40518 deletions(-) delete mode 100644 src/views/error/401.vue delete mode 100644 src/views/error/404.vue delete mode 100644 src/views/flow/components/ActionQueueSingleRun.vue delete mode 100644 src/views/flow/components/Aside.vue delete mode 100644 src/views/flow/components/FormItemRecursive.vue delete mode 100644 src/views/flow/components/LoopIterationResults.vue delete mode 100644 src/views/flow/components/NodeState.vue delete mode 100644 src/views/flow/components/NodeTitle.vue delete mode 100644 src/views/flow/components/OuterNode.vue delete mode 100644 src/views/flow/components/ParamsDrawer.vue delete mode 100644 src/views/flow/components/RuntimeAssignmentsEditor.vue delete mode 100644 src/views/flow/components/RuntimeParamsEditor.vue delete mode 100644 src/views/flow/components/SubFlowExecutionResults.vue delete mode 100644 src/views/flow/components/TaskExecutionLog.vue delete mode 100644 src/views/flow/components/TestRun.vue delete mode 100644 src/views/flow/components/params/ActionQueueParams.vue delete mode 100644 src/views/flow/components/params/BasicNodeParams.vue delete mode 100644 src/views/flow/components/params/CodeNodeParams.vue delete mode 100644 src/views/flow/components/params/DeviceUniversal.vue delete mode 100644 src/views/flow/components/params/EndParams.vue delete mode 100644 src/views/flow/components/params/HttpNodeParams.vue delete mode 100644 src/views/flow/components/params/ImageAnalysisParams.vue delete mode 100644 src/views/flow/components/params/MediaAnalysisParams.vue delete mode 100644 src/views/flow/components/params/RecognizeNodeParams.vue delete mode 100644 src/views/flow/components/params/RobotExecutionTarget.vue delete mode 100644 src/views/flow/components/params/SdAgentNodeParams.vue delete mode 100644 src/views/flow/components/params/StartParams.vue delete mode 100644 src/views/flow/components/params/SubFlowParams.vue delete mode 100644 src/views/flow/components/params/SwitchNodeParams.vue delete mode 100644 src/views/flow/components/params/useQuote.js delete mode 100644 src/views/flow/composables/useFlowEvents.js delete mode 100644 src/views/flow/config.js delete mode 100644 src/views/flow/icon/audio.svg delete mode 100644 src/views/flow/icon/awaken.svg delete mode 100644 src/views/flow/icon/camera.svg delete mode 100644 src/views/flow/icon/dialogue.svg delete mode 100644 src/views/flow/icon/end.svg delete mode 100644 src/views/flow/icon/expression.svg delete mode 100644 src/views/flow/icon/group.svg delete mode 100644 src/views/flow/icon/loop.svg delete mode 100644 src/views/flow/icon/microphone.svg delete mode 100644 src/views/flow/icon/plan.svg delete mode 100644 src/views/flow/icon/sleep.svg delete mode 100644 src/views/flow/icon/start.svg delete mode 100644 src/views/flow/icon/stopLoop.svg delete mode 100644 src/views/flow/icon/switch.svg delete mode 100644 src/views/flow/icon/touch.svg delete mode 100644 src/views/flow/icon/video.svg delete mode 100644 src/views/flow/index.vue delete mode 100644 src/views/flow/nodes/common/endNode.vue delete mode 100644 src/views/flow/nodes/common/selectAreaNode.vue delete mode 100644 src/views/flow/nodes/common/serviceNode.vue delete mode 100644 src/views/flow/nodes/common/startNode.vue delete mode 100644 src/views/flow/nodes/function/actionQueue.vue delete mode 100644 src/views/flow/nodes/function/codeNode.vue delete mode 100644 src/views/flow/nodes/function/currentLoop.vue delete mode 100644 src/views/flow/nodes/function/deviceUniversal.vue delete mode 100644 src/views/flow/nodes/function/httpNode.vue delete mode 100644 src/views/flow/nodes/function/loop.vue delete mode 100644 src/views/flow/nodes/function/recognize.vue delete mode 100644 src/views/flow/nodes/function/sdAgent.vue delete mode 100644 src/views/flow/nodes/function/sleep.vue delete mode 100644 src/views/flow/nodes/function/stopLoop.vue delete mode 100644 src/views/flow/nodes/function/subEnd.vue delete mode 100644 src/views/flow/nodes/function/subFlow.vue delete mode 100644 src/views/flow/nodes/function/subStart.vue delete mode 100644 src/views/flow/nodes/function/switch.vue delete mode 100644 src/views/flow/vue-flow/FlowEdge.vue delete mode 100644 src/views/flow/vue-flow/FlowNode.vue delete mode 100644 src/views/flow/vue-flow/adapter.js delete mode 100644 src/views/inspection/alarm/index.vue delete mode 100644 src/views/inspection/cockpit/canvasUtils.js delete mode 100644 src/views/inspection/cockpit/components/Header.vue delete mode 100644 src/views/inspection/cockpit/components/ManualTakeover/DirectionControl.vue delete mode 100644 src/views/inspection/cockpit/components/ManualTakeover/RoboticArm.vue delete mode 100644 src/views/inspection/cockpit/components/ManualTakeover/VoiceConversation.vue delete mode 100644 src/views/inspection/cockpit/components/ManualTakeover/index.vue delete mode 100644 src/views/inspection/cockpit/components/MapCanvas.vue delete mode 100644 src/views/inspection/cockpit/components/MapOverview.vue delete mode 100644 src/views/inspection/cockpit/components/Monitor.vue delete mode 100644 src/views/inspection/cockpit/components/UrdfView.vue delete mode 100644 src/views/inspection/cockpit/index.vue delete mode 100644 src/views/inspection/point/index.vue delete mode 100644 src/views/inspection/runTask/index.vue delete mode 100644 src/views/inspection/runTask/task-log.vue delete mode 100644 src/views/inspection/runTask/task-steps.vue delete mode 100644 src/views/inspection/task/index.vue delete mode 100644 src/views/intelligenceTest/car/index.vue delete mode 100644 src/views/intelligenceTest/mobilePhone/index.vue delete mode 100644 src/views/intelligenceTest/runningTask/index.vue delete mode 100644 src/views/intelligenceTest/runningTask/task-log.vue delete mode 100644 src/views/intelligenceTest/runningTask/task-steps.vue delete mode 100644 src/views/intelligenceTest/taskManage/index.vue delete mode 100644 src/views/intelligenceTest/testCase/index.vue delete mode 100644 src/views/login.vue delete mode 100644 src/views/monitor/cache/index.vue delete mode 100644 src/views/monitor/cache/list.vue delete mode 100644 src/views/monitor/druid/index.vue delete mode 100644 src/views/monitor/job/detail.vue delete mode 100644 src/views/monitor/job/index.vue delete mode 100644 src/views/monitor/job/log.vue delete mode 100644 src/views/monitor/logininfor/index.vue delete mode 100644 src/views/monitor/online/index.vue delete mode 100644 src/views/monitor/operlog/detail.vue delete mode 100644 src/views/monitor/operlog/index.vue delete mode 100644 src/views/monitor/server/index.vue delete mode 100644 src/views/redirect/index.vue delete mode 100644 src/views/register.vue delete mode 100644 src/views/resource/device/index.vue delete mode 100644 src/views/resource/map/index.vue delete mode 100644 src/views/resource/robot/index.vue delete mode 100644 src/views/resource/terminal/index.vue delete mode 100644 src/views/system/config/index.vue delete mode 100644 src/views/system/dept/index.vue delete mode 100644 src/views/system/dict/data.vue delete mode 100644 src/views/system/dict/detail.vue delete mode 100644 src/views/system/dict/index.vue delete mode 100644 src/views/system/file/index.vue delete mode 100644 src/views/system/group/index.vue delete mode 100644 src/views/system/menu/index.vue delete mode 100644 src/views/system/notice/ReadUsers.vue delete mode 100644 src/views/system/notice/index.vue delete mode 100644 src/views/system/post/index.vue delete mode 100644 src/views/system/role/authUser.vue delete mode 100644 src/views/system/role/index.vue delete mode 100644 src/views/system/role/selectUser.vue delete mode 100644 src/views/system/user/authRole.vue delete mode 100644 src/views/system/user/index.vue delete mode 100644 src/views/system/user/profile/index.vue delete mode 100644 src/views/system/user/profile/resetPwd.vue delete mode 100644 src/views/system/user/profile/userAvatar.vue delete mode 100644 src/views/system/user/profile/userInfo.vue delete mode 100644 src/views/system/user/view.vue delete mode 100644 src/views/system/vehOper/index.vue delete mode 100644 src/views/tool/build/CodeTypeDialog.vue delete mode 100644 src/views/tool/build/DraggableItem.vue delete mode 100644 src/views/tool/build/IconsDialog.vue delete mode 100644 src/views/tool/build/RightPanel.vue delete mode 100644 src/views/tool/build/TreeNodeDialog.vue delete mode 100644 src/views/tool/build/index.vue delete mode 100644 src/views/tool/gen/basicInfoForm.vue delete mode 100644 src/views/tool/gen/createTable.vue delete mode 100644 src/views/tool/gen/editTable.vue delete mode 100644 src/views/tool/gen/genInfoForm.vue delete mode 100644 src/views/tool/gen/importTable.vue delete mode 100644 src/views/tool/gen/index.vue delete mode 100644 src/views/tool/swagger/index.vue diff --git a/src/views/error/401.vue b/src/views/error/401.vue deleted file mode 100644 index b361368..0000000 --- a/src/views/error/401.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - - - diff --git a/src/views/error/404.vue b/src/views/error/404.vue deleted file mode 100644 index f205303..0000000 --- a/src/views/error/404.vue +++ /dev/null @@ -1,227 +0,0 @@ - - - - - diff --git a/src/views/flow/components/ActionQueueSingleRun.vue b/src/views/flow/components/ActionQueueSingleRun.vue deleted file mode 100644 index baf3a56..0000000 --- a/src/views/flow/components/ActionQueueSingleRun.vue +++ /dev/null @@ -1,281 +0,0 @@ - - - - - diff --git a/src/views/flow/components/Aside.vue b/src/views/flow/components/Aside.vue deleted file mode 100644 index a818eef..0000000 --- a/src/views/flow/components/Aside.vue +++ /dev/null @@ -1,251 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/FormItemRecursive.vue b/src/views/flow/components/FormItemRecursive.vue deleted file mode 100644 index 7c0e324..0000000 --- a/src/views/flow/components/FormItemRecursive.vue +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - - diff --git a/src/views/flow/components/LoopIterationResults.vue b/src/views/flow/components/LoopIterationResults.vue deleted file mode 100644 index cb311a6..0000000 --- a/src/views/flow/components/LoopIterationResults.vue +++ /dev/null @@ -1,217 +0,0 @@ - - - - - diff --git a/src/views/flow/components/NodeState.vue b/src/views/flow/components/NodeState.vue deleted file mode 100644 index d53e966..0000000 --- a/src/views/flow/components/NodeState.vue +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - diff --git a/src/views/flow/components/NodeTitle.vue b/src/views/flow/components/NodeTitle.vue deleted file mode 100644 index f8e4e76..0000000 --- a/src/views/flow/components/NodeTitle.vue +++ /dev/null @@ -1,338 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/OuterNode.vue b/src/views/flow/components/OuterNode.vue deleted file mode 100644 index 0cdc977..0000000 --- a/src/views/flow/components/OuterNode.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/ParamsDrawer.vue b/src/views/flow/components/ParamsDrawer.vue deleted file mode 100644 index d26cd31..0000000 --- a/src/views/flow/components/ParamsDrawer.vue +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/RuntimeAssignmentsEditor.vue b/src/views/flow/components/RuntimeAssignmentsEditor.vue deleted file mode 100644 index 96a41e3..0000000 --- a/src/views/flow/components/RuntimeAssignmentsEditor.vue +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/RuntimeParamsEditor.vue b/src/views/flow/components/RuntimeParamsEditor.vue deleted file mode 100644 index 2b8784a..0000000 --- a/src/views/flow/components/RuntimeParamsEditor.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/SubFlowExecutionResults.vue b/src/views/flow/components/SubFlowExecutionResults.vue deleted file mode 100644 index 54f6c45..0000000 --- a/src/views/flow/components/SubFlowExecutionResults.vue +++ /dev/null @@ -1,173 +0,0 @@ - - - - - diff --git a/src/views/flow/components/TaskExecutionLog.vue b/src/views/flow/components/TaskExecutionLog.vue deleted file mode 100644 index c698d7d..0000000 --- a/src/views/flow/components/TaskExecutionLog.vue +++ /dev/null @@ -1,889 +0,0 @@ - - - - - diff --git a/src/views/flow/components/TestRun.vue b/src/views/flow/components/TestRun.vue deleted file mode 100644 index c823b81..0000000 --- a/src/views/flow/components/TestRun.vue +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/ActionQueueParams.vue b/src/views/flow/components/params/ActionQueueParams.vue deleted file mode 100644 index 104bc86..0000000 --- a/src/views/flow/components/params/ActionQueueParams.vue +++ /dev/null @@ -1,585 +0,0 @@ - - - - - diff --git a/src/views/flow/components/params/BasicNodeParams.vue b/src/views/flow/components/params/BasicNodeParams.vue deleted file mode 100644 index dfb1413..0000000 --- a/src/views/flow/components/params/BasicNodeParams.vue +++ /dev/null @@ -1,598 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/CodeNodeParams.vue b/src/views/flow/components/params/CodeNodeParams.vue deleted file mode 100644 index bdac619..0000000 --- a/src/views/flow/components/params/CodeNodeParams.vue +++ /dev/null @@ -1,501 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/DeviceUniversal.vue b/src/views/flow/components/params/DeviceUniversal.vue deleted file mode 100644 index b3f1b95..0000000 --- a/src/views/flow/components/params/DeviceUniversal.vue +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/EndParams.vue b/src/views/flow/components/params/EndParams.vue deleted file mode 100644 index a80fdf7..0000000 --- a/src/views/flow/components/params/EndParams.vue +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/HttpNodeParams.vue b/src/views/flow/components/params/HttpNodeParams.vue deleted file mode 100644 index b3417fb..0000000 --- a/src/views/flow/components/params/HttpNodeParams.vue +++ /dev/null @@ -1,704 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/ImageAnalysisParams.vue b/src/views/flow/components/params/ImageAnalysisParams.vue deleted file mode 100644 index 779cfad..0000000 --- a/src/views/flow/components/params/ImageAnalysisParams.vue +++ /dev/null @@ -1,431 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/MediaAnalysisParams.vue b/src/views/flow/components/params/MediaAnalysisParams.vue deleted file mode 100644 index b53d4af..0000000 --- a/src/views/flow/components/params/MediaAnalysisParams.vue +++ /dev/null @@ -1,567 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/RecognizeNodeParams.vue b/src/views/flow/components/params/RecognizeNodeParams.vue deleted file mode 100644 index b339d05..0000000 --- a/src/views/flow/components/params/RecognizeNodeParams.vue +++ /dev/null @@ -1,387 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/RobotExecutionTarget.vue b/src/views/flow/components/params/RobotExecutionTarget.vue deleted file mode 100644 index b87c223..0000000 --- a/src/views/flow/components/params/RobotExecutionTarget.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - - - diff --git a/src/views/flow/components/params/SdAgentNodeParams.vue b/src/views/flow/components/params/SdAgentNodeParams.vue deleted file mode 100644 index 64a580d..0000000 --- a/src/views/flow/components/params/SdAgentNodeParams.vue +++ /dev/null @@ -1,390 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/StartParams.vue b/src/views/flow/components/params/StartParams.vue deleted file mode 100644 index cf68381..0000000 --- a/src/views/flow/components/params/StartParams.vue +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/SubFlowParams.vue b/src/views/flow/components/params/SubFlowParams.vue deleted file mode 100644 index 65c60d8..0000000 --- a/src/views/flow/components/params/SubFlowParams.vue +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/SwitchNodeParams.vue b/src/views/flow/components/params/SwitchNodeParams.vue deleted file mode 100644 index 2073e29..0000000 --- a/src/views/flow/components/params/SwitchNodeParams.vue +++ /dev/null @@ -1,413 +0,0 @@ - - - - - - diff --git a/src/views/flow/components/params/useQuote.js b/src/views/flow/components/params/useQuote.js deleted file mode 100644 index 35c9861..0000000 --- a/src/views/flow/components/params/useQuote.js +++ /dev/null @@ -1,43 +0,0 @@ -import { ref } from 'vue' -import { getUpstreamInput } from '@/utils/flow' - -export function useQuote(nodeId) { - const quoteOptions = ref([]) - const cascaderRefs = ref([]) - - const refreshQuoteOptions = () => { - quoteOptions.value = getUpstreamInput(nodeId) || [] - } - - // The option tree must exist before Cascader can render a persisted path. - refreshQuoteOptions() - - const handleTypeChange = (property) => { - if (!property) return - if (property.type === 'input') { - property.quote = [] - } else { - property.input = '' - refreshQuoteOptions() - } - } - - const cascaderChange = (value, property) => { - if (!property) return - property.quote = Array.isArray(value) ? [...value] : [] - property.quoteType = value?.[1] === 'input' ? 'input' : 'output' - } - - const visibleChange = (visible) => { - if (visible) refreshQuoteOptions() - } - - return { - quoteOptions, - cascaderRefs, - handleTypeChange, - cascaderChange, - visibleChange, - refreshQuoteOptions, - } -} diff --git a/src/views/flow/composables/useFlowEvents.js b/src/views/flow/composables/useFlowEvents.js deleted file mode 100644 index 39353ae..0000000 --- a/src/views/flow/composables/useFlowEvents.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 文件说明:流程事件订阅组合逻辑,并在卸载时释放监听器。 - * 作用范围:仅服务于流程设计器模块。 - */ -import { onUnmounted } from "vue"; -import { emitter } from "@/utils/eventBus"; - -export const useFlowEvents = () => { - const listeners = []; - - /** - * 订阅 onFlowEvent 对应的数据或交互;作用范围仅限当前组件或模块。 - * @param {*} type 目标类型 - * @param {*} handler 事件处理函数 - */ - const onFlowEvent = (type, handler) => { - emitter.on(type, handler); - listeners.push([type, handler]); - }; - - onUnmounted(() => { - listeners.forEach(([type, handler]) => emitter.off(type, handler)); - listeners.length = 0; - }); - - return { onFlowEvent }; -}; diff --git a/src/views/flow/config.js b/src/views/flow/config.js deleted file mode 100644 index cb7451c..0000000 --- a/src/views/flow/config.js +++ /dev/null @@ -1,897 +0,0 @@ -/** - * 文件说明:定义流程设计器可用的节点、表单字段及下拉选项等静态配置。 - * 作用范围:仅服务于流程设计器模块。 - */ -import cameraSvg from './icon/camera.svg' -import videoSvg from './icon/video.svg' -import loopSvg from './icon/loop.svg' -import stopLoopSvg from './icon/stopLoop.svg' -import switchSvg from './icon/switch.svg' -import microphoneSvg from './icon/microphone.svg' -import sleepSvg from './icon/sleep.svg' -import planSvg from './icon/plan.svg' -import awakenSvg from './icon/awaken.svg' -import dialogueSvg from './icon/dialogue.svg' -import audioSvg from './icon/audio.svg' -import touchSvg from './icon/touch.svg' -import expressionSvg from './icon/expression.svg' - -/** - * 处理与 http method options 相关的状态或数据,该影响范围仅限当前模块。 - */ -const httpMethodOptions = () => { - return [{ - value: 'POST', - label: 'POST' - }, { - value: 'GET', - label: 'GET' - }, { - value: 'PUT', - label: 'PUT' - }, { - value: 'DELETE', - label: 'DELETE' - }] -} - -/** - * 处理与 express options 相关的状态或数据,该影响范围仅限当前模块。 - */ -const expressOptions = () => { - return [{ - value: 1, - label: '高兴' - }, { - value: 2, - label: '惊讶' - }, { - value: 3, - label: '愤怒' - }, { - value: 4, - label: '悲伤' - }, { - value: 5, - label: '睡觉' - }, { - value: 6, - label: '打哈欠' - }] -} - -/** - * 处理与 task type options 相关的状态或数据,该影响范围仅限当前模块。 - */ -const taskTypeOptions = () => { - return [{ - value: 'voice', - label: '语音交互' - }, { - value: 'touch', - label: '触控交互' - }] -} - -/** - * 处理与 voice options 相关的状态或数据,该影响范围仅限当前模块。 - */ -const voiceOptions = () => { - return [{ - value: 'x4_xiaoyan', - label: 'x4_xiaoyan' - }] -} - -/** - * 处理与 inspection event types 相关的状态或数据,该影响范围仅限当前模块。 - */ -const inspectionEventTypes = () => { - return [{ - value: 'No-Glove', - label: '没戴手套' - }, { - value: 'No-Helmet-Glove', - label: '没戴头盔' - }] -} - -export const collapseList = [ - { - collapseTitle: "相机", - nodeList: [ - { - icon: cameraSvg, - name: "开启相机", - type: "serviceNode", - desc: "在获取相机照片时,需要先启动相机", - action: 'CAMERA_START', - nodeType: 'EDGE', - nodeParams: [], - outputParams: [], - outputType: 'json' - }, - { - icon: cameraSvg, - name: "获取图片", - type: "serviceNode", - desc: "获取相机拍摄的照片", - action: 'CAMERA_GETRGBIMAGE', - nodeType: 'EDGE', - nodeParams: [], - outputType: 'img', - outputParams: [{ name: 'imageUrl', type: 'array', desc: '图片地址数组', children: [], disabled: true }] - }, - { - icon: cameraSvg, - name: "关闭相机", - type: "serviceNode", - desc: "获取相机照片后,关闭该相机", - action: 'CAMERA_STOP', - nodeType: 'EDGE', - nodeParams: [], - outputParams: [], - outputType: 'json' - }, - ], - }, - { - collapseTitle: "录像", - nodeList: [ - { - icon: videoSvg, - name: "开启录像", - type: "serviceNode", - desc: "开启摄像头,并开始录像", - action: 'CAMERA_RECORDING_START', - nodeType: 'EDGE', - nodeParams: [], - outputParams: [], - outputType: 'json' - }, - { - icon: videoSvg, - name: "结束录像", - type: "serviceNode", - desc: "停止录像,并关闭摄像头", - action: 'CAMERA_RECORDING_STOP', - nodeType: 'EDGE', - nodeParams: [], - outputType: 'video', - outputParams: [{ name: 'videoUrl', type: 'array', children: [], desc: '视频播放地址数组', disabled: true}] - } - ], - }, - { - collapseTitle: "功能", - nodeList: [ - { - icon: loopSvg, - name: "循环", - type: "loop", - action: 'START_LOOP', - desc: "实现对列表对象循环执行一系列任务", - nodeParams: [{ name: "loopNum", type: "input", input: null, quote: "" }], - outputParams: [], - outputType: 'json' - }, - { - icon: planSvg, - name: "子流程", - type: "subFlow", - action: 'SUB_FLOW', - nodeType: 'NONE', - desc: "执行同一项目中已发布的工作流", - subFlow: {}, - nodeParams: [], - outputParams: [], - outputType: 'json' - }, - { - icon: stopLoopSvg, - name: "结束循环", - type: "stopLoop", - action: 'STOP_LOOP', - desc: "用于立即终止当前所在的循环,跳出循环体", - }, - // { - // icon: startSvg, - // name: "单次循环开始", - // type: "subStart", - // action: 'SUB_START', - // desc: "循环体内部工作流的开始节点,开始循环体内部的单次流程", - // }, - // { - // icon: endSvg, - // name: "单次循环结束", - // type: "subEnd", - // action: 'SUB_END', - // desc: "循环体内部工作流的终止节点,结束循环体内部的单次流程", - // }, - { - icon: switchSvg, - name: "分支", - type: "branch", - action: 'BRANCH', - desc: "连接多个下游分支,根据设定的条件按照顺序查找的方式来匹配运行的分支,如果匹配到某条件则只运行该条件对应的分支,否则继续匹配下一条件直至结束", - }, - { - icon: sleepSvg, - name: "睡眠", - type: "sleep", - desc: "用于睡眠整个流程,表示延迟多少毫秒", - action: 'sleep', - nodeParams: [ - { name: "delayMs", type: "input", componentType: 'number', input: 0, disabled: true } - ], - outputParams: [], - outputType: 'json' - }, - { - icon: expressionSvg, - name: "HTTP请求", - type: "http", - desc: "HTTP请求", - action: 'HTTP', - nodeType: 'HTTP', - nodeParams: [ - { name: "config", type: "input", input: "", children: [ - { name: "url", type: "input", input: "", disabled: true, required: true }, - { name: "method", type: "input", input: "POST", componentType: 'select', selectOptions: httpMethodOptions(), disabled: true }, - { name: "timeout", type: "input", input: "10000", componentType: 'number', required: false, disabled: true } - ], disabled: true, required: true }, - { name: "headers", type: "input", input: "", children: [ - { name: "", type: "input", input: ""} - ], disabled: true, required: true }, - { name: "params", type: "input", input: "", children: [ - { name: "", type: "input", input: ""} - ], disabled: true, required: true }, - { name: "body", type: "input", input: "", children: [ - { name: 'bodyType', type: "input", input: "json", disabled: true }, - { name: 'json', type: "input", input: '{"a": 123}' }, - { name: 'formData', type: "input", input: "", children: []} - ], required: true }, - ], - outputType: 'json', - outputParams: [{ name: 'result', type: 'Object', children: [], desc: 'HTTP请求结果'}] - }, - { - icon: expressionSvg, - name: "代码", - type: "code", - desc: "js代码", - action: 'CODE', - canAddFormItem: true, - nodeParams: [ - { name: "input", type: "input", input: "", required: true }, - { name: "code", type: "input", input: ` -// 方法定义不能修改 -/** - * 处理与 r 相关的状态或数据,该影响范围仅限当前模块。 - * @param {*} params 待处理的参数集合 - */ -function handler(params) { - // 返回值是一个可序列化成 json 的 dict 或 object - const result ={ - type: 2, - message: params.input - } - return result -} - `, required: true } - ], - outputType: 'json', - outputParams: [{ name: 'result', type: 'object', children: [ - {name: 'type', type: 'number', desc: '占位属性'}, - {name: 'message', type: 'string', desc: '占位属性'} - ], desc: 'js节点返回'}] - }, - { - icon: microphoneSvg, - name: "获取当前循环对象", - type: "currentLoop", - desc: "获取当前循环对象", - action: 'GET_CURRENT_OBJECT', - nodeParams: [ - { name: "array", type: "input", input: "" } - ], - outputType: 'json', - outputParams: [ - { name: 'index', type: 'number', desc: '索引'}, - { name: 'object', type: 'object', children: [ - { name: 'test', type: 'string', desc: '占位属性' } - ], desc: '当前循环对象', } - ] - }, - ], - }, - { - collapseTitle: "机器人", - nodeList: [ - { - icon: videoSvg, - name: "AGV控制", - type: "serviceNode", - desc: "控制机器人的底盘", - action: 'AGV_MOVE_TO_POINT', - nodeType: 'EDGE', - nodeParams: [ - { name: "x", type: "input", input: "", disabled: true }, - { name: "y", type: "input", input: "", disabled: true }, - { name: "theta", type: "input", input: "", disabled: true }, - { name: "blockedTimeoutMs", type: "input", componentType: "number", input: 60000, min: 1, required: true, disabled: true }, - ], - outputType: 'json' - }, - { - icon: videoSvg, - name: "AGV站点导航", - type: "serviceNode", - desc: "从AGV站点列表选择目标站点并导航", - action: 'AGV_MOVE_TO_STATION', - nodeType: 'EDGE', - nodeParams: [ - { name: "stationId", type: "input", input: "", componentType: 'select', selectOptions: [], forceSelect: true, disabled: true }, - { name: "blockedTimeoutMs", type: "input", componentType: "number", input: 60000, min: 1, required: true, disabled: true } - ], - outputType: 'json' - }, - { - icon: cameraSvg, - name: "通用指令", - type: "deviceUniversal", - desc: "执行设备通用指令", - action: 'DEVICE_EXECUTE_JSON_COMMAND', - nodeType: 'EDGE', - nodeParams: [ - { name: "requestJson", type: "input", input: `{ - "a":123 -}`, required: false, disabled: true }, - ], - outputParams: [], - outputType: 'json' - }, - { - icon: planSvg, - name: "动作队列", - type: "actionQueue", - desc: "在边缘端按顺序连续执行多个动作", - action: 'SYSTEM_EXECUTE_ACTION_QUEUE', - nodeType: 'EDGE', - nodeParams: [ - { name: "actionId", type: "input", input: "", required: false }, - { name: "totalTimeoutMs", type: "input", componentType: 'number', input: 60000, required: true }, - { name: "steps", type: "input", input: [], required: true }, - ], - outputParams: [ - { name: 'actionId', type: 'string', desc: '动作队列标识' }, - { name: 'completedSteps', type: 'number', desc: '已完成步骤数' }, - { name: 'result', type: 'string', desc: '执行结果' }, - ], - outputType: 'json' - }, - { - icon: videoSvg, - name: "机械臂", - type: "serviceNode", - desc: "控制机器人的手臂", - action: 'ARM_MOVE_TO_POINT', - nodeType: 'EDGE', - nodeParams: [ - { name: "x", type: "input", input: "", disabled: true }, - { name: "y", type: "input", input: "", disabled: true }, - { name: "z", type: "input", input: "", disabled: true }, - { name: "rx", type: "input", input: "", disabled: true }, - { name: "ry", type: "input", input: "", disabled: true }, - { name: "rz", type: "input", input: "", disabled: true }, - { name: "velocity", type: "input", componentType: 'number', max: 5, step: 0.01, input: 0.1, disabled: true }, - { name: "acceleration", type: "input", componentType: 'number', max: 5, step: 0.01, input: 0.2, disabled: true }, - ], - outputType: 'json' - }, - { - icon: videoSvg, - name: "机械臂关节运动", - type: "serviceNode", - desc: "通过关节空间插值运动到目标关节位置", - action: 'ARM_MOVE_TO_J', - nodeType: 'EDGE', - nodeParams: [ - { name: "target", type: "input", input: "[0, 0, 0, 0, 0, 0]", disabled: true }, - { name: "velocity", type: "input", componentType: 'number', max: 5, step: 0.01, input: 0.1, disabled: true }, - { name: "acceleration", type: "input", componentType: 'number', max: 5, step: 0.01, input: 0.2, disabled: true }, - ], - outputType: 'json' - }, - // 使能状态由两个独立节点显式控制。节点本身不接收参数,也不依赖前一运动节点的隐式使能, - // 因而可在流程开始、异常恢复或任务收尾位置按业务需要自由编排。 - { - icon: videoSvg, - name: "开启机械臂使能", - type: "serviceNode", - desc: "开启机械臂使能,后续运动节点不会自动使能", - action: 'ARM_ENABLE', - nodeType: 'EDGE', - nodeParams: [], - outputParams: [], - outputType: 'json' - }, - // 关闭节点与开启节点使用不同 action,边缘执行器据此下发去使能指令; - // 空 outputParams 表示该节点只负责设备状态切换,不向后续节点暴露业务输出。 - { - icon: videoSvg, - name: "关闭机械臂使能", - type: "serviceNode", - desc: "关闭机械臂使能", - action: 'ARM_DISABLE', - nodeType: 'EDGE', - nodeParams: [], - outputParams: [], - outputType: 'json' - }, - { - icon: cameraSvg, - name: "开始监听报警事件", - type: "serviceNode", - desc: "开始监听报警事件", - action: 'INSPECTION_ALERT_LISTEN_START', - nodeType: 'EDGE', - nodeParams: [ - { name: "robotId", type: "input", input: "", disabled: true }, - { name: "eventTypes", type: "input", input: "", componentType: 'select', selectOptions: inspectionEventTypes(), disabled: true } - ], - outputParams: [], - outputType: 'json' - }, - { - icon: cameraSvg, - name: "结束监听报警事件", - type: "serviceNode", - desc: "结束监听报警事件", - action: 'INSPECTION_ALERT_LISTEN_STOP', - nodeType: 'EDGE', - nodeParams: [ - { name: "robotId", type: "input", input: "", disabled: true }, - { name: "eventTypes", type: "input", input: "", componentType: 'select', selectOptions: inspectionEventTypes(), disabled: true } - ], - outputParams: [], - outputType: 'json' - }, - { - icon: dialogueSvg, - name: "巡检仪表读数识别", - type: "recognize", - desc: "巡检仪表读数识别", - action: 'INSPECTION_METER_RECOGNIZE', - nodeType: "LLM", - outputType: 'json', - nodeParams: [ - { name: 'imageUrl', type: "input", input: "", disabled: true }, - { name: 'resultName', type: "input", input: "", disabled: true }, - { name: "alarmRules", type: "input", input: [], disabled: true } - ], - outputParams: [] - }, - { - icon: cameraSvg, - name: "人工巡检判断", - type: "serviceNode", - desc: "创建人工巡检判断任务", - action: 'INSPECTION_MANUAL_REVIEW_CREATE', - nodeType: 'EDGE', - nodeParams: [ - { name: "resultName", type: "input", input: "", disabled: true }, - { name: "videoUrl", type: "input", input: "", required: false, disabled: true }, - { name: "imageUrl", type: "input", input: "", required: false, disabled: true }, - { name: "reviewCriteria", type: "input", input: "", disabled: true }, - { name: "defaultAlarmLevel", type: "input", componentType: 'number', max: 3, step: 1, input: 1, disabled: true }, - ], - outputParams: [], - outputType: 'json' - }, - ], - }, - { - collapseTitle: "音频", - nodeList: [ - { - icon: microphoneSvg, - name: "启动麦克风", - type: "serviceNode", - desc: "用于启动麦克风的节点", - action: 'MICROPHONE_START', - nodeType: 'EDGE', - nodeParams: [], - outputType: 'json' - }, - { - icon: microphoneSvg, - name: "停止麦克风", - type: "serviceNode", - desc: "用于停止麦克风的节点", - action: 'MICROPHONE_STOP', - nodeType: 'EDGE', - nodeParams: [], - outputType: 'audio', - outputParams: [{ name: 'audioUrl', type: 'array', children: [], desc: '录音播放地址数组', disabled: true }] - }, - { - icon: audioSvg, - name: "播放音频", - type: "serviceNode", - desc: "用于播放音频的节点", - action: 'SPEAKER_PLAYAUDIO', - nodeType: 'EDGE', - nodeParams: [ - { name: "audioPath", type: "input", input: "", disabled: true } - ], - outputType: 'json' - }, - ], - }, - { - collapseTitle: "大模型", - nodeList: [ - { - icon: microphoneSvg, - name: "声音类型检测", - type: "mediaAnalysis", - desc: "判断录音是否属于指定的声音类型", - action: "AUDIO_EVENT_CLASSIFY", - nodeType: "LLM", - nodeParams: [ - { name: "profileCode", type: "input", input: "aima.power_state.v1", required: true, disabled: true }, - { name: "expectedLabel", type: "input", input: "", required: true, disabled: true }, - { name: "expectedLabelName", type: "input", input: "", required: false, disabled: true }, - { name: "audioUrl", type: "quote", input: "", quote: "", required: true, disabled: true }, - { name: "asynchronous", type: "input", input: false, required: false, disabled: true, componentType: "switch" }, - ], - outputType: "json", - outputParams: [ - { name: "passed", type: "boolean", desc: "是否检测到目标声音", disabled: true }, - { name: "expectedLabel", type: "string", desc: "目标声音类型编码", disabled: true }, - { name: "expectedLabelName", type: "string", desc: "目标声音类型名称", disabled: true }, - { name: "label", type: "string", desc: "实际声音类型编码,未匹配时为UNKNOWN", disabled: true }, - { name: "labelName", type: "string", desc: "实际声音类型名称", disabled: true }, - { name: "matched", type: "boolean", desc: "是否识别到已知声音", disabled: true }, - { name: "confidence", type: "number", desc: "最高匹配度", disabled: true }, - { name: "decisionReason", type: "string", desc: "检测结论", disabled: true }, - { name: "scores", type: "object", desc: "各分类匹配度", children: [], disabled: true }, - ], - }, - { - icon: videoSvg, - name: "视频智能分析", - type: "mediaAnalysis", - desc: "按分析场景理解测试录像并输出结构化结论", - action: "VIDEO_ANALYZE", - nodeType: "LLM", - nodeParams: [ - { name: "profileCode", type: "input", input: "aima.power_video.v1", required: true, disabled: true }, - { name: "videoUrl", type: "quote", input: "", quote: "", required: true, disabled: true }, - { name: "instruction", type: "input", input: "", required: true, disabled: true }, - { name: "analysisMode", type: "input", input: "AUTO", required: false, disabled: true }, - // 默认返回精简结论;用户开启详细输出时,执行端才补充事件证据。 - { name: "detailedOutput", type: "input", input: false, required: false, disabled: true, componentType: "switch" }, - { name: "analysisTuning", type: "input", input: { sampleFps: 2, maxWidth: 960, confidenceThreshold: 0.75, fallbackToAccurate: true }, required: false, disabled: true }, - { name: "asynchronous", type: "input", input: false, required: false, disabled: true, componentType: "switch" }, - ], - outputType: "json", - outputParams: [ - { name: "result", type: "string", desc: "分析结果", disabled: true }, - { name: "passed", type: "boolean", desc: "是否通过", disabled: true }, - { name: "confidence", type: "number", desc: "判定置信度", disabled: true }, - { name: "evidenceSufficient", type: "boolean", desc: "证据是否充分", disabled: true }, - { name: "decisionReason", type: "string", desc: "判定原因", disabled: true }, - { name: "conclusion", type: "string", desc: "分析结论", disabled: true }, - { name: "summary", type: "string", desc: "分析摘要", disabled: true }, - { name: "events", type: "array", desc: "关键事件", children: [], disabled: true }, - { name: "analysisMode", type: "string", desc: "实际分析模式", disabled: true }, - { name: "fallback", type: "boolean", desc: "是否切换精确分析", disabled: true }, - { name: "detailedOutput", type: "boolean", desc: "是否返回详细事件证据", disabled: true }, - ], - }, - { - // 通用图片分析不内置通过/不通过判定,返回结构完全由用户提示词约定。 - icon: cameraSvg, - name: "通用图片分析", - type: "imageAnalysis", - desc: "按照提示词分析一张或多张图片并返回指定内容", - action: 'IMAGE_ANALYZE', - nodeType: "LLM", - nodeParams: [ - { name: "profileCode", type: "input", input: "common.image_analysis.v1", required: true, disabled: true }, - { name: "imageUrl", type: "quote", input: "", quote: "", required: true, disabled: true }, - { name: "analysisMethod", type: "input", input: "VISION_MODEL", required: false, disabled: true }, - { name: "prompt", type: "input", input: "", required: true, disabled: true, componentType: "textarea" }, - { name: "analysisMode", type: "input", input: "FAST", required: false, disabled: true }, - { name: "analysisTuning", type: "input", input: { maxWidth: 896, maxImages: 12, maxOutputTokens: 384, matchThreshold: 0.48, matchSelector: "BEST", matchIndex: 1, matchSort: "ROW_MAJOR", locateConfidenceThreshold: 0.45 }, required: false, disabled: true }, - { name: "asynchronous", type: "input", input: false, required: false, disabled: true, componentType: "switch" }, - ], - outputType: "json", - outputParams: [ - { name: "result", type: "object", desc: "按提示词返回的结果", children: [], disabled: true }, - { name: "resultText", type: "string", desc: "模型返回的原始文本", disabled: true }, - { name: "matched", type: "boolean", desc: "找图是否匹配", disabled: true }, - { name: "matchScore", type: "number", desc: "匹配分数或定位置信度", disabled: true }, - { name: "coordinates", type: "array", desc: "原图坐标 [x1,y1,x2,y2]", children: [], disabled: true }, - { name: "center", type: "array", desc: "目标中心点 [x,y]", children: [], disabled: true }, - { name: "matchedDescription", type: "string", desc: "模型实际定位的目标描述", disabled: true }, - { name: "refinementMethod", type: "string", desc: "坐标精修方式", disabled: true }, - { name: "matchCount", type: "number", desc: "匹配项数量", disabled: true }, - { name: "matches", type: "array", desc: "全部匹配项", children: [], disabled: true }, - { name: "selectedMatchIndex", type: "number", desc: "当前选择的匹配序号", disabled: true }, - ], - }, - { - icon: microphoneSvg, - name: "获取触控坐标", - type: "serviceNode", - desc: "用于获取触控坐标的节点", - action: 'TOUCH_COORDINATES', - nodeType: "LLM", - nodeParams: [ - { name: "targetFeature", type: "input", input: "运动模式", disabled: true }, - { name: "manufacturer", type: "input", input: "xiaomi", disabled: true }, - { name: "vehType", type: "input", input: "su7", disabled: true }, - ], - outputType: 'json', - outputParams: [{ name: 'coordinates', type: 'object', children: [ - { name: 'x', type: 'number', desc: 'x坐标' }, - { name: 'y', type: 'number', desc: 'y坐标' } - ], desc: '坐标对象', }] - }, { - icon: dialogueSvg, - name: "tts语音合成", - type: "serviceNode", - desc: "将指令文本(text)处理合成语音,输出语音路径(audioPath)", - action: 'GENERATE_ADVANCED_AUDIO', - nodeType: "LLM", - outputType: 'json', - nodeParams: [{ name: 'text', type: "input", input: "", disabled: true }], - outputParams: [{ name: 'audioPath', type: 'string', desc: '语音路径', disabled: true}] - }, { - icon: dialogueSvg, - name: "意图识别", - type: "serviceNode", - desc: "意图识别,输出类型(type) 1: 语音交互 2: 触控交互 3: 闲聊 4: 知识问答", - action: 'INTENT_RECOGNITION', - nodeType: "LLM", - outputType: 'json', - nodeParams: [{ name: 'text', type: "input", input: "", disabled: true }], - outputParams: [{ name: 'type', type: 'string', desc: '1:语音交互 2:触控交互 3: 闲聊 4:知识问答', disabled: true}] - }, { - icon: dialogueSvg, - name: "商道智能体", - type: "sdAgent", - desc: "通过apiKey调用商道大模型", - action: 'AI_AGENT_PLATFORM', - nodeType: "LLM", - outputType: 'json', - nodeParams: [ - { name: "config", type: "input", input: "", children: [ - { name: 'apiKey', type: "input", input: "", disabled: true }, - { name: 'text', type: "input", input: "", disabled: true }, - ]}, - { name: 'invokeTts', type: "input", input: false }, - { name: 'tts', type: "input", input: "", children: [ - { name: 'url', type: "input", input: "", disabled: true }, - { name: 'text', type: "input", input: "", disabled: true }, - { name: 'speed', type: "input", input: "", max: 100, disabled: true }, - { name: 'voice', type: "input", input: "", componentType: 'select', selectOptions: voiceOptions(), disabled: true }, - { name: 'volume', type: "input", input: "", componentType: 'number', max: 100, disabled: true } - ], disabled: true } - ], - outputParams: [{ name: 'result', type: 'string', desc: '商道大模型的返回文案', disabled: true}] - }, { - icon: dialogueSvg, - name: "tts语音播放", - type: "serviceNode", - desc: "调用tts将文案转换为语音播放", - action: 'AI_TTS', - nodeType: "LLM", - outputType: 'json', - nodeParams: [ - { name: 'url', type: "input", input: "", disabled: true }, - { name: 'text', type: "input", input: "", disabled: true }, - { name: 'speed', type: "input", input: "", max: 100, disabled: true }, - { name: 'voice', type: "input", input: "", componentType: 'select', selectOptions: voiceOptions(), disabled: true }, - { name: 'volume', type: "input", input: "", componentType: 'number', max: 100, disabled: true } - ] - }, { - icon: dialogueSvg, - name: "获取当前页面名称", - type: "serviceNode", - desc: "获取当前页面名称", - action: 'GET_CURRENT_PAGE', - nodeType: "LLM", - outputType: 'json', - nodeParams: [ - { name: 'url', type: "input", input: "", disabled: true }, - ], - outputParams: [{ name: 'pageName', type: 'string', desc: '当前页面名称', disabled: true}] - } - ], - }, - { - collapseTitle: "语音交互", - nodeList: [ - { - icon: planSvg, - name: "方案处理", - type: "serviceNode", - desc: "语音交互-方案处理,输入方案id(schemeId),输出唤醒语料(wakeCorpus)和测试语料数组(testCorpus)", - action: 'VI_SCHEME', - nodeParams: [{ name: 'schemeId', type: "input", input: "", disabled: true }], - outputType: 'json', - outputParams: [ - { name: 'wakeCorpus', type: 'object', desc: '唤醒语料', children: []}, - { name: 'testCorpus', type: 'array', desc: '测试语料数组', children: []}, - { name: 'sceneType', type: 'number', desc: '1:唤醒测试,2:单次对话测试,3:连续对话测试', disabled: true } - ] - }, - { - icon: awakenSvg, - name: "唤醒语料", - type: "serviceNode", - desc: "唤醒语料处理,输入唤醒语料(wakeCorpus),输出语音路径(audioPath)", - action: 'VI_CORPUS_WAKE', - nodeType: "EDGE", - outputType: 'json', - nodeParams: [{ name: 'wakeCorpus', type: "input", input: "", disabled: true }], - outputParams: [{ name: 'audioPath', type: 'string', desc: '语音路径', disabled: true}] - }, - { - icon: dialogueSvg, - name: "单次对话语料", - type: "serviceNode", - desc: "测试语料-单次对话语料处理,输入单次对话语料(testCorpus),输出语音路径(audioPath)", - action: 'VI_CORPUS_SINGLE', - nodeType: "EDGE", - outputType: 'json', - nodeParams: [{ name: 'testCorpus', type: "input", input: "", disabled: true }], - outputParams: [{ name: 'audioPath', type: 'string', desc: '语音路径', disabled: true}] - }, - { - icon: dialogueSvg, - name: "连续对话语料", - type: "serviceNode", - desc: "测试语料-连续对话语料处理,输入连续对话语料(testCorpus),输出语音路径(audioPath)", - action: 'VI_CORPUS_CONTINUOUS', - nodeType: "EDGE", - outputType: 'json', - nodeParams: [{ name: 'testCorpus', type: "input", input: "", disabled: true }], - outputParams: [{ name: 'audioPath', type: 'string', desc: '语音路径', disabled: true}] - }, - { - icon: audioSvg, - name: "播放语料", - type: "serviceNode", - desc: "用于播放语料的节点,需要输入语音路径,执行设备由流程角色配置", - action: 'VI_PLAY_CORPUS', - nodeType: "EDGE", - outputType: 'json', - nodeParams: [ - { name: 'audioPath', type: "input", input: "", disabled: true }, - { name: 'bioId', type: "input", input: "", disabled: true, required: false } - ], - } - ], - }, - { - collapseTitle: "触控交互", - nodeList: [ - { - icon: touchSvg, - name: "触控", - type: "serviceNode", - desc: "去触控坐标的点位", - action: 'TOUCH', - nodeType: "EDGE", - nodeParams: [ - { name: "touchParams", type: "input", input: "", disabled: true } - ], - outputType: 'json', - }, - { - icon: expressionSvg, - name: "开始说话", - type: "serviceNode", - desc: "控制机器人说话", - action: 'BIO_HEAD_SPEAK_START', - nodeType: "EDGE", - nodeParams: [], - outputType: 'json', - }, - { - icon: expressionSvg, - name: "停止说话", - type: "serviceNode", - desc: "停止机器人说话", - action: 'BIO_HEAD_SPEAK_STOP', - nodeType: "EDGE", - nodeParams: [], - outputType: 'json', - }, - { - icon: expressionSvg, - name: "表情", - type: "serviceNode", - desc: "控制机器人的面部表情", - action: 'BIO_HEAD_SPECIAL_EXPRESSION', - nodeType: "EDGE", - nodeParams: [ - { name: "expressKey", type: "input",componentType: 'select', selectOptions: expressOptions(), disabled: true }, - ], - outputType: 'json', - }, - { - icon: touchSvg, - name: "路径搜索", - type: "serviceNode", - desc: "路径搜索", - action: 'TI_PATH_SEARCH', - nodeType: "EDGE", - nodeParams: [ - { name: "currentLocation", type: "input", input: "", disabled: true }, - { name: "funcId", type: "input", input: "", disabled: true }, - { name: "vehicleConfigId", type: "input", input: "", disabled: true }, - ], - outputType: 'json', - outputParams: [ - { name: 'nextLocation', type: 'string', desc: '下一路径位置', disabled: true}, - { name: 'isEnd', type: 'string', desc: '是否结束', disabled: true}, - { name: 'iconUrl', type: 'string', desc: '图标路径', disabled: true} - ] - }, - { - icon: touchSvg, - name: "获取触控二维坐标", - type: "serviceNode", - desc: "获取触控二维坐标", - action: 'TI_TOUCH_COORDINATES', - nodeType: "EDGE", - nodeParams: [ - { name: "imageUrl", type: "input", input: "", disabled: true }, - { name: "iconUrl", type: "input", input: "", disabled: true } - ], - outputType: 'json', - outputParams: [ - { name: 'touchCoordinates', type: 'string', desc: '触控二维坐标', disabled: true}, - ] - } - ], - }, - { - collapseTitle: "AI评估", - nodeList: [ - { - icon: expressionSvg, - name: "AI评估预处理", - type: "serviceNode", - desc: "AI评估预处理", - action: 'AI_EVALUATION_PRE', - nodeType: "AE", - nodeParams: [ - { name: "taskType", type: "input", input: "", componentType: 'select', selectOptions: taskTypeOptions(), disabled: true }, - { name: "wakeCorpus", type: "input", input: "", disabled: true, required: false }, - { name: "testCorpus", type: "input", input: "", disabled: true, required: false }, - { name: "sceneType", type: "input", input: "", disabled: true, required: false }, - ], - outputType: 'json', - }, - { - icon: touchSvg, - name: "AI评估执行", - type: "serviceNode", - desc: "AI评估执行", - action: 'AI_EVALUATION_END', - nodeType: "AE", - nodeParams: [ - { name: "videoUrl", type: "input", input: "", disabled: true } - ], - outputType: 'json', - } - ], - }, -] diff --git a/src/views/flow/icon/audio.svg b/src/views/flow/icon/audio.svg deleted file mode 100644 index e71eb39..0000000 --- a/src/views/flow/icon/audio.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/awaken.svg b/src/views/flow/icon/awaken.svg deleted file mode 100644 index 26b7a98..0000000 --- a/src/views/flow/icon/awaken.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/camera.svg b/src/views/flow/icon/camera.svg deleted file mode 100644 index 5d21dd9..0000000 --- a/src/views/flow/icon/camera.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/dialogue.svg b/src/views/flow/icon/dialogue.svg deleted file mode 100644 index b208067..0000000 --- a/src/views/flow/icon/dialogue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/end.svg b/src/views/flow/icon/end.svg deleted file mode 100644 index 81dc559..0000000 --- a/src/views/flow/icon/end.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/expression.svg b/src/views/flow/icon/expression.svg deleted file mode 100644 index ae84256..0000000 --- a/src/views/flow/icon/expression.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/group.svg b/src/views/flow/icon/group.svg deleted file mode 100644 index d2f250d..0000000 --- a/src/views/flow/icon/group.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/views/flow/icon/loop.svg b/src/views/flow/icon/loop.svg deleted file mode 100644 index 00e5311..0000000 --- a/src/views/flow/icon/loop.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/microphone.svg b/src/views/flow/icon/microphone.svg deleted file mode 100644 index d576328..0000000 --- a/src/views/flow/icon/microphone.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/views/flow/icon/plan.svg b/src/views/flow/icon/plan.svg deleted file mode 100644 index d166240..0000000 --- a/src/views/flow/icon/plan.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/sleep.svg b/src/views/flow/icon/sleep.svg deleted file mode 100644 index 75639ab..0000000 --- a/src/views/flow/icon/sleep.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/start.svg b/src/views/flow/icon/start.svg deleted file mode 100644 index 6e6db22..0000000 --- a/src/views/flow/icon/start.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/views/flow/icon/stopLoop.svg b/src/views/flow/icon/stopLoop.svg deleted file mode 100644 index 2cf73c6..0000000 --- a/src/views/flow/icon/stopLoop.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/switch.svg b/src/views/flow/icon/switch.svg deleted file mode 100644 index 58c1870..0000000 --- a/src/views/flow/icon/switch.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/views/flow/icon/touch.svg b/src/views/flow/icon/touch.svg deleted file mode 100644 index 44a14a5..0000000 --- a/src/views/flow/icon/touch.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/views/flow/icon/video.svg b/src/views/flow/icon/video.svg deleted file mode 100644 index 400695e..0000000 --- a/src/views/flow/icon/video.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/views/flow/index.vue b/src/views/flow/index.vue deleted file mode 100644 index e175c93..0000000 --- a/src/views/flow/index.vue +++ /dev/null @@ -1,2994 +0,0 @@ - - - - - diff --git a/src/views/flow/nodes/common/endNode.vue b/src/views/flow/nodes/common/endNode.vue deleted file mode 100644 index 17d291c..0000000 --- a/src/views/flow/nodes/common/endNode.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - diff --git a/src/views/flow/nodes/common/selectAreaNode.vue b/src/views/flow/nodes/common/selectAreaNode.vue deleted file mode 100644 index 27be9eb..0000000 --- a/src/views/flow/nodes/common/selectAreaNode.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - - diff --git a/src/views/flow/nodes/common/serviceNode.vue b/src/views/flow/nodes/common/serviceNode.vue deleted file mode 100644 index b8cc687..0000000 --- a/src/views/flow/nodes/common/serviceNode.vue +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/common/startNode.vue b/src/views/flow/nodes/common/startNode.vue deleted file mode 100644 index a88f2e4..0000000 --- a/src/views/flow/nodes/common/startNode.vue +++ /dev/null @@ -1,101 +0,0 @@ - - - - diff --git a/src/views/flow/nodes/function/actionQueue.vue b/src/views/flow/nodes/function/actionQueue.vue deleted file mode 100644 index c711e3b..0000000 --- a/src/views/flow/nodes/function/actionQueue.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - - - diff --git a/src/views/flow/nodes/function/codeNode.vue b/src/views/flow/nodes/function/codeNode.vue deleted file mode 100644 index 63e3112..0000000 --- a/src/views/flow/nodes/function/codeNode.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/function/currentLoop.vue b/src/views/flow/nodes/function/currentLoop.vue deleted file mode 100644 index 4299bcc..0000000 --- a/src/views/flow/nodes/function/currentLoop.vue +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/function/deviceUniversal.vue b/src/views/flow/nodes/function/deviceUniversal.vue deleted file mode 100644 index d10473c..0000000 --- a/src/views/flow/nodes/function/deviceUniversal.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/function/httpNode.vue b/src/views/flow/nodes/function/httpNode.vue deleted file mode 100644 index f58bd26..0000000 --- a/src/views/flow/nodes/function/httpNode.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/function/loop.vue b/src/views/flow/nodes/function/loop.vue deleted file mode 100644 index 702416b..0000000 --- a/src/views/flow/nodes/function/loop.vue +++ /dev/null @@ -1,265 +0,0 @@ - - - - diff --git a/src/views/flow/nodes/function/recognize.vue b/src/views/flow/nodes/function/recognize.vue deleted file mode 100644 index e9f4279..0000000 --- a/src/views/flow/nodes/function/recognize.vue +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/function/sdAgent.vue b/src/views/flow/nodes/function/sdAgent.vue deleted file mode 100644 index 458ee6c..0000000 --- a/src/views/flow/nodes/function/sdAgent.vue +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/function/sleep.vue b/src/views/flow/nodes/function/sleep.vue deleted file mode 100644 index 37c5f44..0000000 --- a/src/views/flow/nodes/function/sleep.vue +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - diff --git a/src/views/flow/nodes/function/stopLoop.vue b/src/views/flow/nodes/function/stopLoop.vue deleted file mode 100644 index e2f57c9..0000000 --- a/src/views/flow/nodes/function/stopLoop.vue +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - diff --git a/src/views/flow/nodes/function/subEnd.vue b/src/views/flow/nodes/function/subEnd.vue deleted file mode 100644 index 29b57df..0000000 --- a/src/views/flow/nodes/function/subEnd.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/src/views/flow/nodes/function/subFlow.vue b/src/views/flow/nodes/function/subFlow.vue deleted file mode 100644 index 546c8f8..0000000 --- a/src/views/flow/nodes/function/subFlow.vue +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - diff --git a/src/views/flow/nodes/function/subStart.vue b/src/views/flow/nodes/function/subStart.vue deleted file mode 100644 index 0675d52..0000000 --- a/src/views/flow/nodes/function/subStart.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/src/views/flow/nodes/function/switch.vue b/src/views/flow/nodes/function/switch.vue deleted file mode 100644 index 8d63bb2..0000000 --- a/src/views/flow/nodes/function/switch.vue +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - diff --git a/src/views/flow/vue-flow/FlowEdge.vue b/src/views/flow/vue-flow/FlowEdge.vue deleted file mode 100644 index ca50187..0000000 --- a/src/views/flow/vue-flow/FlowEdge.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - diff --git a/src/views/flow/vue-flow/FlowNode.vue b/src/views/flow/vue-flow/FlowNode.vue deleted file mode 100644 index a44b597..0000000 --- a/src/views/flow/vue-flow/FlowNode.vue +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - diff --git a/src/views/flow/vue-flow/adapter.js b/src/views/flow/vue-flow/adapter.js deleted file mode 100644 index c3c66e1..0000000 --- a/src/views/flow/vue-flow/adapter.js +++ /dev/null @@ -1,990 +0,0 @@ -/** - * 文件说明:旧流程数据与 Vue Flow 状态、操作 API 之间的兼容适配层。 - * 作用范围:仅服务于流程设计器模块。 - */ -import { nextTick } from "vue"; -import { v4 as uuid } from "uuid"; -import { MarkerType } from "@vue-flow/core"; - -/** - * 克隆 clone 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} value 待处理的新值 - */ -const clone = (value) => JSON.parse(JSON.stringify(value ?? {})); - -const GROUP_TYPES = new Set(["loop", "selectArea"]); -const TARGET_ONLY_TYPES = new Set(["end", "stopLoop", "subEnd"]); -const SOURCE_ONLY_TYPES = new Set(["start", "subStart"]); -const LOOP_BODY_INSET = { left: 24, top: 112, right: 24, bottom: 24 }; -const GROUP_BODY_INSET = { left: 24, top: 120, right: 24, bottom: 24 }; -const LOOP_MIN_SIZE = { width: 520, height: 360 }; - -/** - * 处理 loopChildExtent 对应的数据或交互;作用范围仅限画布适配层。 - */ -const loopChildExtent = () => ({ - range: "parent", - padding: [ - LOOP_BODY_INSET.top, - LOOP_BODY_INSET.right, - LOOP_BODY_INSET.bottom, - LOOP_BODY_INSET.left, - ], -}); - -/** - * 编组 groupChildExtent 对应的数据或交互;作用范围仅限画布适配层。 - */ -const groupChildExtent = () => ({ - range: "parent", - padding: [ - GROUP_BODY_INSET.top, - GROUP_BODY_INSET.right, - GROUP_BODY_INSET.bottom, - GROUP_BODY_INSET.left, - ], -}); - -/** - * 处理 nodeSize 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} node 当前流程节点 - */ -const nodeSize = (node) => { - // 分支节点采用统一的标准卡片尺寸,忽略旧流程数据中遗留的大尺寸记录。 - if (node.type === "branch") return { width: 372, height: 180 }; - const width = Number(node.properties?.width || node.width); - const height = Number(node.properties?.height || node.height); - if (Number.isFinite(width) && Number.isFinite(height)) { - return { width, height }; - } - if (GROUP_TYPES.has(node.type)) return { width: 720, height: 460 }; - if (TARGET_ONLY_TYPES.has(node.type) || SOURCE_ONLY_TYPES.has(node.type)) { - return { width: 328, height: 120 }; - } - return { width: 372, height: 180 }; -}; - -/** - * 处理 edgeId 对应的数据或交互;作用范围仅限画布适配层。 - */ -const edgeId = () => `edge_${uuid().replace(/-/g, "")}`; -/** - * 处理 nodeId 对应的数据或交互;作用范围仅限画布适配层。 - */ -const nodeId = () => uuid().replace(/-/g, ""); - -/** - * 处理 toVueNode 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} node 当前流程节点 - * @param {*} sizeOverride 调用方传入的 sizeOverride 参数 - * @param {*} positionOverride 调用方传入的 positionOverride 参数 - */ -const toVueNode = (node, sizeOverride, positionOverride) => { - const normalized = clone(node); - normalized.id ||= nodeId(); - normalized.properties ||= {}; - const overrideWidth = Number(sizeOverride?.width); - const overrideHeight = Number(sizeOverride?.height); - const size = Number.isFinite(overrideWidth) && overrideWidth > 0 - && Number.isFinite(overrideHeight) && overrideHeight > 0 - ? { width: overrideWidth, height: overrideHeight } - : nodeSize(normalized); - const center = { - x: Number(normalized.x) || 0, - y: Number(normalized.y) || 0, - }; - const overrideX = Number(positionOverride?.x); - const overrideY = Number(positionOverride?.y); - const position = Number.isFinite(overrideX) && Number.isFinite(overrideY) - ? { x: overrideX, y: overrideY } - : { - x: center.x - size.width / 2, - y: center.y - size.height / 2, - }; - - const dimensions = GROUP_TYPES.has(normalized.type) - ? { width: size.width, height: size.height } - : { width: size.width }; - - return { - id: normalized.id, - type: "flow-node", - position, - ...dimensions, - draggable: normalized.draggable !== false, - selectable: true, - deletable: !SOURCE_ONLY_TYPES.has(normalized.type) && normalized.type !== "end", - connectable: true, - zIndex: GROUP_TYPES.has(normalized.type) ? 0 : 2, - data: { - flowType: normalized.type, - properties: normalized.properties, - children: Array.isArray(normalized.children) ? normalized.children : [], - text: normalized.text, - backend: normalized, - originalCenter: center, - originalPosition: position, - size, - }, - }; -}; - -/** - * 处理 toVueEdge 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} edge 调用方传入的 edge 参数 - */ -const toVueEdge = (edge) => { - const normalized = clone(edge); - normalized.id ||= edgeId(); - return { - id: normalized.id, - source: normalized.sourceNodeId, - target: normalized.targetNodeId, - sourceHandle: normalized.sourceAnchorId || null, - targetHandle: normalized.targetAnchorId || null, - type: "flow-edge", - animated: true, - selectable: true, - focusable: true, - deletable: true, - interactionWidth: 32, - markerEnd: { - type: MarkerType.ArrowClosed, - color: "#ff6b35", - width: 20, - height: 20, - }, - style: { stroke: "#ff6b35", strokeWidth: 2 }, - data: { backend: normalized }, - }; -}; - -/** - * 关联 attachChildrenToGroups 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} nodes 调用方传入的 nodes 参数 - */ -const attachChildrenToGroups = (nodes) => { - // 先建立节点索引和显式父子关系,再用旧数据中的 children 补齐缺失关系。 - // 最后统一换算相对坐标,避免父节点尚未就绪时提前计算造成位置漂移。 - const nodeLookup = new Map(nodes.map((node) => [node.id, node])); - const declaredParents = new Map(); - - nodes.filter((node) => GROUP_TYPES.has(node.data.flowType)).forEach((group) => { - (group.data.children || []).forEach((childId) => { - if (!declaredParents.has(childId)) declaredParents.set(childId, group.id); - }); - }); - - nodes.forEach((child) => { - const parentId = child.data.properties?.parentId || declaredParents.get(child.id); - const parent = nodeLookup.get(parentId); - if (!parent || !GROUP_TYPES.has(parent.data.flowType) || GROUP_TYPES.has(child.data.flowType)) return; - - const isLoop = parent.data.flowType === "loop"; - const relativePosition = { - x: isLoop - ? Math.max(child.position.x - parent.position.x, LOOP_BODY_INSET.left) - : child.position.x - parent.position.x, - y: isLoop - ? Math.max(child.position.y - parent.position.y, LOOP_BODY_INSET.top) - : child.position.y - parent.position.y, - }; - child.parentNode = parentId; - child.extent = isLoop ? loopChildExtent() : groupChildExtent(); - child.expandParent = false; - child.position = relativePosition; - child.zIndex = 5; - child.data.properties = { ...child.data.properties, parentId }; - parent.data.children = Array.from(new Set([...(parent.data.children || []), child.id])); - }); - - nodes.filter((node) => node.data.flowType === "loop").forEach((group) => { - const children = nodes.filter((node) => node.parentNode === group.id); - if (!children.length) return; - const requiredWidth = Math.max(...children.map((child) => ( - child.position.x + Number(child.data.size?.width || 0) + LOOP_BODY_INSET.right - ))); - const requiredHeight = Math.max(...children.map((child) => ( - child.position.y + Number(child.data.size?.height || 0) + LOOP_BODY_INSET.bottom - ))); - const width = Math.max(Number(group.data.size?.width || 0), LOOP_MIN_SIZE.width, requiredWidth); - const height = Math.max(Number(group.data.size?.height || 0), LOOP_MIN_SIZE.height, requiredHeight); - group.width = width; - group.height = height; - group.data.size = { width, height }; - group.data.properties = { ...group.data.properties, width, height }; - }); - - return nodes.sort((left, right) => Number(Boolean(left.parentNode)) - Number(Boolean(right.parentNode))); -}; - -export const toVueFlowData = (graph = {}, options = {}) => { - const nodes = attachChildrenToGroups((graph.nodes || []).map((node) => ( - toVueNode(node, options.nodeSizes?.get(node.id), options.nodePositions?.get(node.id)) - ))); - const nodeLookup = new Map(nodes.map((node) => [node.id, node])); - const edges = (graph.edges || []).map((edge) => { - const vueEdge = toVueEdge(edge); - const source = nodeLookup.get(vueEdge.source); - const target = nodeLookup.get(vueEdge.target); - if (source?.parentNode || target?.parentNode) vueEdge.zIndex = 4; - return vueEdge; - }); - return { nodes, edges }; -}; - -export const createFlowFacade = (store) => { - const handlers = new Map(); - const componentInstances = new Map(); - const loopLayoutStates = new Map(); - let historySuspended = false; - let history = []; - let historyIndex = -1; - - /** - * 获取 getNodes 对应的数据或交互;作用范围仅限画布适配层。 - */ - const getNodes = () => store.getNodes.value || []; - /** - * 获取 getEdges 对应的数据或交互;作用范围仅限画布适配层。 - */ - const getEdges = () => store.getEdges.value || []; - - /** - * 处理 backendNode 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} node 当前流程节点 - */ - const backendNode = (node) => { - const result = clone(node.data.backend); - const size = { - width: Number(node.width || node.dimensions?.width || node.data.size?.width || 0), - height: Number(node.height || node.dimensions?.height || node.data.size?.height || 0), - }; - const parent = node.parentNode ? store.findNode(node.parentNode) : null; - const parentPosition = parent?.position || parent?.computedPosition || { x: 0, y: 0 }; - const absolutePosition = parent - ? { x: parentPosition.x + node.position.x, y: parentPosition.y + node.position.y } - : (node.position || node.computedPosition); - result.id = node.id; - result.type = node.data.flowType; - if (GROUP_TYPES.has(result.type)) { - result.x = absolutePosition.x + size.width / 2; - result.y = absolutePosition.y + size.height / 2; - } else { - const originalCenter = node.data.originalCenter || { - x: absolutePosition.x + size.width / 2, - y: absolutePosition.y + size.height / 2, - }; - const originalPosition = node.data.originalPosition || absolutePosition; - result.x = originalCenter.x + absolutePosition.x - originalPosition.x; - result.y = originalCenter.y + absolutePosition.y - originalPosition.y; - } - result.properties = clone(node.data.properties || {}); - if (parent?.data?.flowType === "selectArea") delete result.properties.parentId; - if (GROUP_TYPES.has(result.type)) { - result.properties.width = size.width; - result.properties.height = size.height; - } - if (node.data.children?.length || GROUP_TYPES.has(result.type)) { - result.children = [...(node.data.children || [])]; - } else { - delete result.children; - } - return result; - }; - - /** - * 处理 backendEdge 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} edge 调用方传入的 edge 参数 - */ - const backendEdge = (edge) => ({ - ...clone(edge.data?.backend), - id: edge.id, - type: edge.data?.backend?.type || "bezier", - sourceNodeId: edge.source, - targetNodeId: edge.target, - sourceAnchorId: edge.sourceHandle || `${edge.source}_1`, - targetAnchorId: edge.targetHandle || `${edge.target}_3`, - }); - - /** - * 处理 emit 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} name 名称或事件名称 - * @param {*} payload 事件数据 - */ - const emit = (name, payload) => { - (handlers.get(name) || []).forEach((handler) => handler(payload)); - }; - - /** - * 处理 recordHistory 对应的数据或交互;作用范围仅限画布适配层。 - */ - const recordHistory = () => { - if (historySuspended) return; - const graph = facade.getGraphData(); - const serialized = JSON.stringify(graph); - if (history[historyIndex]?.serialized === serialized) return; - history = history.slice(0, historyIndex + 1); - history.push({ serialized, graph: clone(graph) }); - if (history.length > 100) history.shift(); - historyIndex = history.length - 1; - }; - - /** - * 更新 changed 对应的数据或交互;作用范围仅限画布适配层。 - */ - const changed = () => { - if (historySuspended) return; - recordHistory(); - emit("history:change", { data: facade.getGraphData() }); - }; - - /** - * 获取 getNodeRect 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} node 当前流程节点 - */ - const getNodeRect = (node) => { - const parent = node.parentNode ? store.findNode(node.parentNode) : null; - const parentPosition = parent?.position || parent?.computedPosition || { x: 0, y: 0 }; - const position = parent - ? { x: parentPosition.x + node.position.x, y: parentPosition.y + node.position.y } - : (node.position || node.computedPosition); - return { - x: Number(position?.x || 0), - y: Number(position?.y || 0), - width: Number(node.width || node.dimensions?.width || node.data.size?.width || 0), - height: Number(node.height || node.dimensions?.height || node.data.size?.height || 0), - }; - }; - - /** - * 获取 getLoopLayoutState 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} group 调用方传入的 group 参数 - */ - const getLoopLayoutState = (group) => { - const current = getNodeRect(group); - const existing = loopLayoutStates.get(group.id); - /** - * 处理 if 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} !existing 调用方传入的 !existing 参数 - */ - if (!existing) { - const state = { base: { ...current }, last: { ...current } }; - loopLayoutStates.set(group.id, state); - return state; - } - - const sizeChanged = Math.abs(current.width - existing.last.width) > 1 - || Math.abs(current.height - existing.last.height) > 1; - /** - * 处理 if 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} sizeChanged 调用方传入的 sizeChanged 参数 - */ - if (sizeChanged) { - existing.base = { ...current }; - } else { - const dx = current.x - existing.last.x; - const dy = current.y - existing.last.y; - existing.base.x += dx; - existing.base.y += dy; - } - existing.last = { ...current }; - return existing; - }; - - /** - * 布局 layoutLoop 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} group 调用方传入的 group 参数 - * @param {*} activeChildId 调用方传入的 activeChildId 参数 - * @param {*} activePosition 调用方传入的 activePosition 参数 - */ - const layoutLoop = (group, activeChildId, activePosition) => { - const state = getLoopLayoutState(group); - const children = getNodes().filter((node) => node.parentNode === group.id); - if (!children.length) return false; - - const snapshots = children.map((child) => { - const rect = getNodeRect(child); - const position = child.id === activeChildId && activePosition - ? { x: activePosition.x, y: activePosition.y } - : { x: rect.x, y: rect.y }; - return { child, position, width: rect.width, height: rect.height }; - }); - const contentLeft = Math.min(...snapshots.map(({ position }) => position.x)); - const contentTop = Math.min(...snapshots.map(({ position }) => position.y)); - const contentRight = Math.max(...snapshots.map(({ position, width }) => position.x + width)); - const contentBottom = Math.max(...snapshots.map(({ position, height }) => position.y + height)); - const left = Math.min(state.base.x, contentLeft - LOOP_BODY_INSET.left); - const top = Math.min(state.base.y, contentTop - LOOP_BODY_INSET.top); - const right = Math.max( - state.base.x + Math.max(state.base.width, LOOP_MIN_SIZE.width), - contentRight + LOOP_BODY_INSET.right, - ); - const bottom = Math.max( - state.base.y + Math.max(state.base.height, LOOP_MIN_SIZE.height), - contentBottom + LOOP_BODY_INSET.bottom, - ); - const width = right - left; - const height = bottom - top; - const properties = { ...group.data.properties, width, height }; - - store.updateNode(group.id, { - position: { x: left, y: top }, - computedPosition: { ...group.computedPosition, x: left, y: top }, - dimensions: { width, height }, - width, - height, - }); - store.updateNodeData(group.id, { - ...group.data, - properties, - size: { width, height }, - }, { replace: true }); - snapshots.forEach(({ child, position }) => { - store.updateNode(child.id, { - position: { x: position.x - left, y: position.y - top }, - computedPosition: { ...child.computedPosition, x: position.x, y: position.y }, - extent: loopChildExtent(), - expandParent: false, - }); - }); - state.last = { x: left, y: top, width, height }; - nextTick(() => store.updateNodeInternals([group.id, ...children.map((child) => child.id)])); - return true; - }; - - /** - * 获取 getAnchors 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} node 当前流程节点 - */ - const getAnchors = (node) => { - const type = node.data.flowType; - /** - * 处理 if 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} type 目标类型 - */ - if (type === "branch") { - return [ - { id: `${node.id}_entry`, name: "left" }, - ...(node.data.properties?.anchor || []).map((item) => ({ ...item, name: "right" })), - ]; - } - if (TARGET_ONLY_TYPES.has(type)) return [{ id: `${node.id}_3`, name: "left" }]; - if (SOURCE_ONLY_TYPES.has(type)) return [{ id: `${node.id}_1`, name: "right" }]; - if (type === "selectArea") return []; - return [ - { id: `${node.id}_1`, name: "right" }, - { id: `${node.id}_3`, name: "left" }, - ]; - }; - - /** - * 处理 modelFor 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - */ - const modelFor = (id) => { - const node = store.findNode(id); - if (!node) return null; - const model = { - id, - type: node.data.flowType, - get x() { return backendNode(node).x; }, - get y() { return backendNode(node).y; }, - get width() { return node.dimensions?.width || node.data.size?.width || 0; }, - get height() { return node.dimensions?.height || node.data.size?.height || 0; }, - get left() { return getNodeRect(node).x; }, - get top() { return getNodeRect(node).y; }, - get parentId() { return node.parentNode || null; }, - get anchors() { return getAnchors(node); }, - get children() { return new Set(node.data.children || []); }, - set children(value) { - const children = Array.from(value || []); - store.updateNodeData(id, { ...node.data, children }, { replace: true }); - changed(); - }, - get draggable() { return node.draggable !== false; }, - set draggable(value) { store.updateNode(id, { draggable: Boolean(value) }); }, - getProperties: () => facade.getProperties(id), - setProperties: (properties) => facade.setProperties(id, properties), - setComponentInstance: (instance) => componentInstances.set(id, instance), - closePopover: () => componentInstances.get(id)?.closePopover?.(), - updateSize: () => store.updateNodeInternals([id]), - setCustomProperties: () => store.updateNodeInternals([id]), - }; - return model; - }; - - const facade = { - /** - * 订阅 on 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} name 名称或事件名称 - * @param {*} handler 事件处理函数 - */ - on(name, handler) { - const list = handlers.get(name) || []; - list.push(handler); - handlers.set(name, list); - return () => facade.off(name, handler); - }, - /** - * 订阅 once 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} name 名称或事件名称 - * @param {*} handler 事件处理函数 - */ - once(name, handler) { - /** - * 处理 wrapped 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} payload 事件数据 - */ - const wrapped = (payload) => { - facade.off(name, wrapped); - handler(payload); - }; - facade.on(name, wrapped); - }, - /** - * 取消订阅 off 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} name 名称或事件名称 - * @param {*} handler 事件处理函数 - */ - off(name, handler) { - if (!handler) handlers.delete(name); - else handlers.set(name, (handlers.get(name) || []).filter((item) => item !== handler)); - }, - emit, - markChanged: changed, - /** - * 获取 getGraphData 对应的数据或交互;作用范围仅限画布适配层。 - */ - getGraphData() { - return { - nodes: getNodes().map(backendNode), - edges: getEdges().map(backendEdge), - }; - }, - /** - * 渲染 render 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} graph 调用方传入的 graph 参数 - * @param {*} options 行为配置 - */ - render(graph, options = {}) { - historySuspended = true; - loopLayoutStates.clear(); - const nodeSizes = options.preserveNodeSizes === true - ? new Map(getNodes().map((node) => [node.id, { - width: Number(node.dimensions?.width || node.width || node.data.size?.width || 0), - height: Number(node.dimensions?.height || node.height || node.data.size?.height || 0), - }])) - : options.nodeSizes; - const nodePositions = options.preserveNodePositions === true - ? new Map(getNodes().map((node) => { - const rect = getNodeRect(node); - return [node.id, { x: rect.x, y: rect.y }]; - })) - : options.nodePositions; - const data = toVueFlowData(graph, { nodeSizes, nodePositions }); - /** - * 处理 finishRender 对应的数据或交互;作用范围仅限画布适配层。 - */ - const finishRender = () => { - historySuspended = false; - if (options.resetHistory !== false) { - history = []; - historyIndex = -1; - recordHistory(); - } - nextTick(() => store.updateNodeInternals()); - }; - /** - * 处理 applyData 对应的数据或交互;作用范围仅限画布适配层。 - */ - const applyData = () => { - store.setNodes(data.nodes); - store.setEdges(data.edges); - finishRender(); - }; - - if (options.replaceNodes === true) { - // Changing parentNode is structural in Vue Flow. Unmount in one tick - // and remount in the next so node wrappers and edges cannot retain - // different graph-node instances for the same id. - store.setEdges([]); - store.setNodes([]); - nextTick(applyData); - } else { - applyData(); - } - }, - /** - * 新增 addNode 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} node 当前流程节点 - */ - addNode(node) { - const vueNode = toVueNode(node); - store.addNodes(vueNode); - changed(); - return backendNode(vueNode); - }, - /** - * 删除 deleteNode 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - */ - deleteNode(id) { - const target = store.findNode(id); - if (target?.data?.flowType === "selectArea") { - facade.ungroup(id); - return; - } - const parentId = target?.parentNode; - const childIds = target?.data?.children || []; - const removeChildren = target?.data?.flowType === "loop" && childIds.length > 0; - const nodeIds = removeChildren ? [id, ...childIds] : id; - const removedIds = new Set(Array.isArray(nodeIds) ? nodeIds : [nodeIds]); - store.removeNodes(nodeIds, true, removeChildren); - getNodes().forEach((node) => { - if (node.data.children?.includes(id) && !removedIds.has(node.id)) { - store.updateNodeData(node.id, { - ...node.data, - children: node.data.children.filter((childId) => childId !== id), - }, { replace: true }); - } - }); - componentInstances.delete(id); - childIds.forEach((childId) => componentInstances.delete(childId)); - changed(); - if (parentId) nextTick(() => facade.resizeGroupToChildren(parentId)); - }, - /** - * 新增 addEdge 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} edge 调用方传入的 edge 参数 - */ - addEdge(edge) { - const vueEdge = toVueEdge(edge); - const source = store.findNode(vueEdge.source); - const target = store.findNode(vueEdge.target); - if (source?.parentNode || target?.parentNode) vueEdge.zIndex = 4; - store.addEdges(vueEdge); - changed(); - return backendEdge(vueEdge); - }, - /** - * 删除 deleteEdge 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - */ - deleteEdge(id) { - store.removeEdges(id); - changed(); - }, - /** - * 删除 deleteEdgeByNodeId 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - */ - deleteEdgeByNodeId(id) { - store.removeEdges(getEdges().filter((edge) => edge.source === id || edge.target === id)); - changed(); - }, - /** - * 获取 getProperties 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - */ - getProperties(id) { - return clone(store.findNode(id)?.data?.properties || {}); - }, - /** - * 设置 setProperties 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - * @param {*} properties 调用方传入的 properties 参数 - */ - setProperties(id, properties) { - const node = store.findNode(id); - if (!node) return; - store.updateNodeData(id, { ...node.data, properties: clone(properties) }, { replace: true }); - nextTick(() => store.updateNodeInternals([id])); - changed(); - }, - getNodeModelById: modelFor, - /** - * 获取 getSelectElements 对应的数据或交互;作用范围仅限画布适配层。 - */ - getSelectElements() { - return { - nodes: (store.getSelectedNodes.value || []).map(backendNode), - edges: (store.getSelectedEdges.value || []).map(backendEdge), - }; - }, - /** - * 清理 clearSelectElements 对应的数据或交互;作用范围仅限画布适配层。 - */ - clearSelectElements() { - store.removeSelectedElements(); - }, - /** - * 处理 selectElementById 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - */ - selectElementById(id) { - store.removeSelectedElements(); - if (!id) return; - const node = store.findNode(id); - if (node) store.addSelectedNodes([node]); - const edge = store.findEdge(id); - if (edge) store.addSelectedEdges([edge]); - }, - /** - * 处理 selectElementsByIds 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} ids 调用方传入的 ids 参数 - */ - selectElementsByIds(ids = []) { - store.removeSelectedElements(); - const nodes = ids.map((id) => store.findNode(id)).filter(Boolean); - if (nodes.length) store.addSelectedNodes(nodes); - }, - /** - * 处理 focusOn 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} { id } 调用方传入的 { id } 参数 - */ - focusOn({ id }) { - const node = store.findNode(id); - if (!node) return; - const center = backendNode(node); - store.setCenter(center.x, center.y, { zoom: Math.max(store.viewport.value?.zoom || 1, 0.7), duration: 300 }); - }, - /** - * 处理 fitView 对应的数据或交互;作用范围仅限画布适配层。 - */ - fitView() { - return store.fitView({ padding: 0.18, duration: 300 }); - }, - /** - * 处理 translateCenter 对应的数据或交互;作用范围仅限画布适配层。 - */ - translateCenter() { - return facade.fitView(); - }, - /** - * 缩放 zoom 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} scale 缩放比例 - * @param {*} center 缩放中心 - */ - zoom(scale, center) { - if (Array.isArray(center) && center.length === 2) { - return store.setCenter(center[0], center[1], { zoom: scale, duration: 250 }); - } - return store.zoomTo(scale, { duration: 250 }); - }, - /** - * 获取 getPointByClient 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} x 客户端横坐标 - * @param {*} y 客户端纵坐标 - */ - getPointByClient(x, y) { - const point = store.screenToFlowCoordinate({ x, y }); - return { canvasOverlayPosition: point, domOverlayPosition: point }; - }, - /** - * 新增 addToGroup 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} groupId 分组节点 ID - * @param {*} childId 子节点 ID - * @param {*} dropCenter 拖放中心坐标 - */ - addToGroup(groupId, childId, dropCenter) { - const group = store.findNode(groupId); - const child = store.findNode(childId); - if (!group || !child || GROUP_TYPES.has(child.data.flowType)) return; - const previousParentId = child.parentNode || child.data?.properties?.parentId; - const graph = facade.getGraphData(); - const groupData = graph.nodes.find((node) => node.id === groupId); - const childData = graph.nodes.find((node) => node.id === childId); - if (!groupData || !childData) return; - - // 节点从循环体外进入循环体后,原连线的两端已处于不同执行作用域,必须全部断开。 - // 在重新渲染父子结构前直接过滤图数据,可保证入边、出边和层级变更在同一次更新中完成。 - const enteringLoop = group.data.flowType === "loop" && previousParentId !== groupId; - if (enteringLoop) { - graph.edges = graph.edges.filter((edge) => ( - edge.sourceNodeId !== childId && edge.targetNodeId !== childId - )); - } - - groupData.children = Array.from(new Set([...(groupData.children || []), childId])); - childData.properties = { ...(childData.properties || {}), parentId: groupId }; - if (dropCenter) { - childData.x = dropCenter.x; - childData.y = dropCenter.y; - } - facade.render(graph, { - resetHistory: false, - replaceNodes: true, - preserveNodeSizes: true, - preserveNodePositions: true, - }); - nextTick(() => { - store.updateNodeInternals([groupId, childId]); - changed(); - }); - }, - /** - * 编组 groupNodes 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} groupNode 调用方传入的 groupNode 参数 - * @param {*} childIds 子节点 ID 集合 - */ - groupNodes(groupNode, childIds = []) { - // 先计算选中节点的外接矩形确定容器尺寸,再把子节点坐标转换为容器内相对坐标。 - // 与分组外节点相连的边保持不变,此处仅更新节点层级和几何信息。 - const graph = facade.getGraphData(); - const selectedIds = new Set(childIds); - const children = graph.nodes.filter((node) => ( - selectedIds.has(node.id) - && !GROUP_TYPES.has(node.type) - && !store.findNode(node.id)?.parentNode - )); - if (!children.length) return null; - - const group = clone(groupNode); - group.id ||= nodeId(); - group.type = "selectArea"; - group.properties = { ...(group.properties || {}), action: "NONE" }; - group.children = children.map((node) => node.id); - children.forEach((node) => { - node.properties = { ...(node.properties || {}), parentId: group.id }; - }); - graph.nodes.push(group); - facade.render(graph, { - resetHistory: false, - replaceNodes: true, - preserveNodeSizes: true, - preserveNodePositions: true, - }); - nextTick(() => { - store.updateNodeInternals([group.id, ...group.children]); - changed(); - }); - return clone(group); - }, - /** - * 处理 ungroup 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} groupId 分组节点 ID - */ - ungroup(groupId) { - const graph = facade.getGraphData(); - const group = graph.nodes.find((node) => node.id === groupId && node.type === "selectArea"); - if (!group) return false; - const childIds = new Set([ - ...(group.children || []), - ...graph.nodes.filter((node) => node.properties?.parentId === groupId).map((node) => node.id), - ]); - graph.nodes = graph.nodes.filter((node) => node.id !== groupId); - graph.nodes.forEach((node) => { - if (!childIds.has(node.id)) return; - const properties = { ...(node.properties || {}) }; - delete properties.parentId; - node.properties = properties; - }); - facade.render(graph, { - resetHistory: false, - replaceNodes: true, - preserveNodeSizes: true, - preserveNodePositions: true, - }); - nextTick(() => { - store.updateNodeInternals([...childIds]); - changed(); - }); - return true; - }, - /** - * 准备 prepareLoopChildDrag 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} childId 子节点 ID - */ - prepareLoopChildDrag(childId) { - const child = store.findNode(childId); - const group = child?.parentNode ? store.findNode(child.parentNode) : null; - if (!group || group.data.flowType !== "loop") return; - store.updateNode(childId, { - extent: loopChildExtent(), - expandParent: false, - }); - getLoopLayoutState(group); - const rect = getNodeRect(child); - return { groupId: group.id, position: { x: rect.x, y: rect.y } }; - }, - /** - * 布局 layoutLoopDuringDrag 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} groupId 分组节点 ID - * @param {*} childId 子节点 ID - * @param {*} position 调用方传入的 position 参数 - */ - layoutLoopDuringDrag(groupId, childId, position) { - const group = store.findNode(groupId); - if (!group || group.data.flowType !== "loop" || !position) return; - layoutLoop(group, childId, position); - }, - /** - * 调整 resizeGroupToChildren 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} groupId 分组节点 ID - * @param {*} options 行为配置 - */ - resizeGroupToChildren(groupId, options = {}) { - // 循环容器沿用统一的内边距和最小尺寸约束,并按配置决定是否记录变更。 - // 拖拽过程可关闭变更标记,避免高频移动产生多余历史记录。 - const group = store.findNode(groupId); - if (!group || group.data.flowType !== "loop") return; - if (layoutLoop(group) && options.markChanged !== false) changed(); - }, - /** - * 移动 moveNodeBy 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - * @param {*} dx 横向位移 - * @param {*} dy 纵向位移 - */ - moveNodeBy(id, dx, dy) { - const node = store.findNode(id); - if (!node) return; - store.updateNode(id, { - position: { - x: node.position.x + dx, - y: node.position.y + dy, - }, - }); - changed(); - }, - /** - * 撤销 undo 对应的数据或交互;作用范围仅限画布适配层。 - */ - undo() { - if (historyIndex <= 0) return false; - historyIndex -= 1; - const snapshot = clone(history[historyIndex].graph); - facade.render(snapshot, { resetHistory: false, replaceNodes: true }); - nextTick(() => emit("history:change", { data: facade.getGraphData() })); - return true; - }, - /** - * 重做 redo 对应的数据或交互;作用范围仅限画布适配层。 - */ - redo() { - if (historyIndex >= history.length - 1) return false; - historyIndex += 1; - const snapshot = clone(history[historyIndex].graph); - facade.render(snapshot, { resetHistory: false, replaceNodes: true }); - nextTick(() => emit("history:change", { data: facade.getGraphData() })); - return true; - }, - /** - * 注册 registerComponentInstance 对应的数据或交互;作用范围仅限画布适配层。 - * @param {*} id 目标元素 ID - * @param {*} instance 组件实例 - */ - registerComponentInstance(id, instance) { - if (instance) componentInstances.set(id, instance); - }, - extension: { - selectionSelect: { - openSelectionSelect: () => emit("selection:open"), - closeSelectionSelect: () => emit("selection:close"), - }, - }, - }; - - return facade; -}; diff --git a/src/views/inspection/alarm/index.vue b/src/views/inspection/alarm/index.vue deleted file mode 100644 index c306a5d..0000000 --- a/src/views/inspection/alarm/index.vue +++ /dev/null @@ -1,452 +0,0 @@ - - - - - diff --git a/src/views/inspection/cockpit/canvasUtils.js b/src/views/inspection/cockpit/canvasUtils.js deleted file mode 100644 index e9751e8..0000000 --- a/src/views/inspection/cockpit/canvasUtils.js +++ /dev/null @@ -1,620 +0,0 @@ -import { useInspectionStore } from "@/store/modules/inspection"; - -const inspectionStore = useInspectionStore(); - - -/** - * 6位十六进制颜色字符串转为 CSS rgba 字符串 - * @param {string} hex - 如 "#ff6e40" - * @param {number} alpha - 透明度 0~1 - * @returns {string} CSS rgba 字符串 - */ -function hexToCssRgba(hexString, alpha) { - const r = parseInt(hexString.slice(1, 3), 16); // 提取 R 分量 - const g = parseInt(hexString.slice(3, 5), 16); // 提取 G 分量 - const b = parseInt(hexString.slice(5, 7), 16); // 提取 B 分量 - return `rgba(${r},${g},${b},${alpha})`; -} - -/** - * 将世界坐标转换为 Canvas 屏幕像素坐标 - * 注意:世界坐标 Y 轴向上,Canvas Y 轴向下,因此需要翻转 - * @param {number} worldX - 世界坐标 X(米) - * @param {number} worldY - 世界坐标 Y(米) - * @returns {{x: number, y: number}} Canvas 上的屏幕像素坐标 - */ -export const worldToScreen = (worldX, worldY, dataStore) => { - const store = dataStore || inspectionStore; - const camera = store.camera - const screenX = (worldX - camera.centerX) * camera.pixelsPerMeter + store.canvasWidthPx / 2; // 水平偏移 + 居中 - const screenY = -(worldY - camera.centerY) * camera.pixelsPerMeter + store.canvasHeightPx / 2; // 垂直翻转 + 居中 - return { x: screenX, y: screenY }; -}; - -/** - * 将 Canvas 屏幕像素坐标反算为世界坐标 - * 与 worldToScreen 互为逆运算 - * @param {number} screenX - Canvas 像素 X - * @param {number} screenY - Canvas 像素 Y - * @returns {{x: number, y: number}} 世界坐标(米) - */ -export const screenToWorld = (screenX, screenY, dataStore) => { - const store = dataStore || inspectionStore; - const camera = store.camera; - const worldX = (screenX - store.canvasWidthPx / 2) / camera.pixelsPerMeter + camera.centerX; // 水平反算 - const worldY = -(screenY - store.canvasHeightPx / 2) / camera.pixelsPerMeter + camera.centerY; // 垂直反算(带翻转) - return { x: worldX, y: worldY }; -}; - - -/** - * 0xAARRGGBB 整数颜色解码为 {r, g, b, a} 对象 - * @param {number} argbInt - 32位 ARGB 整数,如 0xCCFF0040 - * @returns {{r:number, g:number, b:number, a:number}|null} RGBA 分量 (0~255),无效输入返回 null - */ -export const decodeArgbInteger = (argbInt) => { - if (typeof argbInt !== 'number') return null; // 非数字类型直接返回 - return { - a: (argbInt >>> 24) & 0xFF, // 高8位:Alpha 透明度 - r: (argbInt >>> 16) & 0xFF, // 次高8位:Red - g: (argbInt >>> 8) & 0xFF, // 次低8位:Green - b: argbInt & 0xFF, // 低8位:Blue - }; -} - -/** - * 将 decodeArgbInteger 的结果转为 CSS rgba() 字符串 - * @param {{r,g,b,a}} colorObj - RGBA 分量对象 - * @param {number} [alphaOverride] - 可选,覆盖 alpha 值(0~1) - * @returns {string|null} CSS rgba 字符串,如 "rgba(255,0,64,0.3)" - */ -export const toCssRgba = (colorObj, alphaOverride) => { - if (!colorObj) return null; // 空对象返回 null - const alpha = alphaOverride !== undefined // 如果提供了覆盖值 - ? alphaOverride // 使用覆盖值 - : colorObj.a / 255; // 否则将 0~255 映射到 0~1 - return `rgba(${colorObj.r},${colorObj.g},${colorObj.b},${alpha})`; -} - -/** - * 栅格底图绘制函数 - * 将预渲染的离屏 Canvas 图像绘制到主 Canvas 上,并根据当前地图范围进行缩放和平移 - * @param {*} canvasCtx - * @param {*} map - * @param {*} gridOffscreen - */ -export const drawGrid = (canvasCtx, map, dataStore) => { - const store = dataStore || inspectionStore; - const topLeftScreen = worldToScreen(map.originX, map.maxY, store); // 图像左上角(世界坐标→屏幕) - const bottomRightScreen = worldToScreen(map.maxX, map.originY, store); // 图像右下角(世界坐标→屏幕) - canvasCtx.imageSmoothingEnabled = false; // 关闭抗锯齿(保持像素清晰) - canvasCtx.drawImage( - store.gridOffscreen, // 离屏 Canvas 图像源 - topLeftScreen.x, topLeftScreen.y, // 目标左上角 - bottomRightScreen.x - topLeftScreen.x, // 目标宽度 - bottomRightScreen.y - topLeftScreen.y // 目标高度 - ); -} - -/** - * 网格辅助线(每1米一条) - * @param {*} canvasCtx - * @param {*} canvasWidthPx - * @param {*} canvasHeightPx - */ -export const drawGridlines = (canvasCtx, dataStore) => { - // 计算当前可视范围的世界坐标 - const store = dataStore || inspectionStore; - const viewTopLeft = screenToWorld(0, 0, store); // 视口左上角世界坐标 - const viewBottomRight = screenToWorld(store.canvasWidthPx, store.canvasHeightPx, store); // 视口右下角世界坐标 - const viewMinX = Math.floor(Math.min(viewTopLeft.x, viewBottomRight.x)); // 可视X最小整数 - const viewMaxX = Math.ceil(Math.max(viewTopLeft.x, viewBottomRight.x)); // 可视X最大整数 - const viewMinY = Math.floor(Math.min(viewTopLeft.y, viewBottomRight.y)); // 可视Y最小整数 - const viewMaxY = Math.ceil(Math.max(viewTopLeft.y, viewBottomRight.y)); // 可视Y最大整数 - - // 绘制1米间隔的浅色网格线 - canvasCtx.strokeStyle = 'rgba(30,50,80,0.25)'; // 淡蓝灰色 - canvasCtx.lineWidth = 0.5; // 细线 - canvasCtx.beginPath(); - for (let worldX = viewMinX; worldX <= viewMaxX; worldX++) { // 逐列绘制垂直线 - const screenPos = worldToScreen(worldX, 0, store); - canvasCtx.moveTo(screenPos.x, 0); // 从画布顶部 - canvasCtx.lineTo(screenPos.x, store.canvasHeightPx); // 到画布底部 - } - for (let worldY = viewMinY; worldY <= viewMaxY; worldY++) { // 逐行绘制水平线 - const screenPos = worldToScreen(0, worldY, store); - canvasCtx.moveTo(0, screenPos.y); // 从画布左边 - canvasCtx.lineTo(store.canvasWidthPx, screenPos.y); // 到画布右边 - } - canvasCtx.stroke(); -} - -/** - * 绘制高级区域列表 - * @param {*} canvasCtx - * @param {*} map - * @param {*} dataStore - */ -export const drawAdvancedAreaList = (canvasCtx, map, dataStore) => { - const store = dataStore || inspectionStore; - for (let areaIndex = 0; areaIndex < map.advancedAreas.length; areaIndex++) { - const area = map.advancedAreas[areaIndex]; // 当前区域 - const vertices = area.posGroup || []; // 多边形顶点数组 - if (vertices.length < 3) continue; // 少于3个顶点无法构成多边形,跳过 - - // ── 颜色:优先使用 attribute 中的 ARGB 整数,否则用默认品红色 ── - let fillColorCss = 'rgba(224,64,251,0.12)'; // 默认填充(品红半透明) - let strokeColorCss = 'rgba(224,64,251,0.5)'; // 默认描边(品红较不透明) - if (area.attribute) { - const brushColor = decodeArgbInteger(area.attribute.colorBrush); // 解码填充色 - const penColor = decodeArgbInteger(area.attribute.colorPen); // 解码描边色 - if (brushColor) { - // 使用原始 alpha 值的一半作为填充透明度,最小 0.06 - fillColorCss = toCssRgba(brushColor, Math.max(0.06, (brushColor.a / 255) * 0.5)); - } - if (penColor) { - strokeColorCss = toCssRgba(penColor, 0.6); // 描边60%不透明 - } - } - - // ── 绘制多边形 ── - canvasCtx.fillStyle = fillColorCss; // 设置填充色 - canvasCtx.strokeStyle = strokeColorCss; // 设置描边色 - canvasCtx.lineWidth = 1.2; // 描边宽度 - canvasCtx.beginPath(); - const firstVertexScreen = worldToScreen(vertices[0].x, vertices[0].y, store); // 第一个顶点的屏幕位置 - canvasCtx.moveTo(firstVertexScreen.x, firstVertexScreen.y); // 移动到起点 - for (let i = 1; i < vertices.length; i++) { // 依次连接后续顶点 - const vertexScreen = worldToScreen(vertices[i].x, vertices[i].y, store); - canvasCtx.lineTo(vertexScreen.x, vertexScreen.y); - } - canvasCtx.closePath(); // 闭合路径 - canvasCtx.fill(); // 填充 - canvasCtx.stroke(); // 描边 - - // ── 在多边形质心处绘制区域名称标签 ── - let centroidWorldX = 0, centroidWorldY = 0; // 质心世界坐标 - for (const v of vertices) { centroidWorldX += v.x; centroidWorldY += v.y; } // 累加顶点坐标 - centroidWorldX /= vertices.length; // 求平均得到质心 X - centroidWorldY /= vertices.length; // 求平均得到质心 Y - const centroidScreen = worldToScreen(centroidWorldX, centroidWorldY, store); - canvasCtx.font = '500 32px "JetBrains Mono"'; // 标签字体 - canvasCtx.fillStyle = strokeColorCss; // 与描边同色 - canvasCtx.textAlign = 'center'; // 居中对齐 - canvasCtx.fillText(area.instanceName || '', centroidScreen.x, centroidScreen.y + 3); // 绘制文字 - } -}; - -/** - * 绘制高级线列表 - * @param {*} canvasCtx - * @param {*} map - */ -export const drawAdvancedLineList = (canvasCtx, map, dataStore) => { - const store = dataStore || inspectionStore; - for (let advLineIndex = 0; advLineIndex < map.advancedLines.length; advLineIndex++) { - const advLine = map.advancedLines[advLineIndex]; // 当前高级线 - const lineData = advLine.line; // 内部的 line 对象 - if (!lineData || !lineData.startPos || !lineData.endPos) continue; // 缺少端点则跳过 - - const startScreen = worldToScreen(lineData.startPos.x, lineData.startPos.y, store); - const endScreen = worldToScreen(lineData.endPos.x, lineData.endPos.y, store); - - // ── 根据 className 决定颜色和线型 ── - let lineColorHex = '#ff6e40'; // 默认橙色 - let lineDashPattern = []; // 默认实线(无虚线) - const classNameLower = (advLine.className || '').toLowerCase(); - if (classNameLower.includes('forbidden')) { // 禁行线 → 红色虚线 - lineColorHex = '#ff1744'; - lineDashPattern = [8, 4]; // 虚线模式:8px实 4px空 - } else if (classNameLower.includes('virtual')) { // 虚拟线 → 橙色虚线 - lineColorHex = '#ffab40'; - lineDashPattern = [4, 4]; - } - - // 绘制高级线 - canvasCtx.save(); - canvasCtx.shadowColor = lineColorHex; // 辉光色与线条同色 - canvasCtx.shadowBlur = 4; // 辉光半径 - canvasCtx.strokeStyle = lineColorHex; // 线条颜色 - canvasCtx.lineWidth = 2.5; // 线宽(比基础线粗) - canvasCtx.setLineDash(lineDashPattern); // 设置虚线模式 - canvasCtx.globalAlpha = 0.8; // 80%不透明 - canvasCtx.beginPath(); - canvasCtx.moveTo(startScreen.x, startScreen.y); - canvasCtx.lineTo(endScreen.x, endScreen.y); - canvasCtx.stroke(); - canvasCtx.setLineDash([]); // 恢复实线 - canvasCtx.restore(); - - // 在中点绘制名称标签 - // const midpointScreenX = (startScreen.x + endScreen.x) / 2; - // const midpointScreenY = (startScreen.y + endScreen.y) / 2; - // canvasCtx.font = '500 8px "JetBrains Mono"'; - // canvasCtx.fillStyle = hexToCssRgba(lineColorHex, 0.55); // 55%不透明的文字 - // canvasCtx.textAlign = 'center'; - // canvasCtx.fillText(advLine.instanceName || advLine.className || '', midpointScreenX, midpointScreenY - 6); - } -}; - -/** - * 绘制基础直线列表 - * @param {*} canvasCtx - * @param {*} map - * @param {*} dataStore - */ -export const drawNormalLines = (canvasCtx, map, dataStore) => { - const store = dataStore || inspectionStore; - for (let lineIndex = 0; lineIndex < map.normalLines.length; lineIndex++) { - const line = map.normalLines[lineIndex]; // 当前直线 - const startScreen = worldToScreen(line.startPos.x, line.startPos.y, store); // 起点屏幕位置 - const endScreen = worldToScreen(line.endPos.x, line.endPos.y, store); // 终点屏幕位置 - - // 绘制发光直线 - canvasCtx.save(); - canvasCtx.shadowColor = '#00e5ff'; // 阴影颜色(产生辉光) - canvasCtx.shadowBlur = 5; // 辉光扩散半径 - canvasCtx.strokeStyle = '#00e5ff'; // 线条颜色:青色 - canvasCtx.lineWidth = 2; // 线宽 - canvasCtx.globalAlpha = 0.8; // 80%不透明 - canvasCtx.beginPath(); - canvasCtx.moveTo(startScreen.x, startScreen.y); // 从起点 - canvasCtx.lineTo(endScreen.x, endScreen.y); // 到终点 - canvasCtx.stroke(); - canvasCtx.restore(); - - // 在中点绘制方向箭头 - const midpointX = (startScreen.x + endScreen.x) / 2; // 中点X - const midpointY = (startScreen.y + endScreen.y) / 2; // 中点Y - const arrowAngle = Math.atan2(endScreen.y - startScreen.y, endScreen.x - startScreen.x); // 线段方向角 - const arrowLength = 5; // 箭头长度 - canvasCtx.fillStyle = 'rgba(0,229,255,0.6)'; // 箭头填充色 - canvasCtx.beginPath(); - canvasCtx.moveTo(midpointX + Math.cos(arrowAngle) * arrowLength, midpointY + Math.sin(arrowAngle) * arrowLength); // 箭头尖端 - canvasCtx.lineTo(midpointX + Math.cos(arrowAngle + 2.5) * 4, midpointY + Math.sin(arrowAngle + 2.5) * 4); // 左翼 - canvasCtx.lineTo(midpointX + Math.cos(arrowAngle - 2.5) * 4, midpointY + Math.sin(arrowAngle - 2.5) * 4); // 右翼 - canvasCtx.closePath(); - canvasCtx.fill(); - } -}; - -/** - * 绘制高级曲线列表 - * @param {*} canvasCtx - * @param {*} map - * @param {*} dataStore - */ -export const drawAdvancedCurveList = (canvasCtx, map, dataStore) => { - const store = dataStore || inspectionStore; - for (let curveIndex = 0; curveIndex < map.advancedCurves.length; curveIndex++) { - const curve = map.advancedCurves[curveIndex]; // 当前曲线 - - // 提取起点和终点的 pos(注意:startPos/endPos 是 {instanceName, pos:{x,y}} 结构) - const startPoint = curve.startPos?.pos; // 起点世界坐标 - const endPoint = curve.endPos?.pos; // 终点世界坐标 - const controlPoint1 = curve.controlPos1; // 第一控制点(直接 {x,y}) - const controlPoint2 = curve.controlPos2; // 第二控制点(直接 {x,y}) - if (!startPoint || !endPoint) continue; // 缺少端点则跳过 - - // 转换为屏幕坐标 - const startScreen = worldToScreen(startPoint.x, startPoint.y, store); - const endScreen = worldToScreen(endPoint.x, endPoint.y, store); - const cp1Screen = controlPoint1 ? worldToScreen(controlPoint1.x, controlPoint1.y, store) : null; // 可能不存在 - const cp2Screen = controlPoint2 ? worldToScreen(controlPoint2.x, controlPoint2.y, store) : null; - - // ── 绘制贝塞尔曲线(虚线)── - canvasCtx.save(); - canvasCtx.shadowColor = '#76ff03'; // 酸绿色辉光 - canvasCtx.shadowBlur = 5; - canvasCtx.strokeStyle = '#76ff03'; // 酸绿色线条 - canvasCtx.lineWidth = 2; - canvasCtx.setLineDash([8, 5]); // 虚线模式 - canvasCtx.globalAlpha = 0.85; - canvasCtx.beginPath(); - canvasCtx.moveTo(startScreen.x, startScreen.y); // 起点 - if (cp1Screen && cp2Screen) { - // 有2个控制点 → 三次贝塞尔 (cubic bezier) - canvasCtx.bezierCurveTo(cp1Screen.x, cp1Screen.y, cp2Screen.x, cp2Screen.y, endScreen.x, endScreen.y); - } else if (cp1Screen) { - // 仅1个控制点 → 二次贝塞尔 (quadratic bezier) - canvasCtx.quadraticCurveTo(cp1Screen.x, cp1Screen.y, endScreen.x, endScreen.y); - } else { - // 无控制点 → 直线 - canvasCtx.lineTo(endScreen.x, endScreen.y); - } - canvasCtx.stroke(); - canvasCtx.setLineDash([]); // 恢复实线 - canvasCtx.restore(); - - // ── 在 t=0.5 处绘制方向箭头 ── - if (cp1Screen && cp2Screen) { - const t = 0.5; // 参数 t = 0.5(曲线中点) - const oneMinusT = 0.5; // 1-t = 0.5 - // 三次贝塞尔公式计算中点坐标 - const arrowX = oneMinusT ** 3 * startScreen.x + 3 * oneMinusT ** 2 * t * cp1Screen.x + 3 * oneMinusT * t ** 2 * cp2Screen.x + t ** 3 * endScreen.x; - const arrowY = oneMinusT ** 3 * startScreen.y + 3 * oneMinusT ** 2 * t * cp1Screen.y + 3 * oneMinusT * t ** 2 * cp2Screen.y + t ** 3 * endScreen.y; - // 三次贝塞尔的一阶导数(切线方向) - const tangentX = 3 * oneMinusT ** 2 * (cp1Screen.x - startScreen.x) + 6 * oneMinusT * t * (cp2Screen.x - cp1Screen.x) + 3 * t ** 2 * (endScreen.x - cp2Screen.x); - const tangentY = 3 * oneMinusT ** 2 * (cp1Screen.y - startScreen.y) + 6 * oneMinusT * t * (cp2Screen.y - cp1Screen.y) + 3 * t ** 2 * (endScreen.y - cp2Screen.y); - const tangentAngle = Math.atan2(tangentY, tangentX); // 切线角度 - - // 绘制箭头 - canvasCtx.fillStyle = 'rgba(118,255,3,0.7)'; - canvasCtx.beginPath(); - canvasCtx.moveTo(arrowX + Math.cos(tangentAngle) * 5, arrowY + Math.sin(tangentAngle) * 5); - canvasCtx.lineTo(arrowX + Math.cos(tangentAngle + 2.5) * 4, arrowY + Math.sin(tangentAngle + 2.5) * 4); - canvasCtx.lineTo(arrowX + Math.cos(tangentAngle - 2.5) * 4, arrowY + Math.sin(tangentAngle - 2.5) * 4); - canvasCtx.closePath(); - canvasCtx.fill(); - - // 绘制控制点小圆(辅助调试用) - canvasCtx.fillStyle = 'rgba(118,255,3,0.25)'; // 浅绿色半透明 - for (const controlScreen of [cp1Screen, cp2Screen]) { - canvasCtx.beginPath(); - canvasCtx.arc(controlScreen.x, controlScreen.y, 2.5, 0, Math.PI * 2); // 半径2.5px的小圆 - canvasCtx.fill(); - } - } - - // ── 曲线名称标签 ── - // canvasCtx.font = '500 7px "JetBrains Mono"'; - // canvasCtx.fillStyle = 'rgba(118,255,3,0.5)'; - // canvasCtx.textAlign = 'center'; - // const labelScreenY = Math.min(startScreen.y, endScreen.y) - 8; // 标签放在最高点上方 - // canvasCtx.fillText(curve.instanceName || '', (startScreen.x + endScreen.x) / 2, labelScreenY); - } -}; - -/** - * 绘制高级点列表 - * @param {*} canvasCtx - * @param {*} map - * @param {*} dataStore - */ -export const drawAdvancedPointList = (canvasCtx, map, dataStore) => { - const store = dataStore || inspectionStore; - for (let pointIndex = 0; pointIndex < map.advancedPoints.length; pointIndex++) { - const advPoint = map.advancedPoints[pointIndex]; // 当前高级点 - const pointScreen = worldToScreen(advPoint.pos.x, advPoint.pos.y, store); // 屏幕位置 - - // 判断是否被鼠标悬停 - const isHovered = store.hoveredElement && - store.hoveredElement.kind === 'point' && - store.hoveredElement.index === pointIndex; - - // ── 根据 className 决定颜色 ── - let pointColorHex = '#ffd600'; // 默认琥珀色 - const classNameLower = (advPoint.className || '').toLowerCase(); - if (classNameLower.includes('landmark') || classNameLower.includes('land')) { - pointColorHex = '#ffd600'; // LandMark → 琥珀色 - } else if (classNameLower.includes('charge')) { - pointColorHex = '#22c55e'; // 充电点 → 绿色 - } else if (classNameLower.includes('load')) { - pointColorHex = '#3b82f6'; // 装载点 → 蓝色 - } else if (classNameLower.includes('work') || classNameLower.includes('process')) { - pointColorHex = '#a855f7'; // 工位 → 紫色 - } else if (classNameLower.includes('station')) { - pointColorHex = '#00e5ff'; // 站点 → 青色 - } - - // ── 绘制菱形标记 ── - const diamondRadius = isHovered ? 8 : 5; // 悬停时放大 - const pulseAlpha = isHovered ? Math.sin(store.animationTimeSeconds * 5) * 0.2 + 0.8 : 1; // 悬停时脉冲闪烁 - - canvasCtx.save(); - canvasCtx.globalAlpha = pulseAlpha; // 应用透明度 - canvasCtx.shadowColor = pointColorHex; // 辉光颜色 - canvasCtx.shadowBlur = isHovered ? 18 : 8; // 悬停时增强辉光 - - // 绘制旋转45度的正方形(菱形) - canvasCtx.fillStyle = pointColorHex; - canvasCtx.beginPath(); - canvasCtx.moveTo(pointScreen.x, pointScreen.y - diamondRadius); // 上顶点 - canvasCtx.lineTo(pointScreen.x + diamondRadius * 0.7, pointScreen.y); // 右顶点 - canvasCtx.lineTo(pointScreen.x, pointScreen.y + diamondRadius); // 下顶点 - canvasCtx.lineTo(pointScreen.x - diamondRadius * 0.7, pointScreen.y); // 左顶点 - canvasCtx.closePath(); - canvasCtx.fill(); - - // 中心白色小圆点(指示精确位置) - canvasCtx.shadowBlur = 0; - canvasCtx.fillStyle = '#fff'; - canvasCtx.globalAlpha = 0.9; - canvasCtx.beginPath(); - canvasCtx.arc(pointScreen.x, pointScreen.y, 1.8, 0, Math.PI * 2); // 半径1.8px - canvasCtx.fill(); - canvasCtx.restore(); - - // ── 方向箭头(基于 dir 字段,弧度)── - if (advPoint.dir !== undefined && advPoint.dir !== null) { - // dir 可能是字符串(smap 样例中为 "-1.5759999999999958")或数字 - const dirRadians = typeof advPoint.dir === 'string' ? parseFloat(advPoint.dir) : advPoint.dir; - if (!isNaN(dirRadians)) { // 有效方向角 - const arrowLengthPx = 12; // 箭头长度(屏幕像素) - canvasCtx.strokeStyle = hexToCssRgba(pointColorHex, 0.5); // 半透明的线条 - canvasCtx.lineWidth = 1; - canvasCtx.beginPath(); - canvasCtx.moveTo(pointScreen.x, pointScreen.y); // 从点中心出发 - // 注意:世界坐标 Y 向上,但 atan2 使用的 dir 是标准数学角,屏幕 Y 翻转后取负 - canvasCtx.lineTo( - pointScreen.x + Math.cos(dirRadians) * arrowLengthPx, - pointScreen.y - Math.sin(dirRadians) * arrowLengthPx // Y 翻转 - ); - canvasCtx.stroke(); - } - } - - // ── 名称标签 ── - canvasCtx.font = '500 12px "JetBrains Mono"'; - canvasCtx.fillStyle = hexToCssRgba(pointColorHex, 0.7); - canvasCtx.textAlign = 'center'; - canvasCtx.fillText(advPoint.instanceName || '', pointScreen.x, pointScreen.y - diamondRadius - 4); - } -} - -/** - * 绘制地图边界 - * @param {*} canvasCtx - * @param {*} map - * @param {*} dataStore - */ -export const drawMapBoundary = (canvasCtx, map, dataStore) => { - const store = dataStore || inspectionStore; - const boundaryTopLeft = worldToScreen(map.originX, map.maxY, store); // 边界左上角屏幕位置 - const boundaryBottomRight = worldToScreen(map.maxX, map.originY, store); // 边界右下角屏幕位置 - canvasCtx.strokeStyle = 'rgba(0,229,160,0.1)'; // 极淡的青绿色 - canvasCtx.lineWidth = 1; - canvasCtx.setLineDash([5, 4]); // 虚线 - canvasCtx.strokeRect( - boundaryTopLeft.x, boundaryTopLeft.y, - boundaryBottomRight.x - boundaryTopLeft.x, - boundaryBottomRight.y - boundaryTopLeft.y - ); - canvasCtx.setLineDash([]); // 恢复实线 -}; - -/** - * 从 normalPosList 构建占据栅格图像 - * - * 原理:normalPosList 中每个点标记一个自由通行格子。 - * 未出现在列表中的格子 = 障碍物(墙壁) - * 墙壁格子如果紧邻自由格子,则标记为"墙壁边缘",渲染高亮 - * - * @param {Object} parsedMap - parseSmapJson 的输出 - * @param {boolean} showEdgeGlow - 是否计算墙壁边缘高亮效果 - * @returns {HTMLCanvasElement} 离屏 Canvas 元素,包含渲染好的栅格图像 - */ -export const buildOccupancyGridImage = (parsedMap, showEdgeGlow) => { - const gridW = parsedMap.gridWidth; // 栅格宽度(像素) - const gridH = parsedMap.gridHeight; // 栅格高度(像素) - const originX = parsedMap.originX; // 世界坐标原点 X - const originY = parsedMap.originY; // 世界坐标原点 Y - const resolution = parsedMap.resolution; // 分辨率 - - // ── 第一步:遍历 normalPosList,标记自由空间 ── - const occupancyGrid = new Uint8Array(gridW * gridH); // 0=墙壁, 1=自由空间 - for (const freeSpacePoint of parsedMap.normalPositions) { - // 将世界坐标转换为栅格像素坐标 - const gridColX = Math.floor((freeSpacePoint.x - originX) / resolution); // 列号(从左到右) - const pixelRowFromBottom = Math.floor((freeSpacePoint.y - originY) / resolution); // 行号(从下到上,世界坐标系) - const imageRowY = gridH - 1 - pixelRowFromBottom; // 翻转为图像行号(从上到下) - // 安全边界检查后标记为自由空间 - if (gridColX >= 0 && gridColX < gridW && imageRowY >= 0 && imageRowY < gridH) { - occupancyGrid[imageRowY * gridW + gridColX] = 1; // 标记该格为自由 - } - } - - // ── 第二步:遍历每个格子,按类型着色 ── - const offscreenCanvas = document.createElement('canvas'); // 创建离屏 Canvas - offscreenCanvas.width = gridW; // 设置尺寸 - offscreenCanvas.height = gridH; - const offscreenCtx = offscreenCanvas.getContext('2d'); // 获取上下文 - const imageData = offscreenCtx.createImageData(gridW, gridH);// 创建 ImageData - const pixelData = imageData.data; // 像素数据数组 (RGBA 扁平排列) - - // 定义三种颜色 - const FREE_SPACE_R = 10, FREE_SPACE_G = 16, FREE_SPACE_B = 30; // 自由空间:深蓝黑 - const WALL_INTERIOR_R = 22, WALL_INTERIOR_G = 36, WALL_INTERIOR_B = 64; // 墙壁内部:深蓝 - const WALL_EDGE_R = 45, WALL_EDGE_G = 130, WALL_EDGE_B = 255; // 墙壁边缘:亮蓝 - - for (let rowY = 0; rowY < gridH; rowY++) { // 逐行扫描 - for (let colX = 0; colX < gridW; colX++) { // 逐列扫描 - const gridIndex = rowY * gridW + colX; // 一维数组索引 - const pixelOffset = gridIndex << 2; // RGBA 偏移(×4) - - if (occupancyGrid[gridIndex] === 1) { - // ── 自由空间 ── - pixelData[pixelOffset] = FREE_SPACE_R; // R - pixelData[pixelOffset + 1] = FREE_SPACE_G; // G - pixelData[pixelOffset + 2] = FREE_SPACE_B; // B - pixelData[pixelOffset + 3] = 255; // A(不透明) - } else { - // ── 障物(墙壁)── 判断是否为边缘 - let isAdjacentToFreeSpace = false; // 是否紧邻自由空间 - if (showEdgeGlow) { // 仅在启用边缘效果时检测 - if (rowY > 0 && occupancyGrid[(rowY - 1) * gridW + colX] === 1) isAdjacentToFreeSpace = true; // 上方 - else if (rowY < gridH - 1 && occupancyGrid[(rowY + 1) * gridW + colX] === 1) isAdjacentToFreeSpace = true; // 下方 - else if (colX > 0 && occupancyGrid[rowY * gridW + colX - 1] === 1) isAdjacentToFreeSpace = true; // 左方 - else if (colX < gridW - 1 && occupancyGrid[rowY * gridW + colX + 1] === 1) isAdjacentToFreeSpace = true; // 右方 - } - if (isAdjacentToFreeSpace) { - // 墙壁边缘:亮蓝色 - pixelData[pixelOffset] = WALL_EDGE_R; - pixelData[pixelOffset + 1] = WALL_EDGE_G; - pixelData[pixelOffset + 2] = WALL_EDGE_B; - pixelData[pixelOffset + 3] = 255; - } else { - // 墙壁内部:深蓝色 - pixelData[pixelOffset] = WALL_INTERIOR_R; - pixelData[pixelOffset + 1] = WALL_INTERIOR_G; - pixelData[pixelOffset + 2] = WALL_INTERIOR_B; - pixelData[pixelOffset + 3] = 255; - } - } - } - } - - // 将 ImageData 绘制到离屏 Canvas 上 - offscreenCtx.putImageData(imageData, 0, 0); - return offscreenCanvas; -} - -export class MobileRobot { - constructor(id, name, x, y, angleRad = 0, color = '#15ff00', imageUrl = null) { - this.id = id; - this.name = name; - this.x = x; // 世界坐标X (米) - this.y = y; // 世界坐标Y (米) - this.angle = angleRad; // 朝向弧度 - this.imageUrl = imageUrl || '/bot.svg'; - this.color = color; // 颜色 - // 预加载图片 (可选) - this.imgElement = null; - if (this.imageUrl) { - this.init(color, this.imageUrl) - } - } - - async init(color, imageUrl) { - const response = await fetch(imageUrl); - let svgText = await response.text(); - // 替换颜色 - svgText = svgText.replace(/currentColor/g, color); - svgText = svgText.replace(/stroke="[^"]*"/g, `stroke="${color}"`); - // 创建Blob URL - const blob = new Blob([svgText], { type: 'image/svg+xml' }); - const url = URL.createObjectURL(blob); - this.imgElement = new Image(); - this.imgElement.src = url; - } - // 命中检测: 检查世界坐标是否在机器人区域内 (半径0.35米) - hitTest(worldX, worldY, pixelsPerMeter){ - const dx = worldX - this.x; - const dy = worldY - this.y; - const distance = Math.hypot(dx, dy); - const hitRadius = 0.35; // 米 - return distance < hitRadius; - } - - // 绘制到canvas上下文 (屏幕坐标) - draw(ctx, screenX, screenY, color, scale = 1) { - const size = 24; // 绘制大小px - if (this.imgElement && this.imgElement.complete) { - ctx.save(); - ctx.translate(screenX, screenY); - ctx.rotate(-this.angle); // canvas Y向下, 角度翻转适配 - ctx.drawImage(this.imgElement, -size / 2, -size / 2, size, size); - ctx.restore(); - } - // 名字标签 - ctx.font = '12px "JetBrains Mono"'; - ctx.fillStyle = color; - ctx.shadowBlur = 0; - ctx.fillText(this.name, screenX, screenY - 20); - } - - // 更新位置 - setPosition(x, y) { this.x = x; this.y = y; } - setAngle(rad) { this.angle = rad; } -} - diff --git a/src/views/inspection/cockpit/components/Header.vue b/src/views/inspection/cockpit/components/Header.vue deleted file mode 100644 index 7c1da4a..0000000 --- a/src/views/inspection/cockpit/components/Header.vue +++ /dev/null @@ -1,161 +0,0 @@ - - - \ No newline at end of file diff --git a/src/views/inspection/cockpit/components/ManualTakeover/DirectionControl.vue b/src/views/inspection/cockpit/components/ManualTakeover/DirectionControl.vue deleted file mode 100644 index 4e1f1d5..0000000 --- a/src/views/inspection/cockpit/components/ManualTakeover/DirectionControl.vue +++ /dev/null @@ -1,325 +0,0 @@ - - - diff --git a/src/views/inspection/cockpit/components/ManualTakeover/RoboticArm.vue b/src/views/inspection/cockpit/components/ManualTakeover/RoboticArm.vue deleted file mode 100644 index 8ba9ba0..0000000 --- a/src/views/inspection/cockpit/components/ManualTakeover/RoboticArm.vue +++ /dev/null @@ -1,419 +0,0 @@ - - - diff --git a/src/views/inspection/cockpit/components/ManualTakeover/VoiceConversation.vue b/src/views/inspection/cockpit/components/ManualTakeover/VoiceConversation.vue deleted file mode 100644 index 280c094..0000000 --- a/src/views/inspection/cockpit/components/ManualTakeover/VoiceConversation.vue +++ /dev/null @@ -1,1125 +0,0 @@ - - - - - diff --git a/src/views/inspection/cockpit/components/ManualTakeover/index.vue b/src/views/inspection/cockpit/components/ManualTakeover/index.vue deleted file mode 100644 index eaf49da..0000000 --- a/src/views/inspection/cockpit/components/ManualTakeover/index.vue +++ /dev/null @@ -1,622 +0,0 @@ - - - - diff --git a/src/views/inspection/cockpit/components/MapCanvas.vue b/src/views/inspection/cockpit/components/MapCanvas.vue deleted file mode 100644 index 8c8e59c..0000000 --- a/src/views/inspection/cockpit/components/MapCanvas.vue +++ /dev/null @@ -1,527 +0,0 @@ - - - - - diff --git a/src/views/inspection/cockpit/components/MapOverview.vue b/src/views/inspection/cockpit/components/MapOverview.vue deleted file mode 100644 index 34cca2e..0000000 --- a/src/views/inspection/cockpit/components/MapOverview.vue +++ /dev/null @@ -1,433 +0,0 @@ - - - - - diff --git a/src/views/inspection/cockpit/components/Monitor.vue b/src/views/inspection/cockpit/components/Monitor.vue deleted file mode 100644 index 6dd44a5..0000000 --- a/src/views/inspection/cockpit/components/Monitor.vue +++ /dev/null @@ -1,209 +0,0 @@ - - - diff --git a/src/views/inspection/cockpit/components/UrdfView.vue b/src/views/inspection/cockpit/components/UrdfView.vue deleted file mode 100644 index 254c787..0000000 --- a/src/views/inspection/cockpit/components/UrdfView.vue +++ /dev/null @@ -1,292 +0,0 @@ - - - - - diff --git a/src/views/inspection/cockpit/index.vue b/src/views/inspection/cockpit/index.vue deleted file mode 100644 index 916636b..0000000 --- a/src/views/inspection/cockpit/index.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - \ No newline at end of file diff --git a/src/views/inspection/point/index.vue b/src/views/inspection/point/index.vue deleted file mode 100644 index 5f11aa6..0000000 --- a/src/views/inspection/point/index.vue +++ /dev/null @@ -1,419 +0,0 @@ - - - diff --git a/src/views/inspection/runTask/index.vue b/src/views/inspection/runTask/index.vue deleted file mode 100644 index a4ef912..0000000 --- a/src/views/inspection/runTask/index.vue +++ /dev/null @@ -1,824 +0,0 @@ - - - diff --git a/src/views/inspection/runTask/task-log.vue b/src/views/inspection/runTask/task-log.vue deleted file mode 100644 index 31e8947..0000000 --- a/src/views/inspection/runTask/task-log.vue +++ /dev/null @@ -1,469 +0,0 @@ - - - - - diff --git a/src/views/inspection/runTask/task-steps.vue b/src/views/inspection/runTask/task-steps.vue deleted file mode 100644 index 6d7e595..0000000 --- a/src/views/inspection/runTask/task-steps.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - - diff --git a/src/views/inspection/task/index.vue b/src/views/inspection/task/index.vue deleted file mode 100644 index 8a9f73f..0000000 --- a/src/views/inspection/task/index.vue +++ /dev/null @@ -1,404 +0,0 @@ - - - diff --git a/src/views/intelligenceTest/car/index.vue b/src/views/intelligenceTest/car/index.vue deleted file mode 100644 index a4ae1a2..0000000 --- a/src/views/intelligenceTest/car/index.vue +++ /dev/null @@ -1,304 +0,0 @@ - - - diff --git a/src/views/intelligenceTest/mobilePhone/index.vue b/src/views/intelligenceTest/mobilePhone/index.vue deleted file mode 100644 index 89d0a04..0000000 --- a/src/views/intelligenceTest/mobilePhone/index.vue +++ /dev/null @@ -1,321 +0,0 @@ - - - diff --git a/src/views/intelligenceTest/runningTask/index.vue b/src/views/intelligenceTest/runningTask/index.vue deleted file mode 100644 index 28abdd8..0000000 --- a/src/views/intelligenceTest/runningTask/index.vue +++ /dev/null @@ -1,885 +0,0 @@ - - - diff --git a/src/views/intelligenceTest/runningTask/task-log.vue b/src/views/intelligenceTest/runningTask/task-log.vue deleted file mode 100644 index 562bff7..0000000 --- a/src/views/intelligenceTest/runningTask/task-log.vue +++ /dev/null @@ -1,641 +0,0 @@ - - - - - diff --git a/src/views/intelligenceTest/runningTask/task-steps.vue b/src/views/intelligenceTest/runningTask/task-steps.vue deleted file mode 100644 index 667bc41..0000000 --- a/src/views/intelligenceTest/runningTask/task-steps.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - - diff --git a/src/views/intelligenceTest/taskManage/index.vue b/src/views/intelligenceTest/taskManage/index.vue deleted file mode 100644 index 9d0ea7c..0000000 --- a/src/views/intelligenceTest/taskManage/index.vue +++ /dev/null @@ -1,376 +0,0 @@ - - - diff --git a/src/views/intelligenceTest/testCase/index.vue b/src/views/intelligenceTest/testCase/index.vue deleted file mode 100644 index 0c6cc25..0000000 --- a/src/views/intelligenceTest/testCase/index.vue +++ /dev/null @@ -1,344 +0,0 @@ - - - diff --git a/src/views/login.vue b/src/views/login.vue deleted file mode 100644 index 36116e2..0000000 --- a/src/views/login.vue +++ /dev/null @@ -1,239 +0,0 @@ - - - - - diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue deleted file mode 100644 index 271cc8e..0000000 --- a/src/views/monitor/cache/index.vue +++ /dev/null @@ -1,132 +0,0 @@ - - - diff --git a/src/views/monitor/cache/list.vue b/src/views/monitor/cache/list.vue deleted file mode 100644 index 6515fcd..0000000 --- a/src/views/monitor/cache/list.vue +++ /dev/null @@ -1,246 +0,0 @@ - - - diff --git a/src/views/monitor/druid/index.vue b/src/views/monitor/druid/index.vue deleted file mode 100644 index 29c1aa7..0000000 --- a/src/views/monitor/druid/index.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/src/views/monitor/job/detail.vue b/src/views/monitor/job/detail.vue deleted file mode 100644 index ab09d50..0000000 --- a/src/views/monitor/job/detail.vue +++ /dev/null @@ -1,217 +0,0 @@ - - - - - diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue deleted file mode 100644 index 25b4532..0000000 --- a/src/views/monitor/job/index.vue +++ /dev/null @@ -1,435 +0,0 @@ - - - diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue deleted file mode 100644 index 8651c74..0000000 --- a/src/views/monitor/job/log.vue +++ /dev/null @@ -1,251 +0,0 @@ - - - diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue deleted file mode 100644 index 86f9f0b..0000000 --- a/src/views/monitor/logininfor/index.vue +++ /dev/null @@ -1,233 +0,0 @@ - - - diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue deleted file mode 100644 index fee70fe..0000000 --- a/src/views/monitor/online/index.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - diff --git a/src/views/monitor/operlog/detail.vue b/src/views/monitor/operlog/detail.vue deleted file mode 100644 index 6ebc593..0000000 --- a/src/views/monitor/operlog/detail.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue deleted file mode 100644 index 9648905..0000000 --- a/src/views/monitor/operlog/index.vue +++ /dev/null @@ -1,262 +0,0 @@ - - - diff --git a/src/views/monitor/server/index.vue b/src/views/monitor/server/index.vue deleted file mode 100644 index 60ff80c..0000000 --- a/src/views/monitor/server/index.vue +++ /dev/null @@ -1,187 +0,0 @@ - - - diff --git a/src/views/redirect/index.vue b/src/views/redirect/index.vue deleted file mode 100644 index 99dd4f5..0000000 --- a/src/views/redirect/index.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - \ No newline at end of file diff --git a/src/views/register.vue b/src/views/register.vue deleted file mode 100644 index 254cc8e..0000000 --- a/src/views/register.vue +++ /dev/null @@ -1,219 +0,0 @@ - - - - - diff --git a/src/views/resource/device/index.vue b/src/views/resource/device/index.vue deleted file mode 100644 index a28535e..0000000 --- a/src/views/resource/device/index.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - - - diff --git a/src/views/resource/map/index.vue b/src/views/resource/map/index.vue deleted file mode 100644 index 745e05e..0000000 --- a/src/views/resource/map/index.vue +++ /dev/null @@ -1,189 +0,0 @@ - - - diff --git a/src/views/resource/robot/index.vue b/src/views/resource/robot/index.vue deleted file mode 100644 index 04f3b84..0000000 --- a/src/views/resource/robot/index.vue +++ /dev/null @@ -1,339 +0,0 @@ - - - - - diff --git a/src/views/resource/terminal/index.vue b/src/views/resource/terminal/index.vue deleted file mode 100644 index 8bb484f..0000000 --- a/src/views/resource/terminal/index.vue +++ /dev/null @@ -1,75 +0,0 @@ - - - - - diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue deleted file mode 100644 index beaaa7f..0000000 --- a/src/views/system/config/index.vue +++ /dev/null @@ -1,316 +0,0 @@ - - - diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue deleted file mode 100644 index 9c8b317..0000000 --- a/src/views/system/dept/index.vue +++ /dev/null @@ -1,334 +0,0 @@ - - - diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue deleted file mode 100644 index d96fd1f..0000000 --- a/src/views/system/dict/data.vue +++ /dev/null @@ -1,362 +0,0 @@ - - - diff --git a/src/views/system/dict/detail.vue b/src/views/system/dict/detail.vue deleted file mode 100644 index 472267b..0000000 --- a/src/views/system/dict/detail.vue +++ /dev/null @@ -1,202 +0,0 @@ - - - - - diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue deleted file mode 100644 index 1e64264..0000000 --- a/src/views/system/dict/index.vue +++ /dev/null @@ -1,346 +0,0 @@ - - - diff --git a/src/views/system/file/index.vue b/src/views/system/file/index.vue deleted file mode 100644 index 8fa3319..0000000 --- a/src/views/system/file/index.vue +++ /dev/null @@ -1,350 +0,0 @@ - - - diff --git a/src/views/system/group/index.vue b/src/views/system/group/index.vue deleted file mode 100644 index 925ef7d..0000000 --- a/src/views/system/group/index.vue +++ /dev/null @@ -1,289 +0,0 @@ - - - diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue deleted file mode 100644 index 9bc0ee8..0000000 --- a/src/views/system/menu/index.vue +++ /dev/null @@ -1,508 +0,0 @@ - - - diff --git a/src/views/system/notice/ReadUsers.vue b/src/views/system/notice/ReadUsers.vue deleted file mode 100644 index 7590bef..0000000 --- a/src/views/system/notice/ReadUsers.vue +++ /dev/null @@ -1,118 +0,0 @@ - - - - - diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue deleted file mode 100644 index 7541a48..0000000 --- a/src/views/system/notice/index.vue +++ /dev/null @@ -1,306 +0,0 @@ - - - diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue deleted file mode 100644 index 316e0d7..0000000 --- a/src/views/system/post/index.vue +++ /dev/null @@ -1,287 +0,0 @@ - - - diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue deleted file mode 100644 index 6848eb4..0000000 --- a/src/views/system/role/authUser.vue +++ /dev/null @@ -1,179 +0,0 @@ - - - - diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue deleted file mode 100644 index c191194..0000000 --- a/src/views/system/role/index.vue +++ /dev/null @@ -1,584 +0,0 @@ - - - diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue deleted file mode 100644 index 58b621a..0000000 --- a/src/views/system/role/selectUser.vue +++ /dev/null @@ -1,144 +0,0 @@ - - - diff --git a/src/views/system/user/authRole.vue b/src/views/system/user/authRole.vue deleted file mode 100644 index 28b40e7..0000000 --- a/src/views/system/user/authRole.vue +++ /dev/null @@ -1,123 +0,0 @@ - - - diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue deleted file mode 100644 index 6528964..0000000 --- a/src/views/system/user/index.vue +++ /dev/null @@ -1,459 +0,0 @@ - - - diff --git a/src/views/system/user/profile/index.vue b/src/views/system/user/profile/index.vue deleted file mode 100644 index dfb4a66..0000000 --- a/src/views/system/user/profile/index.vue +++ /dev/null @@ -1,94 +0,0 @@ - - - diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue deleted file mode 100644 index e454938..0000000 --- a/src/views/system/user/profile/resetPwd.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue deleted file mode 100644 index 64d2c94..0000000 --- a/src/views/system/user/profile/userAvatar.vue +++ /dev/null @@ -1,180 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue deleted file mode 100644 index 9fcc09b..0000000 --- a/src/views/system/user/profile/userInfo.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - diff --git a/src/views/system/user/view.vue b/src/views/system/user/view.vue deleted file mode 100644 index 593a163..0000000 --- a/src/views/system/user/view.vue +++ /dev/null @@ -1,175 +0,0 @@ - - - diff --git a/src/views/system/vehOper/index.vue b/src/views/system/vehOper/index.vue deleted file mode 100644 index 0a9b389..0000000 --- a/src/views/system/vehOper/index.vue +++ /dev/null @@ -1,349 +0,0 @@ - - - diff --git a/src/views/tool/build/CodeTypeDialog.vue b/src/views/tool/build/CodeTypeDialog.vue deleted file mode 100644 index de0beb7..0000000 --- a/src/views/tool/build/CodeTypeDialog.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - \ No newline at end of file diff --git a/src/views/tool/build/DraggableItem.vue b/src/views/tool/build/DraggableItem.vue deleted file mode 100644 index 9ae2354..0000000 --- a/src/views/tool/build/DraggableItem.vue +++ /dev/null @@ -1,68 +0,0 @@ - - \ No newline at end of file diff --git a/src/views/tool/build/IconsDialog.vue b/src/views/tool/build/IconsDialog.vue deleted file mode 100644 index 98d9c13..0000000 --- a/src/views/tool/build/IconsDialog.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - diff --git a/src/views/tool/build/RightPanel.vue b/src/views/tool/build/RightPanel.vue deleted file mode 100644 index 5fe80fb..0000000 --- a/src/views/tool/build/RightPanel.vue +++ /dev/null @@ -1,906 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/tool/build/TreeNodeDialog.vue b/src/views/tool/build/TreeNodeDialog.vue deleted file mode 100644 index 372d3af..0000000 --- a/src/views/tool/build/TreeNodeDialog.vue +++ /dev/null @@ -1,93 +0,0 @@ - - diff --git a/src/views/tool/build/index.vue b/src/views/tool/build/index.vue deleted file mode 100644 index 64a9317..0000000 --- a/src/views/tool/build/index.vue +++ /dev/null @@ -1,660 +0,0 @@ - - - - - diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue deleted file mode 100644 index 92c3ca9..0000000 --- a/src/views/tool/gen/basicInfoForm.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - diff --git a/src/views/tool/gen/createTable.vue b/src/views/tool/gen/createTable.vue deleted file mode 100644 index b5fedde..0000000 --- a/src/views/tool/gen/createTable.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue deleted file mode 100644 index 9433527..0000000 --- a/src/views/tool/gen/editTable.vue +++ /dev/null @@ -1,212 +0,0 @@ - - - diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue deleted file mode 100644 index 5247772..0000000 --- a/src/views/tool/gen/genInfoForm.vue +++ /dev/null @@ -1,328 +0,0 @@ - - - diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue deleted file mode 100644 index a73ad7a..0000000 --- a/src/views/tool/gen/importTable.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue deleted file mode 100644 index 9359592..0000000 --- a/src/views/tool/gen/index.vue +++ /dev/null @@ -1,309 +0,0 @@ - - - diff --git a/src/views/tool/swagger/index.vue b/src/views/tool/swagger/index.vue deleted file mode 100644 index a3b03bb..0000000 --- a/src/views/tool/swagger/index.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - From 73ee3fe0808a4a9d06f9297a5b6abba924eb9229 Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Tue, 25 Aug 2026 10:26:33 +0800 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 4 +- package.json | 1 + pnpm-lock.yaml | 81 +++++++++++++++-------- src/main.js | 11 +++ src/plugins/cache.js | 15 +++-- src/router/index.js | 41 ++++++------ src/store/modules/permission.js | 4 +- src/utils/auth.js | 2 +- src/views/is/project/evaluate/Run.vue | 2 +- src/views/test/configs/Run.vue | 2 +- src/views/test/log/index.vue | 2 +- src/views/vi/testProject/evaluate/Run.vue | 2 +- vite.config.js | 1 + 13 files changed, 107 insertions(+), 61 deletions(-) diff --git a/.env.development b/.env.development index da134de..368025f 100644 --- a/.env.development +++ b/.env.development @@ -7,8 +7,8 @@ VITE_APP_ENV = 'development' # 招商车研物联网平台/开发环境 VITE_APP_BASE_API = '/dev-api' -VITE_API_URL = http://localhost:14080 -VITE_WS_URL = ws://localhost:14080/ws +VITE_API_URL = http://192.168.0.222:14080 +VITE_WS_URL = ws://192.168.0.222:14080/ws VITE_PORT = 5174 VITE_INSPECTION_TYPE = "inspection" VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/" diff --git a/package.json b/package.json index 0648cb7..793f6a7 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "preview": "vite preview" }, "dependencies": { + "@cmvr/iot-common": "1.0.0", "@element-plus/icons-vue": "2.3.2", "@vue-flow/background": "^1.3.2", "@vue-flow/controls": "^1.1.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0eac5f..50ca951 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: .: dependencies: + '@cmvr/iot-common': + specifier: 1.0.0 + version: 1.0.0(@element-plus/icons-vue@2.3.2(vue@3.5.26))(core-js@3.49.0)(element-plus@2.13.1(vue@3.5.26))(pinia@3.0.4(vue@3.5.26))(vue-router@4.6.4(vue@3.5.26))(vue@3.5.26) '@element-plus/icons-vue': specifier: 2.3.2 version: 2.3.2(vue@3.5.26) @@ -182,6 +185,15 @@ packages: '@bufbuild/protobuf@2.13.0': resolution: {integrity: sha512-acq7c49vxfm1ggJ95P70TX7ABDM0vxr1SYD3BB0o0jnBLB4OAqeHyKuN+cD3w80gXEDQ2zxHpR6CUeA+O/aU9g==} + '@cmvr/iot-common@1.0.0': + resolution: {integrity: sha512-EIdZdRRgyhb4FfclQ6SoDT3NwIAY/7uI2re+zcwwcnc0a0ELKizTn4POFZt/O4mhr5Ikeg8J98cRB/cchV3E9g==} + peerDependencies: + '@element-plus/icons-vue': ^2.3.2 + element-plus: ^2.13.1 + pinia: ^3.0.4 + vue: ^3.5.26 + vue-router: ^4.6.4 + '@codemirror/autocomplete@6.20.3': resolution: {integrity: sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==} @@ -487,42 +499,36 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - libc: [glibc] '@parcel/watcher-linux-arm-musl@2.6.0': resolution: {integrity: sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.6.0': resolution: {integrity: sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.6.0': resolution: {integrity: sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - libc: [musl] '@parcel/watcher-linux-x64-glibc@2.6.0': resolution: {integrity: sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - libc: [glibc] '@parcel/watcher-linux-x64-musl@2.6.0': resolution: {integrity: sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - libc: [musl] '@parcel/watcher-win32-arm64@2.6.0': resolution: {integrity: sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==} @@ -594,79 +600,66 @@ packages: resolution: {integrity: sha512-ggXnsTAEzNQx74XpunRsiZ9aBZDsI7XIa0hm2nzR9f4WzH5/f/d73ZSDaC5ejJ8YLY4NW+V3wr0tjOaeCq8hqA==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.62.3': resolution: {integrity: sha512-2vng+FlzNUhKZxtej3IUqJgbZoQk2M/dwQM20+ULV0R/E/8tr9/P6uEf2iiGIk4HL0zMKh5Jry7mUHdUOvyGgA==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.62.3': resolution: {integrity: sha512-LLLFZKt4/Nraf9rxDkhiU8QVgLF4WmCkfr0L4fj0fPfIZFBib0DeiFk1hhaYKd03LFAFJcxHslhDFlNJLylf5Q==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.62.3': resolution: {integrity: sha512-WJkdQCvS9sWNOUBJZfQRKpZGFBztRzcowI+nndmflKgU4XY+3a420FgTOSKTsVqJbnzSxeT4vaJalpOaPo2YCQ==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.62.3': resolution: {integrity: sha512-PwHXCCS2n64/1Ot6rP1YEYA02MGYBcQlr8CSZZyrUG2O7NH6NklYmvr9v3Jy+5e/eDeNchc/ukmKJi9LuflMIQ==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.62.3': resolution: {integrity: sha512-vUjxINQu3RC8NZS3ykk1gN65gIz8pAopOq2HXuZhiIxHdx7TFvDG+jgrdSgInu1Eza4/Rfi2VzZgyIgEH4WOaw==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.62.3': resolution: {integrity: sha512-wzko4aJ13+0G3kGnviCg5gnXFKd40izKsrf2uOw12US4XqprkDrmwOpeW14aSNa37V8bfPcz5Fkob6LZ3BAPmA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.62.3': resolution: {integrity: sha512-8120ue0JUMSwy11stlwnfdX3pPd+WZYGCDBwEHWtIHi6pOpZmsEF5QKB7a/UN+XFdqvobxz98kv8RTqikyCEBw==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.62.3': resolution: {integrity: sha512-XLFHnR3tXMjbOCh2vtVJHmxt+995uJsTERQyseFDRA0xxMxyTZPLa3OIUlyFaO4mF/Lu0FjmWHCuPXJT1n/IOg==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.62.3': resolution: {integrity: sha512-se6yXvNGMIl0f+RQzyh7XAmia8/9kplQx424wnG2w0C1oi6XgO6Y8otKhdXFHbHs88Ihavzmvh1NWjuovE76BQ==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.62.3': resolution: {integrity: sha512-gNoxRefktVIiGflpONuxWWXZAzIQG++z9qHO3xKwk4WdDMuQja3JHGfE1u0i3PfPDyvhypdk+WrgIJqLhGG7sg==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.62.3': resolution: {integrity: sha512-V4KtWtQfAFMU7+9/A/VDps/VI8CHd3cYz0L8sgJzz8qK7eY7wI4ruFD82UYIYvW9Z4DtlTfhQcsl4XyPHW5uSg==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.62.3': resolution: {integrity: sha512-LBx9LYXvj2CBkMkjLdNAWLwH0MLMin7do2VcVo9kVPibGLkY0BQQut2fv7NVqkXqZ/CrAu9LqDHVV1xHCMpCPw==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.62.3': resolution: {integrity: sha512-ABVf3Q0RCu7NcyCCOZQI0pJ3GuSdfSl8EXcy88QtdceIMIoCUdfhsJChZ64L9zVM2aJHjde1Bhn5uqSRcX9ySA==} @@ -2344,56 +2337,48 @@ packages: engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - libc: glibc sass-embedded-linux-arm@1.97.2: resolution: {integrity: sha512-yDRe1yifGHl6kibkDlRIJ2ZzAU03KJ1AIvsAh4dsIDgK5jx83bxZLV1ZDUv7a8KK/iV/80LZnxnu/92zp99cXQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - libc: glibc sass-embedded-linux-musl-arm64@1.97.2: resolution: {integrity: sha512-NfUqZSjHwnHvpSa7nyNxbWfL5obDjNBqhHUYmqbHUcmqBpFfHIQsUPgXME9DKn1yBlBc3mWnzMxRoucdYTzd2Q==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - libc: musl sass-embedded-linux-musl-arm@1.97.2: resolution: {integrity: sha512-GIO6xfAtahJAWItvsXZ3MD1HM6s8cKtV1/HL088aUpKJaw/2XjTCveiOO2AdgMpLNztmq9DZ1lx5X5JjqhS45g==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - libc: musl sass-embedded-linux-musl-riscv64@1.97.2: resolution: {integrity: sha512-qtM4dJ5gLfvyTZ3QencfNbsTEShIWImSEpkThz+Y2nsCMbcMP7/jYOA03UWgPfEOKSehQQ7EIau7ncbFNoDNPQ==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] - libc: musl sass-embedded-linux-musl-x64@1.97.2: resolution: {integrity: sha512-ZAxYOdmexcnxGnzdsDjYmNe3jGj+XW3/pF/n7e7r8y+5c6D2CQRrCUdapLgaqPt1edOPQIlQEZF8q5j6ng21yw==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - libc: musl sass-embedded-linux-riscv64@1.97.2: resolution: {integrity: sha512-reVwa9ZFEAOChXpDyNB3nNHHyAkPMD+FTctQKECqKiVJnIzv2EaFF6/t0wzyvPgBKeatA8jszAIeOkkOzbYVkQ==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] - libc: glibc sass-embedded-linux-x64@1.97.2: resolution: {integrity: sha512-bvAdZQsX3jDBv6m4emaU2OMTpN0KndzTAMgJZZrKUgiC0qxBmBqbJG06Oj/lOCoXGCxAvUOheVYpezRTF+Feog==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - libc: glibc sass-embedded-unknown-all@1.97.2: resolution: {integrity: sha512-86tcYwohjPgSZtgeU9K4LikrKBJNf8ZW/vfsFbdzsRlvc73IykiqanufwQi5qIul0YHuu9lZtDWyWxM2dH/Rsg==} @@ -2993,6 +2978,48 @@ snapshots: '@bufbuild/protobuf@2.13.0': {} + '@cmvr/iot-common@1.0.0(@element-plus/icons-vue@2.3.2(vue@3.5.26))(core-js@3.49.0)(element-plus@2.13.1(vue@3.5.26))(pinia@3.0.4(vue@3.5.26))(vue-router@4.6.4(vue@3.5.26))(vue@3.5.26)': + dependencies: + '@element-plus/icons-vue': 2.3.2(vue@3.5.26) + '@vue-flow/background': 1.3.2(@vue-flow/core@1.48.2(vue@3.5.26))(vue@3.5.26) + '@vue-flow/controls': 1.1.3(@vue-flow/core@1.48.2(vue@3.5.26))(vue@3.5.26) + '@vue-flow/core': 1.48.2(vue@3.5.26) + '@vueup/vue-quill': 1.2.0(vue@3.5.26) + '@vueuse/core': 14.1.0(vue@3.5.26) + ace-builds: 1.44.0 + axios: 1.13.2 + clipboard: 2.0.11 + dayjs: 1.11.21 + echarts: 5.6.0 + element-plus: 2.13.1(vue@3.5.26) + file-saver: 2.0.5 + fuse.js: 7.1.0 + js-beautify: 1.15.4 + js-cookie: 3.0.5 + jsencrypt: 3.3.2 + json-editor-vue: 0.18.1(vue@3.5.26) + lodash: 4.18.1 + mitt: 3.0.1 + monaco-editor: 0.55.1 + nprogress: 0.2.0 + pako: 2.2.0 + pinia: 3.0.4(vue@3.5.26) + sortablejs: 1.15.7 + splitpanes: 3.1.5 + uuid: 11.1.1 + vue: 3.5.26 + vue-cropper: 1.1.1 + vue-router: 4.6.4(vue@3.5.26) + vue3-ace-editor: 2.2.4(ace-builds@1.44.0)(vue@3.5.26) + vue3-json-viewer: 2.3.0(vue@3.5.26) + vuedraggable: 4.1.0(vue@3.5.26) + xgplayer: 3.0.26(core-js@3.49.0) + transitivePeerDependencies: + - '@typescript-eslint/types' + - '@vue/composition-api' + - core-js + - debug + '@codemirror/autocomplete@6.20.3': dependencies: '@codemirror/language': 6.12.4 diff --git a/src/main.js b/src/main.js index f281aea..169c103 100644 --- a/src/main.js +++ b/src/main.js @@ -1,4 +1,5 @@ import { createApp } from 'vue' +import { configureCmvrCommon } from '@cmvr/iot-common' import Cookies from 'js-cookie' @@ -30,6 +31,16 @@ import { useDict } from '@/utils/dict' import { getConfigKey } from "@/api/system/config" import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi' +configureCmvrCommon({ + apiBaseURL: import.meta.env.VITE_APP_BASE_API, + tokenKey: 'CMVR-Platform-Token', + storagePrefix: 'cmvr:platform', + router, + loginPath: '/login', + homePath: '/index' +}) +import '@cmvr/iot-common/style.css' + // 分页组件 import Pagination from '@/components/Pagination' // 自定义表格工具组件 diff --git a/src/plugins/cache.js b/src/plugins/cache.js index ea8a53f..8422132 100644 --- a/src/plugins/cache.js +++ b/src/plugins/cache.js @@ -1,10 +1,13 @@ +const CachePrefix = 'cmvr:platform:' +const cacheKey = (key) => `${CachePrefix}${key}` + const sessionCache = { set (key, value) { if (!sessionStorage) { return } if (key != null && value != null) { - sessionStorage.setItem(key, value) + sessionStorage.setItem(cacheKey(key), value) } }, get (key) { @@ -14,7 +17,7 @@ const sessionCache = { if (key == null) { return null } - return sessionStorage.getItem(key) + return sessionStorage.getItem(cacheKey(key)) }, setJSON (key, jsonValue) { if (jsonValue != null) { @@ -29,7 +32,7 @@ const sessionCache = { return null }, remove (key) { - sessionStorage.removeItem(key) + sessionStorage.removeItem(cacheKey(key)) } } const localCache = { @@ -38,7 +41,7 @@ const localCache = { return } if (key != null && value != null) { - localStorage.setItem(key, value) + localStorage.setItem(cacheKey(key), value) } }, get (key) { @@ -48,7 +51,7 @@ const localCache = { if (key == null) { return null } - return localStorage.getItem(key) + return localStorage.getItem(cacheKey(key)) }, setJSON (key, jsonValue) { if (jsonValue != null) { @@ -63,7 +66,7 @@ const localCache = { return null }, remove (key) { - localStorage.removeItem(key) + localStorage.removeItem(cacheKey(key)) } } diff --git a/src/router/index.js b/src/router/index.js index 86950ba..7128fcf 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,6 +1,15 @@ import { createWebHistory, createRouter } from "vue-router"; /* Layout */ import Layout from "@/layout"; +import { resolveCommonView } from '@cmvr/iot-common' + +const commonView = (view) => { + const component = resolveCommonView(view) + if (!component) { + throw new Error(`[cmvr-common] view not found: ${view}`) + } + return component +} /** * Note: 路由配置项 @@ -33,28 +42,28 @@ export const constantRoutes = [ children: [ { path: "/redirect/:path(.*)", - component: () => import("@/views/redirect/index.vue"), + component: commonView('redirect/index'), }, ], }, { path: "/login", - component: () => import("@/views/login"), + component: commonView('login'), hidden: true, }, { path: "/register", - component: () => import("@/views/register"), + component: commonView('register'), hidden: true, }, { path: "/:pathMatch(.*)*", - component: () => import("@/views/error/404"), + component: commonView('error/404'), hidden: true, }, { path: "/401", - component: () => import("@/views/error/401"), + component: commonView('error/401'), hidden: true, }, { @@ -126,14 +135,6 @@ export const constantRoutes = [ meta: { title: "触摸交互", noLogin: true }, hidden: true, }, - { - //cockpit - path: "/inspection/cockpit", - component: () => - import("@/views/inspection/cockpit/index.vue"), - meta: { title: "logicFlow", noLogin: true }, - hidden: true, - }, { // 流程运行状态 path: "/logic_flow", @@ -145,7 +146,7 @@ export const constantRoutes = [ { // 流程编排 path: "/flow", - component: () => import("@/views/flow/index.vue"), + component: commonView('flow/index'), meta: { title: "流程编排", noLogin: true }, hidden: true, }, @@ -183,7 +184,7 @@ export const constantRoutes = [ children: [ { path: "profile/:activeTab?", - component: () => import("@/views/system/user/profile/index"), + component: commonView('system/user/profile/index'), name: "Profile", meta: { title: "个人中心", icon: "user" }, }, @@ -201,7 +202,7 @@ export const dynamicRoutes = [ children: [ { path: "role/:userId(\\d+)", - component: () => import("@/views/system/user/authRole"), + component: commonView('system/user/authRole'), name: "AuthRole", meta: { title: "分配角色", activeMenu: "/system/user" }, }, @@ -215,7 +216,7 @@ export const dynamicRoutes = [ children: [ { path: "user/:roleId(\\d+)", - component: () => import("@/views/system/role/authUser"), + component: commonView('system/role/authUser'), name: "AuthUser", meta: { title: "分配用户", activeMenu: "/system/role" }, }, @@ -229,7 +230,7 @@ export const dynamicRoutes = [ children: [ { path: "index/:dictId(\\d+)", - component: () => import("@/views/system/dict/data"), + component: commonView('system/dict/data'), name: "Data", meta: { title: "字典数据", activeMenu: "/system/dict" }, }, @@ -299,7 +300,7 @@ export const dynamicRoutes = [ children: [ { path: "index/:jobId(\\d+)", - component: () => import("@/views/monitor/job/log"), + component: commonView('monitor/job/log'), name: "JobLog", meta: { title: "调度日志", activeMenu: "/monitor/job" }, }, @@ -313,7 +314,7 @@ export const dynamicRoutes = [ children: [ { path: "index/:tableId(\\d+)", - component: () => import("@/views/tool/gen/editTable"), + component: commonView('tool/gen/editTable'), name: "GenEdit", meta: { title: "修改生成配置", activeMenu: "/tool/gen" }, }, diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js index a7f3835..6a8d29b 100644 --- a/src/store/modules/permission.js +++ b/src/store/modules/permission.js @@ -4,6 +4,7 @@ import { getRouters } from '@/api/menu' import Layout from '@/layout/index' import ParentView from '@/components/ParentView' import InnerLink from '@/layout/components/InnerLink' +import { commonViewRegistry } from '@cmvr/iot-common' // 匹配views里面所有的.vue文件 const modules = import.meta.glob('./../../views/**/*.vue') @@ -150,9 +151,10 @@ export const loadView = (view) => { const dir = path.split('views/')[1].split('.vue')[0] if (dir === view) { res = () => modules[path]() + break } } - return res + return res || commonViewRegistry[String(view || '').replace(/^\/+|\.vue$/g, '')] } export default usePermissionStore diff --git a/src/utils/auth.js b/src/utils/auth.js index 08a43d6..3f88270 100644 --- a/src/utils/auth.js +++ b/src/utils/auth.js @@ -1,6 +1,6 @@ import Cookies from 'js-cookie' -const TokenKey = 'Admin-Token' +const TokenKey = 'CMVR-Platform-Token' export function getToken() { return Cookies.get(TokenKey) diff --git a/src/views/is/project/evaluate/Run.vue b/src/views/is/project/evaluate/Run.vue index 313b5b0..9e14590 100644 --- a/src/views/is/project/evaluate/Run.vue +++ b/src/views/is/project/evaluate/Run.vue @@ -68,7 +68,7 @@ import { ref, watch } from "vue"; import { ElMessage } from "element-plus"; import { addValueProperty, formatTableData } from "@/utils/flow"; import { getExecuteRunParams, projectExecute } from "@/api/is/project/index.js"; -import RuntimeAssignmentsEditor from '@/views/flow/components/RuntimeAssignmentsEditor.vue' +import { RuntimeAssignmentsEditor } from '@cmvr/iot-common' import { firstAssignedRobotId, loadFlowItemRuntimeRoles, diff --git a/src/views/test/configs/Run.vue b/src/views/test/configs/Run.vue index 7320dd3..6fdc5a7 100644 --- a/src/views/test/configs/Run.vue +++ b/src/views/test/configs/Run.vue @@ -68,7 +68,7 @@ import { emitter } from "@/utils/eventBus"; import { ElMessage } from "element-plus"; import { getTaskConfig } from "@/api/test/config.js"; import { taskExecute } from "@/api/test/config" -import RuntimeAssignmentsEditor from '@/views/flow/components/RuntimeAssignmentsEditor.vue' +import { RuntimeAssignmentsEditor } from '@cmvr/iot-common' import { firstAssignedRobotId, loadFlowItemScopedRuntimeRoles, diff --git a/src/views/test/log/index.vue b/src/views/test/log/index.vue index e3a4d99..d384919 100644 --- a/src/views/test/log/index.vue +++ b/src/views/test/log/index.vue @@ -218,7 +218,7 @@ import { appendParamsToPath } from "@/utils/fn.js"; import { getTaskConfig } from "@/api/test/config.js"; import { onMounted } from "vue"; import { fetchAllPagedRows } from '@/utils/pagedRequest' -import TaskExecutionLog from '@/views/flow/components/TaskExecutionLog.vue' +import { TaskExecutionLog } from '@cmvr/iot-common' import { useContainerHeight } from "@/hooks/tableHeight"; diff --git a/src/views/vi/testProject/evaluate/Run.vue b/src/views/vi/testProject/evaluate/Run.vue index 2e1a90a..81dc1e0 100644 --- a/src/views/vi/testProject/evaluate/Run.vue +++ b/src/views/vi/testProject/evaluate/Run.vue @@ -68,7 +68,7 @@ import { ref, watch } from "vue"; import { ElMessage } from "element-plus"; import { addValueProperty, formatTableData } from "@/utils/flow"; import { getExecuteRunParams, projectExecute } from "@/api/vi/project.js" -import RuntimeAssignmentsEditor from '@/views/flow/components/RuntimeAssignmentsEditor.vue' +import { RuntimeAssignmentsEditor } from '@cmvr/iot-common' import { firstAssignedRobotId, loadFlowItemRuntimeRoles, diff --git a/vite.config.js b/vite.config.js index b3c084c..39bc171 100644 --- a/vite.config.js +++ b/vite.config.js @@ -30,6 +30,7 @@ export default defineConfig(({ mode, command }) => { // 设置别名 '@': path.resolve(__dirname, './src') }, + dedupe: ['vue', 'vue-router', 'pinia', 'element-plus', '@element-plus/icons-vue'], // https://cn.vitejs.dev/config/#resolve-extensions extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] }, From d81dab5604b6c134e71ca513780caa2df00dedce Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Tue, 25 Aug 2026 14:04:27 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=20jsEncrypt=20?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E8=B7=AF=E5=BE=84=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20Vite=20=E9=85=8D=E7=BD=AE=E4=BB=A5=E6=94=AF=E6=8C=81=20cmvr-?= =?UTF-8?q?iot-common?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/jsencrypt.js | 2 +- vite.config.js | 17 +++++++++++++++++ vite/plugins/auto-import.js | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/utils/jsencrypt.js b/src/utils/jsencrypt.js index 78d9523..91eeff6 100644 --- a/src/utils/jsencrypt.js +++ b/src/utils/jsencrypt.js @@ -1,4 +1,4 @@ -import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' +import JSEncrypt from 'jsencrypt' // 密钥对生成 http://web.chacuo.net/netrsakeypair diff --git a/vite.config.js b/vite.config.js index 39bc171..678a256 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,7 +1,18 @@ import { defineConfig, loadEnv, normalizePath } from 'vite' import path from 'path' +import { realpathSync } from 'node:fs' import createVitePlugins from './vite/plugins' +const isCommonLinked = (() => { + try { + const linkedPath = realpathSync(path.resolve('node_modules/@cmvr/iot-common')) + const localPath = realpathSync(path.resolve('../cmvr-iot-common')) + return path.relative(linkedPath, localPath) === '' + } catch { + return false + } +})() + // https://vitejs.dev/config/ export default defineConfig(({ mode, command }) => { const env = loadEnv(mode, process.cwd()) @@ -12,6 +23,7 @@ export default defineConfig(({ mode, command }) => { plugins: createVitePlugins(env, command === 'build'), optimizeDeps: { exclude: [ + ...(isCommonLinked ? ['@cmvr/iot-common'] : []), 'monaco-editor', 'monaco-editor/esm/vs/base/worker/workerMain.js', 'monaco-editor/esm/vs/editor/editor.main.js', @@ -57,6 +69,11 @@ export default defineConfig(({ mode, command }) => { port: Number(VITE_PORT || 80), host: true, open: true, + ...(isCommonLinked ? { + watch: { + ignored: ['!**/node_modules/@cmvr/iot-common/**'] + } + } : {}), proxy: { // https://cn.vitejs.dev/config/#server-proxy '/dev-api': { diff --git a/vite/plugins/auto-import.js b/vite/plugins/auto-import.js index 1b6ab1d..723d4dc 100644 --- a/vite/plugins/auto-import.js +++ b/vite/plugins/auto-import.js @@ -11,6 +11,7 @@ export default function createAutoImport() { '@/utils/ruoyi': ['selectDictLabel'] } ], + exclude: [/[\\/]cmvr-iot-common[\\/]dist[\\/]/], dts: false }) } From e64af95cd122d456e089ecda3cf5377dc8cd6f6e Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Tue, 25 Aug 2026 14:04:27 +0800 Subject: [PATCH 4/7] =?UTF-8?q?refactor:=20=20=E7=A7=BB=E9=99=A4VueFlow?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91?= =?UTF-8?q?=20-=20=E4=BB=8EVueFlow=E7=9B=AE=E5=BD=95=E4=B8=AD=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E4=BA=86RuntimeNode.vue=E3=80=81customFlow.vue?= =?UTF-8?q?=E5=92=8Cindex.vue=E7=BB=84=E4=BB=B6=E3=80=82=20-=20=E4=BB=8Ero?= =?UTF-8?q?botManger=E7=9B=AE=E5=BD=95=E4=B8=AD=E7=A7=BB=E9=99=A4=E4=BA=86?= =?UTF-8?q?ContextMenu.vue=E5=92=8CTechButtonWithLine.vue=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E3=80=82=20-=20=E9=80=9A=E8=BF=87=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E9=A1=B5=E9=9D=A2=E5=AF=BC=E8=88=AA=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=92=8C=E6=95=B0=E5=AD=97=E8=BD=AC=E6=8D=A2=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=EF=BC=8C=E5=AF=B9index.js=E8=BF=9B=E8=A1=8C=E4=BA=86?= =?UTF-8?q?=E6=95=B4=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/device/arm.js | 26 - src/api/device/camera.js | 9 - src/api/device/dexHand.js | 19 - src/api/device/microphone.js | 46 -- src/api/device/speaker.js | 72 -- src/api/touch_interaction.js | 14 - src/api/tts.js | 30 - src/router/index.js | 87 +-- src/utils/jsencrypt.js | 2 +- .../register/components/Camera/index.vue | 553 -------------- .../register/components/ControlCard/index.vue | 36 - .../components/DexHand/LeftBottomHand.vue | 431 ----------- .../components/DexHand/LeftTopHand.vue | 270 ------- .../components/DexHand/RightBottomCharts.vue | 229 ------ .../components/DexHand/RightTopCharts.vue | 162 ---- .../register/components/DexHand/index.vue | 168 ----- .../device/register/components/Head/index.vue | 316 -------- .../MechanicalArm/components/JointControl.vue | 133 ---- .../MechanicalArm/components/UrdfViewer.vue | 394 ---------- .../components/MechanicalArm/index.vue | 384 ---------- .../register/components/Microphone/index.vue | 233 ------ .../register/components/Motor/index.vue | 76 -- .../register/components/Speaker/index.vue | 278 ------- .../SpeechSynthesis/AudioPlayer.vue | 108 --- .../components/SpeechSynthesis/chat.vue | 699 ------------------ .../components/SpeechSynthesis/img/ai.png | Bin 12001 -> 0 bytes .../components/SpeechSynthesis/img/user.png | Bin 11973 -> 0 bytes .../components/SpeechSynthesis/index.vue | 65 -- .../SpeechSynthesis/soundRecording.vue | 115 --- .../components/TouchInteraction/ai.png | Bin 12001 -> 0 bytes .../components/TouchInteraction/index.vue | 512 ------------- .../components/TouchInteraction/zsj.png | Bin 11973 -> 0 bytes .../components/VueFlow/IPlayer/config.ts | 59 -- .../components/VueFlow/IPlayer/index.vue | 62 -- .../components/VueFlow/RuntimeGroup.vue | 24 - .../components/VueFlow/RuntimeNode.vue | 47 -- .../components/VueFlow/customFlow.vue | 238 ------ .../register/components/VueFlow/index.vue | 205 ----- src/views/device/register/components/index.js | 59 -- src/views/device/robotManger/ContextMenu.vue | 89 --- .../device/robotManger/TechButtonWithLine.vue | 547 -------------- vite.config.js | 17 + vite/plugins/auto-import.js | 1 + 43 files changed, 21 insertions(+), 6794 deletions(-) delete mode 100644 src/api/device/arm.js delete mode 100644 src/api/device/camera.js delete mode 100644 src/api/device/dexHand.js delete mode 100644 src/api/device/microphone.js delete mode 100644 src/api/device/speaker.js delete mode 100644 src/api/touch_interaction.js delete mode 100644 src/api/tts.js delete mode 100644 src/views/device/register/components/Camera/index.vue delete mode 100644 src/views/device/register/components/ControlCard/index.vue delete mode 100644 src/views/device/register/components/DexHand/LeftBottomHand.vue delete mode 100644 src/views/device/register/components/DexHand/LeftTopHand.vue delete mode 100644 src/views/device/register/components/DexHand/RightBottomCharts.vue delete mode 100644 src/views/device/register/components/DexHand/RightTopCharts.vue delete mode 100644 src/views/device/register/components/DexHand/index.vue delete mode 100644 src/views/device/register/components/Head/index.vue delete mode 100644 src/views/device/register/components/MechanicalArm/components/JointControl.vue delete mode 100644 src/views/device/register/components/MechanicalArm/components/UrdfViewer.vue delete mode 100644 src/views/device/register/components/MechanicalArm/index.vue delete mode 100644 src/views/device/register/components/Microphone/index.vue delete mode 100644 src/views/device/register/components/Motor/index.vue delete mode 100644 src/views/device/register/components/Speaker/index.vue delete mode 100644 src/views/device/register/components/SpeechSynthesis/AudioPlayer.vue delete mode 100644 src/views/device/register/components/SpeechSynthesis/chat.vue delete mode 100644 src/views/device/register/components/SpeechSynthesis/img/ai.png delete mode 100644 src/views/device/register/components/SpeechSynthesis/img/user.png delete mode 100644 src/views/device/register/components/SpeechSynthesis/index.vue delete mode 100644 src/views/device/register/components/SpeechSynthesis/soundRecording.vue delete mode 100644 src/views/device/register/components/TouchInteraction/ai.png delete mode 100644 src/views/device/register/components/TouchInteraction/index.vue delete mode 100644 src/views/device/register/components/TouchInteraction/zsj.png delete mode 100644 src/views/device/register/components/VueFlow/IPlayer/config.ts delete mode 100644 src/views/device/register/components/VueFlow/IPlayer/index.vue delete mode 100644 src/views/device/register/components/VueFlow/RuntimeGroup.vue delete mode 100644 src/views/device/register/components/VueFlow/RuntimeNode.vue delete mode 100644 src/views/device/register/components/VueFlow/customFlow.vue delete mode 100644 src/views/device/register/components/VueFlow/index.vue delete mode 100644 src/views/device/register/components/index.js delete mode 100644 src/views/device/robotManger/ContextMenu.vue delete mode 100644 src/views/device/robotManger/TechButtonWithLine.vue diff --git a/src/api/device/arm.js b/src/api/device/arm.js deleted file mode 100644 index a7a167e..0000000 --- a/src/api/device/arm.js +++ /dev/null @@ -1,26 +0,0 @@ -import request from '@/utils/request' -// 移动机械臂 -export function moveJ(data) { - return request({ - url: '/api/humanoid/moveJ', - method: 'post', - data: data - }) -} - -// 获取机械臂状态 -export function status(data) { - return request({ - url: '/api/humanoid/status', - method: 'post', - data: data - }) -} - -export function clearFault(params) { - return request({ - url: '/api/arm/clearFault', - method: 'get', - params - }) -} diff --git a/src/api/device/camera.js b/src/api/device/camera.js deleted file mode 100644 index c10a7be..0000000 --- a/src/api/device/camera.js +++ /dev/null @@ -1,9 +0,0 @@ -import request from '@/utils/request' - -export function getRgbStreamUrl(robotId, deviceId) { - return request({ - url: '/api/edge/camera/rgb-stream-url', - method: 'get', - params: { robotId, deviceId } - }) -} diff --git a/src/api/device/dexHand.js b/src/api/device/dexHand.js deleted file mode 100644 index 0d8793d..0000000 --- a/src/api/device/dexHand.js +++ /dev/null @@ -1,19 +0,0 @@ -import request from '@/utils/request' - -// 获取灵巧手状态 -export function status(query) { - return request({ - url: '/api/dexHand/status', - method: 'get', - params: query - }) -} - -// 设置灵巧手弯曲角度 -export function setDexHandAngle(query) { - return request({ - url: '/api/dexHand/angle', - method: 'get', - params: query - }) -} diff --git a/src/api/device/microphone.js b/src/api/device/microphone.js deleted file mode 100644 index d14002d..0000000 --- a/src/api/device/microphone.js +++ /dev/null @@ -1,46 +0,0 @@ -import request from '@/utils/request' - -// 开始录音 -export function startMicrophoneApi(data) { - return request({ - url: '/api/Microphone/start', - method: 'post', - data: data - }) -} - -// 暂停录音 -export function pauseMicrophoneApi(data) { - return request({ - url: '/api/Microphone/pause', - method: 'post', - data: data - }) -} - -// 恢复录音 -export function resumeMicrophoneApi(data) { - return request({ - url: '/api/Microphone/resume', - method: 'post', - data: data - }) -} - -// 停止录音 -export function stopMicrophoneApi(data) { - return request({ - url: '/api/Microphone/stop', - method: 'post', - data: data - }) -} - -// 播放音频 -export function playSpeaker(data) { - return request({ - url: '/api/Speaker/play', - method: 'post', - data: data - }) -} \ No newline at end of file diff --git a/src/api/device/speaker.js b/src/api/device/speaker.js deleted file mode 100644 index ec9e94e..0000000 --- a/src/api/device/speaker.js +++ /dev/null @@ -1,72 +0,0 @@ -import request from '@/utils/request' - -// 暂停播放 -export function pause(data) { - return request({ - url: '/api/Speaker/pause', - method: 'post', - data: data - }) -} - -// 播放音频 -export function play(data) { - return request({ - url: '/api/Speaker/play', - method: 'post', - data: data - }) -} - -// 恢复播放 -export function resume(data) { - return request({ - url: '/api/Speaker/resume', - method: 'post', - data: data - }) -} - -// 获取扬声器状态 -export function status(query) { - return request({ - url: '/api/Speaker/status', - method: 'get', - params: query - }) -} - -// 停止播放 -export function stop(data) { - return request({ - url: '/api/Speaker/stop', - method: 'post', - data: data - }) -} - -// 获取音量 -export function getVolume(query) { - return request({ - url: '/api/Speaker/volume', - method: 'get', - params: query - }) -} - -// 设置音量 -export function setVolume(data) { - return request({ - url: '/api/Speaker/volume', - method: 'post', - data: data - }) -} - -// 设置音量 -export function getAll() { - return request({ - url: '/api/Speaker/getAll', - method: 'get', - }) -} \ No newline at end of file diff --git a/src/api/touch_interaction.js b/src/api/touch_interaction.js deleted file mode 100644 index 9182549..0000000 --- a/src/api/touch_interaction.js +++ /dev/null @@ -1,14 +0,0 @@ -import request from "@/utils/request.js"; - -export function coordinateMarking(data) { - return request({ - url: '/show/touch/coordinates', - method: 'post', - headers: { - isToken: false, - 'Content-Type': 'multipart/form-data', - 'Authorization':'Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImIzY2QwYjFjLWNlNjgtNDEwNy1hYzA1LTdmYTBlNmQ4NzJmNiJ9.2N9E9IDrFeCe-yRIBly60N0kYYmCscdrhyd8KHmhw2dxLi7B_A1i8bcWRTtx9YryFB3AhkvZkGauMx0CdZ0TDg' - }, - data: data - }) -} diff --git a/src/api/tts.js b/src/api/tts.js deleted file mode 100644 index 0a77f2a..0000000 --- a/src/api/tts.js +++ /dev/null @@ -1,30 +0,0 @@ -import request from '@/utils/request' - -const serviceHeaders = { - Authorization: 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImFiNmEyY2Y0LWM3MjQtNDgyMy1hM2NiLTk4N2NhZWNmMzZiNCJ9.oq-JVRbQuq_ujQ2V0h2jXC3woHPdMQKhnYJ8ixRm-C6Ez4GqJWyHYgmnkw5dbDyhWGdIUH02uv6XT8UiboHD4g', - isToken: false, -} - -export function createTimbre(data) { - return request({ url: '/show/tts/create', method: 'post', headers: { ...serviceHeaders, 'Content-Type': 'multipart/form-data' }, data }) -} - -export function getTts() { - return request({ url: '/show/tts/query', method: 'get', headers: serviceHeaders }) -} - -export function createCorpus(data) { - return request({ url: '/show/tts/corpus', method: 'post', headers: serviceHeaders, data }) -} - -export function getSynthesize(data, config = {}) { - return request({ url: '/show/tts/synthesize', method: 'post', headers: serviceHeaders, responseType: 'blob', data }, config) -} - -export function createAdvancedCorpus(data) { - return request({ url: '/show/tts/corpus/advanced', method: 'post', headers: serviceHeaders, data }) -} - -export function getAdvancedSynthesize(data, config = {}) { - return request({ url: '/show/tts/synthesize/advanced', method: 'post', headers: serviceHeaders, responseType: 'blob', data }, config) -} diff --git a/src/router/index.js b/src/router/index.js index 7128fcf..e54415f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,7 +1,7 @@ import { createWebHistory, createRouter } from "vue-router"; /* Layout */ import Layout from "@/layout"; -import { resolveCommonView } from '@cmvr/iot-common' +import { createDeviceRoutes, resolveCommonView } from '@cmvr/iot-common' const commonView = (view) => { const component = resolveCommonView(view) @@ -66,83 +66,7 @@ export const constantRoutes = [ component: commonView('error/401'), hidden: true, }, - { - path: "/device", - component: Layout, - children: [ - { - path: "mechanical_arm/:id", - component: () => - import("@/views/device/register/components/MechanicalArm/index.vue"), - name: "机械臂示教", - meta: { title: "机械臂详情" }, - hidden: true, - }, - { - path: "camera/:id", - component: () => - import("@/views/device/register/components/Camera/index.vue"), - name: "摄像头示教", - meta: { title: "摄像头详情" }, - hidden: true, - }, - { - path: "head/:id", - component: () => - import("@/views/device/register/components/Head/index.vue"), - name: "人工头示教", - meta: { title: "人工头详情" }, - hidden: true, - }, - { - path: "speaker/:id", - component: () => - import("@/views/device/register/components/Speaker/index.vue"), - name: "扬声器示教", - meta: { title: "扬声器详情" }, - hidden: true, - }, - { - path: "hand/:id", - component: () => - import("@/views/device/register/components/DexHand/index.vue"), - name: "灵巧手示教", - meta: { title: "灵巧手详情" }, - hidden: true, - },{ - path: "microphone/:id", - component: () => - import("@/views/device/register/components/Microphone/index.vue"), - name: "麦克风示教", - meta: { title: "麦克风详情" }, - hidden: true, - } - ], - }, - { - //语音合成 - path: "/speech_synthesis", - component: () => - import("@/views/device/register/components/SpeechSynthesis/index.vue"), - meta: { title: "语音合成", noLogin: true }, - hidden: true, - }, - { - //触摸交互 - path: "/touch_interaction", - component: () => - import("@/views/device/register/components/TouchInteraction/index.vue"), - meta: { title: "触摸交互", noLogin: true }, - hidden: true, - }, - { - // 流程运行状态 - path: "/logic_flow", - component: () => - import("@/views/device/register/components/VueFlow/index.vue"), - meta: { title: "流程运行状态", noLogin: true }, - hidden: true, - }, + ...createDeviceRoutes(Layout), { // 流程编排 path: "/flow", @@ -150,13 +74,6 @@ export const constantRoutes = [ meta: { title: "流程编排", noLogin: true }, hidden: true, }, - { - //电机路由 - path: "/Motor/:id", - component: () => - import("@/views/device/register/components/Motor/index.vue"), - hidden: true, - }, { path: "", component: Layout, diff --git a/src/utils/jsencrypt.js b/src/utils/jsencrypt.js index 78d9523..91eeff6 100644 --- a/src/utils/jsencrypt.js +++ b/src/utils/jsencrypt.js @@ -1,4 +1,4 @@ -import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' +import JSEncrypt from 'jsencrypt' // 密钥对生成 http://web.chacuo.net/netrsakeypair diff --git a/src/views/device/register/components/Camera/index.vue b/src/views/device/register/components/Camera/index.vue deleted file mode 100644 index 27bc45a..0000000 --- a/src/views/device/register/components/Camera/index.vue +++ /dev/null @@ -1,553 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/ControlCard/index.vue b/src/views/device/register/components/ControlCard/index.vue deleted file mode 100644 index 1590fb4..0000000 --- a/src/views/device/register/components/ControlCard/index.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/device/register/components/DexHand/LeftBottomHand.vue b/src/views/device/register/components/DexHand/LeftBottomHand.vue deleted file mode 100644 index 302711f..0000000 --- a/src/views/device/register/components/DexHand/LeftBottomHand.vue +++ /dev/null @@ -1,431 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/device/register/components/DexHand/LeftTopHand.vue b/src/views/device/register/components/DexHand/LeftTopHand.vue deleted file mode 100644 index faeae7c..0000000 --- a/src/views/device/register/components/DexHand/LeftTopHand.vue +++ /dev/null @@ -1,270 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/DexHand/RightBottomCharts.vue b/src/views/device/register/components/DexHand/RightBottomCharts.vue deleted file mode 100644 index bc42122..0000000 --- a/src/views/device/register/components/DexHand/RightBottomCharts.vue +++ /dev/null @@ -1,229 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/device/register/components/DexHand/RightTopCharts.vue b/src/views/device/register/components/DexHand/RightTopCharts.vue deleted file mode 100644 index 09cae93..0000000 --- a/src/views/device/register/components/DexHand/RightTopCharts.vue +++ /dev/null @@ -1,162 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/device/register/components/DexHand/index.vue b/src/views/device/register/components/DexHand/index.vue deleted file mode 100644 index 1185166..0000000 --- a/src/views/device/register/components/DexHand/index.vue +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - diff --git a/src/views/device/register/components/Head/index.vue b/src/views/device/register/components/Head/index.vue deleted file mode 100644 index ae48490..0000000 --- a/src/views/device/register/components/Head/index.vue +++ /dev/null @@ -1,316 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/MechanicalArm/components/JointControl.vue b/src/views/device/register/components/MechanicalArm/components/JointControl.vue deleted file mode 100644 index f53b595..0000000 --- a/src/views/device/register/components/MechanicalArm/components/JointControl.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - \ No newline at end of file diff --git a/src/views/device/register/components/MechanicalArm/components/UrdfViewer.vue b/src/views/device/register/components/MechanicalArm/components/UrdfViewer.vue deleted file mode 100644 index bdcc52b..0000000 --- a/src/views/device/register/components/MechanicalArm/components/UrdfViewer.vue +++ /dev/null @@ -1,394 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/device/register/components/MechanicalArm/index.vue b/src/views/device/register/components/MechanicalArm/index.vue deleted file mode 100644 index 9560acb..0000000 --- a/src/views/device/register/components/MechanicalArm/index.vue +++ /dev/null @@ -1,384 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/Microphone/index.vue b/src/views/device/register/components/Microphone/index.vue deleted file mode 100644 index 86ce97f..0000000 --- a/src/views/device/register/components/Microphone/index.vue +++ /dev/null @@ -1,233 +0,0 @@ - - - diff --git a/src/views/device/register/components/Motor/index.vue b/src/views/device/register/components/Motor/index.vue deleted file mode 100644 index 8ecf371..0000000 --- a/src/views/device/register/components/Motor/index.vue +++ /dev/null @@ -1,76 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/device/register/components/Speaker/index.vue b/src/views/device/register/components/Speaker/index.vue deleted file mode 100644 index e44db5d..0000000 --- a/src/views/device/register/components/Speaker/index.vue +++ /dev/null @@ -1,278 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/SpeechSynthesis/AudioPlayer.vue b/src/views/device/register/components/SpeechSynthesis/AudioPlayer.vue deleted file mode 100644 index be36efc..0000000 --- a/src/views/device/register/components/SpeechSynthesis/AudioPlayer.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - diff --git a/src/views/device/register/components/SpeechSynthesis/chat.vue b/src/views/device/register/components/SpeechSynthesis/chat.vue deleted file mode 100644 index 5a954a1..0000000 --- a/src/views/device/register/components/SpeechSynthesis/chat.vue +++ /dev/null @@ -1,699 +0,0 @@ - - - - diff --git a/src/views/device/register/components/SpeechSynthesis/img/ai.png b/src/views/device/register/components/SpeechSynthesis/img/ai.png deleted file mode 100644 index 79bbe4537df7e7ca847fd3de3e8f2d3a785e5332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12001 zcmV<7E*{Z|P)@~0drDELIAGL9O(c600d`2O+f$vv5yP=IvcrkdE$=VBC z$MmqJ?=WpMY;nM9nmWd!)3-oYV!8yTU3zD*Joe zIo!RwYj)#VC`UAqosOICPh*QMaf!3oLRY($Fqtkh_$&8d$sLroS|=bu`-1>u4E=VV zhkrD49#Fq-cwPXuM^m33gudII_sYACEAFH%+aKt*w&PhKM;wrwH_vv8y#2Zo=JJ9V z2L{d>5H4_;0F#2ofGMaXg_VMM-Gy~0%MKCC044)jggJxBpc31W^E6))sB{(Ki0yO* zw=AG{=fmBJE{;GsB7p34c1=%B*sJ=^UJjdWElo~fSpvxhkUSVB0>^-Qu|Z`T0ZS)e z_omK9&*D;4tP|Fv0u;hbKko;Iw&oeo0$Gth0!JpO&nS>*Z+>iRQQ&f8^Q(+?(~O9r zsWdIpaSW!RWfK4+P%Txa2a>ikxDZx)HHu2T`eh@4yRfY=LDd!tEGiWn!7UR|dtqwL zF`&)^YAP^QZt0=8?nnUi83A(h=3QG&QCv&lZM6iHCz}m({^txKVB0h&P_rytrGiIN zWX7}5*S{6yvOp*^Wq(uI9h_40Zt05X`RKMDQZb1;2_jKMs>fEKW2 zIqa66aX_C|AUAh*b&wY~TLREfjaxEGCIT5i0IO5JECR4JZ4WR5%G(1A14BI%Gf}r$ zP`!+4nFq%4F8xf{S_ZcI{ltUyaL{sJ*BR78mWu$WN1LYwDubrh4A7oq+gXgd#b*rA zrv*s1f#Z33jWOjmkArnWveK(k!|RNR2i17?h3yPp%cJa=naWBVz~p@yI5`+DmlN6m zoX(X)rKs9c93SrpF_;1*gV*B+q!2Lq7*??gCfUqv78su?VHb*#l}A^)W^2cS#BmMI-Xcmg+VPkkB6~{tn>g2J-w>+KoUAM@iP2mg6-pjMeCNivX-~I zU|R)9mw2?!CXDoMu#nCMW)`j@VNnK#x_$uF5s+*%&0GMpz1N|&&|mDo^`&IxddS{3#g6XsT&9h(J!EVIo9FV^H4EoYu} z#;a8uz|6$i@hlaFn#!wn-f;>*vI@3ITv3rLJ)7Rq3i>oT#! zxp=W+V?Cn

Oa?j2R!MFo=Dzm!&Y$GqVV)wa>g6HyOsuX;l-`){Hmu0 z%w+>IfY`f(nARaSdd6j97lX}n0&D^%gC}Y6>Ah136U9rFM2x7`3fxSYsepJJ zXRvo>414#t{82{Kq|II27yQ6vLCt!#YvlpS^mjh4^e4!Sld|EBrDv;Ve-y}8@Myig zl*(bo^5oe$9}?@lZ?6q`;DSBn;}+jk{ zO%-@^X3E4S29;`KjHsTfK_;MN5ggej>9<`olh}7)EP$b9WWhtVqAr8#1*TR3>(?2a zc1nhIYk?IjET*Qyt$Cmj9t@U8cY>Jh@YpV5IjO`Q4+FFF;bDU~PW?6~5)5W1Xx@@A z#RTs)#+SXoMs|Ao%uI56dNdWp%KQmK2Ne-Kloz9NwaXYcgMi5I6npcw&^apP=fX6_3 z@Wd|iydYim`2LlcU&uxM3D{!SR;{vl(;IWV;5lkbIY0M}%*(3m-iOwvXj*4%e?Y_|;!&U43REDkT5a&of1BgV zH?@3uO*W}iOj0NUx+x>meQOUu@&u&28rgRZJzHZ6WquIXkmGdCWx!eMfzJ}4 z56@I!>%IA%^8ha7IR1U%qzu`QxhZVOQwUB4md9Y3#Nsf8BBPGxQR7W1BL&pxdCFf& zkL(k(EBwyk_b`9wJ9B*M561(Ds4BLpE{91S3^%Y{E8oSH=9bnJgB(Wld50E(X`rm1jI&IerR~j|8)hZb&h%Wy3bIFbmsAg9Ot9iiqj03C!tFd0f2Ux z2{B{XUeMjo%#Ve@T)f)%|7IJndu=|z1ZM_8tBD(Qc2HB7rnb?^0nKA-K)Xg6jR$81 zne7j}l0aSQ^AVBRyv)C6%1k0+i}o2?Lo1z87Hs)c>oPbym^M;7-kEX2PA8cf6I81H z-lH5?bbi<-zR2R={L+ZaNYMM+Z_nd@er+E2K3HHid9W`(zl|$jJvpEn^X?P^CZL|SN{xCulPps z_dZnM9oO&1*S@__+x|yin#J`u&ERwY=@^`IS_{J*BSbIO)$Ct5p~2_Aasa>eU-wWd zusZVZ?peSmzpx)~eB}gw8hKm*@fGiS zVgN)HX3(qOy%XR0r=9?0YK5d8ZK^Z*NVKzaVS<3~Zya!ZI#?!I638`gch|OOuxriR+>YsAt$SHiy&dD5 z2Sj}W-oen+9EsQ5ivfP_`oYRqn{@q6`#hLlxP9?hO0}$~8eBsj?_`KE z_so=d|Ht==+H(UAP*{raCKo=+(4ct4H;1B2%}W@OJke9E6MnQrNc* z^-Afa>r@rfQI*1JFGX>9Of61R26A52+f&KnaLm|b5zp@VQ7^1;C7-Zj#6^yW-w8}s zuX=3L(>2D_e)}#tHlB5S?8>p>WiybSY25!v;U`xs5HTDvNpish#tMY*jSVI}O4Iz~f*^eWX1 zF~kn{Hn#YEjOq_zqNd8K)LQ`AH*~qAL$VFdPRd9HW8>P~SK>hlvFiC}j#roI>hnr7 z1QgDG;mYs;9E7aexB?qa$m$Q9fXQJ<%o0iWO4D$B;_u2-Zu+9z>Q85KZ3Eez?!ZN` zSVX|t6r_zDnY(({cuKbDJPNJ|FW|VuCh-e zvv%?Gs|352p>r25BmQ>L83!MAz50c%f$&Hb#_=n~HmW8ns-66uSpl#NlaDdEwS=^} zTSfKJwgcH6et&bsrChTZD+hq|#&(3z4Rz}q%*OcCOFGAzq%qm(_Rt-p6uZf7j8Km? zmW6@k55C&rVC2ddIjo)-qMnoGluc)?bNH2umo9e|k^Fr>Qx#_tJIS*ZV^z4p86D#i zRjMI~Pt3|;k}TjZA{lv#y;T|e*)`QliG@+^lhcc_vIZoxkxq0K4pJOvbu_PvU>k#o zy)-7K;ut(%88-fel~bk`XiJ&#sejq2z;C~5aWFsdN{0`;BE2XKv}V-H4(Gi7=Ydz9 zIl5d1@e6MUPF#%|c*$uzBegG)t8O_8zia71okQix3Xqn4EPD8gcB{t7!j5Dl%Scw% zfLx4?EY#-KP1gn3fZ+7_DFHn|dU9}$r_>POH{qfz*+^WoGLV(wgTNOHE zX;Q$b3YF7%@ZyUn2&o@oC3nH(_^p^SHDJbjSggmuNLJR21(kmZ7LkV={V|P%A9|PR z6B(A17Ju*PSm{wGj?UDeYHhNJ7fvGO^NA~g8{v>P5WD)J6`l>7mhKR*RJQ%%3mi>D zG()|ZkW4W3eK;vFNe|V`frN2R66oSKct&R7c>i`ZP<4N4`F=nhq;-6Y>5{XFMdTU` z@nIq(k9)h@I@D9Gr1qpxdahGZ2@$a9s9U`=nYfcu8BjEN6?!NWhk;OAb#d zG>@%;V`|5Q-;FePL8FraH6QOUeL&g;H^YZ34o7~O0iyiD5jHC;T%~!6h?`UG|VdB%u;FYC`1oeGVSD1KA%C^*QHZP(< zz=3(KJyW-*!+JD&4}|?p^E3mhR`;(xvrZfyR4SFL!r!uHb+m?4CrAsB&e7#KHa5=R z#UeuWcS&=bKMi|Abe=6s9NevMU`Cosds^wpA$J^Z>yB#zX0QUUk7Xb0^AOJ#SO zvZd+0`trydT{4%4!K}`7yja=6DM)gGUU%dUI{HTJcq~20S4^4#wKa@!NF1n0D%YrR zQG!&$F$H|(b}`HlV^$GP>QG7Vm<7S(x!Pk^YI!eADV7mK9vJs!P*m?`m>1kyBAtMN9nx>X|%ffLq2*lENdxH5yjbi>=$t(8;Pm{ZBH;NCSZK=*4p zL2-&q3sr0+E=UOplaxJ#=>yl&_-$fLKocj&Kg?w?H_`6*6OhZ~fv{mJTtl^%O9Po< z2$04NJQ2fWM{UhjsU^+oRG~(=gV>O4!)s|qT3~tm+7ryk3W^SgtFtv$v>C!YU_=)W zQ+rrka;6%11Jp!a-8SY?wN8a)1x-T_fBlk{)BR(Evpn>s>a2CJ*_~>i24+_7_1vWn zESh@Tq@GrVo_eMF7C0oC?BcipVfU%2svU9^`-WCx6I|3;s2fx}#GZ5spmiG7&zY91 z_I|)iPUP5CRdJAacTA#wW0__3aB4zCA9|{mjcJ)nWOu?jY`wY5;vl7&)dAGmF-S6U zGD(X@X5^%tFb}@CzS_obPBocuQ0mMK+j($b&uY`;pBpHD*h5lV9`dlH`>YrbJ?nfO zB>j_OyeMi{wTNFY1lX#7&!J>@^!hvLx&pamC!mK1-?FWa8F*^7GqQ;Es!LOMG4w#f zN;ia|x&tsgApi_GOlg^siMk9kIv1PX4-z%rxDF)O$_~^-TecOlzpB$Bs98<$i5)J84^n*wg*sSHMw}olbcfMa#s&xbd(NJ>(yO_Er7{)ZQj=^5a0RxyN8`ASM z9VnkKMg3v=(NBQ`^N3j-Uq)GZr^-&JOs&*u^>EN{bN0}(J5AAc;qGEPxn@?!J35K# z1gaX9M7fi3I77?1!}vrI;wE9{j(bbo{-qw=@blH|(7=x-y_EVwlWCPobrs!Hz=xbd zZ%2o4(ee@!#%;HL8C4!u9;_spRXag^X-vWszq#tuv$1iTT^xesa?ozG$WG0y4(av| zzZwvYccN}w>?P+y3d-r|8V(ba1?KxH>gRd%(V zg{;FjOdnEqr}=w+Fb82oR;LOW!yU)?PrO+tgWfn9XLE8@AHCgK06z3$BGq|2dwEUO=QOWtw9WNs^`a5s#6~bNlb)S=)%*+{rpT+wsn@F38X_U3`y1Y zPO7cD{@Gyf9AbDC-d6{ny9T&uGr9C@L+gf4KcpJG{p-M^1iW_r;4-r^n$-^K(#0ZD zHf*Q|k_x(;&UMwOgG@uUS`9t)juWS+^30^Ve5E^|gk(E8bxeW%`?8vw{@BhEfAKd9 zGA>f+$v#3(D5P4ad^ZL1`0xvk78pFQ{eBo_CnNtWY#;7U=dHJ5^@Grjf(U|L>O1agQ6Se+J0e)Hl>h=muP zDX*cM@Bnge%UoG$!usnk0ibrnA58qF8)%iDp*EILW*> z+nrRgiaOLGi=Fha^U)<;VcseU%s$$auDS{x1Omw@9>V6>VxmCHBOF0UgOsh<8()N$JoKB6^+r;D}k!;yD&PV?zKjm&Rh9`yulZR`N2>uec02YXjmq>RyQy z_1tMMTl|&uet!s%eiWufSUHf@u^N6z>jh-+KG8ezp=VWR%lJ5l?P1hMzR8J|C8^pH z6H^7oCQG!&9dcr9K1Ng9_?~82+l7INVn;5i>IfW*)`r%!Lv#;gveQ%yj%A>7F@Zr$ zlkG7E^rv&t#;u$HE;v&_Gon%J~R@H1;yIK~)@zD;e zu2VeI2;4SUXh)!DswvgNz7#1Uj+ahy=0-m}M@@b5@{ap}H@_RW@?F4>yTVLmET<@s z1Kx0HC@X!fAlCUJ*&Vu$JDb}oAPxR}#Bnv`&+I&qxaI0OR zgXBtuMLQ)bQ|za<#2RTy55`9rW&@*~=5S4N5|hwO0o9cl^tt2#0O~Gm-D<=)tn@G; z`pQY*#mYt-oEx4Ve*)O{5d!1UFunUf0FOM9s9RCLZ+c~T^+dv#>FF(XG#!Ssau`+- zNFGjW#DU$$`WB?wd*dpbf-0U0;fJtP+W_St6Wecq+Q|JT>3(J_YJ@s2tBN**^l_yX z`&xKAT-i_o-w1mnu%-e}Ya#*DB)>U{tN7vM*Xv91a@oPjvI-oXKK*9_K$U$nz;z!B zOib9xt(~-@Y1<$k4m*YoeOB{u=~_QFcwD`(tSCDg!+F4@J9%C6H6CFg z_W5L_yGBVKF#NI0LJQK?p$Hi}dKs@EBf{g%T5qm=kqxG6&Z79YL z^)}5i#Ihx-^PjjTDDzK$J}Jc2 zmp^f9N9c8Svwz^g{K zlKYkx5%p{A(GsIF0aq^a$5l57kBhR4^)_^lyAC?(J8;xVyjma1d# z3l-wnidq)t`Qwl9i#>MWA$h z?d1m5pbW2dB%0>nBuJ2<}5PAJmpCjjI zf5l1-OaA>k5eHmqVnNk+*)S|p8Tz8295CV_>(!fAG3w0;Vo3y2Ri3IfXQRUzh*)=A zkZjX#8a}<}?Og_aN#D4r9}}|{%GVrRc$ku2d>UW!uTFG0za8cuu*4?wyhuo@?Dppk zZ$7`|9E%gzR%tlxG5+Q4RBw-<23k#Iea}AN^M48a`Y+dGOJ?O?eI6UnIV&`Fsa;n%fGhqRhrHtk{EX|T_8jb8AwvCyW>D*CQ+}Yi7tC=l;!0@)S)zK zY0z)J&7m?N4B|tNjHobG(WvJ4JqY}l-w&$QCNa6lR+_$z0O-{M z=#ros9HQ{YSz74t%BUfS$1u-LU>bj@CAicMtybvTk@K7~7j}|TZR2H_PZ&RkMBI@MtLTK5L|d-2gFf=8w}yU4eB->&^MaYlzc z(^EpnDsK-n6G4pMkfG(fz6ZSPgQx)&#Vx-4)z1Q#UWlrJez2wDSDv)awuBpyyvg*sauCo!w~Km437YydDH0@}DdC01jg*bR85A0Bid(ZQj z_bsJyfGV&Mwd(ZiVVu?Ji`N>zg^S=}=7kTWLS{#t6SaQ|TA8X!L~~l*ClamdqVp5I zRKLBf?4`z*w0Jx@{y%pCGi+%EVp?l6!HsBanPipYaE=K6r3_F`yd^a1LIX=F0CRK@q-*5iz$nkHRfB&*sL3@p_eJ3hHO zEOIAV@LsDSiZjG->_Wa&79Ap~b-hRL%h*KKLe#ab+gCdNVrok~X^joBpn9S-f9!GK zBYyzg^L-4j_D%J{^ z%1o-ERx2>mGMFpM0Omx7Y>KXj$7E{@BUP>XxDbf_YrNxwDpGg3fRk4qt=dxs)*mZi zM>We59*P!ef?v4U2n$UBlBS>B3;gEql0Do%yi%XEI$dnvg8;ijAl`NpWeU#5FgfN) zd9Bs?it9+BqVLB1@MQeeVfI%2cNgUiVdp}tN5Oej&a?7dKGeux6%Pq>VT@)Iyb3hQ zvN|r>?8S5Tdi$u_EK~C#;ZrzV5cV8riV`(>KB379DMkOBM8KVX5IUNH@t0N zPu+X^uz-A^JF%T+cNA!&=OzM}&VO7w62%ZzILz?of zVpgmEGky!EVx=n^fxNBOqoZO_>(8n^g|m57Bi{;Jjj+6w{Y>>(FVGY9=$_WDI5z zvOPWr>-;Fft+5b}_(TEs3)LL#xW)o<&FM3!1Bb^^;7uK97Vq8qE>Q^Ik8f3gYdi|I zmlqGQ9mt2=ym?jl^4LLPe{p;YV zjt~WulL6NOc=8E>VbbZ$b_&?91~3UYVr82F%?cluw3wM$h%MU`j%gnqX#F zz*sg%Dy#57=2?g_TkX)?)#3y-XMCngQMJ^3wL;P?8dt{nu&i5%IB$5VPUZ-#gKG!X z>Z?Ihe)?{Fm_Pp{gG(qzd(KqVRj~;sJ44#V<0Cf$zxN5i4Fl*992vgkYu^{9MI;5W zOVe8k#O>)0%MK(<9ZasO9;w%PB3j?8+T17Aod>qnmc;s`s#tPBrc6lRwZ+-dc1P{h zVp9(m6~G?ALiQEU)(BV(U^#{gJX<9WBvZs)|F_T;|Li$cqp#Xc+h8Ye`^Mh`SN=M= z?0fN~)T#GGZ-S%Tsu{9ZbK5S2e#akU=ce)7Qv)PR6HIRCYEgo{oh^8q>GQC8NaMA~ z0y8-mn^U&OvYMqzHEb{2Qt6p^ptZNKFvwWw?_vi{=(*=}tjtXQYNyZD%9tvuf_bqB z$@F80mH%oBaOyf>&FYGcn#zm0WSalow+Q$vlN&z-r{|783l0s21E<>=w2#wt!!Q6< zo-!a=7)(-_x6##{r`s~Jn`6YzmS<-f93Nt*x0(DR4}YJLouHK_r0^!C#@I(u2Pc9j zw-85#msSr=0LagAXbsO={*D$ivn6U)93UgC*EUZVYVpOVh8I}RI8iR6;S4dLzeCxe zZ8zYM?B%xKfFpG}iitemjsW2H#Q;QA3s1eA*qPr(%JM_i`AX87^MRf0)iNtvp$&74 z)$EF(X7g2~W>>K{Ys2RqGHIg9gn8<?Ls+$1HBbAjbpBtV|G5n+?>TMWqaoLQF39A^*w`%-IUVf zF?kk>*nulHMJY2&VWN{(lK9$z*uQ88S-24X!U`u4c&-DD_kGz;`VN)8S3`*fI+n9i zKcTSWgMSG8@t5nYgj~`!Z>^S>l5OuBx+kw+M*v=Ss35XDEsRtVyLm00_Nw&UmJ@p! z+s_`xS_Ms|SG8l4>;#dDC7YSArbb?lHTmnP9KU4R=TiE-`cZF9BTNCRPn7F+Wv1Ld zhb9=8hXB6s5D(eSxbpk`ePX5mMExvfrsilq=kW3O8@%B8h*>{x$jIS2`NA-dGQ?gk z!p1uoL_A4(S{SLq>Ad^9V{ajzolI9x;dQtf?!L89OkjU+3VUZ)VDEu3?A@PZ-(G`R z^3~=aHCT9=!mD-M(UWGV7@sj`tXdgm|GWf1n@Rv%7 zu*66rYe_%#XXv~HPH!Kn*uAu!rW-%wYF#mSkzdBSCT*P<;q+|1uy&Y9_ER5#nsKF0DM#>WawjF%WEN2oPT4QJCtNM`7yG)%|LO(7wL6rza) zZ$En#BfXj}Vw%nz_w)t?BOh;@Svub* zX3kAfa(gv?`q&g6cwhn#{nI#h{vgN9k0?4N=c3$2?V9s~2s=W4Q5%{e&0qbHOXpS= zZa$kQR+Fl92dK`Oko!xNdwS^aB4|NrLv(s_`2y}n+X@jrXx) zil*ljm|R2l^;j3Y+)O%XGW+5;t6UhVVpGUBo_R#!z{6T zKiTM+V+y6D&I81p~ z0NE67GV5b*i$!)W)dT_SHo^}X<2qqpy)eqj8=qI>*xyoxap&k9UDr0IbNwnDl_O7B#U_B2LjWw3^=oldj$C1Y+|tb4hNE)i3)?-KZc7-*Q$f>LSq0-M zl4qsY`fLyvLX!?c!|?8dX;VBZN9CyeOOgK%64~ESp}mVK00000NkvXXu0mjfVHP(c diff --git a/src/views/device/register/components/SpeechSynthesis/img/user.png b/src/views/device/register/components/SpeechSynthesis/img/user.png deleted file mode 100644 index 481f7e7cbc543d579dc21251b7985b673505c9e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11973 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 diff --git a/src/views/device/register/components/SpeechSynthesis/index.vue b/src/views/device/register/components/SpeechSynthesis/index.vue deleted file mode 100644 index 94b9003..0000000 --- a/src/views/device/register/components/SpeechSynthesis/index.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/SpeechSynthesis/soundRecording.vue b/src/views/device/register/components/SpeechSynthesis/soundRecording.vue deleted file mode 100644 index 5b2a05b..0000000 --- a/src/views/device/register/components/SpeechSynthesis/soundRecording.vue +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - diff --git a/src/views/device/register/components/TouchInteraction/ai.png b/src/views/device/register/components/TouchInteraction/ai.png deleted file mode 100644 index 79bbe4537df7e7ca847fd3de3e8f2d3a785e5332..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12001 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 diff --git a/src/views/device/register/components/TouchInteraction/index.vue b/src/views/device/register/components/TouchInteraction/index.vue deleted file mode 100644 index 08788ae..0000000 --- a/src/views/device/register/components/TouchInteraction/index.vue +++ /dev/null @@ -1,512 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/TouchInteraction/zsj.png b/src/views/device/register/components/TouchInteraction/zsj.png deleted file mode 100644 index 481f7e7cbc543d579dc21251b7985b673505c9e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11973 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 diff --git a/src/views/device/register/components/VueFlow/IPlayer/config.ts b/src/views/device/register/components/VueFlow/IPlayer/config.ts deleted file mode 100644 index 3048428..0000000 --- a/src/views/device/register/components/VueFlow/IPlayer/config.ts +++ /dev/null @@ -1,59 +0,0 @@ -export const conf = { - /** - * 基础功能配置 - * */ - autoplay: false, // 是否自动播放,不自动播放,浏览器有限制规则 - autoplayMuted: false, // 是否自动播放(静音播放) - videoInit: true, // 是否默认初始化video,默认初始化,默认true - playsinline: true, // 是否启用内联播放模式,仅移动端生效 - defaultPlaybackRate: 1, // 默认播放速度(可选:0.5/0.75/1/1.5/2等) - volume: 0.72, // 播放音量(可选:0 ~ 1) - loop: false, // 是否循环播放,默认不循环播放 - startTime: 0, // 点播模式下,初始起播时间 - videoAttributes: {}, // video扩展属性,暂且不配置 - lang: 'zh-cn', // 播放器初始显示语言,设置为中文 - fluid: true, // 是否流式布局(宽高优先于流失布局,默认16:9)注掉上方宽高看效果 - fitVideoSize: 'fixed', // 保持容器宽/高,不做适配,按照容器来 - videoFillMode: 'auto', // 宽高不够自动底色填充(fill拉伸填充等...) - seekedStatus: 'play', // 跳转后继续播放 - // 播放器进度条故事点信息数组 - progressDot: [ - { - id: 0, // 唯一标识,用于删除的时候索引 - time: 30, // 展示的时间点,例子为在播放到10s钟的时候展示 - text: '进度条信息提示...', // hover的时候展示文案,可以为空 - duration: 1, // 展示时间跨度,单位为s - style: { // 指定样式 - backgroundColor: 'white' - } - }, - ], - thumbnail: null, // 进度条预览图配置,普通业务用不到 - marginControls: false, // 是否开启画面和控制栏分离模式,不开启空间多一些 - domEventType: 'default', // 响应的事件类型,不用指定,用默认的即可 - /** - * 交互功能配置(一般使用默认即可) - * */ - /** - * 插件配置,根据需求自选 - * */ - icons: {}, // 使用默认的icon图标 - i18n: [], // 使用默认的中文 - // 自定义一些颜色 - commonStyle: { - progressColor: 'green', // 整个进度条颜色 - playedColor: 'chocolate', // 已播放的进度条颜色 - volumeColor: 'pink', // 音量大小竖向滑块颜色 - }, - controls: true, // 是否使用底部控制栏,默认使用 - miniprogress: true, // 是否使用mini进度条(当底部控制栏隐藏时生效) - screenShot: false, // 关闭截图功能 - rotate: true, // 是否使用视频旋转插件,默认不使用 - download: true, // 是否使用下载按钮,一般不用,一般自定义控制 - pip: true, // 使用使用画中画模式,默认不用 - mini: true, // 是否使用小屏幕控件 - cssFullscreen: true, // 是否使用网页样式全屏按钮开关 - playbackRate: [0.5, 1, 1.5, 2, 3], //传入倍速可选数组 - // playbackRate: true, //false,禁用倍速播放(即控制栏不显示) - keyShortcut: false, // 是否开启快捷键模式 -} diff --git a/src/views/device/register/components/VueFlow/IPlayer/index.vue b/src/views/device/register/components/VueFlow/IPlayer/index.vue deleted file mode 100644 index 55be899..0000000 --- a/src/views/device/register/components/VueFlow/IPlayer/index.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - diff --git a/src/views/device/register/components/VueFlow/RuntimeGroup.vue b/src/views/device/register/components/VueFlow/RuntimeGroup.vue deleted file mode 100644 index dca777e..0000000 --- a/src/views/device/register/components/VueFlow/RuntimeGroup.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/VueFlow/RuntimeNode.vue b/src/views/device/register/components/VueFlow/RuntimeNode.vue deleted file mode 100644 index 6ab3e75..0000000 --- a/src/views/device/register/components/VueFlow/RuntimeNode.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/VueFlow/customFlow.vue b/src/views/device/register/components/VueFlow/customFlow.vue deleted file mode 100644 index 9ba9db2..0000000 --- a/src/views/device/register/components/VueFlow/customFlow.vue +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - diff --git a/src/views/device/register/components/VueFlow/index.vue b/src/views/device/register/components/VueFlow/index.vue deleted file mode 100644 index c6c1b91..0000000 --- a/src/views/device/register/components/VueFlow/index.vue +++ /dev/null @@ -1,205 +0,0 @@ - - - - - diff --git a/src/views/device/register/components/index.js b/src/views/device/register/components/index.js deleted file mode 100644 index 93584d6..0000000 --- a/src/views/device/register/components/index.js +++ /dev/null @@ -1,59 +0,0 @@ -import {controlPageList} from "@/enum/index.js"; -import {ElMessage} from "element-plus"; -import router from "@/router"; - -export const intoControlPage = (path, params) => { - if (!controlPageList.includes(path)) { - ElMessage.warning('该页面不在控制台页面中,无法打开'); - return - } - // const fullPath = `${window.location.origin}${path}/${params}`; - // // 使用 window.open 在新标签页中打开 - // window.open(fullPath, '_blank'); - const fullPath = `${path}/${params}`; // 构造路由路径 - router.push(fullPath); // 使用路由跳转 -} - -// 定义需要转换的属性列表 -const propertiesToConvert = [ - "workModule", - "posStep", - "postureStep", - "jointStep", - "joint1", - "joint2", - "joint3", - "joint4", - "joint5", - "joint6", - "x", - "y", - "z", - "rx", - "ry", - "rz" -]; -export const formatNumber = (data) => { - const res = JSON.parse(JSON.stringify(data)); -// 遍历属性列表并转换值 - propertiesToConvert.forEach(property => { - if (data[property] !== null) { - res[property] = Number(data[property]); - } - }); - return res -} - -//对象中存在数字类型属性时,转换为字符串类型 -export const convertNumbersToStrings = (obj) => { - for (const key in obj) { - if (obj.hasOwnProperty(key)) { - const value = obj[key]; - // 检查值是否不是 null 且是数字类型 - if (value !== null && typeof value === 'number') { - obj[key] = String(value); // 转换为字符串 - } - } - } - return obj; -} diff --git a/src/views/device/robotManger/ContextMenu.vue b/src/views/device/robotManger/ContextMenu.vue deleted file mode 100644 index ab47455..0000000 --- a/src/views/device/robotManger/ContextMenu.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/views/device/robotManger/TechButtonWithLine.vue b/src/views/device/robotManger/TechButtonWithLine.vue deleted file mode 100644 index a2a3526..0000000 --- a/src/views/device/robotManger/TechButtonWithLine.vue +++ /dev/null @@ -1,547 +0,0 @@ - - - - - \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 39bc171..678a256 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,7 +1,18 @@ import { defineConfig, loadEnv, normalizePath } from 'vite' import path from 'path' +import { realpathSync } from 'node:fs' import createVitePlugins from './vite/plugins' +const isCommonLinked = (() => { + try { + const linkedPath = realpathSync(path.resolve('node_modules/@cmvr/iot-common')) + const localPath = realpathSync(path.resolve('../cmvr-iot-common')) + return path.relative(linkedPath, localPath) === '' + } catch { + return false + } +})() + // https://vitejs.dev/config/ export default defineConfig(({ mode, command }) => { const env = loadEnv(mode, process.cwd()) @@ -12,6 +23,7 @@ export default defineConfig(({ mode, command }) => { plugins: createVitePlugins(env, command === 'build'), optimizeDeps: { exclude: [ + ...(isCommonLinked ? ['@cmvr/iot-common'] : []), 'monaco-editor', 'monaco-editor/esm/vs/base/worker/workerMain.js', 'monaco-editor/esm/vs/editor/editor.main.js', @@ -57,6 +69,11 @@ export default defineConfig(({ mode, command }) => { port: Number(VITE_PORT || 80), host: true, open: true, + ...(isCommonLinked ? { + watch: { + ignored: ['!**/node_modules/@cmvr/iot-common/**'] + } + } : {}), proxy: { // https://cn.vitejs.dev/config/#server-proxy '/dev-api': { diff --git a/vite/plugins/auto-import.js b/vite/plugins/auto-import.js index 1b6ab1d..723d4dc 100644 --- a/vite/plugins/auto-import.js +++ b/vite/plugins/auto-import.js @@ -11,6 +11,7 @@ export default function createAutoImport() { '@/utils/ruoyi': ['selectDictLabel'] } ], + exclude: [/[\\/]cmvr-iot-common[\\/]dist[\\/]/], dts: false }) } From 59a020da32ef6c5582b1fcb1f942e566c3b13fd7 Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Tue, 25 Aug 2026 16:54:26 +0800 Subject: [PATCH 5/7] =?UTF-8?q?fix(env):=20=E6=9B=B4=E6=96=B0API=E5=92=8CW?= =?UTF-8?q?ebSocket=20URL=E4=B8=BA=E6=AD=A3=E7=A1=AE=E7=9A=84=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E7=8E=AF=E5=A2=83=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.development b/.env.development index 368025f..705c892 100644 --- a/.env.development +++ b/.env.development @@ -7,8 +7,8 @@ VITE_APP_ENV = 'development' # 招商车研物联网平台/开发环境 VITE_APP_BASE_API = '/dev-api' -VITE_API_URL = http://192.168.0.222:14080 -VITE_WS_URL = ws://192.168.0.222:14080/ws +VITE_API_URL = http://192.168.0.199:14080 +VITE_WS_URL = ws://192.168.0.199:14080/ws VITE_PORT = 5174 VITE_INSPECTION_TYPE = "inspection" VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/" From c0869ddb2bff4a7c8a0e1a29b03d24ddc61f770f Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Wed, 26 Aug 2026 08:45:14 +0800 Subject: [PATCH 6/7] =?UTF-8?q?fix(vite):=20=E6=9B=B4=E6=96=B0monaco-edito?= =?UTF-8?q?r=E6=8F=92=E4=BB=B6=E9=85=8D=E7=BD=AE=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=AF=AD=E8=A8=80=E5=B7=A5=E4=BD=9C=E8=80=85=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vite.config.js | 15 +++++++-------- vite/plugins/index.js | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/vite.config.js b/vite.config.js index 678a256..6377465 100644 --- a/vite.config.js +++ b/vite.config.js @@ -23,14 +23,13 @@ export default defineConfig(({ mode, command }) => { plugins: createVitePlugins(env, command === 'build'), optimizeDeps: { exclude: [ - ...(isCommonLinked ? ['@cmvr/iot-common'] : []), - 'monaco-editor', - 'monaco-editor/esm/vs/base/worker/workerMain.js', - 'monaco-editor/esm/vs/editor/editor.main.js', - 'ts.worker.js', - 'typescript' + ...(isCommonLinked ? ['@cmvr/iot-common'] : []) ], include: [ + 'monaco-editor/esm/vs/editor/editor.all.js', + 'monaco-editor/esm/vs/editor/editor.api.js', + 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution.js', + 'monaco-editor/esm/vs/language/json/monaco.contribution.js', 'monaco-editor/esm/vs/language/typescript/monaco.contribution' ] }, @@ -55,8 +54,8 @@ export default defineConfig(({ mode, command }) => { chunkSizeWarningLimit: 2000, rollupOptions: { output: { - manualChunks: { - monaco: ['monaco-editor'] + manualChunks(id) { + if (id.includes('/node_modules/monaco-editor/')) return 'monaco' }, chunkFileNames: 'static/js/[name]-[hash].js', entryFileNames: 'static/js/[name]-[hash].js', diff --git a/vite/plugins/index.js b/vite/plugins/index.js index fede791..e614915 100644 --- a/vite/plugins/index.js +++ b/vite/plugins/index.js @@ -12,7 +12,7 @@ export default function createVitePlugins(viteEnv, isBuild = false) { const vitePlugins = [ vue(), monacoEditorPlugin({ - languages: ['javascript', 'html', 'css', 'json', 'python', 'java'] + languageWorkers: ['editorWorkerService', 'json', 'typescript'] }) ] vitePlugins.push(createAutoImport()) From eae22075f41ff57b2d096273ab8a172429eca57a Mon Sep 17 00:00:00 2001 From: zhanghao <774378400@qq.com> Date: Wed, 26 Aug 2026 14:11:09 +0800 Subject: [PATCH 7/7] =?UTF-8?q?feat(websocket):=20=E4=BC=98=E5=8C=96WebSoc?= =?UTF-8?q?ket=E8=BF=9E=E6=8E=A5=EF=BC=8C=E6=94=AF=E6=8C=81=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E7=94=A8=E6=88=B7ID=E5=92=8Ctoken=E4=BC=A0=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.js | 3 ++- src/plugins/websocket.js | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index 169c103..4d93a44 100644 --- a/src/main.js +++ b/src/main.js @@ -12,6 +12,7 @@ import '@/assets/styles/index.scss' // global css import App from './App' import store from './store' +import useUserStore from './store/modules/user' import router from './router' import directive from './directive' // directive import WebSocketPlugin from './plugins/websocket' @@ -92,7 +93,7 @@ app.use(plugins) app.use(elementIcons) app.use(WebSocketPlugin, { url: import.meta.env.VITE_WS_URL, - userId: 'your_user_id' + userId: () => useUserStore(store).id }) app.component('svg-icon', SvgIcon) diff --git a/src/plugins/websocket.js b/src/plugins/websocket.js index 2f2ee77..f3c51e4 100644 --- a/src/plugins/websocket.js +++ b/src/plugins/websocket.js @@ -1,3 +1,5 @@ +import { getToken } from '../utils/auth'; + const MEDIA_HEADER_SIZE = 26; const MEDIA_MAGIC = [0x43, 0x4d, 0x56, 0x46]; // CMVF const MEDIA_MIME_TYPES = { @@ -18,6 +20,11 @@ class WebSocketManager { this.maxQueueSize = 100; this.status = false; this.channelSubscriptions = new Set(); + this.connectionUserId = null; + } + + resolveUserId() { + return typeof this.userId === 'function' ? this.userId() : this.userId; } connect() { @@ -25,8 +32,19 @@ class WebSocketManager { console.error('浏览器不支持 WebSocket'); return; } + if (!this.url) { + console.error('WebSocket 地址未配置'); + return; + } - this.ws = new WebSocket(`${this.url}?userId=${this.userId}`, [], { perMessageDeflate: true }); + const userId = this.resolveUserId(); + if (typeof this.userId === 'function' && !userId) return; + const connectionUrl = new URL(this.url, window.location.href); + if (userId) connectionUrl.searchParams.set('userId', userId); + const token = getToken(); + if (token) connectionUrl.searchParams.set('token', token); + this.connectionUserId = userId || null; + this.ws = new WebSocket(connectionUrl.toString(), [], { perMessageDeflate: true }); this.ws.binaryType = 'arraybuffer'; // 确保接收 ArrayBuffer this.ws.onopen = () => { @@ -168,6 +186,12 @@ class WebSocketManager { this.channelSubscriptions.delete(payload.channel); } } + const userId = this.resolveUserId(); + if (this.ws && this.ws.readyState !== WebSocket.CLOSED && this.connectionUserId !== userId) { + this.ws.close(4001, 'user identity changed'); + return; + } + if (!this.ws || this.ws.readyState === WebSocket.CLOSED) this.connect(); if (this.ws && this.ws.readyState === 1) { this.ws.send(JSON.stringify(payload)); } else if (payload?.type !== 'channel_subscription') {