可正常启用

This commit is contained in:
戚辰先生 2024-12-01 17:42:19 +08:00
parent a133dbbfad
commit 4baf9d271b
4 changed files with 126 additions and 88 deletions

View File

@ -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="部门描述"

View File

@ -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');

View File

@ -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

View File

@ -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