From ea9d601bd7942abcff4665a5b643c2f1bd349081 Mon Sep 17 00:00:00 2001 From: kerwin612 Date: Tue, 12 Sep 2023 15:13:32 +0800 Subject: [PATCH] Automatically refresh menu list after modify the data in config/plugin --- src/layouts/BasicLayout.js | 101 ++++------------------- src/models/global.js | 12 ++- src/routes/System/Plugin/index.js | 7 +- src/routes/System/User/DataPermModal.js | 5 +- src/utils/AuthRoute.js | 105 +++++++++++++++++++++++- src/utils/plugin.js | 24 +----- 6 files changed, 133 insertions(+), 121 deletions(-) diff --git a/src/layouts/BasicLayout.js b/src/layouts/BasicLayout.js index 298a4fd02..b71d0fedd 100644 --- a/src/layouts/BasicLayout.js +++ b/src/layouts/BasicLayout.js @@ -32,7 +32,6 @@ import AuthRoute, {checkMenuAuth, getAuthMenus} from "../utils/AuthRoute"; import {getMenuData} from "../common/menu"; import logo from "../assets/logo.svg"; import TitleLogo from "../assets/TitleLogo.svg"; -import {getIntlContent} from "../utils/IntlUtils"; const MyContext = React.createContext(); @@ -116,7 +115,6 @@ class BasicLayout extends React.PureComponent { ? window.sessionStorage.getItem("locale") : "en-US", pluginsLoaded: false, - processedMenus: [] }; } @@ -136,7 +134,6 @@ class BasicLayout extends React.PureComponent { }); return; } - this.processMenus() const { dispatch } = this.props; dispatch({ type: "global/fetchPlatform" @@ -156,6 +153,16 @@ class BasicLayout extends React.PureComponent { }); } + componentDidUpdate() { + const { dispatch } = this.props; + dispatch({ + type: "resource/authorizedMenuTree", + payload: { + authMenu: this.processMenus() + } + }); + } + componentWillUnmount() { this.setState = () => {} } @@ -216,92 +223,13 @@ class BasicLayout extends React.PureComponent { type: "global/changeLanguage", payload: value }); - this.processMenus() }; processMenus() { - const { plugins, menuTree, permissions, dispatch } = this.props - const { pluginsLoaded } = this.state - let menus = getMenuData(); - if (menuTree.length > 0) { - menus = menus.slice(0, 1); - menuTree.forEach(item => { - if (item.name !== 'plug') { - let title = getIntlContent(item.meta.title); - menus.push({ - name : title === '' ? item.meta.title : title, - icon : item.meta.icon, - path : item.url, - locale : item.meta.title, - children: item.children.map(child => { - let childTitle = getIntlContent(child.meta.title); - return { - name : childTitle === '' ? child.meta.title : childTitle, - icon : child.meta.icon, - path : child.url, - locale : child.meta.title, - }; - }) - }); - } - }); - } - - const menuMap = {}; - plugins.forEach(item => { - if (menuMap[item.role] === undefined) { - menuMap[item.role] = []; - } - menuMap[item.role].push(item); - }); - Object.keys(menuMap).forEach((key) => { - menus[0].children.push({ - name: key, - path: `/plug/${menuMap[key][0].role}`, - authority: undefined, - icon: "unordered-list", - children: menuMap[key].map(item => { - const { name } = item; - return { - name: name.replace(name[0], name[0].toUpperCase()), - path: `/plug/${item.role}/${item.name}`, - authority: undefined, - id: item.id, - locale: `SHENYU.MENU.PLUGIN.${item.name.toUpperCase()}`, - exact: true - }; - }) - }); - }); - - menus = getAuthMenus(menus, permissions, pluginsLoaded); - - // Filter empty menu - function removeEmptyMenu(menuArr) { - return menuArr.filter(menu => { - if (Array.isArray(menu.children)) { - if (menu.children.length === 0) { - return false; - } else { - menu.children = removeEmptyMenu(menu.children); - } - } - return true; - }); - } - - if (Array.isArray(menus) && menus.length) { - removeEmptyMenu(menus); - } - - dispatch({ - type: "resource/authorizedMenuTree", - payload: { - authMenu: menus - } - }); + const { plugins, menuTree, permissions } = this.props; + const { pluginsLoaded } = this.state; - this.setState({processedMenus: menus}) + return getAuthMenus(plugins, menuTree, permissions, pluginsLoaded); } render() { @@ -312,7 +240,8 @@ class BasicLayout extends React.PureComponent { location, dispatch } = this.props; - const { localeName, processedMenus } = this.state; + const { localeName } = this.state; + const processedMenus = this.processMenus(); const bashRedirect = this.getBaseRedirect(); const layout = ( diff --git a/src/models/global.js b/src/models/global.js index 621c4be8a..660969193 100644 --- a/src/models/global.js +++ b/src/models/global.js @@ -43,7 +43,7 @@ export default { } }, *fetchPlugins({ payload }, { call, put }) { - const { callback } = payload; + const { callback } = payload ?? {}; const params = { currentPage: 1, pageSize: 50 @@ -52,7 +52,9 @@ export default { if (json.code === 200) { let { dataList } = json.data; - callback(dataList) + if (callback) { + callback(dataList); + } yield put({ type: "savePlugins", payload: { @@ -97,7 +99,7 @@ export default { callback(permissions); }, *refreshPermission({ payload }, { call, put }) { - const { callback } = payload; + const { callback } = payload ?? {}; let permissions = { menu: [], button: [] }; const token = window.sessionStorage.getItem("token"); if(token){ @@ -113,7 +115,9 @@ export default { type: "savePermissions", payload: { permissions } }); - callback(permissions); + if (callback) { + callback(permissions); + } }, *resetPermission(_, { put }) { diff --git a/src/routes/System/Plugin/index.js b/src/routes/System/Plugin/index.js index 0d77b586e..c48a95ac7 100644 --- a/src/routes/System/Plugin/index.js +++ b/src/routes/System/Plugin/index.js @@ -23,7 +23,8 @@ import { resizableComponents } from "../../../utils/resizable"; import AddModal from "./AddModal"; import { getCurrentLocale, getIntlContent } from "../../../utils/IntlUtils"; import AuthButton from "../../../utils/AuthButton"; -import { getUpdateModal, updatePluginsEnabled, refreshGlobalCacheOnUpdated } from "../../../utils/plugin"; +import { refreshAuthMenus } from "../../../utils/AuthRoute"; +import { getUpdateModal, updatePluginsEnabled } from "../../../utils/plugin"; const { Text } = Typography; @@ -179,7 +180,7 @@ export default class Plugin extends Component { }), callback: () => { this.setState({ selectedRowKeys: [] }); - refreshGlobalCacheOnUpdated({ dispatch }); + refreshAuthMenus({ dispatch }); } }); } else { @@ -209,7 +210,7 @@ export default class Plugin extends Component { fetchValue: this.currentQueryPayload(), callback: () => { this.closeModal(true); - refreshGlobalCacheOnUpdated({ dispatch }); + refreshAuthMenus({ dispatch }); } }); }} diff --git a/src/routes/System/User/DataPermModal.js b/src/routes/System/User/DataPermModal.js index 75c582d4a..116ce6c1f 100644 --- a/src/routes/System/User/DataPermModal.js +++ b/src/routes/System/User/DataPermModal.js @@ -67,10 +67,7 @@ export default class DataPermModal extends Component { type: "resource/fetchMenuTree" }); dispatch({ - type: "global/fetchPlugins", - payload: { - callback: () => {} - } + type: "global/fetchPlugins" }); }; diff --git a/src/utils/AuthRoute.js b/src/utils/AuthRoute.js index 379297972..d37ee7adb 100644 --- a/src/utils/AuthRoute.js +++ b/src/utils/AuthRoute.js @@ -21,6 +21,8 @@ import { Redirect } from "react-router-dom"; import { Route } from "dva/router"; import { Spin } from "antd"; import { filterTree } from "./utils"; +import { getIntlContent } from "./IntlUtils"; +import { getMenuData } from "../common/menu"; // not check route url const notCheckRouteUrl = ["/", "/home"]; @@ -85,12 +87,13 @@ export function checkMenuAuth(routeUrl, permissions) { * if authMenusCache is not empty,return from cache, * else return from building * - * @param {Array} menus + * @param {Array} plugins + * @param {Array} menuTree * @param {Array} permissions * @param {Boolean} beginCache */ -export function getAuthMenus(menus, permissions, beginCache) { - let authMenus = []; +export function getAuthMenus(plugins, menuTree, permissions, beginCache) { + if (beginCache && authMenusCache && Object.keys(authMenusCache).length > 0) { let locale = window.sessionStorage.getItem("locale"); let authCacheMenus = authMenusCache[locale]; @@ -98,6 +101,60 @@ export function getAuthMenus(menus, permissions, beginCache) { return authCacheMenus; } } + + let menus = getMenuData(); + if (menuTree.length > 0) { + menus = menus.slice(0, 1); + menuTree.forEach(item => { + if (item.name !== 'plug') { + let title = getIntlContent(item.meta.title); + menus.push({ + name : title === '' ? item.meta.title : title, + icon : item.meta.icon, + path : item.url, + locale : item.meta.title, + children: item.children.map(child => { + let childTitle = getIntlContent(child.meta.title); + return { + name : childTitle === '' ? child.meta.title : childTitle, + icon : child.meta.icon, + path : child.url, + locale : child.meta.title, + }; + }) + }); + } + }); + } + + const menuMap = {}; + plugins.forEach(item => { + if (menuMap[item.role] === undefined) { + menuMap[item.role] = []; + } + menuMap[item.role].push(item); + }); + Object.keys(menuMap).forEach((key) => { + menus[0].children.push({ + name: key, + path: `/plug/${menuMap[key][0].role}`, + authority: undefined, + icon: "unordered-list", + children: menuMap[key].map(item => { + const { name } = item; + return { + name: name.replace(name[0], name[0].toUpperCase()), + path: `/plug/${item.role}/${item.name}`, + authority: undefined, + id: item.id, + locale: `SHENYU.MENU.PLUGIN.${item.name.toUpperCase()}`, + exact: true + }; + }) + }); + }); + + let authMenus = []; if (menus && menus.length > 0) { setMenuIconAndSort(menus, permissions); authMenus = JSON.parse(JSON.stringify(menus)); @@ -120,11 +177,53 @@ export function getAuthMenus(menus, permissions, beginCache) { }); authMenus = authMenus.filter(e => !e.deleted); } + + // Filter empty menu + function removeEmptyMenu(menuArr) { + return menuArr.filter(menu => { + if (Array.isArray(menu.children)) { + if (menu.children.length === 0) { + return false; + } else { + menu.children = removeEmptyMenu(menu.children); + } + } + return true; + }); + } + + if (Array.isArray(authMenus) && authMenus.length) { + removeEmptyMenu(authMenus); + } + if (beginCache) { let locale = window.sessionStorage.getItem("locale"); authMenusCache[locale] = authMenus; } + return authMenus; + +} + +export function refreshAuthMenus({ dispatch }) { + dispatch({ + type: "global/refreshPermission", + payload: { + callback: () => { + dispatch({ + type: "global/fetchPlugins", + payload: { + callback: () => { + resetAuthMenuCache(); + dispatch({ + type: "resource/fetchMenuTree" + }); + } + } + }); + } + } + }); } const setMenuIconAndSort = (menus, permissions) => { diff --git a/src/utils/plugin.js b/src/utils/plugin.js index 7b210e2e8..5f3fcfa16 100644 --- a/src/utils/plugin.js +++ b/src/utils/plugin.js @@ -16,27 +16,9 @@ */ import React from 'react'; -import { resetAuthMenuCache } from "./AuthRoute"; +import { refreshAuthMenus } from "./AuthRoute"; import AddModal from "../routes/System/Plugin/AddModal"; -export function refreshGlobalCacheOnUpdated({ dispatch }) { - dispatch({ - type: "global/fetchPlugins", - payload: { - callback: () => {} - } - }); - - dispatch({ - type: "global/refreshPermission", - payload: { - callback: () => { - resetAuthMenuCache(); - } - } - }); -} - export function getUpdateModal({ pluginId, dispatch, fetchValue, callback, updatedCallback, canceledCallback }) { dispatch({ type: "plugin/fetchItem", @@ -74,7 +56,7 @@ export function getUpdateModal({ pluginId, dispatch, fetchValue, callback, updat if (updatedCallback) { updatedCallback(values); } - refreshGlobalCacheOnUpdated({ dispatch }); + refreshAuthMenus({ dispatch }); } }); }} @@ -99,7 +81,7 @@ export function updatePluginsEnabled({ list, enabled, dispatch, fetchValue, call if (callback) { callback(); } - refreshGlobalCacheOnUpdated({ dispatch }); + refreshAuthMenus({ dispatch }); } }); }