From fe2b569046739dfcaba6ae5a0e1a46976a7b8ce5 Mon Sep 17 00:00:00 2001 From: wuzhuorong <973204353@qq.com> Date: Tue, 16 Jun 2026 11:26:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=89=8D=E7=AB=AF=E9=9B=86?= =?UTF-8?q?=E6=88=90=20LLM=20=E9=A2=84=E8=AD=A6=E6=8E=A8=E9=80=81=E4=B8=8E?= =?UTF-8?q?=E4=BA=8C=E6=AC=A1=E5=88=A4=E6=96=AD=E7=BB=93=E6=9E=9C=E5=B1=95?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/components/ImageDetection.vue | 20 +++++++++ apps/web/src/views/AlertList.vue | 49 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/apps/web/src/components/ImageDetection.vue b/apps/web/src/components/ImageDetection.vue index 28fbeb9..1e6278e 100644 --- a/apps/web/src/components/ImageDetection.vue +++ b/apps/web/src/components/ImageDetection.vue @@ -346,6 +346,9 @@ import { } from '@element-plus/icons-vue' import { detectionApi } from '@/api/detection' import DetectionConfig from './DetectionConfig.vue' +import { useAlertStore } from '@/stores/alertStore' + +const alertStore = useAlertStore() const props = defineProps({ models: { @@ -787,6 +790,23 @@ const handleFightVideoSuccess = (response) => { const detCount = response.data.stats?.total_detections || 0 ElMessage.success(`检测完成:${detCount} 个目标,已提取 ${kfCount} 张关键帧`) + // MVP-3: 将 LLM 管道产出的预警推送到 AlertList + const frameResults = response.data.frame_results || [] + let llmAlertCount = 0 + for (const fr of frameResults) { + const alerts = fr.alert_events || [] + for (const alert of alerts) { + alertStore.addAlert({ + ...alert, + llm_results: fr.llm_results || [], + }) + llmAlertCount++ + } + } + if (llmAlertCount > 0) { + ElMessage.success(`LLM 二次判断完成,已生成 ${llmAlertCount} 条预警记录`) + } + // 如果后端提示编码不兼容,自动标记视频错误 if (response.data.video_codec_warning) { console.warn('视频编码不兼容浏览器,将以关键帧形式展示') diff --git a/apps/web/src/views/AlertList.vue b/apps/web/src/views/AlertList.vue index 29e13bf..11c85f5 100644 --- a/apps/web/src/views/AlertList.vue +++ b/apps/web/src/views/AlertList.vue @@ -156,6 +156,28 @@ #{{ det.track_id }} + + +
+ + {{ alert.llm_results[0].llm_confirmed ? 'LLM确认' : 'LLM否决' }} + + + LLM置信度: {{ ((alert.llm_results[0].llm_confidence || 0) * 100).toFixed(0) }}% + + + {{ alert.llm_results[0].llm_reasoning.slice(0, 50) }}... + +
@@ -534,6 +556,33 @@ onMounted(() => { opacity: 0.8; } +/* MVP-3: LLM 二次判断结果样式 */ +.llm-result { + display: flex; + align-items: center; + gap: 8px; + margin-top: 8px; + padding: 6px 10px; + background: rgba(99, 102, 241, 0.06); + border-left: 3px solid #818CF8; + border-radius: 4px; +} + +.llm-confidence { + font-size: 12px; + color: #A5B4FC; +} + +.llm-reasoning { + font-size: 12px; + color: #9CA3AF; + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + cursor: help; +} + .alert-actions { display: flex; align-items: center;