289 lines
8.1 KiB
TypeScript
289 lines
8.1 KiB
TypeScript
"use client"
|
||
|
||
import { getUserList, userEditById } from "@/components/label/api/user"
|
||
import { User } from "@/components/label/api/user/typing"
|
||
import useAuth from "@/components/label/hooks/useAuth"
|
||
import { useAllUserStore } from "@/components/label/store/auth"
|
||
import {
|
||
ActionIcon,
|
||
Badge,
|
||
Button,
|
||
Group,
|
||
Paper,
|
||
Stack,
|
||
Text,
|
||
TextInput,
|
||
} from "@mantine/core"
|
||
import { modals } from "@mantine/modals"
|
||
import { notifications } from "@mantine/notifications"
|
||
import { IconEdit, IconRefresh, IconSearch } from "@tabler/icons-react"
|
||
import { DataTable, DataTableColumn } from "mantine-datatable"
|
||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||
import CreateUserModal from "./components/CreateUserModal"
|
||
import EditUserModal from "./components/EditUserModal"
|
||
import ImportModal from "./components/ImportModal"
|
||
|
||
export default function TeamEmployeePage() {
|
||
const { isShow } = useAuth()
|
||
const setFlag = useAllUserStore((s) => s.setFlag)
|
||
|
||
const [name, setName] = useState("")
|
||
const [appliedName, setAppliedName] = useState("")
|
||
const [records, setRecords] = useState<User.UserInfo[]>([])
|
||
const [loading, setLoading] = useState(false)
|
||
const [totalItems, setTotalItems] = useState(0)
|
||
const [page, setPage] = useState(1)
|
||
const [pageSize, setPageSize] = useState(20)
|
||
|
||
const [createOpened, setCreateOpened] = useState(false)
|
||
const [editOpened, setEditOpened] = useState(false)
|
||
const [importOpened, setImportOpened] = useState(false)
|
||
const [selectedUser, setSelectedUser] = useState<User.UserInfo | null>(null)
|
||
|
||
const load = useCallback(async () => {
|
||
try {
|
||
setLoading(true)
|
||
const params: User.ListRequest = {
|
||
page_number: page,
|
||
page_size: pageSize,
|
||
}
|
||
if (appliedName.trim()) params.name = appliedName.trim()
|
||
const res = await getUserList(params)
|
||
setRecords(res?.user_list ?? [])
|
||
setTotalItems(res?.total_items ?? 0)
|
||
} catch (e) {
|
||
setRecords([])
|
||
setTotalItems(0)
|
||
notifications.show({
|
||
color: "red",
|
||
title: "加载失败",
|
||
message: e instanceof Error ? e.message : "请求失败",
|
||
})
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}, [appliedName, page, pageSize])
|
||
|
||
useEffect(() => {
|
||
queueMicrotask(load)
|
||
}, [load])
|
||
|
||
const columns = useMemo(() => {
|
||
const cols: DataTableColumn<User.UserInfo>[] = [
|
||
{ accessor: "uid", title: "UID", width: 120, textAlign: "center" },
|
||
{ accessor: "name", title: "姓名", width: 120, textAlign: "center" },
|
||
{
|
||
accessor: "work_status",
|
||
title: "状态",
|
||
width: 100,
|
||
textAlign: "center",
|
||
render: (record) =>
|
||
record.work_status === 1 ? (
|
||
<Badge color="green" variant="light">
|
||
在职
|
||
</Badge>
|
||
) : (
|
||
<Badge color="gray" variant="light">
|
||
离职
|
||
</Badge>
|
||
),
|
||
},
|
||
{
|
||
accessor: "group_name",
|
||
title: "组织",
|
||
width: 180,
|
||
textAlign: "center",
|
||
},
|
||
{
|
||
accessor: "base_city",
|
||
title: "所在地",
|
||
width: 180,
|
||
textAlign: "center",
|
||
},
|
||
{
|
||
accessor: "operation",
|
||
title: "操作",
|
||
width: 220,
|
||
textAlign: "center",
|
||
render: (record) => (
|
||
<Group justify="center" gap={4} wrap="nowrap">
|
||
{isShow("edit") ? (
|
||
<Button
|
||
variant="subtle"
|
||
size="compact-xs"
|
||
onClick={() => {
|
||
modals.openConfirmModal({
|
||
title: "重置密码",
|
||
centered: true,
|
||
children: (
|
||
<Text size="sm">是否确定重置当前用户密码为 123456?</Text>
|
||
),
|
||
labels: { confirm: "确定", cancel: "取消" },
|
||
onConfirm: async () => {
|
||
await userEditById({ password: "123456" }, record.uid)
|
||
notifications.show({
|
||
color: "green",
|
||
title: "操作成功",
|
||
message: "已重置密码",
|
||
})
|
||
},
|
||
})
|
||
}}>
|
||
重置密码
|
||
</Button>
|
||
) : null}
|
||
{isShow("edit") ? (
|
||
<ActionIcon
|
||
variant="subtle"
|
||
color="blue"
|
||
onClick={() => {
|
||
setSelectedUser(record)
|
||
setEditOpened(true)
|
||
}}>
|
||
<IconEdit size={16} />
|
||
</ActionIcon>
|
||
) : null}
|
||
</Group>
|
||
),
|
||
},
|
||
]
|
||
return cols
|
||
}, [isShow])
|
||
|
||
return (
|
||
<Stack w="100%" h="calc(100vh - 56px)" p="md" gap="md">
|
||
<Paper
|
||
withBorder
|
||
p="md"
|
||
radius="md"
|
||
style={{
|
||
borderColor:
|
||
"light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
|
||
}}>
|
||
<Group justify="space-between" wrap="wrap">
|
||
<Group>
|
||
<TextInput
|
||
placeholder="请输入姓名"
|
||
size="xs"
|
||
radius="xs"
|
||
value={name}
|
||
onChange={(e) => setName(e.currentTarget.value)}
|
||
/>
|
||
<Button
|
||
size="xs"
|
||
radius="xs"
|
||
leftSection={<IconSearch size={16} />}
|
||
onClick={() => {
|
||
setAppliedName(name)
|
||
setPage(1)
|
||
}}>
|
||
查询
|
||
</Button>
|
||
<Button
|
||
variant="default"
|
||
size="xs"
|
||
radius="xs"
|
||
leftSection={<IconRefresh size={16} />}
|
||
onClick={() => {
|
||
setName("")
|
||
setAppliedName("")
|
||
setPage(1)
|
||
setPageSize(20)
|
||
}}>
|
||
重置
|
||
</Button>
|
||
</Group>
|
||
{/* <Group>
|
||
{isShow("add") ? (
|
||
<Button
|
||
size="xs"
|
||
radius="xs"
|
||
leftSection={<IconPlus size={16} />}
|
||
onClick={() => setCreateOpened(true)}>
|
||
新增用户
|
||
</Button>
|
||
) : null}
|
||
{isShow("add") ? (
|
||
<Button
|
||
size="xs"
|
||
radius="xs"
|
||
variant="default"
|
||
leftSection={<IconUpload size={16} />}
|
||
onClick={() => setImportOpened(true)}>
|
||
批量导入
|
||
</Button>
|
||
) : null}
|
||
</Group> */}
|
||
</Group>
|
||
</Paper>
|
||
|
||
<Paper
|
||
withBorder
|
||
p="md"
|
||
radius="md"
|
||
style={{
|
||
borderColor:
|
||
"light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
|
||
flex: 1,
|
||
minHeight: 0,
|
||
display: "flex",
|
||
}}>
|
||
<DataTable<User.UserInfo>
|
||
withTableBorder
|
||
withRowBorders
|
||
fetching={loading}
|
||
records={records}
|
||
columns={columns}
|
||
noRecordsText="暂无数据"
|
||
totalRecords={totalItems}
|
||
recordsPerPage={pageSize}
|
||
page={page}
|
||
onPageChange={setPage}
|
||
onRecordsPerPageChange={(v) => {
|
||
setPageSize(v)
|
||
setPage(1)
|
||
}}
|
||
recordsPerPageOptions={[10, 20, 50, 100]}
|
||
scrollAreaProps={{ type: "auto" }}
|
||
style={{ width: "100%" }}
|
||
/>
|
||
</Paper>
|
||
|
||
<CreateUserModal
|
||
opened={createOpened}
|
||
onCloseAction={(refresh) => {
|
||
setCreateOpened(false)
|
||
if (refresh) {
|
||
setFlag(true)
|
||
load()
|
||
}
|
||
}}
|
||
/>
|
||
|
||
<ImportModal
|
||
opened={importOpened}
|
||
onCloseAction={(refresh) => {
|
||
setImportOpened(false)
|
||
if (refresh) {
|
||
setFlag(true)
|
||
load()
|
||
}
|
||
}}
|
||
/>
|
||
|
||
<EditUserModal
|
||
opened={editOpened}
|
||
data={selectedUser}
|
||
onCloseAction={(refresh) => {
|
||
setEditOpened(false)
|
||
setSelectedUser(null)
|
||
if (refresh) {
|
||
setFlag(true)
|
||
load()
|
||
}
|
||
}}
|
||
/>
|
||
</Stack>
|
||
)
|
||
}
|