diff --git a/src/pages/layout.tsx b/src/pages/layout.tsx index bc082b0..8d617d2 100644 --- a/src/pages/layout.tsx +++ b/src/pages/layout.tsx @@ -25,6 +25,7 @@ import { GlobalState } from '@/store'; import getUrlParams from '@/utils/getUrlParams'; import styles from '@/style/layout.module.less'; import NoAccess from '@/pages/exception/403'; +import { openWindow, OpenWindowOptions } from '@/utils/common'; const MenuItem = Menu.Item; const SubMenu = Menu.SubMenu; @@ -91,8 +92,17 @@ function PageLayout({ children }: { children: ReactNode }) { const [breadcrumb, setBreadCrumb] = useState([]); - function onClickMenuItem(key) { - setSelectedKeys([key]); + function onClickMenuItem(key: string) { + if (key === 'componentDevelopment') { + const url = `/ideContainer`; + const params: OpenWindowOptions = { + target: '_blank', + menu: false, + identity: key + }; + openWindow(url, params); + } + else setSelectedKeys([key]); } function toggleCollapse() { @@ -138,6 +148,7 @@ function PageLayout({ children }: { children: ReactNode }) { function renderRoutes(locale) { return function travel(_routes: IRoute[], level, parentNode = []) { return _routes.map((route) => { + console.log('route:', route); const { ignore } = route; const iconDom = getIconFromKey(route.key); const titleDom = ( @@ -164,13 +175,23 @@ function PageLayout({ children }: { children: ReactNode }) { } menuMap.current.set(route.key, { menuItem: true }); - return ( - - + + if (route?.openWindow) { + return ( + {titleDom} - - - ); + + ); + } + else { + return ( + + + {titleDom} + + + ); + } }); }; } diff --git a/src/routes/modules/componentDevelopment.ts b/src/routes/modules/componentDevelopment.ts index 97a772c..47f8dd3 100644 --- a/src/routes/modules/componentDevelopment.ts +++ b/src/routes/modules/componentDevelopment.ts @@ -2,5 +2,6 @@ import { IRoute } from '@/routes/types'; export const componentDevelopmentModule: IRoute = { name: 'menu.componentDevelopment', - key: 'componentDevelopment' + key: 'componentDevelopment', + openWindow: true }; \ No newline at end of file diff --git a/src/routes/types.ts b/src/routes/types.ts index 421447b..9fd3867 100644 --- a/src/routes/types.ts +++ b/src/routes/types.ts @@ -8,4 +8,6 @@ export type IRoute = AuthParams & { children?: IRoute[]; // 当前路由是否渲染菜单项,为 true 的话不会在菜单中显示,但可通过路由地址访问。 ignore?: boolean; + // 当前路由是在新窗口打开,为 true 的话点击菜单后不会渲染出页面 + openWindow?: boolean; }; \ No newline at end of file diff --git a/src/utils/common.ts b/src/utils/common.ts index b1b2c7b..0005f6a 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -1,5 +1,28 @@ import dayjs from 'dayjs'; +export type TargetContext = '_self' | '_parent' | '_blank' | '_top'; + +export interface OpenWindowOptions { + target?: TargetContext; + + [key: string]: any; +} + +// 新窗口打开处理函数 +export function openWindow(url: string, opts?: OpenWindowOptions) { + const { target = '_blank', ...others } = opts || {}; + + const queryString = Object.entries(others) + .filter(([key, value]) => value !== undefined && value !== null) + .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`) + .join('&'); + + // 构造带查询参数的完整 URL + const fullUrl = queryString ? `${url}${url.includes('?') ? '&' : '?'}${queryString}` : url; + + window.open(fullUrl, target); +} + // 格式化实例类型 export function formatInstanceType(value: string): string { switch (value) { @@ -35,8 +58,6 @@ export function formatInstanceStatus(value: string): string { export function formatTimestamp(timestamp: number): string { // 判断时间戳是秒级还是毫秒级 const isMillisecond = timestamp.toString().length >= 13; - const millisecondTimestamp = isMillisecond ? timestamp : timestamp * 1000; - return dayjs(millisecondTimestamp).format('YYYY-MM-DD HH:mm:ss'); } \ No newline at end of file