| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import { fetchDeleteDept } from '@/services/dept';
- import { PageContainer } from '@ant-design/pro-components';
- import { useIntl } from '@umijs/max';
- import { Button, Empty, Popconfirm, Space, Spin, Tree, message } from 'antd';
- import type { DataNode } from 'antd/es/tree';
- import { DeptForm } from './components/Form';
- import { DeptUserTable } from './components/UserTable';
- import { useDeptPage } from './hooks/useDeptPage';
- export default function DeptPage() {
- const intl = useIntl();
- const {
- loading,
- treeData,
- selectedDeptId,
- setSelectedDeptId,
- selectedDeptIds,
- filteredUsers,
- loadData,
- productRolesBase,
- } = useDeptPage();
- const handleDelete = async (id: number) => {
- const res = await fetchDeleteDept({ id });
- if (!res.success) return;
- message.success('删除成功');
- if (selectedDeptId === id) setSelectedDeptId(undefined);
- loadData();
- };
- const renderTitle = (node: API.DeptItem) => (
- <Space>
- <span>{node.name}</span>
- <DeptForm
- mode="edit"
- initialValues={node}
- onSuccess={loadData}
- trigger={<a className="text-xs">编辑</a>}
- />
- <DeptForm
- mode="add"
- initialValues={{ parentId: node.id }}
- onSuccess={loadData}
- trigger={<a className="text-xs">新建子部门</a>}
- />
- <Popconfirm title="确认删除?" onConfirm={() => handleDelete(node.id)}>
- <a className="text-xs text-red-500">删除</a>
- </Popconfirm>
- </Space>
- );
- const renderNodes = (items: API.DeptItem[]): DataNode[] =>
- items.map((item) => ({
- key: item.id,
- title: renderTitle(item),
- children: item.children ? renderNodes(item.children) : undefined,
- }));
- return (
- <PageContainer title={intl.formatMessage({ id: 'admin.dept.title' })}>
- <div className="mb-4">
- <DeptForm
- mode="add"
- initialValues={{ parentId: 0 }}
- onSuccess={loadData}
- trigger={
- <Button type="primary">{intl.formatMessage({ id: 'admin.dept.createRoot' })}</Button>
- }
- />
- </div>
- <div className="flex gap-4">
- <div className="w-80 shrink-0 border border-gray-100 rounded p-3 bg-white">
- <Spin spinning={loading}>
- {treeData.length > 0 && (
- <Tree
- treeData={renderNodes(treeData)}
- defaultExpandAll
- showLine
- selectedKeys={selectedDeptId ? [selectedDeptId] : []}
- onSelect={(keys) => setSelectedDeptId(keys[0] as number | undefined)}
- />
- )}
- </Spin>
- </div>
- <div className="flex-1 min-w-0">
- {selectedDeptIds ? (
- <DeptUserTable users={filteredUsers} productRolesBase={productRolesBase} />
- ) : (
- <Empty description="请在左侧选择部门" className="py-16" />
- )}
- </div>
- </div>
- </PageContainer>
- );
- }
|