feat: 漏洞新增 severity=critical(严重) 与 name(漏洞名称)字段

severity 严重级:
- report_finding 工具 severity 说明改为 critical|high|medium|low
- DB 排序 CASE、report 报告 sevRank、FindingStats 增加 critical
- 前端 Severity 类型、status.ts 新增 rose 色调(实心高强调,视觉高于高危)、
  发现页严重度筛选/统计卡、任务发现 Tab 排序、dashboard 汇总均加入严重

name 漏洞名称:
- findings 表加 name 列(schema + ALTER TABLE ADD COLUMN IF NOT EXISTS 补旧库)
- report_finding 工具新增 name 入参(非必填),写入 node payload 与独立 findings 行
- DBFinding/AddFinding/AddStandaloneFinding、FindingDTO、findingPayload、report 全链路透传
- 发现列表页与任务发现 Tab 展示 name,为空时回退 vulnclass;vulnclass 移到展开详情「类型」
- report 报告标题优先 name,回退 vulnclass

无 CHECK 约束,旧库仅需补 name 列;critical/name 均向后兼容。
db 测试补充 critical 排序/统计与 name 往返断言。
This commit is contained in:
Autumn-27 committed 2026-08-18 11:21:08 -04:00
1 parent 7b3eec2166
commit ff3d41ea35
14 files changed
+96 -56

No files matched your search

+3 -2
View File
@@ -239,7 +239,7 @@ export default function DashboardPage() {
}, [tasks]);
const findingsBySev = React.useMemo(() => {
const m = { high: 0, medium: 0, low: 0 };
const m = { critical: 0, high: 0, medium: 0, low: 0 };
for (const f of findings) {
if (f.severity in m) m[f.severity as keyof typeof m]++;
}
@@ -491,7 +491,8 @@ export default function DashboardPage() {
{findings.length}
</div>
</CardHeader>
<CardContent className="flex gap-2.5 text-[10px]">
<CardContent className="flex flex-wrap gap-2.5 text-[10px]">
<span className="text-rose-500">严重 {findingsBySev.critical}</span>
<span className="text-red-400">高危 {findingsBySev.high}</span>
<span className="text-amber-400">中危 {findingsBySev.medium}</span>
<span className="text-slate-400">低危 {findingsBySev.low}</span>
+13 -2
View File
@@ -52,6 +52,7 @@ const FINDING_STATUSES: FindingStatus[] = [
const EMPTY_STATS: FindingStats = {
total: 0,
pending: 0,
critical: 0,
high: 0,
medium: 0,
low: 0,
@@ -156,6 +157,7 @@ export default function FindingsPage() {
const statCards: { label: string; value: number; tone?: string }[] = [
{ label: "发现总数", value: stats.total },
{ label: "待处理", value: stats.pending, tone: "text-amber-500" },
{ label: "严重", value: stats.critical, tone: "text-rose-600" },
{ label: "高危", value: stats.high, tone: "text-red-500" },
{ label: "中危", value: stats.medium, tone: "text-amber-500" },
{ label: "低危", value: stats.low, tone: "text-slate-500" },
@@ -168,7 +170,7 @@ export default function FindingsPage() {
<p className="text-muted-foreground text-sm">跨任务漏洞汇总</p>
</div>
<div className="flex flex-1 flex-col gap-4 md:gap-6">
<div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5">
<div className="grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6">
{statCards.map((s) => (
<Card key={s.label} className="gap-1 py-4">
<CardHeader className="px-4">
@@ -186,6 +188,7 @@ export default function FindingsPage() {
{(
[
["all", "全部"],
["critical", "严重"],
["high", "高危"],
["medium", "中危"],
["low", "低危"],
@@ -293,7 +296,7 @@ export default function FindingsPage() {
<TableCell className="max-w-md">
<div className="flex min-w-0 flex-col gap-0.5">
<span className="truncate font-medium">
{f.vulnclass || "未分类"}
{f.name || f.vulnclass || "未分类"}
</span>
<span className="truncate text-xs text-muted-foreground">
{f.summary}
@@ -380,6 +383,14 @@ export default function FindingsPage() {
<div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
<ShieldAlertIcon className="size-3.5" />
证据 · {f.id}
{f.vulnclass && (
<span>
· 类型:
<code className="rounded bg-muted px-1.5 py-0.5 font-mono">
{f.vulnclass}
</code>
</span>
)}
{f.param_id && (
<code className="rounded bg-muted px-1.5 py-0.5 font-mono">
{f.param_id}
@@ -52,7 +52,7 @@ function Row({
<StatusBadge domain="severity" value={f.severity} dot />
<div className="flex min-w-0 flex-col">
<span className="truncate font-medium">
{f.vulnclass || "未分类"}
{f.name || f.vulnclass || "未分类"}
</span>
<span className="truncate text-xs text-muted-foreground">
{f.summary}
@@ -161,7 +161,7 @@ export function FindingsTab({ taskId }: { taskId: string }) {
const items = findings
.filter((f) => f.task_id === taskId)
.sort((a, b) => {
const order = { high: 0, medium: 1, low: 2 };
const order = { critical: 0, high: 1, medium: 2, low: 3 };
return order[a.severity] - order[b.severity];
});