import React, { useEffect, useState } from 'react'; import styles from './style/sideBar.module.less'; import { IconApps } from '@arco-design/web-react/icon'; import { menuData1, menuData2 } from './config/menuData'; import { ResizeBox, Tree } from '@arco-design/web-react'; import { Selected } from '@/pages/ideContainer/types'; import { useDispatch, useSelector } from 'react-redux'; import { updateMenuData } from '@/store/ideContainer'; import { getProjectEnv } from '@/api/apps'; import _ from 'lodash'; const TreeNode = Tree.Node; interface MenuItemType { title: string; key?: string; children?: MenuItemType[]; path?: string; icon?: React.ReactNode; [key: string]: string | MenuItemType[] | React.ReactNode; } interface SideBarProps { subMenuData: any; selectedKey?: string; identity?: string; onMenuSelect?: (selected: Selected) => void; } const compTypeMap = { appComponent: '普通组件', subComponent: '复合组件' }; const SideBar: React.FC = ({ selectedKey, identity, subMenuData, onMenuSelect }) => { const [menu, setMenu] = useState([]); const [subMenuWidth, setSubMenuWidth] = useState(200); // 子菜单宽度状态 const [isSubMenuCollapsed, setIsSubMenuCollapsed] = useState(false); // 子菜单收起状态 const [activeKey, setActiveKey] = useState(0); const [mainMenuSelectedKey, setMainMenuSelectedKey] = useState(''); const { menuData } = useSelector(state => state.ideContainer); const dispatch = useDispatch(); function getMenuData(): MenuItemType[] { switch (identity) { case 'scene': const menuData = _.cloneDeep(menuData1); const newSubMenuData = _.cloneDeep(subMenuData); const subMenuKey = Object.keys(newSubMenuData)[0]; const subMenuValue: any = Object.values(newSubMenuData)[0]; const menuIndex = menuData.findIndex(v => v.key === subMenuKey); // 构建数据结构,这是目录默认需要的数据结构 subMenuValue.forEach(v => { v.title = v.name; v.key = `compFlow-${v.id}`; v.path = 'compFlow'; v.parentKey = menu[activeKey]?.key; v.children = [ { title: '事件', children: null }, { title: '组件列表', children: null } ]; }); menuData[menuIndex]['children'] = subMenuValue; dispatch(updateMenuData({ 'scene': menuData })); return menuData; case 'componentDevelopment' : dispatch(updateMenuData({ 'componentDevelopment': menuData2 })); return menuData2; default: return menuData1; } } // 处理子菜单区域的拖拽调整大小 const handleSubMenuResize = (e: MouseEvent, { width }: { width: number }) => { setSubMenuWidth(width); }; // 切换子菜单区域的收起/展开状态 const toggleSubMenu = () => { setIsSubMenuCollapsed(!isSubMenuCollapsed); setSubMenuWidth(isSubMenuCollapsed ? 200 : 0); }; // 处理菜单项点击事件 const handleMenuItemClick = (item: MenuItemType, index: number) => { setActiveKey(index); // 如果点击的是当前已激活的菜单项,则切换子菜单的展开/收起状态 if (selectedKey === `${item.key}`) { toggleSubMenu(); } else { // 如果点击的是其他菜单项,则展开子菜单(如果已收起) if (isSubMenuCollapsed) { setIsSubMenuCollapsed(false); setSubMenuWidth(200); } } const mainMenuKey = `${item.key}`; setMainMenuSelectedKey(mainMenuKey); // 调用外部传入的菜单选择处理函数 onMenuSelect?.({ ...item }); }; const getProjectEnvData = async (data) => { if (!data.path || !data.key) return; const parentKey = menu[activeKey]?.key; const currentMenu = _.cloneDeep(menuData[identity]); const index = currentMenu.findIndex(v => v.key === parentKey); const res: any = await getProjectEnv(data.id); if (res.code === 200) { const children = currentMenu[index].children.find(v => v.id === data.id); children.children[0].children = res.data.events.map(item => { return { title: item, children: null }; }); children.children[1].children = Object.keys(res.data.compList).map(item => { return { title: compTypeMap[item], children: res.data.compList[item].map(item => { return { title: item, children: null }; }) }; }); // 更新 menuData 中的数据 dispatch(updateMenuData({ ...menuData, [identity]: currentMenu })); // 同时更新本地 menu 状态以触发重新渲染 setMenu(prevMenu => { const newMenu = [...prevMenu]; newMenu[activeKey] = { ...newMenu[activeKey], children: currentMenu[index].children }; return newMenu; }); } }; // 渲染子菜单 const renderMenuItems = (menuItems?: MenuItemType[], parentKey = '0') => { if (menuItems && menuItems.length) { return menuItems.map((item, index) => { const key = `${parentKey}-${index}`; const treeNodeProps = { title: item.title, key: key, dataRef: item // 传递原始数据,包含 path、key 等信息 }; if (item.children && item.children.length > 0) { return ( {renderMenuItems(item.children, key)} ); } else { return ; } }); } return null; }; useEffect(() => { setMainMenuSelectedKey(selectedKey); }, [selectedKey]); useEffect(() => { setMenu(getMenuData()); }, [subMenuData]); return (
{menu.map((item, index) => (
handleMenuItemClick(item, index)} >
{item.icon || } {item.title}
))}
{ const selectedNode = info.node; const originalData = selectedNode.props.dataRef; getProjectEnvData(originalData); // 保持主菜单的选中状态 const mainMenuKey = `${menu[activeKey]?.key}`; setMainMenuSelectedKey(mainMenuKey); // 调用外部传入的菜单选择处理函数 originalData.key && onMenuSelect?.({ ...originalData } as Selected); }} > {renderMenuItems(menu[activeKey]?.children)}
); }; export default SideBar;