diff --git a/db/exploration.go b/db/exploration.go index 56a31d5..e5b0fd5 100644 --- a/db/exploration.go +++ b/db/exploration.go @@ -1299,6 +1299,7 @@ type TaskListMetrics struct { LastActivity int64 Goals GoalCounts RunningIntents int // kind='intent' 且 state='running' 的条数,即运行中 Worker 数 + Findings int // findings 表里该任务的漏洞条数 } // TaskListMetricsAll returns list aggregates for every live task in one query. @@ -1314,7 +1315,8 @@ func (d *DB) TaskListMetricsAll() (map[int64]TaskListMetrics, error) { COALESCE(latest_activity.created_at,0), COALESCE(goal_metrics.total,0), COALESCE(goal_metrics.met,0), - COALESCE(intent_metrics.running,0) + COALESCE(intent_metrics.running,0), + COALESCE(finding_metrics.findings,0) FROM tasks task LEFT JOIN LATERAL ( SELECT SUM(input_tokens) AS input_tokens, @@ -1342,6 +1344,11 @@ func (d *DB) TaskListMetricsAll() (map[int64]TaskListMetrics, error) { FROM exploration_nodes WHERE exploration_id=task.exploration_id AND kind='intent' AND state='running' ) intent_metrics ON true + LEFT JOIN LATERAL ( + SELECT COUNT(*) AS findings + FROM findings + WHERE task_id=task.id + ) finding_metrics ON true WHERE task.deleted_at IS NULL`) if err != nil { return nil, err @@ -1361,6 +1368,7 @@ func (d *DB) TaskListMetricsAll() (map[int64]TaskListMetrics, error) { &metrics.Goals.Total, &metrics.Goals.Met, &metrics.RunningIntents, + &metrics.Findings, ); err != nil { return nil, err } diff --git a/server/dto.go b/server/dto.go index 0e1ff46..de51334 100644 --- a/server/dto.go +++ b/server/dto.go @@ -51,6 +51,7 @@ type TaskDTO struct { GoalsTotal int `json:"goals_total"` GoalsMet int `json:"goals_met"` InFlight int `json:"in_flight"` // 运行中 Worker 数(state=running 的意图) + Findings int `json:"findings"` // 该任务已登记的漏洞数(findings 表) LLMProfileID *int64 `json:"llm_profile_id,omitempty"` // LLM profile used for this task; nil = default LLMProfileIDs []int64 `json:"llm_profile_ids"` ActiveLLMProfileID *int64 `json:"active_llm_profile_id,omitempty"` diff --git a/server/server.go b/server/server.go index 7f804f3..5e6d0d9 100644 --- a/server/server.go +++ b/server/server.go @@ -1040,6 +1040,7 @@ func (s *Server) listTasks(w http.ResponseWriter, r *http.Request) { dto.GoalsTotal = metric.Goals.Total dto.GoalsMet = metric.Goals.Met dto.InFlight = metric.RunningIntents + dto.Findings = metric.Findings dtos = append(dtos, dto) } writeJSON(w, 200, map[string]any{"tasks": dtos, "active": active}) diff --git a/web/src/app/(main)/function/tasks/page.tsx b/web/src/app/(main)/function/tasks/page.tsx index 1cd442d..89df25d 100644 --- a/web/src/app/(main)/function/tasks/page.tsx +++ b/web/src/app/(main)/function/tasks/page.tsx @@ -950,6 +950,7 @@ export default function TasksPage() { onSort={sortTasksBy} /> 目标进度 + 漏洞 运行中 Worker } - + - {task.goal} + + {task.goal} + @@ -1213,6 +1216,13 @@ const TaskRow = React.memo(function TaskRow({ — )} + + {task.findings && task.findings > 0 ? ( + {task.findings} + ) : ( + 0 + )} + {task.in_flight && task.in_flight > 0 ? ( {task.in_flight} diff --git a/web/src/lib/mock/data.ts b/web/src/lib/mock/data.ts index 6eaa336..1ed2d77 100644 --- a/web/src/lib/mock/data.ts +++ b/web/src/lib/mock/data.ts @@ -65,6 +65,7 @@ export const tasks: Task[] = [ paused: false, active: true, in_flight: 3, + findings: 4, stalled: false, goals_total: 5, goals_met: 2, @@ -90,6 +91,7 @@ export const tasks: Task[] = [ paused: false, active: false, in_flight: 2, + findings: 2, stalled: false, goals_total: 4, goals_met: 1, diff --git a/web/src/lib/mock/handler.ts b/web/src/lib/mock/handler.ts index d240c7a..da22153 100644 --- a/web/src/lib/mock/handler.ts +++ b/web/src/lib/mock/handler.ts @@ -1192,6 +1192,7 @@ function route(m: string, path: string, seg: string[], q: URLSearchParams, b: Re paused: false, active: true, in_flight: 0, + findings: 0, stalled: false, goals_total: 0, goals_met: 0, diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts index 165dd52..7dc8e3f 100644 --- a/web/src/lib/types.ts +++ b/web/src/lib/types.ts @@ -23,6 +23,7 @@ export interface Task { queued?: boolean; active?: boolean; in_flight?: number; + findings?: number; // 该任务已登记的漏洞数 last_activity?: string; stalled?: boolean; goals_total?: number;