可正常启用
This commit is contained in:
parent
a133dbbfad
commit
4baf9d271b
@ -1,41 +1,55 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Table, Button, Modal, Form, Input, Space, InputNumber, Switch, TreeSelect, Select } from 'antd';
|
||||
import { Table, Button, Modal, Form, Input, Space, InputNumber, Switch, TreeSelect, Select, message } from 'antd';
|
||||
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import type { DepartmentResponse } from './types';
|
||||
import { useTableData } from '@/hooks/useTableData';
|
||||
import type { FixedType } from 'rc-table/lib/interface';
|
||||
import { getDepartmentTree } from './service';
|
||||
import type { UserResponse } from '@/pages/System/User/types';
|
||||
import { getUsers } from './service';
|
||||
import request from '@/utils/request';
|
||||
import type { FixedType } from 'rc-table/lib/interface';
|
||||
|
||||
interface TreeSelectNode {
|
||||
title: string;
|
||||
value: number;
|
||||
disabled?: boolean;
|
||||
children?: TreeSelectNode[];
|
||||
}
|
||||
|
||||
const DepartmentPage: React.FC = () => {
|
||||
const {
|
||||
list: departments,
|
||||
pagination,
|
||||
loading,
|
||||
loadData: fetchDepartments,
|
||||
handleCreate,
|
||||
handleUpdate,
|
||||
handleDelete
|
||||
} = useTableData({
|
||||
service: {
|
||||
baseUrl: '/api/v1/department'
|
||||
},
|
||||
defaultParams: {
|
||||
sortField: 'createTime',
|
||||
sortOrder: 'descend'
|
||||
}
|
||||
});
|
||||
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [editingDepartment, setEditingDepartment] = useState<DepartmentResponse | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [departmentTree, setDepartmentTree] = useState<DepartmentResponse[]>([]);
|
||||
const [users, setUsers] = useState<UserResponse[]>([]);
|
||||
const [modalVisible, setModalVisible] = useState(false);
|
||||
const [editingDepartment, setEditingDepartment] = useState<DepartmentResponse | null>(null);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
// 加载部门树数据
|
||||
const loadDepartmentTree = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getDepartmentTree();
|
||||
setDepartmentTree(response || []);
|
||||
} catch (error) {
|
||||
message.error('加载部门数据失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取扁平化的部门列表
|
||||
const getFlatDepartments = (departments: DepartmentResponse[]): DepartmentResponse[] => {
|
||||
return departments.reduce((acc, dept) => {
|
||||
acc.push(dept);
|
||||
if (dept.children?.length) {
|
||||
acc.push(...getFlatDepartments(dept.children));
|
||||
}
|
||||
return acc;
|
||||
}, [] as DepartmentResponse[]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
Promise.all([
|
||||
getDepartmentTree().then(setDepartmentTree),
|
||||
loadDepartmentTree(),
|
||||
getUsers().then(setUsers)
|
||||
]);
|
||||
}, []);
|
||||
@ -43,8 +57,10 @@ const DepartmentPage: React.FC = () => {
|
||||
const handleAdd = () => {
|
||||
setEditingDepartment(null);
|
||||
form.resetFields();
|
||||
// 获取当前最大排序值
|
||||
const maxSort = Math.max(0, ...departments.map(dept => dept.sort));
|
||||
|
||||
const allDepartments = getFlatDepartments(departmentTree);
|
||||
const maxSort = Math.max(0, ...allDepartments.map(dept => dept.sort));
|
||||
|
||||
form.setFieldsValue({
|
||||
enabled: true,
|
||||
sort: maxSort + 1
|
||||
@ -54,52 +70,67 @@ const DepartmentPage: React.FC = () => {
|
||||
|
||||
const handleEdit = (record: DepartmentResponse) => {
|
||||
setEditingDepartment(record);
|
||||
form.setFieldsValue(record);
|
||||
form.setFieldsValue({
|
||||
...record,
|
||||
parentId: record.parentId || undefined
|
||||
});
|
||||
setModalVisible(true);
|
||||
};
|
||||
|
||||
// 修改提交处理,确保更新后重新构建树形结构
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
const data = {
|
||||
...values,
|
||||
parentId: values.parentId || 0
|
||||
};
|
||||
|
||||
if (editingDepartment) {
|
||||
const success = await handleUpdate(editingDepartment.id, {
|
||||
...values,
|
||||
await request.put(`/api/v1/department/${editingDepartment.id}`, {
|
||||
...data,
|
||||
version: editingDepartment.version
|
||||
});
|
||||
if (success) {
|
||||
setModalVisible(false);
|
||||
fetchDepartments();
|
||||
getDepartmentTree().then(setDepartmentTree);
|
||||
}
|
||||
message.success('更新成功');
|
||||
} else {
|
||||
const success = await handleCreate(values);
|
||||
if (success) {
|
||||
setModalVisible(false);
|
||||
fetchDepartments();
|
||||
getDepartmentTree().then(setDepartmentTree);
|
||||
}
|
||||
await request.post('/api/v1/department', data);
|
||||
message.success('创建成功');
|
||||
}
|
||||
setModalVisible(false);
|
||||
loadDepartmentTree();
|
||||
} catch (error) {
|
||||
console.error('操作失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = (id: number) => {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '确定要删除该部门吗?',
|
||||
onOk: async () => {
|
||||
try {
|
||||
await request.delete(`/api/v1/department/${id}`);
|
||||
message.success('删除成功');
|
||||
loadDepartmentTree();
|
||||
} catch (error) {
|
||||
message.error('删除失败');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '部门名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 250,
|
||||
fixed: 'left' as FixedType,
|
||||
sorter: true
|
||||
fixed: 'left' as FixedType
|
||||
},
|
||||
{
|
||||
title: '部门编码',
|
||||
dataIndex: 'code',
|
||||
key: 'code',
|
||||
width: 120,
|
||||
sorter: true
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '部门描述',
|
||||
@ -112,8 +143,7 @@ const DepartmentPage: React.FC = () => {
|
||||
title: '排序',
|
||||
dataIndex: 'sort',
|
||||
key: 'sort',
|
||||
width: 80,
|
||||
sorter: true
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '负责人',
|
||||
@ -151,7 +181,7 @@ const DepartmentPage: React.FC = () => {
|
||||
danger
|
||||
icon={<DeleteOutlined/>}
|
||||
onClick={() => handleDelete(record.id)}
|
||||
disabled={record.children?.length > 0}
|
||||
disabled={Boolean(record.children?.length)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
@ -178,7 +208,6 @@ const DepartmentPage: React.FC = () => {
|
||||
size="middle"
|
||||
bordered
|
||||
defaultExpandAllRows
|
||||
indentSize={24}
|
||||
/>
|
||||
|
||||
<Modal
|
||||
@ -189,10 +218,26 @@ const DepartmentPage: React.FC = () => {
|
||||
width={600}
|
||||
destroyOnClose
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
>
|
||||
<Form form={form} layout="vertical">
|
||||
<Form.Item name="parentId" label="上级部门">
|
||||
<TreeSelect
|
||||
treeData={departmentTree.map(dept => ({
|
||||
title: dept.name,
|
||||
value: dept.id,
|
||||
disabled: editingDepartment?.id === dept.id,
|
||||
children: dept.children?.map(child => ({
|
||||
title: child.name,
|
||||
value: child.id,
|
||||
disabled: editingDepartment?.id === child.id
|
||||
}))
|
||||
}))}
|
||||
placeholder="不选择则为顶级部门"
|
||||
allowClear
|
||||
treeDefaultExpandAll
|
||||
disabled={Boolean(editingDepartment?.children?.length)}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="code"
|
||||
label="部门编码"
|
||||
@ -212,26 +257,6 @@ const DepartmentPage: React.FC = () => {
|
||||
<Input placeholder="请输入部门名称"/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="parentId"
|
||||
label="上级部门"
|
||||
>
|
||||
<TreeSelect
|
||||
treeData={departmentTree.map(dept => ({
|
||||
title: dept.name,
|
||||
value: dept.id,
|
||||
children: dept.children?.map(child => ({
|
||||
title: child.name,
|
||||
value: child.id
|
||||
}))
|
||||
}))}
|
||||
placeholder="请选择上级部门"
|
||||
allowClear
|
||||
treeDefaultExpandAll
|
||||
disabled={editingDepartment?.children?.length > 0}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="description"
|
||||
label="部门描述"
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import request from '@/utils/request';
|
||||
import type { Page } from '@/types/base/page';
|
||||
import type { DepartmentResponse, DepartmentRequest, DepartmentQuery } from './types';
|
||||
import {UserResponse} from "@/pages/System/User/types";
|
||||
|
||||
const BASE_URL = '/api/v1/department';
|
||||
|
||||
@ -25,6 +26,5 @@ export const deleteDepartment = (id: number) =>
|
||||
request.delete(`${BASE_URL}/${id}`);
|
||||
|
||||
// 获取用户列表(不分页)
|
||||
export const getUsers = () =>
|
||||
request.get<UserResponse[]>('/api/v1/user/list');
|
||||
export const getUsers = () => request.get<UserResponse[]>('/api/v1/user/list');
|
||||
|
||||
@ -79,7 +79,7 @@ const MenuPage: React.FC = () => {
|
||||
const result: MenuResponse[] = [];
|
||||
|
||||
menuList.forEach(menu => {
|
||||
menuMap.set(menu.id, { ...menu, children: [] });
|
||||
menuMap.set(menu.id, { ...menu });
|
||||
});
|
||||
|
||||
menuList.forEach(menu => {
|
||||
@ -88,7 +88,9 @@ const MenuPage: React.FC = () => {
|
||||
result.push(node);
|
||||
} else {
|
||||
const parent = menuMap.get(menu.parentId)!;
|
||||
parent.children = parent.children || [];
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
parent.children.push(node);
|
||||
}
|
||||
});
|
||||
@ -249,12 +251,11 @@ const MenuPage: React.FC = () => {
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
dataSource={menuTree}
|
||||
rowKey="id"
|
||||
scroll={{x: 1500}}
|
||||
rowKey={(record) => String(record.id)}
|
||||
pagination={false}
|
||||
size="middle"
|
||||
bordered
|
||||
indentSize={24}
|
||||
defaultExpandAllRows
|
||||
/>
|
||||
|
||||
<Modal
|
||||
|
||||
@ -9,6 +9,7 @@ import type {FixedType, AlignType, SortOrder} from 'rc-table/lib/interface';
|
||||
import {Response} from "@/utils/request.ts";
|
||||
import {TablePaginationConfig} from "antd/es/table";
|
||||
import {FilterValue, SorterResult} from "antd/es/table/interface";
|
||||
import { getDepartmentTree } from '../Department/service'; // 导入部门树接口
|
||||
|
||||
const UserPage: React.FC = () => {
|
||||
const {
|
||||
@ -103,11 +104,24 @@ const UserPage: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const getTreeData = (deps: DepartmentDTO[]): any[] => {
|
||||
return deps.map(dept => ({
|
||||
const loadDepartmentTree = async () => {
|
||||
try {
|
||||
const data = await getDepartmentTree();
|
||||
setDepartments(data);
|
||||
} catch (error) {
|
||||
message.error('加载部门数据失败');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadDepartmentTree();
|
||||
}, []);
|
||||
|
||||
const getTreeData = (departments: DepartmentDTO[]) => {
|
||||
return departments.map(dept => ({
|
||||
title: dept.name,
|
||||
value: dept.id,
|
||||
children: dept.children && dept.children.length > 0 ? getTreeData(dept.children) : undefined
|
||||
children: dept.children ? getTreeData(dept.children) : undefined
|
||||
}));
|
||||
};
|
||||
|
||||
@ -331,16 +345,14 @@ const UserPage: React.FC = () => {
|
||||
>
|
||||
<Input placeholder="请输入手机号"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="deptId"
|
||||
label="所属部门"
|
||||
>
|
||||
<Form.Item name="departmentId" label="所属部门">
|
||||
<TreeSelect
|
||||
treeData={getTreeData(departments)}
|
||||
placeholder="请选择所属部门"
|
||||
allowClear
|
||||
treeDefaultExpandAll
|
||||
style={{width: '100%'}}
|
||||
showSearch
|
||||
treeNodeFilterProp="title"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
|
||||
Loading…
Reference in New Issue
Block a user