"use client" import { getProjectList } from "@/components/label/api/project" import { getAllSyncServerList, getDataSyncTaskList, newSyncTask, updateSyncTaskStatus, } from "@/components/label/api/sync" import { Response } from "@/components/label/api/sync/typing" import useAuth from "@/components/label/hooks/useAuth" import { ActionIcon, Button, Group, Modal, Paper, Select, Stack, Text, } from "@mantine/core" import { modals } from "@mantine/modals" import { notifications } from "@mantine/notifications" import { IconPlayerPause, IconPlayerPlay, IconPlus, IconRefresh, IconSearch, IconTrash, IconX } from "@tabler/icons-react" import { DataTable, DataTableColumn } from "mantine-datatable" import { useCallback, useEffect, useMemo, useState } from "react" const StatusEnum = new Map([ [1, "待同步"], [2, "同步中"], [3, "同步失败"], [4, "同步成功"], [5, "待删除"], [6, "删除中"], [7, "删除失败"], [8, "删除完成"], [9, "等待暂停"], [10, "已暂停"], [11, "等待关闭"], [12, "已关闭"], ]) export default function TeamSyncTaskPage() { const { isShow } = useAuth() const [records, setRecords] = useState([]) const [loading, setLoading] = useState(false) const [totalItems, setTotalItems] = useState(0) const [page, setPage] = useState(1) const [pageSize, setPageSize] = useState(20) const [status, setStatus] = useState(null) const [projectId, setProjectId] = useState(null) const [serverId, setServerId] = useState(null) const [appliedStatus, setAppliedStatus] = useState(null) const [appliedProjectId, setAppliedProjectId] = useState(null) const [appliedServerId, setAppliedServerId] = useState(null) const [projectOpt, setProjectOpt] = useState>([]) const [serverAllOpt, setServerAllOpt] = useState>([]) const [serverOnlineOpt, setServerOnlineOpt] = useState>( [] ) const [serverMap, setServerMap] = useState>(new Map()) const [open, setOpen] = useState(false) const [newProjectId, setNewProjectId] = useState(null) const [newServerId, setNewServerId] = useState(null) const [creating, setCreating] = useState(false) const loadOptions = useCallback(async () => { const [projectRes, serverRes] = await Promise.all([ getProjectList({ page_number: 1, page_size: 10000 }), getAllSyncServerList(), ]) const projects = projectRes?.project_list ?? [] setProjectOpt(projects.map((p) => ({ label: p.name, value: String(p.id) }))) const allServers = serverRes ?? [] setServerAllOpt(allServers.map((s) => ({ label: s.ip, value: String(s.id) }))) setServerOnlineOpt( allServers .filter((s) => s.is_online) .map((s) => ({ label: s.ip, value: String(s.id) })) ) setServerMap(new Map(allServers.map((s) => [s.id, s.ip]))) }, []) const load = useCallback(async () => { try { setLoading(true) const params: any = { page_number: page, page_size: pageSize, } if (appliedStatus) params.status = Number(appliedStatus) if (appliedProjectId) params.project_id = Number(appliedProjectId) if (appliedServerId) params.sync_server_id = Number(appliedServerId) const res = await getDataSyncTaskList(params) setRecords(res?.sync_tasks ?? []) setTotalItems(res?.total_items ?? 0) } catch (e) { setRecords([]) setTotalItems(0) notifications.show({ color: "red", title: "加载失败", message: e instanceof Error ? e.message : "请求失败", }) } finally { setLoading(false) } }, [appliedProjectId, appliedServerId, appliedStatus, page, pageSize]) useEffect(() => { queueMicrotask(loadOptions) }, [loadOptions]) useEffect(() => { load() }, [load]) const performStatusAction = async (id: number, statusTo: number, successText: string) => { try { await updateSyncTaskStatus(id, statusTo) notifications.show({ color: "green", title: "操作成功", message: successText, }) load() } catch (e) { notifications.show({ color: "red", title: "操作失败", message: e instanceof Error ? e.message : "请求失败", }) } } const columns = useMemo(() => { const cols: DataTableColumn[] = [ { accessor: "id", title: "ID", width: 80 }, { accessor: "uuid", title: "UUID", width: 320 }, { accessor: "status", title: "状态", width: 120, render: (record) => StatusEnum.get(record.status ?? 0) ?? "-", }, { accessor: "project_name", title: "项目名称", width: 260 }, { accessor: "sync_server_id", title: "同步服务IP", width: 160, render: (record) => record.sync_server_id ? serverMap.get(record.sync_server_id) ?? "-" : "-", }, { accessor: "location", title: "IP所在地", width: 140 }, { accessor: "create_at", title: "创建时间", width: 180 }, { accessor: "update_at", title: "更新时间", width: 180 }, { accessor: "operation", title: "操作", width: 200, textAlign: "center", render: (record) => { const couldRun = isShow("task_edit") && [10].includes(record.status ?? -1) const couldStop = isShow("task_edit") && [1, 2].includes(record.status ?? -1) const couldDelete = isShow("task_edit") && [1, 2, 3, 4, 9, 10].includes(record.status ?? -1) const couldClose = isShow("task_edit") && ![11, 12].includes(record.status ?? -1) return ( {couldRun ? ( performStatusAction(record.id as number, 1, "已恢复同步") }> ) : null} {couldStop ? ( { modals.openConfirmModal({ title: "暂停任务", centered: true, children: ( 是否确定暂停当前同步任务? ), labels: { confirm: "确定", cancel: "取消" }, onConfirm: () => performStatusAction(record.id as number, 9, "已暂停任务"), }) }}> ) : null} {couldDelete ? ( { modals.openConfirmModal({ title: "删除任务", centered: true, children: ( 是否确定删除当前同步任务? ), labels: { confirm: "确定", cancel: "取消" }, confirmProps: { color: "red" }, onConfirm: () => performStatusAction(record.id as number, 5, "已提交删除"), }) }}> ) : null} {couldClose ? ( { modals.openConfirmModal({ title: "关闭任务", centered: true, children: ( 是否确定关闭当前同步任务? ), labels: { confirm: "确定", cancel: "取消" }, onConfirm: () => performStatusAction(record.id as number, 11, "已关闭任务"), }) }}> ) : null} ) }, }, ] return cols }, [isShow, serverMap]) const createTask = async () => { if (!newProjectId || !newServerId) { notifications.show({ color: "yellow", title: "参数不完整", message: "请先选择项目和同步服务", }) return } try { setCreating(true) await newSyncTask({ project_id: Number(newProjectId), sync_server_id: Number(newServerId), }) notifications.show({ color: "green", title: "操作成功", message: "已新增同步任务", }) setOpen(false) setNewProjectId(null) setNewServerId(null) load() } catch (e) { notifications.show({ color: "red", title: "操作失败", message: e instanceof Error ? e.message : "请求失败", }) } finally { setCreating(false) } } return (