import { type Key, useEffect, useState } from "react" import { Avatar, Button, DatePicker, Form, Input, Select, Space, Table, Tag, Tree, type TreeDataNode, Typography, } from "antd" import { App } from "antd" import { type AxiosError } from "axios" import { getCountries, getCountryCallingCode } from "libphonenumber-js" import { DeptApi, UserApi } from "@/api" import { PhoneNumberUtils, DepartmentUtils } from "@/utils" import { DeleteOutlined, EditOutlined, ExportOutlined, ImportOutlined, KeyOutlined, PlusOutlined, SearchOutlined, UndoOutlined, } from "@ant-design/icons" import AddUserDialogue from "@/components/add-user-dialogue" import EditUserDialogue from "@/components/edit-user-dialogue" import type { QueryUserRequest } from "@/types/web/request" import type { QueryUserForm, UserFormValues } from "@/types/form" import type { GeneralErrorResponse, UserDetailResponse } from "@/types/web/response" import type { Department } from "@/types/entity" import type { TreeNode } from "@/types/tree" import { useAppSelector } from "@/store" export default function UserPage() { const { message, modal } = App.useApp() const user = useAppSelector((state) => state.auth.user!) const [queryForm] = Form.useForm() const [addUserForm] = Form.useForm() const [editUserForm] = Form.useForm() const [department, setDepartment] = useState>() const [departmentTree, setDepartmentTree] = useState([]) const [selectedDepartment, setSelectedDepartment] = useState(1) const [users, setUsers] = useState([]) const [pageNum, setPageNum] = useState(1) const [totalElementCount, setTotalElementCount] = useState(0) const [pageSize, setPageSize] = useState(10) const onAddUserFinish = async () => { try { const values = await addUserForm.validateFields() await UserApi.addUser(values) void message.success(`用户 ${values.username} 创建成功`) return true } catch (error: unknown) { console.log(error) if (error instanceof Error && error.message.includes("Validation Failed")) { return false } const err = error as AxiosError void message.error(err.response?.data.message ?? "创建失败,请稍后再试") return false } } const handleAddUser = () => { modal .confirm({ title: "添加用户", content: , width: 600, onOk: onAddUserFinish, }) .then( () => { const formValues = queryForm.getFieldsValue() queryUsers(pageNum, pageSize, selectedDepartment!, formValues) }, () => { console.error("用户取消添加用户") } ) } const onEditUserFinish = async () => { try { const values = await editUserForm.validateFields() await UserApi.editUser(values) void message.success(`用户更新成功`) return true } catch (error: unknown) { if (error instanceof Error && error.message.includes("Validation Failed")) { return false } const err = error as AxiosError void message.error(err.response?.data.message ?? "更新失败,请稍后再试") return false } } const handleEditUser = (user: UserDetailResponse) => { modal .confirm({ title: `编辑用户: ${user.username}`, content: , width: 600, onOk: onEditUserFinish, }) .then( () => { const formValues = queryForm.getFieldsValue() queryUsers(pageNum, pageSize, selectedDepartment, formValues) }, () => { console.error("用户取消添加用户") } ) } const handleDeleteUser = (user: UserDetailResponse) => { const isLastElementOnPage = users.length === 1 && pageNum > 1 modal.confirm({ title: ( <> 确认删除用户 {user.username} 吗? ), content: "删除后数据将无法恢复。", okText: "删除", cancelText: "取消", okButtonProps: { danger: true }, onOk: async () => { try { await UserApi.deleteUser(user.id) void message.success(`用户 ${user.username} 删除成功`) setTotalElementCount((count) => count - 1) if (isLastElementOnPage) { setPageNum((prevPage) => prevPage - 1) } else { queryUsers(pageNum, pageSize, selectedDepartment, queryForm.getFieldsValue()) } } catch (error: unknown) { const err = error as AxiosError void message.error(err.response?.data.message ?? "删除失败,请稍后再试") } }, }) } // Query users const queryUsers = ( pageNum: number, pageSize: number, departmentId: number, formValues: QueryUserForm | null ) => { const queryUserRequest: QueryUserRequest = { createdAtEnd: null, createdAtStart: null, phoneNumber: null, regionAbbreviation: null, status: null, username: null, pageNum, pageSize, departmentId, } if (formValues && formValues.qUsername) { queryUserRequest.username = formValues.qUsername } if (formValues && formValues.qRegionAbbreviation) { queryUserRequest.regionAbbreviation = formValues.qRegionAbbreviation } if (formValues && formValues.qPhoneNumber) { queryUserRequest.phoneNumber = formValues.qPhoneNumber } if (formValues && formValues.qStatus) { queryUserRequest.status = formValues.qStatus } if (formValues && formValues.qCreatedAtStart) { queryUserRequest.createdAtStart = formValues.qCreatedAtStart.format("YYYY-MM-DD HH:mm:ss") } if (formValues && formValues.qCreatedAtEnd) { queryUserRequest.createdAtEnd = formValues.qCreatedAtEnd.format("YYYY-MM-DD HH:mm:ss") } console.log(`queryUsers ==> `, queryUserRequest) UserApi.fetchUsers(queryUserRequest) .then((userResponse) => { console.log(userResponse) setUsers(userResponse.content) setPageNum(userResponse.pageable.pageNumber + 1) setPageSize(userResponse.pageable.pageSize) setTotalElementCount(userResponse.totalElements) }) .catch((error: unknown) => { const err = error as AxiosError void message.error(err.response?.data.message ?? "发生未知错误,请稍后再试") }) } useEffect(() => { DeptApi.fetchDepartmentTree() .then((departmentResponse) => { setDepartment(departmentResponse) setDepartmentTree(DepartmentUtils.transformDepartmentData([departmentResponse])) }) .catch((error: unknown) => { const err = error as AxiosError void message.error(err.response?.data.message ?? "发生未知错误,请稍后再试") }) }, []) useEffect(() => { const formValues = queryForm.getFieldsValue() queryUsers(pageNum, pageSize, selectedDepartment, formValues) }, [pageNum, pageSize, selectedDepartment]) const regionOptions = getCountries().map((country) => { const callingCode = getCountryCallingCode(country) return { label: `${country} (+${callingCode})`, value: country, key: country, } }) const userStatusOptions = [ { label: "已启用", value: "ACTIVE", key: "ACTIVE", }, { label: "已停用", value: "INACTIVE", key: "INACTIVE", }, { label: "已禁用", value: "LOCKED", key: "LOCKED", }, ] return (
{ if (typeof selectedKey == "number") { setSelectedDepartment(selectedKey) } }} selectedKeys={[selectedDepartment]} />
className="mt-0 mb-6" form={queryForm} layout="inline" labelAlign="right" onFinish={(values) => { console.log("Query User Form ==> ", values) queryUsers(pageNum, pageSize, Number(selectedDepartment), values) }} onReset={() => { queryUsers(pageNum, pageSize, Number(selectedDepartment), null) }}> label="用户名" name="qUsername"> label="用户状态" name="qStatus"> noStyle name="qPhoneNumber"> name="qCreatedAtStart"> name="qCreatedAtEnd"> rowKey="id" dataSource={users} pagination={{ current: pageNum, total: totalElementCount, pageSize: pageSize, defaultCurrent: 1, defaultPageSize: 10, pageSizeOptions: [10, 25, 50], showSizeChanger: true, onShowSizeChange: (pageNum, pageSize) => { console.log(`onSizeChange ==> pageNum = ${pageNum}, pageSize = ${pageSize}`) setPageNum(pageNum) setPageSize(pageSize) }, onChange: (pageNum, pageSize) => { console.log(`onChange ==> pageNum = ${pageNum}, pageSize = ${pageSize}`) setPageNum(pageNum) setPageSize(pageSize) }, }} columns={[ { title: "用户 ID", dataIndex: "id" }, { title: "用户名称", dataIndex: "username" }, { title: "姓名", dataIndex: "fullName" }, { title: "电子邮箱", dataIndex: "email" }, { title: "联系电话", render: (user: UserDetailResponse) => { return PhoneNumberUtils.formatInternationalPhoneNumber( user.regionAbbreviation, user.phoneNumber ) }, key: "phoneNumber", }, { title: "头像", render: (user: UserDetailResponse) => { return }, key: "avatarUrl", }, { title: "用户状态", render: (user: UserDetailResponse) => { const colour = user.status == "ACTIVE" ? "green" : "red" return ( {user.status} ) }, key: "status", }, { title: "所在部门", dataIndex: "departmentName" }, { title: "用户岗位", dataIndex: "positionName" }, { title: "操作", render: (value: UserDetailResponse) => { return String(value.id) == String(user.id) ? ( <> ) : ( ) }, }, ]} />
) }