/* * @Author: code4eat awesomedema@gmail.com * @Date: 2022-12-14 14:14:32 * @LastEditors: code4eat awesomedema@gmail.com * @LastEditTime: 2023-08-10 14:01:11 * @FilePath: /BudgetManaSystem/src/app.ts * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ // 运行时配置 // 全局初始化数据配置,用于 Layout 用户信息和权限初始化 // 更多信息见文档:https://next.umijs.org/docs/api/runtime-config#getinitialstate import { AxiosResponse } from '@umijs/max'; import { message, notification } from 'antd'; import type { RequestConfig } from 'umi'; import iconEnum from './menuIcons.js'; import Report from './pages/reports/index'; import Static from './pages/static/index'; import DevicePixelRatio from './utils/devicePixelRatio.js'; import Icon, { createFromIconfontCN, FolderOutlined } from '@ant-design/icons'; import { getPlatformMenu } from '@/services/auth'; import { useState } from 'react'; import './utils/zhongtaiC' import { RuntimeAntdConfig } from '@umijs/max'; const IconFont = createFromIconfontCN({ scriptUrl: '', }); // 错误处理方案: 错误类型 enum ErrorShowType { SILENT = 0, WARN_MESSAGE = 1, ERROR_MESSAGE = 2, NOTIFICATION = 3, REDIRECT = 9, } // 与后端约定的响应数据格式 interface ResponseStructure { success?: boolean; code?: string; data: any; errorCode?: number; errorMessage?: string; showType?: ErrorShowType; } interface UserData { name?: string, ruleVersion?: string, token?: string, userId?: number, youshuToken?: string } export async function getInitialState(): Promise<{ isCollapsed: boolean, spacicalPageParamsType?: any[], userData: UserData,memuData:any[] }> { new DevicePixelRatio().init(); return { isCollapsed: false, spacicalPageParamsType: [], userData: {},memuData:[] }; } export const request: RequestConfig = { // 统一的请求设定 timeout: 100000000, headers: { 'X-Requested-With': 'XMLHttpRequest' }, // transformResponse:[function (data) { // try { // // 如果转换成功则返回转换的数据结果 // return JSONbig.parse(data); // } catch (error) { // // 如果转换失败,则包装为统一数据格式并返回 // return data // } // }], // 错误处理: umi@3 的错误处理方案。 errorConfig: { // 错误抛出 errorThrower: (res: ResponseStructure) => { const { success, data, errorCode, errorMessage, showType } = res; //console.log({success, data, errorCode, errorMessage, showType}); if (!success) { const error: any = new Error(errorMessage); error.name = 'BizError'; error.info = { errorCode, errorMessage, showType, data }; throw error; // 抛出自制的错误 } }, // 错误接收及处理 errorHandler: (error: any, opts: any) => { if (opts?.skipErrorHandler) throw error; // 我们的 errorThrower 抛出的错误。 if (error.name === 'BizError') { const errorInfo: ResponseStructure | undefined = error.info; if (errorInfo) { const { errorMessage, errorCode } = errorInfo; switch (errorInfo.showType) { case ErrorShowType.SILENT: // do nothing break; case ErrorShowType.WARN_MESSAGE: message.warning(errorMessage); break; case ErrorShowType.ERROR_MESSAGE: message.error(errorMessage); break; case ErrorShowType.NOTIFICATION: notification.open({ description: errorMessage, message: errorCode, }); break; case ErrorShowType.REDIRECT: // TODO: redirect break; default: message.error(errorMessage); } } } else if (error.response) { // Axios 的错误 // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围 message.error(`Response status:${error.response.status}`); } else if (error.request) { // 请求已经成功发起,但没有收到响应 // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例, // 而在node.js中是 http.ClientRequest 的实例 message.error('None response! Please retry.'); } else { // 发送请求时出了点问题 message.error('Request error, please retry.'); } }, }, // 请求拦截器 requestInterceptors: [ (config: RequestConfig) => { // 拦截请求配置,进行个性化处理。 const userData = localStorage.getItem('userData'); const { token = '' } = JSON.parse(userData as any); return { ...config, url: `/gateway${config.url}`, headers: { token } } // return { ...config } } ], // 响应拦截器 responseInterceptors: [ (response: AxiosResponse) => { // 拦截响应数据,进行个性化处理 const { status, data: { success, status: code, errorMessage, data: respData }, config: { method } } = response; try { if (status == 200) { // 网络请求成功 if (method == 'post') { if (code == 200) { return response.data.data == null ? { success: true, data: true } : response.data } else { notification.error({ message: '', description: errorMessage, placement: 'topRight', icon: <> }) return false } } else { if (status != 200) { message.error('请求失败!'); return false } else { if (code == 200) { //console.log({code,'response.data':response.data}); return response.data } else { notification.error({ message: '', description: errorMessage, placement: 'topRight', icon: <> }) return false; } } } } else { return false } } catch (error) { console.log({ error }); } } ] }; export function patchClientRoutes({ routes }: { routes: any }) { const treeLoop = (treeData: any) => { // console.log({treeData}); if(treeData.routes){ const paths = [...new Array(20).keys()].map((a, index) => ({ path: `${treeData.path == '/'?'':treeData.path}/reports/${index}`, exact: true, element: , })); const lanhuPagePaths = [...new Array(20).keys()].map((a, index) => ({ path: `${treeData.path == '/'?'':treeData.path}/static/${index}`, exact: true, element: , })); //console.log({paths}); paths.forEach((a: any) => { treeData.routes.push(a); }); lanhuPagePaths.forEach((a: any) => { treeData.routes.push(a); }); } if (treeData.routes && treeData.routes.length > 0) { treeData.routes.forEach((a: any) => { treeLoop(a); }) } } treeLoop(routes[0]); } export type menuDataItemType = { path: string, name: string, icon: any, component?: string, softUrl?: string, // 帆软url children?: menuDataItemType[] } // 将服务端获取的菜单 icon 字符串映射为对应的 icon Dom const mappingIcon = (menuData: menuDataItemType[]) => { if (menuData.length == 0) { 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; }; const imgNode = (props: any) => { return }; const fileIcon = (params: any) => { return }; const setting = (params: any) => { return }; const secondaryDistribute = (params: any) => { return }; const reportCheck = (params: any) => { return }; const crosstabReport = (params: any) => { return }; //布局配置 export const layout = ({ initialState, setInitialState }: { initialState: any, setInitialState: any }) => { const { isCollapsed } = initialState; const [openKeys, set_openKeys] = useState([]); const [selectedKeys, set_selectedKeys] = useState([]); const onCollapse = (isCollapsed: boolean): void => { setInitialState({ ...initialState, isCollapsed }).then(); }; return { menuHeaderRender: false, token: { sider: { colorMenuBackground: '#fff', colorTextMenuActive: '#3376FE', colorTextMenuSelected: '#3376FE', colorTextMenuTitle: '#17181A', colorTextMenu: '#17181A', //colorBgMenuItemHover:'##f0f2f5', colorBgMenuItemSelected: '#F2F6FF', // colorBgMenuItemCollapsedHover:'#f0f2f5', // //colorBgMenuItemCollapsedSelected:'blue' } }, siderWidth: 200, menu: { locale: false, request: async () => { const userData = localStorage.getItem('userData'); const currentSelectedTab = localStorage.getItem('currentSelectedTab'); if (currentSelectedTab) { const { menuId, path } = JSON.parse(currentSelectedTab); const systemId = menuId; const data: any[] = await getPlatformMenu(systemId); if (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) { //非一般页面 if (t[key] == 1 || t[key] == 2 || t[key] == 3) { //网易有数页面 result.push({ contentType: t[key], path: t['path'], reportId: t['reportId'], url: t['youshuUrl'], }); } if (t[key] == 5) { result.push({ contentType: t[key], path: t['path'], reportId: t['reportId'], url: t['softUrl'], }); } } if (t.children && t.children.length > 0) { looper(t.children, key); } }); } looper(data, key); return result; }; const _menu = getVFromTree(data, 'contentType'); setInitialState((t: any) => ({ ...t, spacicalPageParamsType: _menu,memuData:data, userData: JSON.parse(userData as string) })); //return mappingIcon(data); function addIconToPath(node: any, paths: string[]) { if (paths.includes(node.path)) { if (node.path == '/home') { node.icon = ; } if (node.path == '/budgetMana') { node.icon = ; } if (node.path == '/setting') { node.icon = ; } if (node.path == '/reportCheck') { node.icon = ; } if (node.path == '/secondaryDistribute') { node.icon = ; } if (node.path == '/reportCheck') { node.icon = ; } if (node.path == '/crosstabReport') { node.icon = ; } } if (node.children) { node.children.forEach((child: any) => addIconToPath(child, paths)); } // node.icon = ; // if (node.children) { // node.children.forEach((child: any) => addIconToPath(child, paths)); // } } data.forEach((item: any) => { addIconToPath(item, ['/home', '/budgetMana', '/setting', '/reportCheck', '/secondaryDistribute','/crosstabReport']); }); return data } } }, }, onPageChange: (location: Location) => { // console.log({location}); // const {pathname} = location; // localStorage.setItem('currentPath',pathname); }, collapsedButtonRender: () => { return (
{ onCollapse(isCollapsed ? false : true); } }>
) }, collapsed: isCollapsed, contentStyle: { border: '16px solid #F7F9FC', //height: '94.5vh', //以去除顶部导航高度 borderRadius: '22px', background: '#F7F9FC', height:'calc(100vh - 48px)' // overflow:'scroll', // margin:'20px 20px' }, }; };