import React from "react" import { Table, Tag, Button, Popconfirm, Tooltip } from "antd" import { RedoOutlined, InfoCircleOutlined, ClockCircleOutlined } from "@ant-design/icons" import type { ColumnsType } from "antd/es/table" import type { TaskItem, TaskStatus } from "@/api/tasks" import { STATUS_CONFIG, TYPE_LABELS } from "../constants" import { formatDuration, formatTime } from "../utils" import { TaskErrorDetail } from "./TaskErrorDetail" interface TaskTableProps { dataSource: TaskItem[] loading: boolean total: number page: number pageSize: number expandedTaskId: string | null expandedTaskDetail: TaskItem | null retryLoading: boolean onPageChange: (page: number, pageSize: number) => void onExpand: (expanded: boolean, record: TaskItem) => void onRetry: (id: string) => void onViewDetail: (record: TaskItem) => void } /** * 任务列表表格 * 含列定义、分页、展开行 */ export const TaskTable: React.FC = ({ dataSource, loading, total, page, pageSize, expandedTaskId, expandedTaskDetail, retryLoading, onPageChange, onExpand, onRetry, onViewDetail, }) => { // 表格列定义 const columns: ColumnsType = [ { title: "任务ID", dataIndex: "id", key: "id", width: 120, ellipsis: true, render: (id: string) => ( {id.slice(0, 8)}... ), }, { title: "类型", dataIndex: "task_type", key: "task_type", width: 100, render: (type: string) => { const config = TYPE_LABELS[type] || { label: type, color: "default" } return {config.label} }, }, { title: "状态", dataIndex: "status", key: "status", width: 120, render: (status: TaskStatus, record: TaskItem) => { const config = STATUS_CONFIG[status] || { label: status, color: "default", icon: null, } return ( {config.label} {status === "running" && record.progress > 0 && ( {record.progress}% )} ) }, }, { title: "当前步骤", dataIndex: "current_step", key: "current_step", width: 150, ellipsis: true, render: (step: string) => {step || "-"}, }, { title: "耗时", dataIndex: "duration_seconds", key: "duration_seconds", width: 100, render: (seconds: number) => {formatDuration(seconds)}, }, { title: "创建时间", dataIndex: "created_at", key: "created_at", width: 120, render: (time: string) => {formatTime(time)}, }, { title: "操作", key: "action", width: 100, fixed: "right", render: (_: unknown, record: TaskItem) => { if (record.status === "failed" && record.retryable) { return ( onRetry(record.id)} okText="确定" cancelText="取消" > ) } if (record.status === "failed") { return ( ) } return - }, }, ] return ( `共 ${t} 条`, onChange: onPageChange, }} expandable={{ expandedRowRender: (record) => ( ), expandedRowKeys: expandedTaskId ? [expandedTaskId] : [], onExpand, rowExpandable: (record) => record.status === "failed" && (!!record.error_info || !!record.error_message), }} scroll={{ x: 800 }} className="task-table" locale={{ emptyText: (

暂无任务记录

), }} /> ) }