feat(ideContainer): 新增组件开发相关功能

- 新增组件列表、组件审核、组件编码、组件部署、组件测试等功能菜单- 实现 URL 参数解析,根据身份展示不同菜单
- 优化侧边栏菜单,根据身份动态加载菜单项
- 重构 IDEContainer 组件,支持新功能
master
钟良源 6 months ago
parent 774a9b29fb
commit f3fdf25e03

@ -34,4 +34,42 @@ export const menuData = [
children: null, children: null,
path: 'globalVar' path: 'globalVar'
} }
];
export const menuData2 = [
{
title: '组件列表',
children: [
{
title: '我的组件',
children: null,
path: 'myComponents'
},
{
title: '协同组件',
children: null,
path: 'matchingComponents'
},
{
title: '组件审核',
children: null,
path: 'componentReview'
}
]
},
{
title: '组件编码',
children: null,
path: 'componentCoding'
},
{
title: '组件部署',
children: null,
path: 'componentDeployment'
},
{
title: '组件测试',
children: null,
path: 'componentTest'
}
]; ];

@ -1,24 +1,40 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import styles from './style/index.module.less'; import styles from './style/index.module.less';
import SideBar from './sideBar'; import SideBar from './sideBar';
import LogBar from './logBar'; import LogBar from './logBar';
import RightSideBar from './rightSideBar'; import RightSideBar from './rightSideBar';
import { getUrlParams } from '@/utils/common';
interface Selected { interface Selected {
currentPath?: string; currentPath?: string;
currentKey?: string; currentKey?: string;
} }
// 假设您有这些组件 type UrlParamsOptions = {
identity?: string;
[key: string]: string
};
const AppFlowComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>; const AppFlowComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const CompListComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>; const CompListComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const AppInstanceComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>; const AppInstanceComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const EventComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>; const EventComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const GlobalVarComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>; const GlobalVarComponent = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const MyComponents = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const MatchingComponents = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const ComponentReview = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const ComponentCoding = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const ComponentDeployment = () => <div style={{ height: '70vh', width: '100%' }}></div>;
const ComponentTest = () => <div style={{ height: '70vh', width: '100%' }}></div>;
function IDEContainer() { function IDEContainer() {
const [selected, setSelected] = useState<Selected>({}); const [selected, setSelected] = useState<Selected>({});
const [urlParams, setUrlParams] = useState<UrlParamsOptions>({});
useEffect(() => {
setUrlParams(getUrlParams(window.location.href) as UrlParamsOptions);
}, []);
// 根据选中的菜单项渲染对应组件 // 根据选中的菜单项渲染对应组件
const renderContent = () => { const renderContent = () => {
@ -33,8 +49,20 @@ function IDEContainer() {
return <EventComponent />; return <EventComponent />;
case 'globalVar': case 'globalVar':
return <GlobalVarComponent />; return <GlobalVarComponent />;
case 'myComponents':
return <MyComponents />;
case 'matchingComponents':
return <MatchingComponents />;
case 'componentReview':
return <ComponentReview />;
case 'componentCoding':
return <ComponentCoding />;
case 'componentDeployment':
return <ComponentDeployment />;
case 'componentTest':
return <ComponentTest />;
default: default:
return <AppFlowComponent />; return <div></div>;
} }
}; };
return ( return (
@ -43,12 +71,13 @@ function IDEContainer() {
<SideBar <SideBar
onMenuSelect={(select) => setSelected(select)} onMenuSelect={(select) => setSelected(select)}
selectedKey={selected.currentKey} selectedKey={selected.currentKey}
identity={urlParams.identity}
/> />
<div className={styles.content}> <div className={styles.content}>
<div className={styles.mainContent}> <div className={styles.mainContent}>
{renderContent()} {renderContent()}
</div> </div>
<LogBar></LogBar> {urlParams.identity !== 'componentDevelopment' && <LogBar></LogBar>}
</div> </div>
<RightSideBar></RightSideBar> <RightSideBar></RightSideBar>

@ -1,11 +1,11 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import styles from './style/sideBar.module.less'; import styles from './style/sideBar.module.less';
import { Layout, Menu } from '@arco-design/web-react'; import { Layout, Menu } from '@arco-design/web-react';
import { IconApps, IconMenuFold, IconMenuUnfold } from '@arco-design/web-react/icon'; import { IconApps, IconMenuFold, IconMenuUnfold } from '@arco-design/web-react/icon';
import { GlobalState } from '@/store'; import { GlobalState } from '@/store';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import getUrlParams from '@/utils/getUrlParams'; import getUrlParams from '@/utils/getUrlParams';
import { menuData } from './config/menuData'; import { menuData, menuData2 } from './config/menuData';
const Sider = Layout.Sider; const Sider = Layout.Sider;
@ -21,11 +21,13 @@ interface MenuItemType {
interface SideBarProps { interface SideBarProps {
onMenuSelect?: ({ currentPath, currentKey }) => void; onMenuSelect?: ({ currentPath, currentKey }) => void;
selectedKey?: string; selectedKey?: string;
identity?: string;
} }
const SideBar: React.FC<SideBarProps> = ({ onMenuSelect, selectedKey }) => { const SideBar: React.FC<SideBarProps> = ({ onMenuSelect, selectedKey, identity }) => {
const urlParams = getUrlParams(); const urlParams = getUrlParams();
const [collapsed, setCollapsed] = useState<boolean>(false); const [collapsed, setCollapsed] = useState<boolean>(false);
const [menu, setMenu] = useState([]);
const { userInfo, settings, userLoading } = useSelector( const { userInfo, settings, userLoading } = useSelector(
(state: GlobalState) => state (state: GlobalState) => state
); );
@ -40,6 +42,21 @@ const SideBar: React.FC<SideBarProps> = ({ onMenuSelect, selectedKey }) => {
setCollapsed((collapsed) => !collapsed); setCollapsed((collapsed) => !collapsed);
} }
function getMenuData(): MenuItemType[] {
switch (identity) {
case 'scene':
return menuData;
case 'componentDevelopment' :
return menuData2;
default:
return menuData;
}
}
useEffect(() => {
setMenu(getMenuData());
}, [identity]);
// 递归渲染菜单项 // 递归渲染菜单项
const renderMenuItems = (items: MenuItemType[], parentKey = '') => { const renderMenuItems = (items: MenuItemType[], parentKey = '') => {
return items.map((item, index) => { return items.map((item, index) => {
@ -81,7 +98,7 @@ const SideBar: React.FC<SideBarProps> = ({ onMenuSelect, selectedKey }) => {
<Menu <Menu
selectedKeys={selectedKey ? [selectedKey] : ['0']} selectedKeys={selectedKey ? [selectedKey] : ['0']}
> >
{renderMenuItems(menuData)} {renderMenuItems(menu)}
</Menu> </Menu>
{/*<div className={styles['collapse-btn']} onClick={toggleCollapse}>*/} {/*<div className={styles['collapse-btn']} onClick={toggleCollapse}>*/}
{/* {collapsed ? <IconMenuUnfold /> : <IconMenuFold />}*/} {/* {collapsed ? <IconMenuUnfold /> : <IconMenuFold />}*/}

@ -148,7 +148,6 @@ function PageLayout({ children }: { children: ReactNode }) {
function renderRoutes(locale) { function renderRoutes(locale) {
return function travel(_routes: IRoute[], level, parentNode = []) { return function travel(_routes: IRoute[], level, parentNode = []) {
return _routes.map((route) => { return _routes.map((route) => {
console.log('route:', route);
const { ignore } = route; const { ignore } = route;
const iconDom = getIconFromKey(route.key); const iconDom = getIconFromKey(route.key);
const titleDom = ( const titleDom = (

@ -2,6 +2,7 @@ import React, { useState } from 'react';
import style from './style/engineering.module.less'; import style from './style/engineering.module.less';
import { Input, Grid, Card, Result, Pagination } from '@arco-design/web-react'; import { Input, Grid, Card, Result, Pagination } from '@arco-design/web-react';
import { IconPlus, IconApps } from '@arco-design/web-react/icon'; import { IconPlus, IconApps } from '@arco-design/web-react/icon';
import { openWindow, OpenWindowOptions } from '@/utils/common';
const InputSearch = Input.Search; const InputSearch = Input.Search;
const Row = Grid.Row; const Row = Grid.Row;
@ -27,8 +28,13 @@ const Engineering: React.FC<EngineeringProps> = ({ dataType, showAdd = true }) =
}; };
const openEngineHandle = (index: number) => { const openEngineHandle = (index: number) => {
const ideUrl = '/ideContainer?menu=false'; const url = `/ideContainer`;
window.open(ideUrl, '_blank'); const params: OpenWindowOptions = {
target: '_blank',
menu: false,
identity: 'scene'
};
openWindow(url, params);
}; };
return ( return (

@ -23,6 +23,33 @@ export function openWindow(url: string, opts?: OpenWindowOptions) {
window.open(fullUrl, target); window.open(fullUrl, target);
} }
/**
* URL
* @param url - URL
* @param key -
* @returns
*/
export function getUrlParams(url: string, key?: string): Record<string, string> | string | object | null {
try {
const urlObj = new URL(url, window.location.origin);
const params = new URLSearchParams(urlObj.search);
if (key) {
return params.get(key);
}
const result: Record<string, string> = {};
params.forEach((value, key) => {
result[key] = value;
});
return result;
} catch (error) {
console.error('解析URL失败:', error);
return key ? null : {};
}
}
// 格式化实例类型 // 格式化实例类型
export function formatInstanceType(value: string): string { export function formatInstanceType(value: string): string {
switch (value) { switch (value) {

Loading…
Cancel
Save