From eab4337a77c583bd608d7765f5682bab5a925ef7 Mon Sep 17 00:00:00 2001 From: 16337 <1633794139@qq.com> Date: Tue, 10 Mar 2026 15:25:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9AROI=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E7=AE=97=E6=B3=95=E6=97=B6=E6=A0=A1=E9=AA=8CRTSP?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E6=9C=89=E6=95=88=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 截图加载失败时阻止算法绑定并提示"RTSP拉流地址无效", 通过Canvas截图加载状态逐层传递到算法绑定组件实现校验。 Co-Authored-By: Claude Opus 4.6 --- .../views/aiot/device/roi/components/RoiAlgorithmBind.vue | 6 ++++++ .../src/views/aiot/device/roi/components/RoiCanvas.vue | 5 ++++- apps/web-antd/src/views/aiot/device/roi/index.vue | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/web-antd/src/views/aiot/device/roi/components/RoiAlgorithmBind.vue b/apps/web-antd/src/views/aiot/device/roi/components/RoiAlgorithmBind.vue index 8d011b802..af13384d2 100644 --- a/apps/web-antd/src/views/aiot/device/roi/components/RoiAlgorithmBind.vue +++ b/apps/web-antd/src/views/aiot/device/roi/components/RoiAlgorithmBind.vue @@ -25,11 +25,13 @@ import AlgorithmParamEditor from './AlgorithmParamEditor.vue'; interface Props { roiId: string; bindings: AiotDeviceApi.RoiAlgoBinding[]; + snapOk: boolean; } const props = withDefaults(defineProps(), { roiId: '', bindings: () => [], + snapOk: false, }); const emit = defineEmits<{ @@ -70,6 +72,10 @@ async function handleBind() { message.warning('请选择算法'); return; } + if (!props.snapOk) { + message.error('RTSP 拉流地址无效,请先在摄像头管理中修正拉流地址'); + return; + } try { await bindAlgo({ roiId: props.roiId, diff --git a/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue b/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue index f32621952..d41de2b27 100644 --- a/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue +++ b/apps/web-antd/src/views/aiot/device/roi/components/RoiCanvas.vue @@ -21,6 +21,7 @@ const emit = defineEmits<{ 'roi-drawn': [data: { roi_type: string; coordinates: string }]; 'roi-selected': [roiId: string | null]; 'roi-deleted': [roiId: string]; + 'snap-status': [ok: boolean]; }>(); const wrapper = ref(); @@ -77,12 +78,14 @@ onUnmounted(() => { function onImageLoad() { loading.value = false; + emit('snap-status', true); nextTick(() => initCanvas()); } function onImageError() { loading.value = false; - errorMsg.value = '截图加载失败,请确认摄像头正在拉流'; + errorMsg.value = '截图加载失败,请确认摄像头拉流地址是否有效'; + emit('snap-status', false); // 关键:截图失败也初始化 canvas,使 ROI 区域可见可操作 nextTick(() => initCanvas()); } diff --git a/apps/web-antd/src/views/aiot/device/roi/index.vue b/apps/web-antd/src/views/aiot/device/roi/index.vue index e5dd122a0..2bd72fe5b 100644 --- a/apps/web-antd/src/views/aiot/device/roi/index.vue +++ b/apps/web-antd/src/views/aiot/device/roi/index.vue @@ -64,6 +64,7 @@ const roiList = ref([]); const selectedRoiId = ref(null); const selectedRoiBindings = ref([]); const snapUrl = ref(''); +const snapOk = ref(false); const edgeDevices = ref>([]); @@ -157,6 +158,10 @@ async function refreshSnap() { await buildSnapUrl(true); } +function onSnapStatus(ok: boolean) { + snapOk.value = ok; +} + // ==================== ROI 数据加载 ==================== async function loadRois() { @@ -352,6 +357,7 @@ function handlePush() { @roi-drawn="onRoiDrawn" @roi-selected="onRoiSelected" @roi-deleted="onRoiDeleted" + @snap-status="onSnapStatus" /> @@ -471,6 +477,7 @@ function handlePush() {