/*
* @Author: your name
* @Date: 2021-09-03 14:28:27
* @LastEditTime: 2022-03-11 18:01:43
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /MedicalWisdomCheckSys/src/app.tsx
*/
import type { Settings as LayoutSettings } from '@ant-design/pro-layout';
import { PageLoading } from '@ant-design/pro-layout';
import type { RunTimeLayoutConfig} from 'umi';
import {history, Link } from 'umi';
import { notification, Modal } from 'antd';
// import 'yet-another-abortcontroller-polyfill'
import RightContent from '@/components/RightContent';
import { BookOutlined, LinkOutlined } from '@ant-design/icons';
import iconEnum from './menuIcons';
import {loginOut} from '@/utils';
import logoIcon from '../public/logo.png';
import { getMenus } from './services/user';
import {updateUserInfo} from '@/pages/user/Login/service';
import type { RequestOptionsInit,Context } from 'umi-request';
const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/user/login';
let hospSign: any='';
let ifStopNextRequet: boolean = false; // 控制当出现token过期阻止后面弹窗提示
if(history){
hospSign = history.location.query?.hospSign;
if(!hospSign){
hospSign = localStorage.getItem('hospSign');
console.log({'localStorage':hospSign});
}
}
/** 获取用户信息比较慢的时候会展示一个 loading */
// export const initialStateConfig = {
// loading: ,
// };
export type menuDataItemType = {
path: string,
name: string,
icon: any,
component: string,
softUrl?: string, // 帆软url
children?: menuDataItemType[]
}
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */
export async function getInitialState(): Promise<{
settings?: Partial;
currentUser?: API.CurrentUserData;
logo?: string;
isDev?: boolean,
spacicalPageParamsType?:any[];
goSetting?: boolean,// 设置栏触发
resetPasswordHandle?: (formData: any) => Promise,
fetchUserMenu?: () => Promise,
menu?: menuDataItemType[],
clearUserData?: () => Promise; // 清空用户数据
fetchUserInfo?: () => Promise;
postDataToTop?: (data: any) => Promise,
}> {
const fetchUserInfo = async () => {
try {
const userData = localStorage.getItem('userData');
if(userData){
return JSON.parse(userData);
}
throw Error;
} catch (error) {
history.push(`${loginPath}?hospSign=${hospSign}`);
}
return undefined;
};
const fetchUserMenu = async ()=>{
const menu = await getMenus();
if(menu){
return menu;
}
}
const resetPasswordHandle = async (data: API.EditUserInfoType)=>{
const resp = await updateUserInfo(data);
if(resp){
return Promise.resolve(true);
}
return Promise.resolve(false);
}
const clearUserData = ()=>{
localStorage.removeItem('userData');
return Promise.resolve(true);
};
// 如果是登录页面,不执行
if (history.location.pathname !== loginPath) {
const currentUser = await fetchUserInfo();
return {
fetchUserInfo,
currentUser,
logo:logoIcon,
clearUserData,
menu:[],
fetchUserMenu,
resetPasswordHandle,
isDev:process.env.NODE_ENV == 'development',
settings: {
navTheme:'dark',
layout:'side'
},
};
}
return {
fetchUserInfo,
settings: {},
};
}
const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
const userData = localStorage.getItem('userData');
const authHeader = {token:''};
if(userData){
const {token}: API.CurrentUserData = JSON.parse(userData);
authHeader.token = token;
}
return {
url: `${url}`,
options: { ...options, interceptors: true, headers: authHeader },
};
};
interface responseInterceptorsOptions extends RequestOptionsInit {
isCloseNotify?: boolean, // 是否关闭POST请求后反馈
responseSpecifyFeedback?: {
successMessage: string,
errorMessage: string,
isShow: boolean, // 是否启用
}
}
const responseInterceptors = async (response: Response, options: responseInterceptorsOptions) => {
// console.log({response,options});
const requestMethod = options.method;
const {url,responseSpecifyFeedback,isCloseNotify=false} = options;
try {
const {status} = response;
if(status == 200){
// 网络请求成功
const _response = await response.clone().json();
const { status: dataStatus,errorCode,errorMessage,data} = _response;
if(dataStatus == 200){
// 接口请求成功
if(requestMethod=='POST'&&url != "/api/pfm/login"&&!isCloseNotify){
if(responseSpecifyFeedback&&responseSpecifyFeedback.isShow){
// 当指定了请求成功反馈时
console.log({responseSpecifyFeedback});
console.log(responseSpecifyFeedback.successMessage);
notification.success({
message:responseSpecifyFeedback.successMessage
});
}else{
// 否则用默认提示
notification.success({
message:'操作成功!'
});
}
}
if(data){
return data;
}
return true;
}if(errorCode == 499){
if(!ifStopNextRequet){
Modal.confirm({
title: '抱歉,登录已过期请重新登录!',
onOk: () => {
ifStopNextRequet = false;
loginOut();
}
});
}
ifStopNextRequet = true;
}else {
// 接口请求信息错误
notification.error({
message:errorMessage
});
}
}else {
// 网络请求失败
notification.error({
message:'服务器错误!'
});
throw Error;
}
}catch(error){
console.log({error});
}
};
const demo1Middleware = async (ctx: Context, next: () => void) => {
await next();
};
type RequestConfig = Record
export const request: RequestConfig = {
// 新增自动添加AccessToken的请求前拦截器
errorHandler: (error: any) => {
console.log({ error });
throw error;
},
middlewares: [demo1Middleware],
requestInterceptors: [authHeaderInterceptor],
responseInterceptors: [responseInterceptors],
};
// 将服务端获取的菜单 icon 字符串映射为对应的 icon Dom
const mappingIcon = (menuData: menuDataItemType[]) => {
if(menuData.length==0){
console.log('空菜单');
return [
{
path:'',
name: '',
icon: '',
component: './404',
}
]
}
const mappingMenu: menuDataItemType[] = menuData.map(item => ({
...item,
icon: item.icon&&iconEnum[item.icon],
children: item.children ? mappingIcon(item.children) : [],
}));
return mappingMenu;
};
// export const qiankun = {
// // 应用加载之前
// async bootstrap(props:any) {
// console.log('MedicalWisdomCheckSys bootstrap', props);
// },
// // 应用 render 之前触发
// async mount(props:any) {
// console.log('MedicalWisdomCheckSys mount', props);
// },
// // 应用卸载之后触发
// async unmount(props:any) {
// console.log('MedicalWisdomCheckSys unmount', props);
// },
// };
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState,setInitialState }) => {
return {
logo:initialState?.logo,
rightContentRender: () => ,
disableContentMargin: false,
waterMarkProps: {
// content: initialState?.currentUser?.name,
},
// footerRender: () => ,
onPageChange:() => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(`${loginPath}?hospSign=${hospSign}`);
}
},
menu: {
params:{
currentUser:initialState?.currentUser
},
request: async () => {
// initialState.currentUser 中包含了所有用户信息
if(initialState){
const { currentUser,isDev} = initialState;
if(false){
// 开发环境
return []
}
if (currentUser) {
const data: any[] = await getMenus();
if(data){
await setInitialState(t=>({...t,menu:data}));
/**
*
* 菜单跳转报表临时处理,后期统一换成中台调用
*/
const getVFromTree = (data:any[], key: string) => {
let result: any[] = [];
function looper(data: any[], key: string) {
data.forEach((t) => {
if (t[key] && t[key] != 0) {
//非一般页面
result.push({
contentType: t[key],
path: t['path'],
reportId: t['reportId'],
url: t['youshuUrl'],
});
}
if (t.children && t.children.length > 0) {
looper(t.children, key);
}
});
}
looper(data, key);
return result;
};
const _menu = getVFromTree(data, 'contentType');
setInitialState((t) => ({ ...t, spacicalPageParamsType: _menu }));
/////////////////////////////--------临时处理----------///////////////////////////////////////////////
return mappingIcon(data);
}
} else {
return [
{
component: './404',
}
]
}
}
return []
},
},
links: isDev
? [
OpenAPI 文档
,
业务组件文档
,
]
: [],
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: unAccessible
,
...initialState?.settings,
};
};