Files
shihezi-admin/src/app.tsx
2025-04-25 15:02:46 +08:00

272 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { AvatarDropdown, AvatarName, Footer, SelectLang } from '@/components';
import type { Settings as LayoutSettings } from '@ant-design/pro-components';
import { SettingDrawer } from '@ant-design/pro-components';
import type { RunTimeLayoutConfig } from '@umijs/max';
import { history } from '@umijs/max';
import defaultSettings from '../config/defaultSettings';
import { errorConfig } from './requestErrorConfig';
import { clearSessionToken, getAccessToken, getRefreshToken, getTokenExpireTime } from './access';
import {
getRemoteMenu,
getRoutersInfo,
getUserInfo,
patchRouteWithRemoteMenus,
setRemoteMenu,
} from './services/session';
import { PageEnum } from './enums/pagesEnums';
import { stringify } from 'querystring';
import { message } from 'antd';
const isDev = process.env.NODE_ENV === 'development';
const loginOut = async () => {
clearSessionToken();
setRemoteMenu(null);
const { search, pathname } = window.location;
const urlParams = new URL(window.location.href).searchParams;
/** 此方法会跳转到 redirect 参数所在的位置 */
const redirect = urlParams.get('redirect');
// Note: There may be security issues, please note
console.log('redirect', window.location.pathname, redirect);
if (window.location.pathname !== '/qingdao/user/login' && !redirect) {
history.replace({
pathname: '/user/login',
search: stringify({
redirect: pathname.replace('/qingdao', '') + search,
}),
});
}
};
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */
export async function getInitialState(): Promise<{
settings?: Partial<LayoutSettings>;
currentUser?: API.CurrentUser;
loading?: boolean;
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
const fetchUserInfo = async () => {
try {
const response = await getUserInfo({
skipErrorHandler: true,
});
if (response.user.avatar === '') {
response.user.avatar =
'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png';
}
return {
...response.user,
permissions: response.permissions,
roles: response.roles,
} as API.CurrentUser;
} catch (error) {
console.log(error);
history.push(PageEnum.LOGIN);
}
return undefined;
};
// 如果不是登录页面,执行
const { location } = history;
if (location.pathname !== PageEnum.LOGIN) {
const currentUser = await fetchUserInfo();
return {
fetchUserInfo,
currentUser,
settings: defaultSettings as Partial<LayoutSettings>,
};
}
return {
fetchUserInfo,
settings: defaultSettings as Partial<LayoutSettings>,
};
}
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
return {
// actionsRender: () => [<Question key="doc" />, <SelectLang key="SelectLang" />],
actionsRender: () => [<SelectLang key="SelectLang" />],
avatarProps: {
src: initialState?.currentUser?.avatar,
title: <AvatarName />,
render: (_, avatarChildren) => {
return <AvatarDropdown menu="True">{avatarChildren}</AvatarDropdown>;
},
},
waterMarkProps: {
// content: initialState?.currentUser?.nickName,
},
// actionRef: layoutActionRef,
menu: {
locale: false,
// // 每当 initialState?.currentUser?.userid 发生修改时重新执行 request
params: {
userId: initialState?.currentUser?.userId,
},
request: async () => {
if (!initialState?.currentUser?.userId) {
return [];
}
return getRemoteMenu();
},
},
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== PageEnum.LOGIN) {
history.push(PageEnum.LOGIN);
}
},
layoutBgImgList: [
{
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
left: 85,
bottom: 100,
height: '303px',
},
{
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
bottom: -68,
right: -45,
height: '303px',
},
{
src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
bottom: 0,
left: 0,
width: '331px',
},
],
pure: false,
// links: isDev
// ? [
// <Link key="openapi" to="/umi/plugin/openapi" target="_blank">
// <LinkOutlined />
// <span>OpenAPI 文档</span>
// </Link>,
// ]
// : [],
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: <div>unAccessible</div>,
// 增加一个 loading 的状态
childrenRender: (children) => {
// if (initialState?.loading) return <PageLoading />;
return (
<>
{children}
<SettingDrawer
disableUrlParams
enableDarkTheme
settings={initialState?.settings}
onSettingChange={(settings) => {
setInitialState((preInitialState) => ({
...preInitialState,
settings,
}));
}}
/>
</>
);
},
...initialState?.settings,
};
};
export async function onRouteChange({ clientRoutes, location }) {
const menus = getRemoteMenu();
// console.log('onRouteChange', clientRoutes, location, menus);
if (menus === null && location.pathname !== PageEnum.LOGIN) {
console.log('refresh');
// history.go(0);
}
}
// export function patchRoutes({ routes, routeComponents }) {
// console.log('patchRoutes', routes, routeComponents);
// }
export async function patchClientRoutes({ routes }) {
// console.log('patchClientRoutes', routes);
patchRouteWithRemoteMenus(routes);
}
export async function render(oldRender: () => void) {
console.log('render get routers', oldRender);
const token = getAccessToken();
if (!token || token?.length === 0) {
oldRender();
return;
}
await getRoutersInfo().then((res) => {
console.log('render get routers', 123);
setRemoteMenu(res);
oldRender();
});
}
/**
* @name request 配置,可以配置错误处理
* 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
* @doc https://umijs.org/docs/max/request#配置
*/
const checkRegion = 5 * 60 * 1000;
export const request = {
...errorConfig,
baseURL: process.env.NODE_ENV === 'development' ? '' : 'https://qd.zhaopinzao8dian.com/api',
// baseURL: 'http://39.98.44.136:8080',
requestInterceptors: [
(url: any, options: { headers: any }) => {
const headers = options.headers ? options.headers : [];
console.log('request ====>:', url);
const authHeader = headers['Authorization'];
const isToken = headers['isToken'];
if (!authHeader && isToken !== false) {
const expireTime = getTokenExpireTime();
if (expireTime) {
const left = Number(expireTime) - new Date().getTime();
const refreshToken = getRefreshToken();
if (left < checkRegion && refreshToken) {
if (left < 0) {
clearSessionToken();
}
} else {
const accessToken = getAccessToken();
if (accessToken) {
headers['Authorization'] = `Bearer ${accessToken}`;
}
}
} else {
clearSessionToken();
}
}
if (process.env.NODE_ENV !== 'development') {
if (url.startsWith('/api')) {
url = url.replace(/^\/api/, '');
}
}
return { url, options };
},
],
responseInterceptors: [
(response) => {
// 不再需要异步处理读取返回体内容可直接在data中读出部分字段可在 config 中找到
const { data = {} as any, config } = response;
switch (data.code) {
case 401:
loginOut();
break;
}
if (data.code !== 200 && data.msg) {
message.info(data.msg);
}
// console.log('data: ', data)
// console.log('config: ', config)
return response;
},
],
};