187 lines
5.4 KiB
TypeScript
187 lines
5.4 KiB
TypeScript
import { LinkOutlined } from "@ant-design/icons";
|
||
import type { Settings as LayoutSettings } from "@ant-design/pro-components";
|
||
import { SettingDrawer } from "@ant-design/pro-components";
|
||
import type { RequestConfig, RunTimeLayoutConfig } from "@umijs/max";
|
||
import { history, Link } from "@umijs/max";
|
||
import React from "react";
|
||
import {
|
||
AvatarDropdown,
|
||
AvatarName,
|
||
Footer,
|
||
Question,
|
||
SelectLang,
|
||
} from "@/components";
|
||
import { getInfo } from "@/services/login";
|
||
import type { UserVO, TokenType } from "@/services/login/types";
|
||
import defaultSettings from "../config/defaultSettings";
|
||
import { errorConfig } from "./requestErrorConfig";
|
||
import "@ant-design/v5-patch-for-react-19";
|
||
import { getAccessToken, getRefreshToken, getTenantId } from "./utils/auth";
|
||
|
||
const isDev = process.env.NODE_ENV === "development";
|
||
const isDevOrTest = isDev || process.env.CI;
|
||
const loginPath = "/user/login";
|
||
|
||
/**
|
||
* @see https://umijs.org/docs/api/runtime-config#getinitialstate
|
||
* */
|
||
export async function getInitialState(): Promise<{
|
||
settings?: Partial<LayoutSettings>;
|
||
currentUser?: { user: UserVO };
|
||
loading?: boolean;
|
||
fetchUserInfo?: () => Promise<{ user: UserVO } | undefined>;
|
||
}> {
|
||
const fetchUserInfo = async () => {
|
||
// history.push(loginPath);
|
||
try {
|
||
const token = getAccessToken();
|
||
if (!token) {
|
||
throw new Error("No token found");
|
||
}
|
||
const msg = await getInfo();
|
||
return msg.data;
|
||
} catch (_error) {
|
||
history.push(loginPath);
|
||
}
|
||
return undefined;
|
||
};
|
||
// 如果不是登录页面,执行
|
||
const { location } = history;
|
||
if (
|
||
![loginPath, "/user/register", "/user/register-result"].includes(
|
||
location.pathname
|
||
)
|
||
) {
|
||
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" />,
|
||
],
|
||
avatarProps: {
|
||
src: initialState?.currentUser?.user.avatar,
|
||
title: <AvatarName />,
|
||
render: (_, avatarChildren) => (
|
||
<AvatarDropdown>{avatarChildren}</AvatarDropdown>
|
||
),
|
||
},
|
||
waterMarkProps: {
|
||
content: initialState?.currentUser?.user.nickname,
|
||
},
|
||
footerRender: () => <Footer />,
|
||
onPageChange: () => {
|
||
const { location } = history;
|
||
// 如果没有登录,重定向到 login
|
||
console.log(initialState);
|
||
if (!initialState?.currentUser && location.pathname !== loginPath) {
|
||
history.push(loginPath);
|
||
}
|
||
},
|
||
bgLayoutImgList: [
|
||
{
|
||
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",
|
||
},
|
||
],
|
||
links: isDevOrTest
|
||
? [
|
||
<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}
|
||
{isDevOrTest && (
|
||
<SettingDrawer
|
||
disableUrlParams
|
||
enableDarkTheme
|
||
settings={initialState?.settings}
|
||
onSettingChange={(settings) => {
|
||
setInitialState((preInitialState) => ({
|
||
...preInitialState,
|
||
settings,
|
||
}));
|
||
}}
|
||
/>
|
||
)}
|
||
</>
|
||
);
|
||
},
|
||
...initialState?.settings,
|
||
};
|
||
};
|
||
|
||
/**
|
||
* @name request 配置,可以配置错误处理
|
||
* 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
|
||
* @doc https://umijs.org/docs/max/request#配置
|
||
*/
|
||
export const request: RequestConfig = {
|
||
baseURL: isDev ? "" : "https://proapi.azurewebsites.net",
|
||
...errorConfig,
|
||
// 添加请求拦截器
|
||
requestInterceptors: [
|
||
(url, options) => {
|
||
// 为所有请求添加 API 前缀
|
||
if (url && !url.startsWith(process.env.API_PREFIX || "/admin-api")) {
|
||
url = (process.env.API_PREFIX || "/admin-api") + url;
|
||
}
|
||
// 获取存储在本地的 token 和 tenantId
|
||
const token = getAccessToken();
|
||
const tenantId = getTenantId(); // 默认租户ID为1
|
||
console.log(tenantId);
|
||
// 设置统一的请求头
|
||
const headers: Record<string, string> = {
|
||
...options.headers,
|
||
Accept: "*",
|
||
"tenant-id": tenantId,
|
||
};
|
||
// 如果有token,则添加Authorization头
|
||
if (token) {
|
||
headers["Authorization"] = `Bearer ${getAccessToken()}`;
|
||
}
|
||
return { url, options: { ...options, headers } };
|
||
},
|
||
],
|
||
};
|