2020-02-12 01:02:23 +08:00
|
|
|
import memoizeOne from 'memoize-one';
|
|
|
|
import isEqual from 'lodash/isEqual';
|
|
|
|
import { message } from 'antd';
|
|
|
|
import router from 'umi/router';
|
|
|
|
import { formatMessage } from 'umi/locale';
|
|
|
|
import Authorized from '../utils/Authorized';
|
|
|
|
import { menu } from '../defaultSettings';
|
|
|
|
import {
|
|
|
|
dynamicRoutes,
|
|
|
|
dynamicButtons,
|
|
|
|
list,
|
2021-11-05 01:26:59 +08:00
|
|
|
parentList,
|
2020-02-12 01:02:23 +08:00
|
|
|
submit,
|
|
|
|
detail,
|
|
|
|
remove,
|
|
|
|
tree,
|
2021-11-05 01:26:59 +08:00
|
|
|
dataScopeList,
|
2020-02-12 01:02:23 +08:00
|
|
|
} from '../services/menu';
|
2021-11-05 01:26:59 +08:00
|
|
|
import { dict } from '../services/dict';
|
2020-02-12 01:02:23 +08:00
|
|
|
import { getRoutes, setRoutes, getButtons, setButtons } from '../utils/authority';
|
|
|
|
import { MENU_NAMESPACE } from '../actions/menu';
|
|
|
|
import { formatRoutes, formatButtons } from '../utils/utils';
|
|
|
|
|
|
|
|
const { check } = Authorized;
|
|
|
|
|
|
|
|
// Conversion router to menu.
|
|
|
|
function formatter(data, parentAuthority, parentName) {
|
|
|
|
return data
|
|
|
|
.map(item => {
|
|
|
|
if (!item.name || !item.path) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
let locale = 'menu';
|
|
|
|
if (parentName) {
|
|
|
|
locale = `${parentName}.${item.name}`;
|
|
|
|
} else {
|
|
|
|
locale = `menu.${item.name}`;
|
|
|
|
}
|
|
|
|
// if enableMenuLocale use item.name,
|
|
|
|
// close menu international
|
|
|
|
const name = menu.disableLocal
|
|
|
|
? item.name
|
|
|
|
: formatMessage({ id: locale, defaultMessage: item.name });
|
|
|
|
const result = {
|
|
|
|
...item,
|
|
|
|
name,
|
|
|
|
locale,
|
|
|
|
authority: item.authority || parentAuthority,
|
|
|
|
};
|
|
|
|
if (item.routes) {
|
|
|
|
const children = formatter(item.routes, item.authority, locale);
|
|
|
|
// Reduce memory usage
|
|
|
|
result.children = children;
|
|
|
|
}
|
|
|
|
delete result.routes;
|
|
|
|
return result;
|
|
|
|
})
|
|
|
|
.filter(item => item);
|
|
|
|
}
|
|
|
|
|
|
|
|
const memoizeOneFormatter = memoizeOne(formatter, isEqual);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get SubMenu or Item
|
|
|
|
*/
|
|
|
|
const getSubMenu = item => {
|
|
|
|
// doc: add hideChildrenInMenu
|
|
|
|
if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) {
|
|
|
|
return {
|
|
|
|
...item,
|
|
|
|
children: filterMenuData(item.children), // eslint-disable-line
|
|
|
|
};
|
|
|
|
}
|
|
|
|
return item;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* filter menuData
|
|
|
|
*/
|
|
|
|
const filterMenuData = menuData => {
|
|
|
|
if (!menuData) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
return menuData
|
|
|
|
.filter(item => item.name && !item.hideInMenu)
|
|
|
|
.map(item => check(item.authority, getSubMenu(item)))
|
|
|
|
.filter(item => item);
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* 获取面包屑映射
|
|
|
|
* @param {Object} menuData 菜单配置
|
|
|
|
*/
|
|
|
|
const getBreadcrumbNameMap = menuData => {
|
|
|
|
const routerMap = {};
|
|
|
|
|
|
|
|
const flattenMenuData = data => {
|
|
|
|
data.forEach(menuItem => {
|
|
|
|
if (menuItem.children) {
|
|
|
|
flattenMenuData(menuItem.children);
|
|
|
|
}
|
|
|
|
// Reduce memory usage
|
|
|
|
routerMap[menuItem.path] = menuItem;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
flattenMenuData(menuData);
|
|
|
|
return routerMap;
|
|
|
|
};
|
|
|
|
|
|
|
|
const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual);
|
|
|
|
|
|
|
|
export default {
|
|
|
|
namespace: MENU_NAMESPACE,
|
|
|
|
|
|
|
|
state: {
|
|
|
|
menuData: [],
|
|
|
|
breadcrumbNameMap: {},
|
|
|
|
data: {
|
|
|
|
list: [],
|
|
|
|
pagination: false,
|
|
|
|
},
|
|
|
|
init: {
|
|
|
|
tree: [],
|
|
|
|
},
|
2021-11-05 01:26:59 +08:00
|
|
|
dict: {
|
|
|
|
dataScopeType: [],
|
|
|
|
},
|
2020-02-12 01:02:23 +08:00
|
|
|
detail: {},
|
2021-11-05 01:26:59 +08:00
|
|
|
drawer: {
|
|
|
|
visible: false,
|
|
|
|
menuId: '',
|
|
|
|
menuName: '',
|
|
|
|
dataScope: {
|
|
|
|
list: [],
|
|
|
|
pagination: false,
|
|
|
|
},
|
|
|
|
},
|
2020-02-12 01:02:23 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
effects: {
|
|
|
|
*fetchMenuData({ payload }, { call, put }) {
|
|
|
|
const { authority } = payload;
|
|
|
|
// 设置菜单数据
|
|
|
|
let routes = getRoutes();
|
|
|
|
if (routes.length === 0) {
|
|
|
|
const response = yield call(dynamicRoutes);
|
|
|
|
routes = formatRoutes(response.data);
|
|
|
|
setRoutes(routes);
|
|
|
|
}
|
|
|
|
// 设置按钮数据
|
|
|
|
let buttons = getButtons();
|
|
|
|
if (buttons.length === 0) {
|
|
|
|
const response = yield call(dynamicButtons);
|
|
|
|
buttons = formatButtons(response.data);
|
|
|
|
setButtons(buttons);
|
|
|
|
}
|
|
|
|
const menuData = filterMenuData(memoizeOneFormatter(routes, authority));
|
|
|
|
const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(menuData);
|
|
|
|
yield put({
|
|
|
|
type: 'save',
|
|
|
|
payload: { menuData, breadcrumbNameMap },
|
|
|
|
});
|
|
|
|
},
|
|
|
|
*fetchList({ payload }, { call, put }) {
|
|
|
|
const response = yield call(list, payload);
|
|
|
|
if (response.success) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveList',
|
|
|
|
payload: {
|
|
|
|
list: response.data,
|
|
|
|
pagination: false,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2021-11-05 01:26:59 +08:00
|
|
|
*fetchParentList({ payload }, { call, put }) {
|
|
|
|
const response = yield call(parentList, payload);
|
|
|
|
if (response.success) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveList',
|
|
|
|
payload: {
|
|
|
|
list: response.data,
|
|
|
|
pagination: false,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2020-02-12 01:02:23 +08:00
|
|
|
*fetchInit({ payload }, { call, put }) {
|
|
|
|
const response = yield call(tree, payload);
|
|
|
|
if (response.success) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveInit',
|
|
|
|
payload: {
|
|
|
|
tree: response.data,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
*fetchDetail({ payload }, { call, put }) {
|
|
|
|
const response = yield call(detail, payload);
|
|
|
|
if (response.success) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveDetail',
|
|
|
|
payload: {
|
|
|
|
detail: response.data,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
*clearDetail({ payload }, { put }) {
|
|
|
|
yield put({
|
|
|
|
type: 'removeDetail',
|
|
|
|
payload: { payload },
|
|
|
|
});
|
|
|
|
},
|
|
|
|
*selectIcon({ payload }, { put }) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveIcon',
|
|
|
|
payload: {
|
|
|
|
detail: payload,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
},
|
2021-11-05 01:26:59 +08:00
|
|
|
*showDrawer({ payload }, { put }) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveDrawer',
|
|
|
|
payload,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
*loadDataScopeDrawer({ payload }, { call, put }) {
|
|
|
|
const response = yield call(dataScopeList, payload);
|
|
|
|
if (response.success) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveLoadDataScopeDrawer',
|
|
|
|
payload: {
|
|
|
|
dataScope: {
|
|
|
|
list: response.data.records,
|
|
|
|
pagination: {
|
|
|
|
total: response.data.total,
|
|
|
|
current: response.data.current,
|
|
|
|
pageSize: response.data.size,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
*loadDataScopeDict({ payload }, { call, put }) {
|
|
|
|
const response = yield call(dict, payload);
|
|
|
|
if (response.success) {
|
|
|
|
yield put({
|
|
|
|
type: 'saveDataScopeDict',
|
|
|
|
payload: {
|
|
|
|
dataScopeType: response.data,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2020-02-12 01:02:23 +08:00
|
|
|
*submit({ payload }, { call }) {
|
|
|
|
const response = yield call(submit, payload);
|
|
|
|
if (response.success) {
|
|
|
|
message.success('提交成功');
|
|
|
|
router.push('/system/menu');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
*remove({ payload }, { call }) {
|
|
|
|
const {
|
|
|
|
data: { keys },
|
|
|
|
success,
|
|
|
|
} = payload;
|
|
|
|
const response = yield call(remove, { ids: keys });
|
|
|
|
if (response.success) {
|
|
|
|
success();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
reducers: {
|
|
|
|
save(state, action) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
...action.payload,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
saveList(state, action) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
data: action.payload,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
saveInit(state, action) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
init: action.payload,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
saveDetail(state, action) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
detail: action.payload.detail,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
saveIcon(state, action) {
|
|
|
|
const newState = state;
|
|
|
|
newState.detail.source = action.payload.detail.source;
|
|
|
|
return {
|
|
|
|
...newState,
|
|
|
|
};
|
|
|
|
},
|
2021-11-05 01:26:59 +08:00
|
|
|
saveDrawer(state, action) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
drawer: action.payload,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
saveLoadDataScopeDrawer(state, action) {
|
|
|
|
const newState = state;
|
|
|
|
newState.drawer.dataScope = action.payload.dataScope;
|
|
|
|
return {
|
|
|
|
...newState,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
saveDataScopeDict(state, action) {
|
|
|
|
const newState = state;
|
|
|
|
newState.dict.dataScopeType = action.payload.dataScopeType;
|
|
|
|
return {
|
|
|
|
...newState,
|
|
|
|
};
|
|
|
|
},
|
2020-02-12 01:02:23 +08:00
|
|
|
removeDetail(state) {
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
detail: {},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|