"use client" import React from "react" import { ColumnDef } from "@tanstack/react-table" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { MoreHorizontal, Trash2, ChevronsUpDown, ChevronUp, ChevronDown, Check, Edit, X as XIcon, } from "lucide-react" import { IconTarget, IconBolt, IconSettings, } from "@tabler/icons-react" import * as yaml from "js-yaml" import type { ScanEngine } from "@/types/engine.types" /** * 解析引擎的 YAML 配置并检测功能是否启用 * * 判断逻辑: * - 如果 YAML 中存在该配置项(即使是空对象 {}),则认为启用了该功能 * - 空对象表示使用默认配置启用该功能 */ function parseEngineFeatures(engine: ScanEngine) { // 如果引擎有 configuration 字段,解析 YAML if (engine.configuration) { try { const config = yaml.load(engine.configuration) as any return { subdomain_discovery: !!config?.subdomain_discovery, port_scan: !!config?.port_scan, site_scan: !!config?.site_scan, directory_scan: !!config?.directory_scan, url_fetch: !!config?.url_fetch || !!config?.fetch_url, // 兼容 fetch_url osint: !!config?.osint, vulnerability_scan: !!config?.vulnerability_scan, waf_detection: !!config?.waf_detection, screenshot: !!config?.screenshot, } } catch (error) { console.error("Failed to parse YAML configuration:", error) } } // 无配置时,所有功能默认为禁用 return { subdomain_discovery: false, port_scan: false, site_scan: false, directory_scan: false, url_fetch: false, osint: false, vulnerability_scan: false, waf_detection: false, screenshot: false, } } /** * 功能支持状态组件 */ function FeatureStatus({ enabled }: { enabled?: boolean }) { if (enabled) { return (
) } return (
) } /** * 数据表格列头组件 */ function DataTableColumnHeader({ column, title, }: { column: { getCanSort: () => boolean getIsSorted: () => false | "asc" | "desc" toggleSorting: (desc?: boolean) => void } title: string }) { if (!column.getCanSort()) { return
{title}
} const isSorted = column.getIsSorted() return ( ) } // 列创建函数的参数类型 interface CreateColumnsProps { formatDate: (dateString: string) => string handleEdit: (engine: ScanEngine) => void handleDelete: (engine: ScanEngine) => void } /** * 引擎行操作组件 */ function EngineRowActions({ engine, onEdit, onDelete, }: { engine: ScanEngine onEdit: () => void onDelete: () => void }) { return ( 编辑引擎 删除 ) } /** * 创建引擎表格列定义 */ export const createEngineColumns = ({ formatDate, handleEdit, handleDelete, }: CreateColumnsProps): ColumnDef[] => [ // 引擎名称列 - 可点击编辑 { accessorKey: "name", size: 200, minSize: 150, maxSize: 350, header: ({ column }) => ( ), cell: ({ row }) => { const name = row.getValue("name") as string return ( 编辑引擎 ) }, }, // Subdomain Discovery { id: "subdomain_discovery", header: "Subdomain Discovery", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // Port Scan { id: "port_scan", header: "Port Scan", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // Site Scan (原 HTTP Crawl) { id: "site_scan", header: "Site Scan", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // Directory Scan { id: "directory_scan", header: "Directory Scan", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // URL Fetch { id: "url_fetch", header: "URL Fetch", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // OSINT { id: "osint", header: "OSINT", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // Vulnerability Scan { id: "vulnerability_scan", header: "Vulnerability Scan", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // WAF Detection { id: "waf_detection", header: "WAF Detection", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // Screenshot { id: "screenshot", header: "Screenshot", size: 80, minSize: 60, maxSize: 100, cell: ({ row }) => { const features = parseEngineFeatures(row.original) return }, enableSorting: false, }, // 操作列 { id: "actions", size: 60, minSize: 60, maxSize: 60, enableResizing: false, cell: ({ row }) => ( handleEdit(row.original)} onDelete={() => handleDelete(row.original)} /> ), enableSorting: false, enableHiding: false, }, ]