From 74e09e170efbe54bb58eee5151f46c37f96d983a Mon Sep 17 00:00:00 2001 From: ZLY Date: Tue, 23 Sep 2025 14:05:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(ideContainer):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84=E5=B9=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8A=A8=E6=80=81=E5=BA=94=E7=94=A8=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 store 中的 selected 字段替换为 info,用于存储完整的 URL 参数信息- 调整 menuData 的结构以支持 identity 区分不同菜单 - 引入 getAppListBySceneId 接口,根据场景 ID 动态获取应用列表 - 修改 SideBar 组件逻辑,支持构建带子菜单的树形结构 - 更新 tab 切换逻辑,使用 key 替代 path 作为唯一标识- 移除无用的 ResizeBox 导入,优化代码结构 --- src/pages/ideContainer/config/menuData.ts | 2 +- src/pages/ideContainer/index.tsx | 56 +++++++++++++---------- src/pages/ideContainer/navBar.tsx | 11 +++-- src/pages/ideContainer/sideBar.tsx | 33 +++++++++++-- src/pages/scene/engineering.tsx | 4 +- src/store/ideContainer.ts | 14 +++--- 6 files changed, 78 insertions(+), 42 deletions(-) diff --git a/src/pages/ideContainer/config/menuData.ts b/src/pages/ideContainer/config/menuData.ts index 0df5c22..bd337e3 100644 --- a/src/pages/ideContainer/config/menuData.ts +++ b/src/pages/ideContainer/config/menuData.ts @@ -1,4 +1,4 @@ -export const menuData = [ +export const menuData1 = [ { title: '应用列表', path: '', diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index 9603378..090426b 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useState } from 'react'; -import { ResizeBox } from '@arco-design/web-react'; import { getUrlParams } from '@/utils/common'; import styles from './style/index.module.less'; import SideBar from './sideBar'; @@ -8,8 +7,12 @@ import RightSideBar from './rightSideBar'; import NavBar from './navBar'; import ProjectContainer from '@/pages/orchestration/project'; import ApplicationContainer from '@/pages/orchestration/application'; -import { menuData, menuData2 } from './config/menuData'; +import { menuData1, menuData2 } from './config/menuData'; import { Selected } from '@/pages/ideContainer/types'; +import { updateInfo } from '@/store/ideContainer'; +import { useDispatch, useSelector } from 'react-redux'; +import { getAppListBySceneId } from '@/api/apps'; +import * as url from 'node:url'; type UrlParamsOptions = { identity?: string; @@ -41,11 +44,29 @@ function IDEContainer() { const [subMenuWidth, setSubMenuWidth] = useState(200); // 子菜单宽度状态 // 用于跟踪已打开的tab,保持组件状态 const [openedTabs, setOpenedTabs] = useState>(new Set()); + const [subMenuData, setSubMenuData] = useState({}); + const { menuData } = useSelector((state) => state.ideContainer); + const dispatch = useDispatch(); + + const getAppList = async () => { + const res: any = await getAppListBySceneId({ + pageSize: 999, + currPage: 1, + sceneId: urlParams.id + }); + if (res.code === 200) setSubMenuData({ 'appList': res.data.list }); + }; useEffect(() => { setUrlParams(getUrlParams(window.location.href) as UrlParamsOptions); + dispatch(updateInfo(getUrlParams(window.location.href) as UrlParamsOptions)); + }, []); + useEffect(() => { + if (urlParams.id) getAppList(); + }, [urlParams.id]); + // 当selected.path变化时,添加到已打开的tab集合中 useEffect(() => { if (selected.path) { @@ -122,37 +143,25 @@ function IDEContainer() { setSubMenuWidth(width); }; - // 根据identity获取对应的菜单数据 - const getCurrentMenuData = () => { - switch (urlParams.identity) { - case 'scene': - return menuData; - case 'componentDevelopment': - return menuData2; - default: - return menuData; - } - }; - // 处理tab切换 - const handleTabChange = (path: string) => { - if (path) { + const handleTabChange = (key: string) => { + if (key) { // 根据path查找对应的菜单项 - const findMenuItem = (menuItems: any[], path: string): any => { + const findMenuItem = (menuItems: any[], key: string): any => { for (const item of menuItems) { - if (item.path === path) { + if (item.key === key) { return item; } if (item.children) { - const found = findMenuItem(item.children, path); + const found = findMenuItem(item.children, key); if (found) return found; } } return null; }; - const menuItems = getCurrentMenuData(); - const menuItem = findMenuItem(menuItems, path); + const menuItems = menuData[urlParams.identity]; + const menuItem = findMenuItem(menuItems, key); if (menuItem) { setSelected({ @@ -184,16 +193,17 @@ function IDEContainer() { <>
setSelected(select)} selectedKey={selected.key} identity={urlParams.identity} + subMenuData={subMenuData} + onMenuSelect={(select) => setSelected(select)} />
{/*顶部导航栏*/} diff --git a/src/pages/ideContainer/navBar.tsx b/src/pages/ideContainer/navBar.tsx index 93bd615..91f3489 100644 --- a/src/pages/ideContainer/navBar.tsx +++ b/src/pages/ideContainer/navBar.tsx @@ -40,25 +40,26 @@ const NavBar: React.FC = ({ selected, menuData, onTabChange, onTabC useEffect(() => { if (selected?.path) { const path = selected.path; + const key = selected.key; const title = selected.title; // 检查tab是否已存在 - const existingTab = tabs.find(tab => tab.path === path && tab.title === title); + const existingTab = tabs.find(tab => tab.key === key && tab.title === title); if (!existingTab) { // 创建新tab const title = menuData ? findMenuTitle(selected, menuData, path) : path; const newTab = { - key: path, + key: key, title: title, path: path }; setTabs(prev => [...prev, newTab]); - setActiveTab(path); + setActiveTab(key); } else { // 如果tab已存在,激活它 - setActiveTab(path); + setActiveTab(key); } } }, [selected, menuData]); @@ -86,7 +87,7 @@ const NavBar: React.FC = ({ selected, menuData, onTabChange, onTabC // 查找对应的tab并通知父组件 const tab = tabs.find(t => t.key === key); if (tab) { - onTabChange?.(tab.path); + onTabChange?.(tab.key); } }; diff --git a/src/pages/ideContainer/sideBar.tsx b/src/pages/ideContainer/sideBar.tsx index 28deaf3..3a4612b 100644 --- a/src/pages/ideContainer/sideBar.tsx +++ b/src/pages/ideContainer/sideBar.tsx @@ -1,9 +1,12 @@ import React, { useEffect, useState } from 'react'; import styles from './style/sideBar.module.less'; import { IconApps } from '@arco-design/web-react/icon'; -import { menuData, menuData2 } from './config/menuData'; +import { menuData1, menuData2 } from './config/menuData'; import { ResizeBox, Tree } from '@arco-design/web-react'; import { Selected } from '@/pages/ideContainer/types'; +import { useDispatch } from 'react-redux'; +import { updateMenuData } from '@/store/ideContainer'; +import _ from 'lodash'; const TreeNode = Tree.Node; @@ -13,29 +16,49 @@ interface MenuItemType { children?: MenuItemType[]; path?: string; icon?: React.ReactNode; + + [key: string]: string | MenuItemType[] | React.ReactNode; } interface SideBarProps { - onMenuSelect?: (selected: Selected) => void; + subMenuData: any; selectedKey?: string; identity?: string; + onMenuSelect?: (selected: Selected) => void; } -const SideBar: React.FC = ({ onMenuSelect, selectedKey, identity }) => { +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 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 = selectedKey; + v.children = null; + }); + menuData[menuIndex]['children'] = subMenuValue; + dispatch(updateMenuData({ 'scene': menuData })); return menuData; case 'componentDevelopment' : + dispatch(updateMenuData({ 'componentDevelopment': menuData2 })); return menuData2; default: - return menuData; + return menuData1; } } @@ -102,7 +125,7 @@ const SideBar: React.FC = ({ onMenuSelect, selectedKey, identity } useEffect(() => { setMenu(getMenuData()); - }, [identity]); + }, [subMenuData]); return (
= ({ dataType, showAdd = true }) = const params: OpenWindowOptions = { target: '_blank', menu: false, - identity: 'scene' + identity: 'scene', + id: item.id, + dataType }; openWindow(url, params); }; diff --git a/src/store/ideContainer.ts b/src/store/ideContainer.ts index 850874e..271f78f 100644 --- a/src/store/ideContainer.ts +++ b/src/store/ideContainer.ts @@ -1,14 +1,14 @@ import { createSlice } from '@reduxjs/toolkit'; interface IDEContainerState { - selected?: string; - menuData?: any[]; + info: any; + menuData: any; logBarStatus?: boolean; } const initialState: IDEContainerState = { - selected: '', - menuData: [], + info: {}, + menuData: {}, logBarStatus: false }; @@ -16,8 +16,8 @@ const ideContainerSlice = createSlice({ name: 'ideContainer', initialState, reducers: { - updateSelected(state, action) { - state.selected = action.payload; + updateInfo(state, action) { + state.info = action.payload; }, updateMenuData(state, action) { state.menuData = action.payload; @@ -28,6 +28,6 @@ const ideContainerSlice = createSlice({ } }); -export const { updateSelected, updateMenuData, updateLogBarStatus } = ideContainerSlice.actions; +export const { updateInfo, updateMenuData, updateLogBarStatus } = ideContainerSlice.actions; export default ideContainerSlice.reducer; \ No newline at end of file