import { Alert, Button, Card, type CardProps, Col, message, Popconfirm, Row, Space, Table, type TableProps, Tag, Tree, type TreeDataNode, type TreeProps, Typography } from "antd"; import {BankOutlined, DeleteOutlined, PlusOutlined, TeamOutlined, UserOutlined} from "@ant-design/icons"; import {useEffect, useRef, useState} from "react"; import {queryDept, createDept, updateDept, deleteDept, deptUsers} from "@/api/system/sys_dept.ts"; import type {ISysDept} from "@/domain/iSysDept.ts"; import {isArray, omit} from 'lodash'; import type {FormColumn} from "@/components/XinFormField/FieldRender/typings.ts"; import XinForm, {type XinFormRef} from "@/components/XinForm"; import * as React from "react"; import {useTranslation} from "react-i18next"; import AuthButton from "@/components/AuthButton"; import useAuth from "@/hooks/useAuth.ts"; import type ISysUser from "@/domain/iSysUser.ts"; const deptMap = new Map(); interface TableParams { page: number; pageSize: number; total: number; } const Dept = () => { const {t} = useTranslation(); const {auth} = useAuth(); /** 部门信息表单 */ const formRef = useRef>(null); /** 新增表单 */ const modalFormRef = useRef>(null); /** 当前选中的部门 key */ const [selectKey, setSelectKey] = useState(''); /** 当前(多选框)选择的部门 keys */ const [checkedKeys , setCheckedKeys] = useState([]); /** 标签页 KEY */ const [tabKey, setTabKey] = useState('info'); /** 标签页 Tab */ const tabList: CardProps['tabList'] = [ { key: 'info', label: t("system.dept.tab.info") }, { key: 'users', label: t("system.dept.tab.users"), disabled: !auth("system.dept.users") }, ]; /** 部门数据 */ const [deptData, setDeptData] = useState([]); /** 部门用户列表数据 */ const [users, setUsers] = useState([]); /** 部门用户列表表格参数 */ const [tableParams, setTableParams] = useState({ page: 1, pageSize: 10, total: 0 }); /** 加载状态 */ const [loading, setLoading] = useState(false); const [tableLoading, setTableLoading] = useState(false); /** 获取部门用户列表 */ const selectUsers = async (id: number, params?: TableParams) => { try { setTableLoading(true); const data = await deptUsers(id, omit(params || tableParams, 'total')); setUsers(data.data.data!.data); setTableParams({ ...tableParams, total: data.data.data!.total }) } finally { setTableLoading(false); } } /** 刷新部门数据 */ const refreshDept = async () => { setLoading(true); /** 转换部门类型 */ const convertDeptToTreeData = (depts: ISysDept[]): TreeDataNode[] => { if (!depts?.length) return []; return depts.map(dept => { deptMap.set(dept.id!.toString(), omit(dept, 'children')); return { title: dept.name || t("system.dept.tab.users"), key: dept.id?.toString() || '', icon: dept.type === 0 ? : dept.type === 1 ? : , children: convertDeptToTreeData(dept.children || []) } }); }; try { const res = await queryDept(); if(res.data.data && res.data.data.length > 0) { deptMap.clear(); setDeptData(convertDeptToTreeData(res.data.data)); if(!selectKey || !deptMap.has(selectKey)) { setSelectKey(res.data.data[0].id!.toString()); formRef.current?.setFieldsValue(omit(res.data.data[0], 'children')); if(auth("system.dept.users")) { await selectUsers(res.data.data[0].id!); } } } } finally { setLoading(false); } }; /** 新增部门点击事件 */ const addChange = (children: boolean = false) => { modalFormRef.current?.resetFields(); modalFormRef.current?.setFieldsValue({ parent_id: children ? Number(selectKey) : 0, sort: 0, status: 0, type: 0 }) modalFormRef.current?.open(); } /** 部门选择事件 */ const onSelect: TreeProps['onSelect'] = (key) => { if(key && key.length >= 1) { setSelectKey(key[0].toString()); const deptInfo = deptMap.get(key[0].toString()); if (deptInfo) { formRef.current?.setFieldsValue(deptInfo); } selectUsers(Number(key[0])).then(); } } /** 部门多选框选中事件 */ const onCheck: TreeProps['onCheck'] = (checkedKeys) => { if(isArray(checkedKeys)) { setCheckedKeys(checkedKeys); }else { setCheckedKeys(checkedKeys.checked); } } /** 表单提交 */ const onSubmit = async (data: ISysDept, update: boolean = false) => { try { setLoading(true); if(!update) { await createDept(data); message.success(t("system.dept.createSuccess")); modalFormRef.current?.close(); }else { await updateDept(Number(selectKey), data); message.success(t("system.dept.updateSuccess")); } await refreshDept(); }finally { setLoading(false); } } /** 批量删除 */ const onDeleteConfirm = async () => { try { setLoading(true); await deleteDept(checkedKeys); await refreshDept(); setCheckedKeys([]); message.success(t("system.dept.deleteSuccess")); }finally { setLoading(false); } } /** 表单列数据 */ const columns: FormColumn[] = [ { title: t("system.dept.column.name"), valueType: 'text', dataIndex: 'name', rules: [{required: true, message: t("system.dept.column.name.required")}], }, { title: t("system.dept.column.code"), valueType: 'text', dataIndex: 'code', rules: [{required: true, message: t("system.dept.column.code.required")}], }, { title: t("system.dept.column.type"), valueType: 'radioButton', dataIndex: 'type', fieldProps: { options: [ { value: 0, label: t("system.dept.column.type.0") }, { value: 1, label: t("system.dept.column.type.1") }, { value: 2, label: t("system.dept.column.type.2") }, ], }, rules: [{required: true, message: t("system.dept.column.type.required")}], }, { title: t("system.dept.column.parent"), valueType: 'treeSelect', dataIndex: 'parent_id', fieldProps: { treeData: [ { title: t("system.dept.column.parent.0"), value: 0, children: deptData } ], fieldNames: { label: 'title', value: 'key' }, disabled: true }, rules: [{required: true, message: t("system.dept.column.parent.required")}], }, { title: t("system.dept.column.email"), valueType: 'text', dataIndex: 'email', }, { title: t("system.dept.column.address"), valueType: 'text', dataIndex: 'address', }, { title: t("system.dept.column.phone"), valueType: 'text', dataIndex: 'phone', }, { title: t("system.dept.column.sort"), valueType: 'digit', dataIndex: 'sort', rules: [{required: true, message: t("system.dept.column.sort.required")}], }, { title: t("system.dept.column.status"), valueType: 'radioButton', dataIndex: 'status', fieldProps: { options: [ { value: 0, label: t("system.dept.column.status.0") }, { value: 1, label: t("system.dept.column.status.1") }, ] }, rules: [{required: true, message: t("system.dept.column.status.required")}], }, { title: t("system.dept.column.remark"), valueType: 'textarea', dataIndex: 'remark', }, ]; /** 部门用户列表表格列 */ const usersColumns: TableProps['columns'] = [ { title: t("system.dept.users.column.id"), dataIndex: 'id', key: 'id', align: 'center', }, { title: t("system.dept.users.column.username"), dataIndex: 'username', key: 'username', align: 'center', }, { title: t("system.dept.users.column.nickname"), dataIndex: 'nickname', key: 'nickname', align: 'center', }, { title: t("system.dept.users.column.nickname"), dataIndex: 'email', key: 'email', align: 'center', }, { title: t("system.dept.users.column.mobile"), dataIndex: 'mobile', key: 'mobile', align: 'center', }, { title: t("system.dept.users.column.status"), dataIndex: 'status', key: 'status', align: 'center', render: (value) => ( <> {value === 1 && {t("system.dept.users.column.status.0")}} {value === 0 && {t("system.dept.users.column.status.1")}} ) }, ]; /** 初始化 */ useEffect(() => { refreshDept() }, []); return ( <>
{t("system.dept.page.title")} {t("system.dept.page.description")}
layoutType={'ModalForm'} formRef={modalFormRef} modalProps={{ title: t("system.dept.createModalTitle"), styles: { body: { paddingTop: 20} }, width: 800 }} onFinish={async (data: ISysDept) => { await onSubmit(data, false); return true; }} columns={columns} layout={'vertical'} grid rowProps={{gutter: [30, 0]}} colProps={{ span: 12 }} /> onDeleteConfirm()} >