import type { ColumnsType } from "antd/es/table"; import { CheckCircleOutlined, DeleteOutlined, EditOutlined, StopOutlined } from "@ant-design/icons"; import { App as AntApp, Button, Popconfirm, Space, Table, Tag } from "antd"; import type { Model, ModelListResponse, Provider } from "../../../../shared/api"; interface ModelTableProps { data: ModelListResponse | undefined; loading: boolean; onDelete: (id: string) => Promise; onDisable: (id: string) => Promise; onEdit: (model: Model) => void; onEnable: (id: string) => Promise; onPageChange: (page: number, pageSize: number) => void; page: number; pageSize: number; providers: Provider[]; } const CAPABILITY_LABELS: Record = { "audio-generation": "音频生成", "audio-recognition": "音频识别", "image-generation": "图片生成", "image-recognition": "图片识别", reasoning: "推理", text: "文本", "video-generation": "视频生成", "video-recognition": "视频识别", }; function getProviderName(providerId: string, providers: Provider[]): string { return providers.find((p) => p.id === providerId)?.name ?? providerId; } const COLUMNS: ColumnsType = [ { dataIndex: "name", ellipsis: true, title: "模型名称", width: 160 }, { dataIndex: "modelId", ellipsis: true, title: "模型 ID", width: 180 }, { dataIndex: "providerId", ellipsis: true, title: "供应商", width: 120, }, { dataIndex: "capabilities", render: (value: string[]) => value.length > 0 ? ( {value.map((c) => ( {CAPABILITY_LABELS[c] ?? c} ))} ) : null, title: "能力", width: 200, }, { align: "center", dataIndex: "enabled", render: (value: boolean) => (value ? 已启用 : 已禁用), title: "状态", width: 100, }, { align: "center", dataIndex: "createdAt", render: (_value: unknown, record: Model) => formatDatetime(record.createdAt), title: "创建时间", width: 185, }, ]; export function ModelTable({ data, loading, onDelete, onDisable, onEdit, onEnable, onPageChange, page, pageSize, providers, }: ModelTableProps) { const { message } = AntApp.useApp(); const handleEnable = async (id: string) => { try { await onEnable(id); message.success("模型已启用"); } catch (err) { message.error((err as Error).message); } }; const handleDisable = async (id: string) => { try { await onDisable(id); message.success("模型已禁用"); } catch (err) { message.error((err as Error).message); } }; const handleDelete = async (id: string) => { try { await onDelete(id); message.success("模型已删除"); } catch (err) { message.error((err as Error).message); } }; const columnsWithProvider: ColumnsType = COLUMNS.map((col) => "dataIndex" in col && col.dataIndex === "providerId" ? { ...col, render: (_value: unknown, record: Model) => getProviderName(record.providerId, providers), } : col, ); const operationColumn: ColumnsType[number] = { dataIndex: "op", fixed: "right", render: (_value: unknown, record: Model) => ( {record.enabled ? ( void handleDisable(record.id)} title="确认禁用此模型?"> ) : ( )} void handleDelete(record.id)} title="确认删除此模型?" > ), title: "操作", width: 220, }; return ( ); } function formatDatetime(dateStr: string): string { const d = new Date(dateStr); const pad = (n: number) => String(n).padStart(2, "0"); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; }