You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 lines
13 KiB
JavaScript

import React from 'react';
import {
DeleteOutlined,
EditOutlined,
PlusOutlined,
SearchOutlined,
RedoOutlined,
DownOutlined,
ExclamationCircleFilled,
UpOutlined,
InfoCircleFilled,
QuestionCircleFilled,
DownloadOutlined
} from '@ant-design/icons';
import {connect, history} from '@umijs/max';
import {Button, Card, Divider, Dropdown, message, Modal, Popconfirm, Space, Switch, Tag, Row, Col, Tree} from 'antd';
import StandardTable from '@/components/StandardTable';
import { MyIcon } from "@/components/Icon"
import style from "@/global.less";
import styles from './SystemMenuList.less';
import datadictionary from "@/utils/dataDictionary";
import {formatDate} from "@/utils/formatUtils";
import { formatDictText, checkButtonAuthority } from "@/utils/globalCommon";
const { confirm } = Modal;
// 菜单类型
const menu_type = datadictionary.menu_type || [];
const menu_status = datadictionary.menu_status || [];
const menu_level = datadictionary.menu_level || [];
const mockData = {
list: [
{
id: '1',
name: '效率管理',
code: 'hrefficiency',
type: '1',
level: '1',
status: '1',
path: '/topnavbar00/hrefficiency',
component: '',
icon: 'setting',
createTime: '2023-01-01 10:00:00',
createUser: 'admin',
children: [
{
id: '2',
name: '工时仪表盘',
code: 'timesheet',
type: '2',
level: '2',
status: '1',
path: '/topnavbar00/hrefficiency/timesheet',
component: './hrefficiency_timesheet/TimeSheetList',
icon: 'dashboard',
createTime: '2023-01-01 10:05:00',
createUser: 'admin'
},
{
id: '3',
name: '员工仪表盘',
code: 'staffsheet',
type: '2',
level: '2',
status: '1',
path: '/topnavbar00/hrefficiency/staffsheet',
component: './hrefficiency_staffsheet/StaffSheetList',
icon: 'user',
createTime: '2023-01-01 10:10:00',
createUser: 'admin'
}
]
},
{
id: '4',
name: '系统管理',
code: 'system',
type: '1',
level: '1',
status: '1',
path: '/topnavbar00/hrefficiency/system',
component: './nav_system_content/SystemContentList',
icon: 'control',
createTime: '2023-01-02 14:30:00',
createUser: 'admin'
}
],
pagination: {
total: 2,
pageSize: 10,
current: 1
}
};
@connect(({ systemMenu }) => ({
systemMenu
}))
export default class SystemMenuList extends React.Component {
state = {
selectedRows: [],
advancedFormVisible: false,
filterData: {},
pagination: {
pageSize: 10,
current: 1
},
tableData: mockData.list,
treeData: [],
expandedKeys: []
};
componentDidMount() {
this.getMenuList();
this.buildTreeData();
}
// 获取菜单列表
getMenuList = () => {
const { dispatch } = this.props;
const { pagination, filterData } = this.state;
try {
dispatch({
type: 'systemMenu/fetchList',
payload: {
pageNum: pagination.current,
pageSize: pagination.pageSize,
...filterData
},
callback: (res) => {
this.setState({
tableData: res?.list || mockData.list,
pagination: {
...pagination,
total: res?.total || mockData.pagination.total
}
}, () => {
this.buildTreeData();
});
}
});
} catch (error) {
console.error('获取菜单列表失败:', error);
this.setState({
tableData: mockData.list,
pagination: mockData.pagination
}, () => {
this.buildTreeData();
});
}
};
// 构建树数据
buildTreeData = () => {
const { tableData } = this.state;
const treeData = this.transformToTree(tableData);
this.setState({ treeData });
};
// 转换为树结构
transformToTree = (data) => {
return data.map(item => {
const node = {
title: item.name,
key: item.id,
dataRef: item
};
if (item.children && item.children.length > 0) {
node.children = this.transformToTree(item.children);
}
return node;
});
};
// 表格选择变化
handleSelectChange = (selectedRowKeys, selectedRows) => {
this.setState({ selectedRows });
};
// 分页变化
handleTableChange = (pagination) => {
this.setState({
pagination: {
...this.state.pagination,
current: pagination.current
}
}, () => {
this.getMenuList();
});
};
// 新增菜单
handleAdd = () => {
// 新增逻辑
message.success('新增菜单功能');
};
// 编辑菜单
handleEdit = (record) => {
// 编辑逻辑
message.success('编辑菜单功能');
};
// 删除菜单
handleDelete = (record) => {
confirm({
title: '确定要删除这个菜单吗?',
icon: <ExclamationCircleFilled />,
onOk: () => {
// 删除逻辑
message.success('删除菜单成功');
}
});
};
// 批量删除
handleBatchDelete = () => {
const { selectedRows } = this.state;
if (selectedRows.length === 0) {
message.warning('请选择要删除的菜单');
return;
}
confirm({
title: `确定要删除选中的${selectedRows.length}个菜单吗?`,
icon: <ExclamationCircleFilled />,
onOk: () => {
// 批量删除逻辑
message.success('批量删除菜单成功');
}
});
};
// 启用/禁用菜单
handleStatusChange = (record) => {
const newStatus = record.status === '1' ? '0' : '1';
confirm({
title: `确定要${newStatus === '1' ? '启用' : '禁用'}这个菜单吗?`,
icon: <ExclamationCircleFilled />,
onOk: () => {
// 状态变更逻辑
message.success(`${newStatus === '1' ? '启用' : '禁用'}菜单成功`);
}
});
};
// 展开/折叠树节点
handleExpand = (expandedKeys) => {
this.setState({ expandedKeys });
};
// 点击树节点
handleTreeSelect = (selectedKeys, info) => {
// 树节点选择逻辑
console.log('Selected', selectedKeys, info);
};
render() {
const { selectedRows, tableData, pagination, treeData, expandedKeys } = this.state;
const columns = [
{
title: '菜单名称',
dataIndex: 'name',
key: 'name',
ellipsis: true
},
{
title: '菜单编码',
dataIndex: 'code',
key: 'code',
ellipsis: true
},
{
title: '菜单类型',
dataIndex: 'type',
key: 'type',
render: text => formatDictText(menu_type, text)
},
{
title: '菜单级别',
dataIndex: 'level',
key: 'level',
render: text => formatDictText(menu_level, text)
},
{
title: '路径',
dataIndex: 'path',
key: 'path',
ellipsis: true
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
render: text => (
<Tag color={text === '1' ? 'green' : 'red'}>
{text === '1' ? '启用' : '禁用'}
</Tag>
)
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
ellipsis: true
},
{
title: '创建人',
dataIndex: 'createUser',
key: 'createUser',
ellipsis: true
},
{
title: '操作',
key: 'action',
fixed: 'right',
width: 160,
render: (_, record) => (
<Space size="middle">
<Button
type="link"
size="small"
icon={<EditOutlined />}
onClick={() => this.handleEdit(record)}
>
编辑
</Button>
<Button
type="link"
size="small"
danger
icon={<DeleteOutlined />}
onClick={() => this.handleDelete(record)}
>
删除
</Button>
<Switch
checked={record.status === '1'}
onChange={() => this.handleStatusChange(record)}
/>
</Space>
)
}
];
return (
<div className={style.contentWrapper}>
<Card className={style.contentCard}>
<div className={styles.header}>
<div className={styles.headerLeft}>
<h2 className={styles.title}>菜单配置</h2>
</div>
<div className={styles.headerRight}>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={this.handleAdd}
>
新增菜单
</Button>
<Button
danger
style={{ marginLeft: 8 }}
onClick={this.handleBatchDelete}
disabled={selectedRows.length === 0}
>
批量删除
</Button>
</div>
</div>
<Divider />
<div className={styles.menuContent}>
<div className={styles.menuTreeSection}>
<h3 className={styles.sectionTitle}>菜单树</h3>
<div className={styles.menuTree}>
<Tree
treeData={treeData}
expandedKeys={expandedKeys}
onExpand={this.handleExpand}
onSelect={this.handleTreeSelect}
className={styles.tree}
/>
</div>
</div>
<Divider />
<StandardTable
rowKey="id"
selectedRows={selectedRows}
data={{
list: tableData,
pagination
}}
columns={columns}
onSelectRow={this.handleSelectChange}
onChange={this.handleTableChange}
/>
</div>
</Card>
</div>
);
}
}