tab 优化

This commit is contained in:
lix
2025-07-24 08:46:25 +08:00
parent e7502c2b2d
commit c966ea30d9
5 changed files with 69 additions and 46 deletions

View File

@ -58,7 +58,7 @@ function TabLayout({
) )
return ( return (
<div className={styles['rumtime-keep-alive-tabs-layout']} hidden={!isKeep || activeKeyLowerCase === '/dashboard'}> <div className={styles['rumtime-keep-alive-tabs-layout']} hidden={activeKeyLowerCase === '/dashboard'}>
<Tabs <Tabs
hideAdd hideAdd
onChange={(key: string) => { onChange={(key: string) => {
@ -103,3 +103,7 @@ export const getCustomTabs = () => {
collapsed: global.collapsed, collapsed: global.collapsed,
}))(TabLayout); }))(TabLayout);
}; };
export const getKeepAlive = () => {
return ['PLACEHOLDER']
}

View File

@ -64,7 +64,7 @@ const GlobalHeaderRight: React.FC<{}> = (props) => {
sessionStorage.clear(); sessionStorage.clear();
cookie.remove('mall3_token'); cookie.remove('mall3_token');
setTimeout(() => { setTimeout(() => {
history.push('/internal-login'); history.push('/login');
}, 1000); }, 1000);
} }
}) })

View File

@ -3,8 +3,8 @@ import ProLayout, {
BasicLayoutProps as ProLayoutProps, BasicLayoutProps as ProLayoutProps,
Settings, Settings,
} from '@ant-design/pro-layout'; } from '@ant-design/pro-layout';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useEffect, useMemo, useRef, useContext } from 'react';
import { Link, connect, Dispatch, history, useLocation, useKeepOutlets, useAppData } from '@umijs/max'; import { Link, connect, Dispatch, history, useLocation, useKeepOutlets, KeepAliveContext } from '@umijs/max';
import { Result, Button, message } from 'antd'; import { Result, Button, message } from 'antd';
import Authorized from '@/utils/Authorized'; import Authorized from '@/utils/Authorized';
import RightContent from '@/components/GlobalHeader/RightContent'; import RightContent from '@/components/GlobalHeader/RightContent';
@ -13,6 +13,7 @@ import { getMatchMenu } from '@umijs/route-utils';
import { getMenu } from './services' import { getMenu } from './services'
import logo from '../assets/logo.svg'; import logo from '../assets/logo.svg';
import { getSessionRoleData, getSessionUserData } from '@/utils/session'; import { getSessionRoleData, getSessionUserData } from '@/utils/session';
import { getPathKeyMap } from '@/utils/pathKeyMap';
import { import {
HomeOutlined, HomeOutlined,
@ -35,7 +36,7 @@ import {
IdcardOutlined, IdcardOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
const menuIconMap = { const menuIconMap: { [key: string]: React.ReactNode } = {
"HomeOutlined": <HomeOutlined />, "HomeOutlined": <HomeOutlined />,
"ContactsOutlined": <ContactsOutlined />, "ContactsOutlined": <ContactsOutlined />,
"DesktopOutlined": <DesktopOutlined />, "DesktopOutlined": <DesktopOutlined />,
@ -105,7 +106,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
const mall3_token: any = sessionStorage.getItem('Authorization');//当前登录token const mall3_token: any = sessionStorage.getItem('Authorization');//当前登录token
const userData: any = getSessionUserData();//当前登录人信息 const userData: any = getSessionUserData();//当前登录人信息
const children = useKeepOutlets(); const children = useKeepOutlets();
const routeData = useAppData(); const { setKeepalive } = useContext(KeepAliveContext);
useEffect(() => { useEffect(() => {
if (getSessionRoleData()?.roleId) { if (getSessionRoleData()?.roleId) {
@ -116,13 +117,17 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
if (res.code == 200) { if (res.code == 200) {
setMenuData(res.data || []) setMenuData(res.data || [])
if (dispatch) { if (dispatch) {
const pathKeyMap = getPathKeyMap(res.data || [])
dispatch({ dispatch({
type: 'user/saveMenuData', type: 'user/saveMenuData',
payload: { payload: {
menuData: res.data || [], menuData: res.data || [],
routeData: routeData.routes, pathKeyMap,
}, },
}); });
const keys = Array.from(pathKeyMap.keys())
// @ts-ignore
setKeepalive(keys)
} }
setmenuShow(true) setmenuShow(true)
} else { } else {
@ -194,7 +199,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
); );
}} }}
rightContentRender={() => <RightContent />} rightContentRender={() => <RightContent />}
postMenuData={(menuData) => { postMenuData={(menuData: any) => {
menuDataRef.current = menuData || []; menuDataRef.current = menuData || [];
return menuData || []; return menuData || [];
}} }}

View File

@ -1,6 +1,8 @@
import { Effect, Reducer } from '@umijs/max'; import { Effect, Reducer } from '@umijs/max';
import { queryCurrent, query as queryUsers } from '@/services/user'; import { queryCurrent, query as queryUsers } from '@/services/user';
import { getPathKeyMap } from '@/utils/pathKeyMap';
import type { PathKeyMap } from '@/utils/pathKeyMap';
export interface CurrentUser { export interface CurrentUser {
avatar?: string; avatar?: string;
@ -16,12 +18,6 @@ export interface CurrentUser {
unreadCount?: number; unreadCount?: number;
} }
export interface PathKeyMap {
name: string;
icon?: string;
routeName?: string;
}
export interface UserModelState { export interface UserModelState {
currentUser?: CurrentUser; currentUser?: CurrentUser;
menuData?: any[]; menuData?: any[];
@ -77,37 +73,26 @@ const UserModel: UserModelType = {
}, },
saveMenuData(state, action) { saveMenuData(state, action) {
const menuData = action.payload.menuData || []; const menuData = action.payload.menuData || [];
const routeData = action.payload.routeData || []; const pathKeyMap = action.payload.pathKeyMap;
const pathKeyMap = new Map<string, PathKeyMap>();
// 将menuData转换为pathKeyMap 递归处理 // let i = 1;
const convertToPathKeyMap = (menuData: any[]) => { // while (routeData[i]) {
menuData.forEach((item: any) => { // const item = routeData[i];
const path = item.path ? item.path.toLowerCase() : ''; // if (item.name) {
pathKeyMap.set(path, {name: item.name, icon: item.icon}); // const pathname = item.path.toLowerCase();
if (item.children) { // if (pathKeyMap.has(pathname)) {
convertToPathKeyMap(item.children); // const target = pathKeyMap.get(pathname)!;
} // const newItem = {
}); // ...target,
}; // routeName: item.name,
convertToPathKeyMap(menuData); // }
let i = 1; // pathKeyMap.set(pathname, newItem);
while (routeData[i]) { // } else {
const item = routeData[i]; // pathKeyMap.set(pathname, { name: item.name, icon: item.icon });
if (item.name) { // }
const pathname = item.path.toLowerCase(); // }
if (pathKeyMap.has(pathname)) { // i++;
const target = pathKeyMap.get(pathname)!; // }
const newItem = {
...target,
routeName: item.name,
}
pathKeyMap.set(pathname, newItem);
} else {
pathKeyMap.set(pathname, { name: item.name, icon: item.icon });
}
}
i++;
}
return { return {
...state, ...state,
menuData: action.payload || [], menuData: action.payload || [],

29
src/utils/pathKeyMap.ts Normal file
View File

@ -0,0 +1,29 @@
export interface MenuData {
name: string;
icon: string;
path: string;
children?: MenuData[];
}
export interface PathKeyMap {
name: string;
icon?: string;
routeName?: string;
}
export const getPathKeyMap = (menuData: MenuData[]) => {
const pathKeyMap = new Map<string, PathKeyMap>();
const convertToPathKeyMap = (menuData: MenuData[]) => {
menuData.forEach((item: any) => {
const path = item.path ? item.path.toLowerCase() : '';
// 如果 path 以 "/api" 开头则跳过
if (path && !path.startsWith('/api')) {
pathKeyMap.set(path, {name: item.name, icon: item.icon});
}
if (item.children) {
convertToPathKeyMap(item.children);
}
});
};
convertToPathKeyMap(menuData);
return pathKeyMap;
}