React
主要配置项为layout的menuDataRender方法
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
return {
...
menuDataRender: () => { // 看这里
console.log('menuDataRender', initialState?.menuData);
return initialState?.menuData || [];
},
...initialState?.settings,
};
};
在此之前,需要给initialState?.menuData赋值,也就是修改getInitialState方法
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: API.CurrentUser;
features?: GetFeaturesModel;
featureIndex?: any;
menuData?: MenuDataItem[];
loading?: boolean;
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
....
const fetchFeatures = async () => {
return await GetFeatures({ groupName: 'BI' });
};
// 如果不是登录页面,执行
if (
history.location.pathname !== loginPath &&
history.location.pathname !== '/user/loginByCode' &&
history.location.pathname !== '/user/loginByCode/'
) {
const authority: Authority = new Authority();
const jwtToken = authority.getToken();
// console.log('jwtToken', jwtToken);
const { token_type, access_token, expires_in, refresh_token } = jwtToken;
if (expires_in > 0 && access_token.length > 0) {
const currentUser = await fetchUserInfo();
const features = await fetchFeatures();
const menuData = FixMenuItem(features.content);
console.log('currentUser', currentUser);
return {
fetchUserInfo,
currentUser,
menuData: menuData,
features: features.content,
featureIndex: convertToFeatureIndex(features.content),
settings: defaultSettings,
};
} else if (refresh_token) {
console.log('RefreshToken getInitialState');
const refreshResponse = await refreshToken(authority, refresh_token);
// 刷新token的请求是否成功
if (refreshResponse && refreshResponse.success) {
const currentUser = await fetchUserInfo();
const features = await fetchFeatures();
const menuData = FixMenuItem(features.content);
console.log('currentUser', currentUser);
return {
fetchUserInfo,
currentUser,
menuData: menuData,
features: features.content,
featureIndex: convertToFeatureIndex(features.content),
settings: defaultSettings,
};
}
}
}
return {
fetchUserInfo,
settings: defaultSettings,
};
}
这里有也给FixMenuItem方法,需要根据实际从服务器返回的数据转换为ant.design pro指定的menuDataItem格式
import type { MenuDataItem, Settings as LayoutSettings } from '@ant-design/pro-layout';
import { FileOutlined, LinkOutlined, AccountBookOutlined, FolderOutlined, TeamOutlined, PieChartOutlined, SettingOutlined, ProfileOutlined, ToolOutlined } from '@ant-design/icons';
import * as icons from '@ant-design/icons' // 获取使用权
const capitalizeWords = (str: string) => {
return str
.toLowerCase()
.split(' ')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
};
const IconMaps = {
"link": <LinkOutlined />,
"file": <FileOutlined />,
"account-book": <AccountBookOutlined />,
"folder": <FolderOutlined />,
"team": <TeamOutlined />,
"pie-chart": <PieChartOutlined />,
// "setting": <SettingOutlined />,
"profile": <ProfileOutlined />,
"tool": <ToolOutlined />,
};
const iconToElement = (name: string, iconType: string = 'Outlined') => {
const names = name.split('-');
for (let i = 0; i < names.length; i++) {
const item = names[i];
names[i] = capitalizeWords(item);
}
name = names.join('');
React.createElement(icons && (icons as any)[name + iconType], {
style: { fontSize: '16px' }
})
}
const FixMenuItem = (features: GetFeaturesModel, iconType = 'Outlined'): MenuDataItem[] => {
const items: MenuDataItem[] = [];
console.log('features123', features)
features?.items.forEach((itemData) => {
const item: MenuDataItem = {};
items.push(item);
item.name = itemData.name;
if (itemData.icon) {
const icon = itemData.icon;
item.icon = IconMaps[icon] || iconToElement(icon);
}
if (!item.icon) {
item.icon = <FolderOutlined />;
}
item.path = '/' + itemData.flag;
item.children = [];
itemData.pages?.forEach((pageItem: PageInfo) => {
if (pageItem.features.filter(x => x.featureFlag == 'index' && x.enable).length > 0) {
const subItem: MenuDataItem = {
name: pageItem.name,
path: pageItem.url
};
item.children?.push(subItem)
}
});
});
console.log('MenuDataItem', items);
return items
};
注意:
在config配置好的路由,虽然menu作用已经不在,但是route的功能还是在的,包括权限控制,所以还是要就加route