"use client" import { getTaskWorkFlow } from "@/components/label/api/task" import { Button, Group, Modal, ScrollArea, Stack, Text } from "@mantine/core" import { notifications } from "@mantine/notifications" import { DataTable, DataTableColumn } from "mantine-datatable" import { useEffect, useMemo, useState } from "react" import TaskStatusTag from "./TaskStatusTag" type WorkflowRecord = Record type WorkflowRow = WorkflowRecord & { __rowId: string __index: number } const DISPLAY_COLUMNS: Array<{ accessor: string; title: string }> = [ { accessor: "task_status_src", title: "原状态" }, { accessor: "task_status_dst", title: "目标状态" }, { accessor: "old_username", title: "原处理人" }, { accessor: "new_username", title: "目标处理人" }, { accessor: "create_at", title: "创建时间" }, { accessor: "action", title: "操作" }, ] const MONOSPACE_STYLE = { fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace', whiteSpace: "pre-wrap" as const, wordBreak: "break-word" as const, } function toPlainRecord(value: unknown): WorkflowRecord { if (value && typeof value === "object" && !Array.isArray(value)) { return value as WorkflowRecord } return { value } } function parseStatusValue(value: unknown) { if (typeof value === "number" && Number.isFinite(value)) return value if (typeof value === "string" && value.trim() !== "") { const status = Number(value) return Number.isFinite(status) ? status : null } return null } function formatWorkflowValue(value: unknown) { if (value === null || value === undefined || value === "") return "-" if (typeof value === "boolean") return value ? "是" : "否" if (Array.isArray(value) || typeof value === "object") { return JSON.stringify(value) } return String(value) } export default function WorkflowModal(props: { opened: boolean taskId: number | null onCloseAction: () => void }) { const { opened, taskId, onCloseAction } = props const [loading, setLoading] = useState(false) const [records, setRecords] = useState([]) const rows = useMemo(() => { return records.map((item, index) => { const record = toPlainRecord(item) const rawId = record.id ?? record.workflow_id ?? record.log_id ?? index return { ...record, __index: index + 1, __rowId: String(rawId), } }) }, [records]) const columns = useMemo[]>(() => { return [ { accessor: "__index", title: "序号", width: 72, }, ...DISPLAY_COLUMNS.map>( ({ accessor, title }) => ({ accessor, title, render: (record) => { const status = accessor === "task_status_src" || accessor === "task_status_dst" ? parseStatusValue(record[accessor]) : null if (status !== null) { return } return ( {formatWorkflowValue(record[accessor])} ) }, }) ), ] }, []) useEffect(() => { if (!opened || !taskId) return const run = async () => { setLoading(true) try { const res = await getTaskWorkFlow(taskId) setRecords(res ?? []) } catch (e) { setRecords([]) notifications.show({ color: "red", title: "加载失败", message: e instanceof Error ? e.message : "请求失败", }) } finally { setLoading(false) } } run() }, [opened, taskId]) return ( withTableBorder withRowBorders pinLastColumn idAccessor="__rowId" records={rows} width={Math.max(columns.length * 140, 640)} columns={columns} noRecordsText={loading ? "加载中..." : "暂无数据"} minHeight={220} /> ) }