From 47922c2083f8f55716066a3fd6adcad8a96e492c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E6=98=8E?= <83812544+Ed1s0nZ@users.noreply.github.com> Date: Tue, 28 Apr 2026 10:23:24 +0800 Subject: [PATCH] Add files via upload --- web/static/css/style.css | 14 ++++++++++++- web/static/i18n/en-US.json | 3 +++ web/static/i18n/zh-CN.json | 3 +++ web/static/js/chat.js | 11 +++++++++++ web/static/js/router.js | 10 +++++----- web/static/js/tasks.js | 18 +++++++++++++++-- web/static/js/vulnerability.js | 36 ++++++++++++++++++++++++++++++++++ web/templates/index.html | 7 +++++++ 8 files changed, 94 insertions(+), 8 deletions(-) diff --git a/web/static/css/style.css b/web/static/css/style.css index 1ef67f03..96b8f66a 100644 --- a/web/static/css/style.css +++ b/web/static/css/style.css @@ -8970,7 +8970,7 @@ header { /* 任务管理 · 队列卡片:单行主网格 + 进度列内统计,降低高度 */ .batch-queue-item__inner--grid { display: grid; - grid-template-columns: minmax(0, 1fr) minmax(128px, auto) minmax(88px, 14%) 44px; + grid-template-columns: minmax(0, 1fr) minmax(128px, auto) minmax(88px, 14%) minmax(40px, max-content); grid-template-rows: auto; grid-template-areas: "lead cluster progress actions"; column-gap: 22px; @@ -9051,6 +9051,12 @@ header { justify-self: end; align-self: center; padding-left: 6px; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + justify-content: flex-end; + gap: 6px; } .batch-queue-item__idline--lead { @@ -9137,6 +9143,12 @@ header { } .batch-queue-icon-btn:hover { + color: var(--accent-color, #0066ff); + border-color: rgba(0, 102, 255, 0.35); + background: rgba(0, 102, 255, 0.08); +} + +.batch-queue-icon-btn--danger:hover { color: var(--error-color, #dc3545); border-color: rgba(220, 53, 69, 0.35); background: rgba(220, 53, 69, 0.06); diff --git a/web/static/i18n/en-US.json b/web/static/i18n/en-US.json index 7a59ffae..bdce7bd1 100644 --- a/web/static/i18n/en-US.json +++ b/web/static/i18n/en-US.json @@ -303,6 +303,8 @@ "clearHistory": "Clear history", "cancelTask": "Cancel task", "viewConversation": "View conversation", + "viewVulnerabilities": "View vulnerabilities", + "viewVulnerabilitiesQueueTitle": "View vulnerabilities: open management filtered to this queue", "retryTask": "Retry", "conversationIdLabel": "Conversation ID", "statusPending": "Pending", @@ -1702,6 +1704,7 @@ }, "contextMenu": { "viewAttackChain": "View attack chain", + "viewVulnerabilities": "View vulnerabilities", "downloadMarkdown": "Download Markdown", "downloadMarkdownSummary": "Summary", "downloadMarkdownFull": "Full", diff --git a/web/static/i18n/zh-CN.json b/web/static/i18n/zh-CN.json index abc79e61..b6738db9 100644 --- a/web/static/i18n/zh-CN.json +++ b/web/static/i18n/zh-CN.json @@ -303,6 +303,8 @@ "clearHistory": "清空历史", "cancelTask": "取消任务", "viewConversation": "查看对话", + "viewVulnerabilities": "查看漏洞", + "viewVulnerabilitiesQueueTitle": "查看漏洞:打开漏洞管理并筛选本队列", "retryTask": "重试", "conversationIdLabel": "对话ID", "statusPending": "待执行", @@ -1702,6 +1704,7 @@ }, "contextMenu": { "viewAttackChain": "查看攻击链", + "viewVulnerabilities": "查看漏洞", "downloadMarkdown": "下载 Markdown", "downloadMarkdownSummary": "简版", "downloadMarkdownFull": "完整版", diff --git a/web/static/js/chat.js b/web/static/js/chat.js index 89408057..96c5f430 100644 --- a/web/static/js/chat.js +++ b/web/static/js/chat.js @@ -6121,6 +6121,17 @@ async function downloadConversationMarkdownFromContext(includeToolDetails = fals closeContextMenu(); } +// 从上下文菜单跳转到漏洞管理,并按当前对话 ID 筛选 +function navigateToVulnerabilitiesForContextConversation() { + const convId = contextMenuConversationId; + if (!convId) { + closeContextMenu(); + return; + } + closeContextMenu(); + window.location.hash = 'vulnerabilities?conversation_id=' + encodeURIComponent(convId); +} + // 从上下文菜单删除对话 function deleteConversationFromContext() { const convId = contextMenuConversationId; diff --git a/web/static/js/router.js b/web/static/js/router.js index a983f9ff..6313cd12 100644 --- a/web/static/js/router.js +++ b/web/static/js/router.js @@ -1,19 +1,19 @@ // 页面路由管理 let currentPage = 'dashboard'; -/** 仅当停留在 chat 时保留 ?conversation= 等查询串,其它页面只使用 pageId */ +/** chat、漏洞管理页在切换时保留当前 hash 上的查询串(如 ?conversation= / ?conversation_id=) */ function buildHashForPage(pageId) { - if (pageId !== 'chat') { + if (pageId !== 'chat' && pageId !== 'vulnerabilities') { return pageId; } const full = window.location.hash.slice(1); const parts = full.split('?'); const curPage = parts[0]; const q = parts.length > 1 ? parts.slice(1).join('?') : ''; - if (curPage === 'chat' && q) { - return 'chat?' + q; + if (curPage === pageId && q) { + return pageId + '?' + q; } - return 'chat'; + return pageId; } let chatConversationFromHashSeq = 0; diff --git a/web/static/js/tasks.js b/web/static/js/tasks.js index 0056be48..70adbb84 100644 --- a/web/static/js/tasks.js +++ b/web/static/js/tasks.js @@ -531,6 +531,7 @@ function renderTaskItem(task, statusMap, isHistory = false) { ${isHistory && completedText ? completedText : timeText} ${canCancel ? `` : ''} + ${task.conversationId ? `` : ''} ${task.conversationId ? `` : ''} @@ -708,6 +709,17 @@ function viewConversation(conversationId) { } } +// 跳转漏洞管理并按对话 ID 或批量队列 ID 筛选(队列 ID 走 task_id,与列表筛选项一致) +function navigateToVulnerabilitiesFromTasksPage(kind, id) { + if (!id) return; + const enc = encodeURIComponent(id); + if (kind === 'queue') { + window.location.hash = 'vulnerabilities?task_id=' + enc; + } else if (kind === 'conversation') { + window.location.hash = 'vulnerabilities?conversation_id=' + enc; + } +} + // 刷新任务列表 async function refreshTasks() { await loadTasks(); @@ -1134,6 +1146,8 @@ function renderBatchQueues() { const progress = stats.total > 0 ? Math.round((stats.completed + stats.failed + stats.cancelled) / stats.total * 100) : 0; // 允许删除待执行、已完成或已取消状态的队列 const canDelete = queue.status === 'pending' || queue.status === 'completed' || queue.status === 'cancelled'; + // 操作列常驻「查看漏洞」,不再使用 --no-actions 隐藏整列(否则无法从运行中队列跳转漏洞页) + const noActionsClass = ''; const loadedRoles = batchQueuesState.loadedRoles || []; const roleIcon = getRoleIconForDisplay(queue.role, loadedRoles); @@ -1157,7 +1171,6 @@ function renderBatchQueues() { : `