You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xgd_system/src/layouts/LeftMenuTree/index.tsx

207 lines
6.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { FC, useEffect, useRef, useState } from 'react';
import styles from './index.less';
import { history, useLocation, useParams } from 'umi';
import { Menu, Tree } from 'antd';
interface PageProps {
data: Array<{
// 菜单名称
name: string;
// 是否展开
check: boolean;
// 内容是否有目录结构
isTree?: boolean;
// 菜单列表 name: 名称; url: 路由; img: 图标;
data: Array<{ name: string; url: string; img: any; }>
}>;
}
const LeftMenuCom: FC<PageProps> = ({ data }) => {
const [list, setList] = useState<any>([]);
const route = useLocation();
const urlParams = useParams();
const [selectedKeys, setSelectedKeys] = useState<any>([]);
const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
const [showContextMenu, setShowContextMenu] = useState(false);
const treeRef = useRef(null);
const [menuItems, setMenuItems] = useState<any>([]);
useEffect(() => {
menuItemsConfig();
data.forEach((item, index) => {
// 默认展开第一个
// item.check = (index == 0 ? true : false);
// 默认全部展开
item.check = true;
if (item?.isTree) setSelectedKeys([urlParams?.id])
})
setList([...data])
const handleClickOutside = (e: any) => {
if (treeRef.current && !treeRef.current.contains(e.target)) {
// 点击了 MyTree 组件以外的地方,隐藏菜单
setShowContextMenu(false);
}
};
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, [])
const menuItemsConfig = () => {
if (`/registerManage/deviceRegister/${urlParams?.id}` == route?.pathname) {
setMenuItems([
{key: '1', label: '删除'},
{key: '2', label: '刷新'},
])
}else if (`/registerManage/unitLocation/${urlParams?.id}` == route?.pathname) {
setMenuItems([
{key: '1', label: '修改'},
{key: '2', label: '刷新'},
{key: '3', label: '新建'},
{key: '4', label: '删除'}
])
}
}
const handleRightClick = (e: any, node: any) => {
if (node?.isFolder) return
e.preventDefault();
setContextMenuPosition({ x: e.clientX, y: e.clientY }); // 记录右键菜单位置
setSelectedKeys([node.key]); // 根据节点设置选中的 keys
setShowContextMenu(true); // 显示右键菜单
};
const handleSelect = (selectedKeys: any, name: any) => {
if (selectedKeys.length == 0) return;
setSelectedKeys(selectedKeys);
switch (name) {
case '设备注册':
history.push(`/registerManage/deviceRegister/${selectedKeys[0]}`)
break;
case '单位位置管理':
history.push(`/registerManage/unitLocation/${selectedKeys[0]}`)
break;
}
};
const handleContextMenuClick = (e: any) => {
setShowContextMenu(false); // 隐藏右键菜单
};
const treeData = [
{
title: 'Parent 1',
key: '0-1',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 1',
key: '0-1-1',
},
{
title: 'Child 2',
key: '0-1-2',
},
],
},
{
title: 'Parent 2',
key: '0-2',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 3',
key: '0-2-1',
},
{
title: 'Child 4',
key: '0-2-2',
},
],
},
];
return (
<div>
{list.map((item: any, index: number) => {
return (
<div key={index}>
{/* 类型 */}
<div className={styles.menu_item} onClick={() => {
list[index].check = !list[index].check;
setList([...list])
}}>
<div>{item.name}</div>
<div className={styles.triangle} style={{ transform: list[index].check ? 'rotate(90deg)' : '' }}></div>
</div>
{/* 列表 */}
<div className={styles.item_warp} style={{ display: list[index].check ? 'block' : 'none' }}>
{
item?.isTree ?
// 树结构
<div>
<Tree
style={{ padding: 20 }}
onContextMenu={(e) => e.preventDefault()}
onRightClick={({ event, node }) => handleRightClick(event, node)}
onSelect={(e) => { handleSelect(e, item.name) }}
selectedKeys={selectedKeys}
treeData={treeData}
blockNode={true}
defaultExpandAll={true}
/>
{showContextMenu && (
<div ref={treeRef}>
<Menu
style={{
zIndex: 99,
width: 111,
position: 'absolute',
left: contextMenuPosition.x,
top: contextMenuPosition.y,
boxShadow: '0px 4px 8px 0px rgba(156, 172, 180, 0.5)'
}}
mode="vertical"
onClick={handleContextMenuClick}
items={menuItems}
/>
</div>
)}
</div> :
// 列表item
item.data.map((item1: any, index1: number) => {
return (
<div className={styles.item1} key={index1} onClick={() => {
setSelectedKeys([])
history.push(item1.url)
}}>
<div className={styles.item1_img}></div>
<div className={styles.item1_name} style={{ color: (route.pathname == item1.url ? 'red' : '') }}>
{item1.name}
</div>
</div>
)
})
}
</div>
</div>
)
})}
</div >
)
}
export default LeftMenuCom