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 (
-
+ );
+ }
+ 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