perf(format): code format

This commit is contained in:
zhangheng
2026-02-27 10:21:43 +08:00
parent 6cb8f98004
commit e3ca3e9c31
15 changed files with 257 additions and 142 deletions

View File

@@ -6,14 +6,7 @@ import {
getDownloadLog, getDownloadLog,
} from "@/components/label/api/workload" } from "@/components/label/api/workload"
import useAuth from "@/components/label/hooks/useAuth" import useAuth from "@/components/label/hooks/useAuth"
import { import { ActionIcon, Button, Group, Paper, Stack, Text } from "@mantine/core"
ActionIcon,
Button,
Group,
Paper,
Stack,
Text,
} from "@mantine/core"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { IconDownload, IconFileExport, IconRefresh } from "@tabler/icons-react" import { IconDownload, IconFileExport, IconRefresh } from "@tabler/icons-react"
import dayjs from "dayjs" import dayjs from "dayjs"
@@ -99,7 +92,9 @@ export default function TeamCostPage() {
title: "导出时间", title: "导出时间",
width: 200, width: 200,
render: (record) => render: (record) =>
record.create_at ? dayjs(record.create_at).format("YYYY-MM-DD HH:mm:ss") : "-", record.create_at
? dayjs(record.create_at).format("YYYY-MM-DD HH:mm:ss")
: "-",
}, },
{ accessor: "file_name", title: "导出文件名", width: 280 }, { accessor: "file_name", title: "导出文件名", width: 280 },
{ accessor: "create_user", title: "操作人", width: 160 }, { accessor: "create_user", title: "操作人", width: 160 },

View File

@@ -77,7 +77,10 @@ export default function TeamDailypaperPage() {
const { isShow } = useAuth() const { isShow } = useAuth()
const treeData = useAllUserStore((s) => s.treeData) const treeData = useAllUserStore((s) => s.treeData)
const leaderOptions = useMemo(() => flattenLeaderTree(treeData ?? []), [treeData]) const leaderOptions = useMemo(
() => flattenLeaderTree(treeData ?? []),
[treeData]
)
const defaultFilters = useMemo(() => { const defaultFilters = useMemo(() => {
return { return {
@@ -116,7 +119,8 @@ export default function TeamDailypaperPage() {
}) })
const [modalOpened, setModalOpened] = useState(false) const [modalOpened, setModalOpened] = useState(false)
const [editingRecord, setEditingRecord] = useState<Daily.DailyWorkList | null>(null) const [editingRecord, setEditingRecord] =
useState<Daily.DailyWorkList | null>(null)
const [searchExpanded, setSearchExpanded] = useState(false) const [searchExpanded, setSearchExpanded] = useState(false)
const queryParams = useMemo(() => { const queryParams = useMemo(() => {
@@ -147,7 +151,13 @@ export default function TeamDailypaperPage() {
} }
}) })
return params return params
}, [appliedFilters, page, pageSize, sortStatus.columnAccessor, sortStatus.direction]) }, [
appliedFilters,
page,
pageSize,
sortStatus.columnAccessor,
sortStatus.direction,
])
const load = useCallback(async () => { const load = useCallback(async () => {
if (!queryTrigger) return if (!queryTrigger) return
@@ -182,7 +192,9 @@ export default function TeamDailypaperPage() {
useEffect(() => { useEffect(() => {
const run = async () => { const run = async () => {
const res = await getSelfProjectList() const res = await getSelfProjectList()
setProjectOptions((res ?? []).map((p) => ({ label: p.label, value: String(p.value) }))) setProjectOptions(
(res ?? []).map((p) => ({ label: p.label, value: String(p.value) }))
)
} }
queueMicrotask(run) queueMicrotask(run)
}, []) }, [])
@@ -237,7 +249,11 @@ export default function TeamDailypaperPage() {
item.obj_type === 0 || item.obj_type === 1 item.obj_type === 0 || item.obj_type === 1
? (objTypeTextMap.get(item.obj_type) ?? "-") ? (objTypeTextMap.get(item.obj_type) ?? "-")
: "-", : "-",
item.residual_pm === true ? "正" : item.residual_pm === false ? "负" : "-", item.residual_pm === true
? "正"
: item.residual_pm === false
? "负"
: "-",
item.start_time ?? "-", item.start_time ?? "-",
item.end_time ?? "-", item.end_time ?? "-",
item.work_time ?? 0, item.work_time ?? 0,
@@ -274,7 +290,8 @@ export default function TeamDailypaperPage() {
accessor: "week", accessor: "week",
title: "星期", title: "星期",
width: 90, width: 90,
render: (record) => (record.date ? weekDayText(dayjs(record.date).day()) : "-"), render: (record) =>
record.date ? weekDayText(dayjs(record.date).day()) : "-",
}, },
{ {
accessor: "set_type", accessor: "set_type",
@@ -299,7 +316,8 @@ export default function TeamDailypaperPage() {
accessor: "accounting_type", accessor: "accounting_type",
title: "核算方式", title: "核算方式",
width: 140, width: 140,
render: (record) => accountTypeMap.get(record.accounting_type ?? "") ?? "-", render: (record) =>
accountTypeMap.get(record.accounting_type ?? "") ?? "-",
}, },
{ {
accessor: "project_name", accessor: "project_name",
@@ -348,14 +366,23 @@ export default function TeamDailypaperPage() {
title: "余量正负", title: "余量正负",
width: 100, width: 100,
render: (record) => render: (record) =>
record.residual_pm === true ? "正" : record.residual_pm === false ? "负" : "-", record.residual_pm === true
? "正"
: record.residual_pm === false
? "负"
: "-",
}, },
{ accessor: "start_time", title: "开始时间", width: 120 }, { accessor: "start_time", title: "开始时间", width: 120 },
{ accessor: "end_time", title: "结束时间", width: 120 }, { accessor: "end_time", title: "结束时间", width: 120 },
{ accessor: "work_time", title: "工时", width: 90, sortable: true }, { accessor: "work_time", title: "工时", width: 90, sortable: true },
{ accessor: "rate", title: "额定倍率", width: 90 }, { accessor: "rate", title: "额定倍率", width: 90 },
{ accessor: "standard_size", title: "标准量", width: 90, sortable: true }, { accessor: "standard_size", title: "标准量", width: 90, sortable: true },
{ accessor: "completed_size", title: "完成量", width: 90, sortable: true }, {
accessor: "completed_size",
title: "完成量",
width: 90,
sortable: true,
},
{ accessor: "residual_size", title: "余量", width: 90, sortable: true }, { accessor: "residual_size", title: "余量", width: 90, sortable: true },
{ {
accessor: "residual_work_time", accessor: "residual_work_time",
@@ -430,7 +457,9 @@ export default function TeamDailypaperPage() {
title: "删除日报", title: "删除日报",
centered: true, centered: true,
children: ( children: (
<Text size="sm"></Text> <Text size="sm">
</Text>
), ),
labels: { confirm: "删除", cancel: "取消" }, labels: { confirm: "删除", cancel: "取消" },
confirmProps: { color: "red" }, confirmProps: { color: "red" },
@@ -530,7 +559,9 @@ export default function TeamDailypaperPage() {
radius="xs" radius="xs"
type="date" type="date"
value={filters.date_start} value={filters.date_start}
onChange={(e) => setFilters((s) => ({ ...s, date_start: e.target.value }))} onChange={(e) =>
setFilters((s) => ({ ...s, date_start: e.target.value }))
}
/> />
<TextInput <TextInput
label="结束日期" label="结束日期"
@@ -538,7 +569,9 @@ export default function TeamDailypaperPage() {
radius="xs" radius="xs"
type="date" type="date"
value={filters.date_end} value={filters.date_end}
onChange={(e) => setFilters((s) => ({ ...s, date_end: e.target.value }))} onChange={(e) =>
setFilters((s) => ({ ...s, date_end: e.target.value }))
}
/> />
<MultiSelect <MultiSelect
label="员工姓名" label="员工姓名"
@@ -578,7 +611,9 @@ export default function TeamDailypaperPage() {
searchable searchable
clearable clearable
value={filters.set_type ? [filters.set_type] : []} value={filters.set_type ? [filters.set_type] : []}
onChange={(v) => setFilters((s) => ({ ...s, set_type: v[0] ?? "" }))} onChange={(v) =>
setFilters((s) => ({ ...s, set_type: v[0] ?? "" }))
}
/> />
<MultiSelect <MultiSelect
label="出勤类型" label="出勤类型"
@@ -588,7 +623,9 @@ export default function TeamDailypaperPage() {
searchable searchable
clearable clearable
value={filters.actual_type ? [filters.actual_type] : []} value={filters.actual_type ? [filters.actual_type] : []}
onChange={(v) => setFilters((s) => ({ ...s, actual_type: v[0] ?? "" }))} onChange={(v) =>
setFilters((s) => ({ ...s, actual_type: v[0] ?? "" }))
}
/> />
<MultiSelect <MultiSelect
label="工作类别" label="工作类别"
@@ -598,7 +635,9 @@ export default function TeamDailypaperPage() {
searchable searchable
clearable clearable
value={filters.work_type ? [filters.work_type] : []} value={filters.work_type ? [filters.work_type] : []}
onChange={(v) => setFilters((s) => ({ ...s, work_type: v[0] ?? "" }))} onChange={(v) =>
setFilters((s) => ({ ...s, work_type: v[0] ?? "" }))
}
/> />
<MultiSelect <MultiSelect
label="核算方式" label="核算方式"
@@ -620,10 +659,15 @@ export default function TeamDailypaperPage() {
searchable searchable
clearable clearable
value={ value={
filters.performance_accounting ? [filters.performance_accounting] : [] filters.performance_accounting
? [filters.performance_accounting]
: []
} }
onChange={(v) => onChange={(v) =>
setFilters((s) => ({ ...s, performance_accounting: v[0] ?? "" })) setFilters((s) => ({
...s,
performance_accounting: v[0] ?? "",
}))
} }
/> />
<MultiSelect <MultiSelect
@@ -634,7 +678,9 @@ export default function TeamDailypaperPage() {
searchable searchable
clearable clearable
value={filters.obj_type ? [filters.obj_type] : []} value={filters.obj_type ? [filters.obj_type] : []}
onChange={(v) => setFilters((s) => ({ ...s, obj_type: v[0] ?? "" }))} onChange={(v) =>
setFilters((s) => ({ ...s, obj_type: v[0] ?? "" }))
}
/> />
</SimpleGrid> </SimpleGrid>
</Collapse> </Collapse>
@@ -656,10 +702,7 @@ export default function TeamDailypaperPage() {
}}> }}>
<Stack gap={12} align="stretch" style={{ flex: 1, minHeight: 0 }}> <Stack gap={12} align="stretch" style={{ flex: 1, minHeight: 0 }}>
<Flex justify="space-between" align="center" w="100%"> <Flex justify="space-between" align="center" w="100%">
<Button <Button size="xs" radius="xs" onClick={handleExportData}>
size="xs"
radius="xs"
onClick={handleExportData}>
</Button> </Button>
<ActionIcon onClick={load} variant="transparent"> <ActionIcon onClick={load} variant="transparent">
@@ -704,7 +747,9 @@ export default function TeamDailypaperPage() {
<Group gap="md"> <Group gap="md">
<Text size="sm">{summaryText.total_work_time}</Text> <Text size="sm">{summaryText.total_work_time}</Text>
<Text size="sm">{summaryText.total_standard_size}</Text> <Text size="sm">{summaryText.total_standard_size}</Text>
<Text size="sm">{summaryText.total_completed_size}</Text> <Text size="sm">
{summaryText.total_completed_size}
</Text>
<Text size="sm">{summaryText.total_residual_size}</Text> <Text size="sm">{summaryText.total_residual_size}</Text>
<Text size="sm"> <Text size="sm">
{summaryText.total_residual_work_time} {summaryText.total_residual_work_time}

View File

@@ -1,14 +1,7 @@
"use client" "use client"
import { getUserGroupAll, userAdd } from "@/components/label/api/user" import { getUserGroupAll, userAdd } from "@/components/label/api/user"
import { import { Button, Group, Modal, Select, Stack, TextInput } from "@mantine/core"
Button,
Group,
Modal,
Select,
Stack,
TextInput,
} from "@mantine/core"
import { useForm } from "@mantine/form" import { useForm } from "@mantine/form"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { useEffect, useState } from "react" import { useEffect, useState } from "react"
@@ -22,9 +15,9 @@ export default function CreateUserModal({
opened, opened,
onCloseAction, onCloseAction,
}: ComponentProps) { }: ComponentProps) {
const [groupOpts, setGroupOpts] = useState<Array<{ label: string; value: string }>>( const [groupOpts, setGroupOpts] = useState<
[] Array<{ label: string; value: string }>
) >([])
const [submitting, setSubmitting] = useState(false) const [submitting, setSubmitting] = useState(false)
const form = useForm({ const form = useForm({
@@ -116,11 +109,7 @@ export default function CreateUserModal({
onClick={() => onCloseAction()}> onClick={() => onCloseAction()}>
</Button> </Button>
<Button <Button type="submit" size="xs" radius="xs" loading={submitting}>
type="submit"
size="xs"
radius="xs"
loading={submitting}>
</Button> </Button>
</Group> </Group>

View File

@@ -2,14 +2,7 @@
import { getUserGroupAll, userEditById } from "@/components/label/api/user" import { getUserGroupAll, userEditById } from "@/components/label/api/user"
import { User } from "@/components/label/api/user/typing" import { User } from "@/components/label/api/user/typing"
import { import { Button, Group, Modal, Select, Stack, TextInput } from "@mantine/core"
Button,
Group,
Modal,
Select,
Stack,
TextInput,
} from "@mantine/core"
import { useForm } from "@mantine/form" import { useForm } from "@mantine/form"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { useEffect, useMemo, useState } from "react" import { useEffect, useMemo, useState } from "react"
@@ -25,9 +18,9 @@ export default function EditUserModal({
data, data,
onCloseAction, onCloseAction,
}: ComponentProps) { }: ComponentProps) {
const [groupOpts, setGroupOpts] = useState<Array<{ label: string; value: string }>>( const [groupOpts, setGroupOpts] = useState<
[] Array<{ label: string; value: string }>
) >([])
const [submitting, setSubmitting] = useState(false) const [submitting, setSubmitting] = useState(false)
const groupValueByName = useMemo(() => { const groupValueByName = useMemo(() => {
@@ -153,11 +146,7 @@ export default function EditUserModal({
onClick={() => onCloseAction()}> onClick={() => onCloseAction()}>
</Button> </Button>
<Button <Button type="submit" size="xs" radius="xs" loading={submitting}>
type="submit"
size="xs"
radius="xs"
loading={submitting}>
</Button> </Button>
</Group> </Group>

View File

@@ -121,7 +121,9 @@ export default function ImportModal({ opened, onCloseAction }: ComponentProps) {
XLSX.utils.book_append_sheet(wb, ws, "用户信息") XLSX.utils.book_append_sheet(wb, ws, "用户信息")
wb.Sheets["用户信息"]["!rows"] = [{ hpx: 20 }, { hpx: 20 }, { hpx: 20 }] wb.Sheets["用户信息"]["!rows"] = [{ hpx: 20 }, { hpx: 20 }, { hpx: 20 }]
wb.Sheets["用户信息"]["!cols"] = [{ wch: 20 }, { wch: 20 }, { wch: 20 }] wb.Sheets["用户信息"]["!cols"] = [{ wch: 20 }, { wch: 20 }, { wch: 20 }]
wb.Sheets["用户信息"]["!merges"] = [{ s: { c: 0, r: 0 }, e: { c: 2, r: 2 } }] wb.Sheets["用户信息"]["!merges"] = [
{ s: { c: 0, r: 0 }, e: { c: 2, r: 2 } },
]
if (wb.Sheets["用户信息"]["A1"]) { if (wb.Sheets["用户信息"]["A1"]) {
wb.Sheets["用户信息"]["A1"].s = { alignment: { wrapText: true } } wb.Sheets["用户信息"]["A1"].s = { alignment: { wrapText: true } }
} }
@@ -251,11 +253,7 @@ export default function ImportModal({ opened, onCloseAction }: ComponentProps) {
}}> }}>
</Button> </Button>
<Button <Button size="xs" radius="xs" onClick={submit} loading={submitting}>
size="xs"
radius="xs"
onClick={submit}
loading={submitting}>
</Button> </Button>
</Group> </Group>

View File

@@ -16,7 +16,7 @@ import {
} from "@mantine/core" } from "@mantine/core"
import { modals } from "@mantine/modals" import { modals } from "@mantine/modals"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { IconEdit, IconPlus, IconRefresh, IconSearch, IconUpload } from "@tabler/icons-react" import { IconEdit, IconRefresh, IconSearch } from "@tabler/icons-react"
import { DataTable, DataTableColumn } from "mantine-datatable" import { DataTable, DataTableColumn } from "mantine-datatable"
import { useCallback, useEffect, useMemo, useState } from "react" import { useCallback, useEffect, useMemo, useState } from "react"
import CreateUserModal from "./components/CreateUserModal" import CreateUserModal from "./components/CreateUserModal"
@@ -193,7 +193,7 @@ export default function TeamEmployeePage() {
</Button> </Button>
</Group> </Group>
<Group> {/* <Group>
{isShow("add") ? ( {isShow("add") ? (
<Button <Button
size="xs" size="xs"
@@ -213,7 +213,7 @@ export default function TeamEmployeePage() {
批量导入 批量导入
</Button> </Button>
) : null} ) : null}
</Group> </Group> */}
</Group> </Group>
</Paper> </Paper>

View File

@@ -19,12 +19,12 @@ interface ComponentProps {
export default function CreateModal({ opened, onCloseAction }: ComponentProps) { export default function CreateModal({ opened, onCloseAction }: ComponentProps) {
const storeUserOpts = useAllUserStore((s) => s.userOpts) const storeUserOpts = useAllUserStore((s) => s.userOpts)
const [groupOpts, setGroupOpts] = useState<Array<{ label: string; value: string }>>( const [groupOpts, setGroupOpts] = useState<
[] Array<{ label: string; value: string }>
) >([])
const [userOpts, setUserOpts] = useState<Array<{ label: string; value: string }>>( const [userOpts, setUserOpts] = useState<
[] Array<{ label: string; value: string }>
) >([])
const [submitting, setSubmitting] = useState(false) const [submitting, setSubmitting] = useState(false)
const finalUserOpts = useMemo(() => { const finalUserOpts = useMemo(() => {
@@ -51,7 +51,9 @@ export default function CreateModal({ opened, onCloseAction }: ComponentProps) {
getUserAll(), getUserAll(),
]) ])
setGroupOpts(groupRes ?? []) setGroupOpts(groupRes ?? [])
setUserOpts((userRes ?? []).map((u) => ({ label: u.label, value: String(u.value) }))) setUserOpts(
(userRes ?? []).map((u) => ({ label: u.label, value: String(u.value) }))
)
} }
queueMicrotask(run) queueMicrotask(run)
}, [opened]) }, [opened])
@@ -125,11 +127,7 @@ export default function CreateModal({ opened, onCloseAction }: ComponentProps) {
onClick={() => onCloseAction()}> onClick={() => onCloseAction()}>
</Button> </Button>
<Button <Button type="submit" size="xs" radius="xs" loading={submitting}>
type="submit"
size="xs"
radius="xs"
loading={submitting}>
</Button> </Button>
</Group> </Group>

View File

@@ -15,7 +15,12 @@ import {
TextInput, TextInput,
} from "@mantine/core" } from "@mantine/core"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { IconPlus, IconRefresh, IconSearch, IconUserCircle } from "@tabler/icons-react" import {
IconPlus,
IconRefresh,
IconSearch,
IconUserCircle,
} from "@tabler/icons-react"
import { useCallback, useEffect, useMemo, useState } from "react" import { useCallback, useEffect, useMemo, useState } from "react"
import CreateModal from "./components/CreateModal" import CreateModal from "./components/CreateModal"

View File

@@ -37,7 +37,8 @@ export default function TeamSyncServerPage() {
const [appliedOnline, setAppliedOnline] = useState<string | null>(null) const [appliedOnline, setAppliedOnline] = useState<string | null>(null)
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [editingRecord, setEditingRecord] = useState<Response.SyncServer | null>(null) const [editingRecord, setEditingRecord] =
useState<Response.SyncServer | null>(null)
const [editingLocation, setEditingLocation] = useState("") const [editingLocation, setEditingLocation] = useState("")
const [submitting, setSubmitting] = useState(false) const [submitting, setSubmitting] = useState(false)

View File

@@ -21,7 +21,15 @@ import {
} from "@mantine/core" } from "@mantine/core"
import { modals } from "@mantine/modals" import { modals } from "@mantine/modals"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { IconPlayerPause, IconPlayerPlay, IconPlus, IconRefresh, IconSearch, IconTrash, IconX } from "@tabler/icons-react" import {
IconPlayerPause,
IconPlayerPlay,
IconPlus,
IconRefresh,
IconSearch,
IconTrash,
IconX,
} from "@tabler/icons-react"
import { DataTable, DataTableColumn } from "mantine-datatable" import { DataTable, DataTableColumn } from "mantine-datatable"
import { useCallback, useEffect, useMemo, useState } from "react" import { useCallback, useEffect, useMemo, useState } from "react"
@@ -56,11 +64,15 @@ export default function TeamSyncTaskPage() {
const [appliedProjectId, setAppliedProjectId] = useState<string | null>(null) const [appliedProjectId, setAppliedProjectId] = useState<string | null>(null)
const [appliedServerId, setAppliedServerId] = useState<string | null>(null) const [appliedServerId, setAppliedServerId] = useState<string | null>(null)
const [projectOpt, setProjectOpt] = useState<Array<{ label: string; value: string }>>([]) const [projectOpt, setProjectOpt] = useState<
const [serverAllOpt, setServerAllOpt] = useState<Array<{ label: string; value: string }>>([]) Array<{ label: string; value: string }>
const [serverOnlineOpt, setServerOnlineOpt] = useState<Array<{ label: string; value: string }>>( >([])
[] const [serverAllOpt, setServerAllOpt] = useState<
) Array<{ label: string; value: string }>
>([])
const [serverOnlineOpt, setServerOnlineOpt] = useState<
Array<{ label: string; value: string }>
>([])
const [serverMap, setServerMap] = useState<Map<number, string>>(new Map()) const [serverMap, setServerMap] = useState<Map<number, string>>(new Map())
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
@@ -78,7 +90,9 @@ export default function TeamSyncTaskPage() {
setProjectOpt(projects.map((p) => ({ label: p.name, value: String(p.id) }))) setProjectOpt(projects.map((p) => ({ label: p.name, value: String(p.id) })))
const allServers = serverRes ?? [] const allServers = serverRes ?? []
setServerAllOpt(allServers.map((s) => ({ label: s.ip, value: String(s.id) }))) setServerAllOpt(
allServers.map((s) => ({ label: s.ip, value: String(s.id) }))
)
setServerOnlineOpt( setServerOnlineOpt(
allServers allServers
.filter((s) => s.is_online) .filter((s) => s.is_online)
@@ -122,7 +136,11 @@ export default function TeamSyncTaskPage() {
load() load()
}, [load]) }, [load])
const performStatusAction = async (id: number, statusTo: number, successText: string) => { const performStatusAction = async (
id: number,
statusTo: number,
successText: string
) => {
try { try {
await updateSyncTaskStatus(id, statusTo) await updateSyncTaskStatus(id, statusTo)
notifications.show({ notifications.show({
@@ -156,7 +174,9 @@ export default function TeamSyncTaskPage() {
title: "同步服务IP", title: "同步服务IP",
width: 160, width: 160,
render: (record) => render: (record) =>
record.sync_server_id ? serverMap.get(record.sync_server_id) ?? "-" : "-", record.sync_server_id
? (serverMap.get(record.sync_server_id) ?? "-")
: "-",
}, },
{ accessor: "location", title: "IP所在地", width: 140 }, { accessor: "location", title: "IP所在地", width: 140 },
{ accessor: "create_at", title: "创建时间", width: 180 }, { accessor: "create_at", title: "创建时间", width: 180 },
@@ -167,10 +187,13 @@ export default function TeamSyncTaskPage() {
width: 200, width: 200,
textAlign: "center", textAlign: "center",
render: (record) => { render: (record) => {
const couldRun = isShow("task_edit") && [10].includes(record.status ?? -1) const couldRun =
const couldStop = isShow("task_edit") && [1, 2].includes(record.status ?? -1) isShow("task_edit") && [10].includes(record.status ?? -1)
const couldStop =
isShow("task_edit") && [1, 2].includes(record.status ?? -1)
const couldDelete = const couldDelete =
isShow("task_edit") && [1, 2, 3, 4, 9, 10].includes(record.status ?? -1) isShow("task_edit") &&
[1, 2, 3, 4, 9, 10].includes(record.status ?? -1)
const couldClose = const couldClose =
isShow("task_edit") && ![11, 12].includes(record.status ?? -1) isShow("task_edit") && ![11, 12].includes(record.status ?? -1)
@@ -199,7 +222,11 @@ export default function TeamSyncTaskPage() {
), ),
labels: { confirm: "确定", cancel: "取消" }, labels: { confirm: "确定", cancel: "取消" },
onConfirm: () => onConfirm: () =>
performStatusAction(record.id as number, 9, "已暂停任务"), performStatusAction(
record.id as number,
9,
"已暂停任务"
),
}) })
}}> }}>
<IconPlayerPause size={16} /> <IconPlayerPause size={16} />
@@ -219,7 +246,11 @@ export default function TeamSyncTaskPage() {
labels: { confirm: "确定", cancel: "取消" }, labels: { confirm: "确定", cancel: "取消" },
confirmProps: { color: "red" }, confirmProps: { color: "red" },
onConfirm: () => onConfirm: () =>
performStatusAction(record.id as number, 5, "已提交删除"), performStatusAction(
record.id as number,
5,
"已提交删除"
),
}) })
}}> }}>
<IconTrash size={16} /> <IconTrash size={16} />
@@ -238,7 +269,11 @@ export default function TeamSyncTaskPage() {
), ),
labels: { confirm: "确定", cancel: "取消" }, labels: { confirm: "确定", cancel: "取消" },
onConfirm: () => onConfirm: () =>
performStatusAction(record.id as number, 11, "已关闭任务"), performStatusAction(
record.id as number,
11,
"已关闭任务"
),
}) })
}}> }}>
<IconX size={16} /> <IconX size={16} />
@@ -437,7 +472,11 @@ export default function TeamSyncTaskPage() {
onChange={setNewServerId} onChange={setNewServerId}
/> />
<Group justify="flex-end"> <Group justify="flex-end">
<Button variant="default" size="xs" radius="xs" onClick={() => setOpen(false)}> <Button
variant="default"
size="xs"
radius="xs"
onClick={() => setOpen(false)}>
</Button> </Button>
<Button <Button

View File

@@ -35,9 +35,7 @@ export function flattenLeaderTree(
export function toNumberArray(values?: string[]) { export function toNumberArray(values?: string[]) {
if (!values || values.length === 0) return undefined if (!values || values.length === 0) return undefined
const numbers = values const numbers = values.map((v) => Number(v)).filter((v) => Number.isFinite(v))
.map((v) => Number(v))
.filter((v) => Number.isFinite(v))
return numbers.length > 0 ? numbers : undefined return numbers.length > 0 ? numbers : undefined
} }

View File

@@ -1,6 +1,9 @@
"use client" "use client"
import { getProjectList, getProjectTypeList } from "@/components/label/api/project" import {
getProjectList,
getProjectTypeList,
} from "@/components/label/api/project"
import { getTaskList } from "@/components/label/api/task" import { getTaskList } from "@/components/label/api/task"
import { Task } from "@/components/label/api/task/typing" import { Task } from "@/components/label/api/task/typing"
import TaskStatusTag from "@/components/label/components/TaskStatusTag" import TaskStatusTag from "@/components/label/components/TaskStatusTag"
@@ -18,7 +21,13 @@ import {
Text, Text,
} from "@mantine/core" } from "@mantine/core"
import { notifications } from "@mantine/notifications" import { notifications } from "@mantine/notifications"
import { IconChevronDown, IconChevronUp, IconDownload, IconRefresh, IconSearch } from "@tabler/icons-react" import {
IconChevronDown,
IconChevronUp,
IconDownload,
IconRefresh,
IconSearch,
} from "@tabler/icons-react"
import { DataTable, DataTableColumn } from "mantine-datatable" import { DataTable, DataTableColumn } from "mantine-datatable"
import { useEffect, useMemo, useState } from "react" import { useEffect, useMemo, useState } from "react"
import * as XLSX from "xlsx-js-style" import * as XLSX from "xlsx-js-style"
@@ -37,24 +46,25 @@ const emptyFilters = {
function toNumberArray(values?: string[]) { function toNumberArray(values?: string[]) {
if (!values || values.length === 0) return undefined if (!values || values.length === 0) return undefined
const arr = values const arr = values.map((v) => Number(v)).filter((v) => Number.isFinite(v))
.map((v) => Number(v))
.filter((v) => Number.isFinite(v))
return arr.length > 0 ? arr : undefined return arr.length > 0 ? arr : undefined
} }
export default function TaskListTable() { export default function TaskListTable() {
const treeData = useAllUserStore((s) => s.treeData) const treeData = useAllUserStore((s) => s.treeData)
const userOptions = useMemo(() => flattenLeaderTree(treeData ?? []), [treeData]) const userOptions = useMemo(
() => flattenLeaderTree(treeData ?? []),
[treeData]
)
const [collapsed, setCollapsed] = useState(true) const [collapsed, setCollapsed] = useState(true)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [projectTypeOpts, setProjectTypeOpts] = useState<Array<{ label: string; value: string }>>( const [projectTypeOpts, setProjectTypeOpts] = useState<
[] Array<{ label: string; value: string }>
) >([])
const [projectNameOpts, setProjectNameOpts] = useState<Array<{ label: string; value: string }>>( const [projectNameOpts, setProjectNameOpts] = useState<
[] Array<{ label: string; value: string }>
) >([])
const [filters, setFilters] = useState(emptyFilters) const [filters, setFilters] = useState(emptyFilters)
const [records, setRecords] = useState<Task.DataProps[]>([]) const [records, setRecords] = useState<Task.DataProps[]>([])
@@ -69,14 +79,18 @@ export default function TaskListTable() {
]) ])
if (typesRes.status === "fulfilled") { if (typesRes.status === "fulfilled") {
setProjectTypeOpts((typesRes.value ?? []).map((t) => ({ label: t, value: t }))) setProjectTypeOpts(
(typesRes.value ?? []).map((t) => ({ label: t, value: t }))
)
} else { } else {
setProjectTypeOpts([]) setProjectTypeOpts([])
} }
if (projectsRes.status === "fulfilled") { if (projectsRes.status === "fulfilled") {
const list = projectsRes.value?.project_list ?? [] const list = projectsRes.value?.project_list ?? []
setProjectNameOpts(list.map((p) => ({ label: p.name, value: String(p.id) }))) setProjectNameOpts(
list.map((p) => ({ label: p.name, value: String(p.id) }))
)
} else { } else {
setProjectNameOpts([]) setProjectNameOpts([])
} }
@@ -101,7 +115,8 @@ export default function TaskListTable() {
page_size: nextFilters.page_size, page_size: nextFilters.page_size,
get_data: false, get_data: false,
} }
if (nextFilters.project_type.length > 0) payload.project_type = nextFilters.project_type if (nextFilters.project_type.length > 0)
payload.project_type = nextFilters.project_type
if (nextFilters.project_id.length > 0) { if (nextFilters.project_id.length > 0) {
payload.project_id = toNumberArray(nextFilters.project_id) payload.project_id = toNumberArray(nextFilters.project_id)
} }
@@ -153,7 +168,10 @@ export default function TaskListTable() {
title: "状态", title: "状态",
width: 160, width: 160,
render: (record) => ( render: (record) => (
<TaskStatusTag status={record.label_status} rejected={record.rejected} /> <TaskStatusTag
status={record.label_status}
rejected={record.rejected}
/>
), ),
}, },
{ accessor: "current_username", title: "当前负责人", width: 120 }, { accessor: "current_username", title: "当前负责人", width: 120 },
@@ -214,8 +232,16 @@ export default function TaskListTable() {
width: 120, width: 120,
render: (record) => record.label_object_size?.second_comment_size ?? 0, render: (record) => record.label_object_size?.second_comment_size ?? 0,
}, },
{ accessor: "first_commit_label_time", title: "标注首次提交时间", width: 180 }, {
{ accessor: "first_commit_review1_time", title: "审核首次提交时间", width: 180 }, accessor: "first_commit_label_time",
title: "标注首次提交时间",
width: 180,
},
{
accessor: "first_commit_review1_time",
title: "审核首次提交时间",
width: 180,
},
{ accessor: "reject_times", title: "驳回次数", width: 100 }, { accessor: "reject_times", title: "驳回次数", width: 100 },
{ {
accessor: "label_work_time", accessor: "label_work_time",
@@ -329,7 +355,13 @@ export default function TaskListTable() {
variant="subtle" variant="subtle"
size="xs" size="xs"
radius="xs" radius="xs"
rightSection={collapsed ? <IconChevronDown size={14} /> : <IconChevronUp size={14} />} rightSection={
collapsed ? (
<IconChevronDown size={14} />
) : (
<IconChevronUp size={14} />
)
}
onClick={() => setCollapsed((v) => !v)}> onClick={() => setCollapsed((v) => !v)}>
{collapsed ? "展开筛选" : "收起筛选"} {collapsed ? "展开筛选" : "收起筛选"}
</Button> </Button>
@@ -387,10 +419,12 @@ export default function TaskListTable() {
label="任务状态" label="任务状态"
size="xs" size="xs"
radius="xs" radius="xs"
data={Array.from(TaskStatusEnum.entries()).map(([value, label]) => ({ data={Array.from(TaskStatusEnum.entries()).map(
label, ([value, label]) => ({
value: String(value), label,
}))} value: String(value),
})
)}
searchable searchable
clearable clearable
value={filters.label_status} value={filters.label_status}
@@ -445,7 +479,11 @@ export default function TaskListTable() {
</Stack> </Stack>
</Paper> </Paper>
<Paper withBorder p="sm" radius="sm" style={{ flex: 1, minHeight: 0, display: "flex" }}> <Paper
withBorder
p="sm"
radius="sm"
style={{ flex: 1, minHeight: 0, display: "flex" }}>
<DataTable<Task.DataProps> <DataTable<Task.DataProps>
withTableBorder withTableBorder
withRowBorders withRowBorders
@@ -453,7 +491,7 @@ export default function TaskListTable() {
records={records} records={records}
columns={columns} columns={columns}
noRecordsText="暂无数据" noRecordsText="暂无数据"
rowKey="id" idAccessor="id"
scrollAreaProps={{ type: "auto" }} scrollAreaProps={{ type: "auto" }}
style={{ width: "100%" }} style={{ width: "100%" }}
/> />
@@ -472,7 +510,9 @@ export default function TaskListTable() {
<Text size="sm">{totalSize?.question_size ?? 0}</Text> <Text size="sm">{totalSize?.question_size ?? 0}</Text>
<Text size="sm">{totalSize?.review_size ?? 0}</Text> <Text size="sm">{totalSize?.review_size ?? 0}</Text>
<Text size="sm">(1){totalSize?.first_comment_size ?? 0}</Text> <Text size="sm">(1){totalSize?.first_comment_size ?? 0}</Text>
<Text size="sm">(2){totalSize?.second_comment_size ?? 0}</Text> <Text size="sm">
(2){totalSize?.second_comment_size ?? 0}
</Text>
</Group> </Group>
</Paper> </Paper>
</Stack> </Stack>

View File

@@ -21,7 +21,12 @@ import {
} from "mantine-datatable" } from "mantine-datatable"
import { useEffect, useMemo, useState } from "react" import { useEffect, useMemo, useState } from "react"
import * as XLSX from "xlsx-js-style" import * as XLSX from "xlsx-js-style"
import { DimensionType, GroupedData, MetricColumn, dimensionOpts } from "./config" import {
DimensionType,
GroupedData,
MetricColumn,
dimensionOpts,
} from "./config"
function emptyGroupedData(): GroupedData { function emptyGroupedData(): GroupedData {
return { return {
@@ -42,8 +47,12 @@ export default function WorkloadMetricsTable(props: {
}) { }) {
const { title, sheetName, fileName, metrics, fetchData } = props const { title, sheetName, fileName, metrics, fetchData } = props
const [startDate, setStartDate] = useState(dayjs().subtract(1, "day").format("YYYY-MM-DD")) const [startDate, setStartDate] = useState(
const [endDate, setEndDate] = useState(dayjs().subtract(1, "day").format("YYYY-MM-DD")) dayjs().subtract(1, "day").format("YYYY-MM-DD")
)
const [endDate, setEndDate] = useState(
dayjs().subtract(1, "day").format("YYYY-MM-DD")
)
const [dimension, setDimension] = useState<DimensionType>("all") const [dimension, setDimension] = useState<DimensionType>("all")
const [data, setData] = useState<GroupedData>(emptyGroupedData()) const [data, setData] = useState<GroupedData>(emptyGroupedData())
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
@@ -152,14 +161,18 @@ export default function WorkloadMetricsTable(props: {
{ accessor: "user_name", title: "用户名", width: 120 }, { accessor: "user_name", title: "用户名", width: 120 },
{ accessor: "group_name", title: "用户组", width: 160 }, { accessor: "group_name", title: "用户组", width: 160 },
], ],
order_by_group_name: [{ accessor: "group_name", title: "用户组", width: 180 }], order_by_group_name: [
{ accessor: "group_name", title: "用户组", width: 180 },
],
order_by_project_name: [ order_by_project_name: [
{ accessor: "project_name", title: "项目名称", width: 220 }, { accessor: "project_name", title: "项目名称", width: 220 },
], ],
order_by_project_type: [ order_by_project_type: [
{ accessor: "project_type", title: "项目类型", width: 220 }, { accessor: "project_type", title: "项目类型", width: 220 },
], ],
order_by_user_name: [{ accessor: "user_name", title: "用户名", width: 180 }], order_by_user_name: [
{ accessor: "user_name", title: "用户名", width: 180 },
],
} }
return allCols[dimension] return allCols[dimension]
}, [dimension]) }, [dimension])
@@ -319,7 +332,11 @@ export default function WorkloadMetricsTable(props: {
</SimpleGrid> </SimpleGrid>
</Paper> </Paper>
<Paper withBorder p="sm" radius="sm" style={{ flex: 1, minHeight: 0, display: "flex" }}> <Paper
withBorder
p="sm"
radius="sm"
style={{ flex: 1, minHeight: 0, display: "flex" }}>
<DataTable<any> <DataTable<any>
withTableBorder withTableBorder
withRowBorders withRowBorders
@@ -327,7 +344,7 @@ export default function WorkloadMetricsTable(props: {
records={sortedRecords} records={sortedRecords}
columns={columns} columns={columns}
noRecordsText="暂无数据" noRecordsText="暂无数据"
rowKey={rowKey as any} idAccessor={rowKey as any}
scrollAreaProps={{ type: "auto" }} scrollAreaProps={{ type: "auto" }}
style={{ width: "100%" }} style={{ width: "100%" }}
sortStatus={sortStatus} sortStatus={sortStatus}

View File

@@ -1,11 +1,11 @@
import httpFetch from "@/api/fetch" import httpFetch from "@/api/fetch"
import { BASE_LABEL_API } from "../const"
import { import {
LabelResult, LabelResult,
LoginInfo, LoginInfo,
RequestLabelResult, RequestLabelResult,
ServerResponse, ServerResponse,
} from "./typing" } from "./typing"
import { BASE_LABEL_API } from "../const"
// 获取标注结果 // 获取标注结果
export const getLabelResult = (task_id: number) => { export const getLabelResult = (task_id: number) => {
@@ -31,7 +31,7 @@ export const saveLabelResult = (data: RequestLabelResult) => {
export const getServerImage = async (data: { export const getServerImage = async (data: {
data_names: string[] data_names: string[]
/** /**
* 0-图片 1-点云 * 0-图片 1-点云 2-视频
*/ */
data_type: number data_type: number
flag?: number flag?: number

View File

@@ -58,7 +58,8 @@ export const newSyncTask = (data: {
// 更新同步任务状态 // 更新同步任务状态
export const updateSyncTaskStatus = (id: number, status: number) => { export const updateSyncTaskStatus = (id: number, status: number) => {
return httpFetch({ return httpFetch({
url: BASE_LABEL_API + `/api/v1/label_server/data_sync/update_sync_task/${id}`, url:
BASE_LABEL_API + `/api/v1/label_server/data_sync/update_sync_task/${id}`,
method: "PUT", method: "PUT",
body: JSON.stringify({ status }), body: JSON.stringify({ status }),
}) })