123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- /*
- * @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: <Report />,
- }));
-
- const lanhuPagePaths = [...new Array(20).keys()].map((a, index) => ({
- path: `${treeData.path == '/'?'':treeData.path}/static/${index}`,
- exact: true,
- element: <Static />,
- }));
-
- //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 <IconFont type='icon-shouye' {...props} />
- };
- const fileIcon = (params: any) => {
- return <IconFont type='icon-jixiaoguanli' />
- };
- const setting = (params: any) => {
- return <IconFont type='icon-xitongshezhi' />
- };
- const secondaryDistribute = (params: any) => {
- return <IconFont type='icon-ercifenpei' />
- };
- const reportCheck = (params: any) => {
- return <IconFont type='icon-baobiaochaxun' />
- };
- const crosstabReport = (params: any) => {
- return <IconFont type='icon-baobiaochaxun' />
- };
- //布局配置
- export const layout = ({ initialState, setInitialState }: { initialState: any, setInitialState: any }) => {
- const { isCollapsed } = initialState;
- const [openKeys, set_openKeys] = useState<string[]>([]);
- const [selectedKeys, set_selectedKeys] = useState<string[]>([]);
- 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 = <Icon component={imgNode} />;
- }
- if (node.path == '/budgetMana') {
- node.icon = <Icon component={fileIcon} />;
- }
- if (node.path == '/setting') {
- node.icon = <Icon component={setting} />;
- }
- if (node.path == '/reportCheck') {
- node.icon = <Icon component={setting} />;
- }
- if (node.path == '/secondaryDistribute') {
- node.icon = <Icon component={secondaryDistribute} />;
- }
- if (node.path == '/reportCheck') {
- node.icon = <Icon component={reportCheck} />;
- }
- if (node.path == '/crosstabReport') {
- node.icon = <Icon component={reportCheck} />;
- }
- }
- if (node.children) {
- node.children.forEach((child: any) => addIconToPath(child, paths));
- }
- // node.icon = <FolderOutlined />;
- // 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 (
- <div style={{
- position: 'absolute', zIndex: 10, right: 17, bottom: 12,
- display: 'flex', justifyContent: 'center', alignItems: 'center',
- cursor: 'pointer', width: 24, height: 24
- }} onClick={
- () => {
- onCollapse(isCollapsed ? false : true);
- }
- }><IconFont className='menuCollapseIcon' type={isCollapsed ? 'icon-celanzhankai' : 'icon-celanshouqi'} /></div>
- )
- },
- collapsed: isCollapsed,
- contentStyle: {
- border: '16px solid #F7F9FC',
- //height: '94.5vh', //以去除顶部导航高度
- borderRadius: '22px',
- background: '#F7F9FC',
- height:'calc(100vh - 48px)'
- // overflow:'scroll',
- // margin:'20px 20px'
- },
- };
- };
|