"use client" import { ProjectDetail } from "@/components/label/api/project/typing" import { getTaskList, taskAcquire } from "@/components/label/api/task" import { Task } from "@/components/label/api/task/typing" import { useBackUrlStore, usePermissionStore, } from "@/components/label/store/auth" import { OwnTaskStatusOpts } from "@/components/label/utils/constants" import { SettingContentPanel, SettingDataTable, SettingFilterActions, SettingFilterPanel, SettingHeaderActions, SettingListHeader, } from "@/components/setting/PageSurface" import { Button, Collapse, Group, Select, SimpleGrid, Stack, Text, TextInput, } from "@mantine/core" import { notifications } from "@mantine/notifications" import { IconChevronDown, IconChevronUp, IconRefresh, IconSearch, } from "@tabler/icons-react" import { DataTableColumn } from "mantine-datatable" import { useRouter, useSearchParams } from "next/navigation" import { useCallback, useEffect, useMemo, useState } from "react" import TaskStatusTag from "./components/TaskStatusTag" function createInitialFilters() { return { search_id: "", search_status: "0", } } export default function OwnTaskTableContainer(props: { info: ProjectDetail.DataProps | undefined userEnums: { allEnum: Map labelEnum: Map review1Enum: Map review2Enum: Map } }) { const { info, userEnums } = props const urlParams = useSearchParams() const id = urlParams.get("id") const type = urlParams.get("type") const projectId = typeof id === "string" && !isNaN(Number(id)) ? Number(id) : -1 const router = useRouter() const { setBackProps } = useBackUrlStore() const user_id = usePermissionStore((s) => s.user_id) const [total, setTotal] = useState(0) const [pageNumber, setPageNumber] = useState(1) const [pageSize, setPageSize] = useState(15) const [searchExpanded, setSearchExpanded] = useState(false) const [filters, setFilters] = useState(() => createInitialFilters()) const [form, setForm] = useState<{ search_id: string search_status: string }>(createInitialFilters()) const [records, setRecords] = useState([]) const [loading, setLoading] = useState(false) const [queryTrigger, setQueryTrigger] = useState(0) const [isLabel, isReview1, isReview2] = useMemo(() => { const uid = typeof user_id === "number" ? user_id : Number(user_id ?? 0) return [ userEnums.labelEnum?.has(uid), userEnums.review1Enum?.has(uid), userEnums.review2Enum?.has(uid), ] }, [userEnums, user_id]) const appliedParams = useMemo(() => { const uid = typeof user_id === "number" ? user_id : Number(user_id ?? 0) const next: Task.ListRequest = { page_number: pageNumber ?? 1, page_size: pageSize ?? 20, current_uid: uid ? [uid] : undefined, project_id: projectId !== -1 ? [projectId] : undefined, get_data: false, } if (form.search_id) { const idValue = Number(form.search_id) if (Number.isFinite(idValue)) next.id = [idValue] } if (form.search_status !== "0") { const statusValue = Number(form.search_status) if (Number.isFinite(statusValue)) next.label_status = [statusValue] } else { delete next.label_status } return next }, [ form.search_id, form.search_status, pageNumber, pageSize, projectId, user_id, ]) const load = useCallback(async () => { if (!queryTrigger) return if (projectId === -1) return setLoading(true) try { const res = await getTaskList(appliedParams) setRecords(res?.task_list ?? []) setTotal(res?.total_items ?? 0) } catch (e) { setRecords([]) setTotal(0) notifications.show({ color: "red", title: "加载失败", message: e instanceof Error ? e.message : "请求失败", }) } finally { setLoading(false) } }, [appliedParams, projectId, queryTrigger, setTotal]) useEffect(() => { load() }, [load]) useEffect(() => { queueMicrotask(() => { setQueryTrigger((v) => v + 1) }) }, []) const handleAcquireTask = async (label_action: 1 | 2 | 3) => { const uid = typeof user_id === "number" ? user_id : Number(user_id ?? 0) if (!uid || projectId === -1) return try { await taskAcquire({ uid, project_id: projectId, label_action, }) notifications.show({ color: "green", title: "操作成功", message: "领取成功", }) setQueryTrigger((v) => v + 1) } catch (e) { notifications.show({ color: "red", title: "领取失败", message: e instanceof Error ? e.message : "请求失败", }) } } const handleSearch = () => { setPageNumber(1) setForm({ ...filters }) setQueryTrigger((v) => v + 1) } const handleReset = () => { const next = createInitialFilters() setFilters(next) setForm(next) setPageNumber(1) setQueryTrigger((v) => v + 1) } const handleRefresh = () => { setQueryTrigger((v) => v + 1) } const columns = useMemo(() => { const cols: DataTableColumn[] = [ { accessor: "id", title: "任务ID", width: 100, render: (record) => ( ), }, { accessor: "label_status", title: "状态", width: 150, render: (record) => ( ), }, { accessor: "label_object_size.object_size", title: "对象总数", width: 110, render: (record) => record.label_object_size?.object_size ?? "-", }, { accessor: "label_object_size.valid_size", title: "有效数", width: 100, render: (record) => record.label_object_size?.valid_size ?? "-", }, { accessor: "label_object_size.new_size", title: "新增数", width: 100, render: (record) => record.label_object_size?.new_size ?? "-", }, { accessor: "label_object_size.prelabel_size", title: "预标注总数", width: 120, render: (record) => record.label_object_size?.prelabel_size ?? "-", }, { accessor: "label_object_size.prelabel_modify_size", title: "预标注修改数", width: 130, render: (record) => record.label_object_size?.prelabel_modify_size ?? "-", }, { accessor: "label_object_size.first_comment_size", title: "批注一轮", width: 110, render: (record) => record.label_object_size?.first_comment_size ?? "-", }, { accessor: "label_object_size.second_comment_size", title: "批注二轮", width: 110, render: (record) => record.label_object_size?.second_comment_size ?? "-", }, ] return cols }, [info, projectId, router, setBackProps, type]) return ( 筛选条件 setFilters((s) => ({ ...s, search_id: e.target.value, })) } style={{ width: 160 }} />