feat(team): add page
This commit is contained in:
288
app/management/team/employee/page.tsx
Normal file
288
app/management/team/employee/page.tsx
Normal file
@@ -0,0 +1,288 @@
|
||||
"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, IconPlus, IconRefresh, IconSearch, IconUpload } 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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user