import { sagas as commonSagas, reducers as commonReducers } from './commonModels';
import { getNavData, GetNavDataOptions } from './router/nav';
import './app.less';
import router, { NavData } from './router';
import { message as antdMessage, Spin } from 'antd';
import { history, adminNormalActions } from './util/util';
import menuModel, { MenuDecorator, MenuState, GetOperatorInfoConfig
, setGetOperatorInfoConfig } from './commonModels/menu';
import React from 'react';
import TTApp, { AppOptions, AppPersistConfig, StoreConfig } from '@epig/luna';
import { createTransform } from '@epig/luna/lib/persist';
import DefaultLoadingComponent from './components/DefaultLoadingComponent';
import { setDefaultLoadingComponent } from './components/DynamicComponent';
import { ApiPath } from '@epig/luna/lib/model/apiHelper';
import { setGetCommonParams } from '@epig/luna/lib/hooks/useApi';
const apiReg = {
api: /^api-/,
error: /_error$/,
};
function getTokenFromStore(tokenState, tokenKeys) {
const token = {};
tokenKeys.forEach(key => {
if (typeof tokenState[key] !== 'undefined' && tokenState[key] !== null) {
token[key] = tokenState[key];
}
});
return token;
}
export const addTokenMiddleware = (tokenKeys = []) => store => next => action => {
const tokenState = store.getState().token;
if (tokenState) {
const token = getTokenFromStore(tokenState, tokenKeys);
if (apiReg.api.test(action.type)) {
let result = next({
...action,
payload: {
...token,
...action.payload,
},
});
return result;
}
}
let result2 = next(action);
return result2;
};
export function isRequestErrorAction(action) {
return apiReg.api.test(action.type) && apiReg.error.test(action.type);
}
export const requestErrorMiddleware = message => store => next => action => {
let result = next(action);
if (isRequestErrorAction(action)) {
const error = action.payload.error;
if (message) {
message.error(error.des);
}
if (error.status === -103 || error.status === 401) {
next(adminNormalActions.loginTimeout({}));
if (!history) {
console.error('history不能为空,使用setHistory方法设置history');
} else {
history.push({
pathname: '/user/login',
});
}
}
}
return result;
};
const closeModalPaneMiddleware = store => next => action => {
const menu = store.getState().menu as MenuState;
if (menu.modalPaneConfig) {
if ((menu.modalPaneConfig.cancelActionNames || []).indexOf(action.type) >= 0) {
store.dispatch(menuModel.actions.simple.cancelModal({}));
}
}
return next(action);
};
export function defaultAdminRequestErrorHandle(res) {
if (res.payload.error || res.payload.res.status !== 0) {
let error = res.payload.error;
if (!error) {
error = res.payload.res;
}
return error;
}
return null;
}
let defaultTransform = createTransform(
(state, key) => {
if (key === 'menu') {
return {
menus: [],
exception: null,
paneConfigs: state.paneConfigs.map(item => {
return {
...item,
componentName: item.originComponentName,
options: null,
};
}),
name: state.name,
avatar: state.avatar,
headerTheme: state.headerTheme,
siderTheme: state.siderTheme,
previewHeaderTheme: null,
previewSiderTheme: null,
breadcrumbNames: state.breadcrumbNames,
activeSubMenu: state.activeSubMenu,
};
}
return state;
},
(state, key) => {
if (key === 'menu') {
return {
...state,
menus: [],
exception: null,
};
}
return state;
},
{ whitelist: ['menu'] },
);
export interface AdminStoreConfig extends StoreConfig {
noAddToken?: boolean;
tokenKeys?: any[];
noHandleRequestError?: boolean;
}
const defaultAdminPersistConfig: AppPersistConfig = {
key: 'admin',
whiteList: [
'token',
'menu',
],
transforms: [defaultTransform],
wrapperLoadingComponent: (
),
};
export interface TTAppModelOptions {
noCommonModels?: boolean;
message?: any;
syncModels?: {reducers: any; sagas: any};
basePath?: ApiPath;
}
export interface CommonContainers {
[key: string]: {
component: any;
models: any[];
};
}
export interface TTAdminAppOptions {
persistConfig?: AppPersistConfig;
model?: TTAppModelOptions;
store?: AdminStoreConfig;
routes?: () => any[];
appName: string;
/**
* 自定义navData
*/
getNavData?: any;
/**
* 不请求菜单
*/
noRequestMenu?: boolean;
/**
* 自定义菜单,用于前端写死菜单的情况
*/
customMenus?: ((state: any) => MenuDecorator[]) | MenuDecorator[];
/**
* 多标签页(默认值为true)
*/
multipleTab?: boolean;
/**
* 配置异步加载的Loading组件
*/
DynamicDefaultLoadingComponent?: React.ReactNode;
/** 自定义请求错误处理 */
adminRequestErrorHandle?: (res: any) => any;
processResponse?: (res: any) => any;
/** 发起checkPermission action,配合noRequestMenu使用 */
checkPermission?: boolean;
navDataOptions?: GetNavDataOptions;
getOperatorInfoConfig?: GetOperatorInfoConfig;
/**
* 公共容器,用于多个容器用到同一个子容器的情况
*/
commonContainers?: () => CommonContainers;
}
const DEFAULT_TTADMINAPP_OPTIONS: TTAdminAppOptions = {
appName: '',
noRequestMenu: false,
multipleTab: true,
customMenus: [],
DynamicDefaultLoadingComponent: ,
};
export default class TTAdminApp {
appName: string;
noRequestMenu: boolean;
checkPermission: boolean;
commonContainers: () => CommonContainers;
private _nav: NavData[];
private _routes: () => any[];
private _getNavData: any;
private _core: TTApp;
private _navDataOptions: GetNavDataOptions;
constructor(options: TTAdminAppOptions) {
this._navDataOptions = options.navDataOptions || {};
options = {
...DEFAULT_TTADMINAPP_OPTIONS,
...options,
};
const message = options.model ? options.model.message || antdMessage : antdMessage;
let storeOptions = options.store || {};
storeOptions = {
...storeOptions,
middlewares: [
closeModalPaneMiddleware,
].concat(storeOptions.middlewares || []),
};
if (!storeOptions.noAddToken) {
const tokenKeys = storeOptions.tokenKeys || ['token', 'operatorId'];
storeOptions.middlewares = [
addTokenMiddleware(tokenKeys),
].concat(storeOptions.middlewares);
setGetCommonParams(() => {
const tokenState = this._core.store.getState().token || {};
const token = getTokenFromStore(tokenState, tokenKeys);
return token;
});
}
if (!storeOptions.noHandleRequestError) {
storeOptions.middlewares = [
requestErrorMiddleware(message),
].concat(storeOptions.middlewares);
}
const persistConfig = {
...defaultAdminPersistConfig,
...(options.persistConfig || {}),
};
let ttAppOptions: AppOptions = {
store: storeOptions,
persistConfig: persistConfig,
render: () => {
return router(this._nav, this);
},
model: {
message: message,
requestErrorHandle: options.adminRequestErrorHandle || defaultAdminRequestErrorHandle,
basePath: options.model ? options.model.basePath || '' : '',
processRes: options.processResponse,
},
};
this._core = new TTApp(ttAppOptions);
setGetOperatorInfoConfig(options.getOperatorInfoConfig);
if (!options.model || !options.model.noCommonModels) {
this.model(commonReducers, commonSagas);
}
if (options.model && options.model.syncModels) {
this.model(options.model.syncModels.reducers, options.model.syncModels.sagas);
}
/**
* 读取缓存前要先加载所有同步model
*/
this._core.persist();
if (!options.model || !options.model.noCommonModels) {
this._core.store.dispatch(menuModel.actions.simple.changeMultiTab({
multipleTab: options.multipleTab,
}));
if (options.noRequestMenu) {
this._core.store.dispatch(menuModel.actions.simple.setMenus({
menus: typeof options.customMenus === 'function'
? options.customMenus(this._core.store.getState()) : options.customMenus,
noRequestMenu: options.noRequestMenu,
}));
}
}
this._getNavData = options.getNavData || null;
this._routes = options.routes;
this.appName = options.appName;
this.noRequestMenu = options.noRequestMenu;
this.checkPermission = options.checkPermission;
this.commonContainers = options.commonContainers;
setDefaultLoadingComponent(() => options.DynamicDefaultLoadingComponent );
}
setRouter() {
if (this._getNavData) {
return this._getNavData();
}
return getNavData(this._routes, this._navDataOptions);
}
model(reducers, sagas) {
this._core.model(reducers, sagas);
}
start(containerId: string) {
this._nav = this.setRouter();
this._core.start(containerId);
}
}