| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- // 路由components映射
- import type { IRouteProps } from 'umi';
- import type { MenuItem } from '@/pages/system/Menu/typing';
- import type { BUTTON_PERMISSION, MENUS_CODE_TYPE } from './router';
- import { getDetailNameByCode, MENUS_CODE } from './router';
- /** localStorage key */
- export const MENUS_DATA_CACHE = 'MENUS_DATA_CACHE';
- export const MENUS_BUTTONS_CACHE = 'MENUS_BUTTONS_CACHE';
- const DetailCode = 'detail';
- // 额外子级路由
- const extraRouteObj = {
- notice: {
- children: [
- { code: 'Config', name: '通知配置' },
- { code: 'Template', name: '通知模版' },
- ],
- },
- 'media/Cascade': {
- children: [
- { code: 'Save', name: '新增' },
- { code: 'Channel', name: '选择通道' },
- ],
- },
- 'media/Device': {
- children: [
- { code: 'Save', name: '详情' },
- { code: 'Channel', name: '通道列表' },
- { code: 'Playback', name: '回放' },
- ],
- },
- 'rule-engine/Scene': {
- children: [
- { code: 'Save', name: '详情' },
- { code: 'Save2', name: '测试详情' },
- ],
- },
- 'device/Firmware': {
- children: [{ code: 'Task', name: '升级任务' }],
- },
- // 'link/Channel': {
- // children: [
- // {
- // code: 'Opcua',
- // name: 'OPC UA',
- // children: [
- // {
- // code: 'Access',
- // name: '数据点绑定',
- // },
- // ],
- // },
- // {
- // code: 'Modbus',
- // name: 'Modbus',
- // children: [
- // {
- // code: 'Access',
- // name: '数据点绑定',
- // },
- // ],
- // },
- // ],
- // },
- demo: {
- children: [{ code: 'AMap', name: '地图' }],
- },
- 'system/Platforms': {
- children: [
- { code: 'Api', name: '赋权' },
- { code: 'View', name: 'Api详情' },
- ],
- },
- 'system/DataSource': {
- children: [{ code: 'Management', name: '管理' }],
- },
- 'system/Menu': {
- children: [{ code: 'Setting', name: '菜单配置' }],
- },
- 'system/Apply': {
- children: [
- { code: 'Api', name: '赋权' },
- { code: 'View', name: 'Api详情' },
- { code: 'Save', name: '详情' },
- ],
- },
- };
- //额外路由
- export const extraRouteArr = [
- {
- code: 'account',
- id: 'accout',
- name: '个人中心',
- url: '/account',
- hideInMenu: true,
- children: [
- {
- code: 'account/Center',
- name: '基本设置',
- url: '/account/center',
- },
- {
- code: 'account/NotificationSubscription',
- name: '通知订阅',
- url: '/account/NotificationSubscription',
- },
- {
- code: 'account/NotificationRecord',
- name: '通知记录',
- url: '/account/NotificationRecord',
- },
- ],
- },
- ];
- /**
- * 根据url获取映射的组件
- * @param files
- */
- const findComponents = (files: __WebpackModuleApi.RequireContext) => {
- const modules = {};
- files.keys().forEach((key) => {
- // 删除路径开头的./ 以及结尾的 /index;
- const str = key.replace(/(\.\/|\.tsx)/g, '').replace('/index', '');
- modules[str] = files(key).default;
- });
- return modules;
- };
- /**
- * 扁平化路由树
- * @param routes
- */
- export const flatRoute = (routes: MenuItem[]): MenuItem[] => {
- return routes.reduce<MenuItem[]>((pValue, currValue) => {
- const menu: MenuItem[] = [];
- const { children, ...extraRoute } = currValue;
- menu.push(extraRoute);
- return [...pValue, ...menu, ...flatRoute(children || [])];
- }, []);
- };
- /**
- * 获取菜单详情组件
- * @param baseCode
- * @url 菜单url
- */
- const findDetailRoute = (baseCode: string, url: string): MenuItem | undefined => {
- if (baseCode) {
- const allComponents = findComponents(require.context('@/pages', true, /index(\.tsx)$/));
- const code = `${baseCode}/Detail`;
- const path = `${url}/${DetailCode}/:id`;
- const component = allComponents[code];
- return component
- ? ({ path: path, url: path, name: getDetailNameByCode[code], hideInMenu: true, code } as
- | MenuItem
- | any)
- : undefined;
- }
- return undefined;
- };
- const findExtraRoutes = (baseCode: string, children: any[], url: string) => {
- const allComponents = findComponents(require.context('@/pages', true, /index(\.tsx)$/));
- return children
- .map((route) => {
- const code = `${baseCode}/${route.code}`;
- const path = `${url}/${route.code}`;
- const component = allComponents[code];
- const _route: any = {
- path: path,
- url: path,
- name: route.name,
- hideInMenu: true,
- code: code,
- };
- if (route.children && route.children.length) {
- _route.children = findExtraRoutes(code, route.children, path);
- }
- return component ? _route : undefined;
- })
- .filter((item) => !!item);
- };
- /**
- * 处理实际路由情况,会包含不显示的子级路由,比如详情
- * @param routes
- * @param level
- */
- export const handleRoutes = (routes?: MenuItem[], level = 1): MenuItem[] => {
- return routes
- ? routes.map((item) => {
- // 判断当前是否有额外子路由
- const extraRoutes = extraRouteObj[item.code];
- if (extraRoutes) {
- if (extraRoutes.children) {
- const eRoutes = findExtraRoutes(item.code, extraRoutes.children, item.url);
- item.children = item.children ? [...eRoutes, ...item.children] : eRoutes;
- }
- }
- const detailComponent = findDetailRoute(item.code, item.url);
- if (detailComponent) {
- item.children = item.children ? [detailComponent, ...item.children] : [detailComponent];
- }
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- if (item.children) {
- item.children = handleRoutes(item.children, level + 1);
- }
- item.level = level;
- return item;
- })
- : [];
- };
- /**
- * 处理为正确的路由格式
- * @param extraRoutes 后端菜单数据
- * @param level 路由层级
- */
- const getRoutes = (extraRoutes: MenuItem[], level = 1): IRouteProps[] => {
- const allComponents = findComponents(require.context('@/pages', true, /index(\.tsx)$/));
- return extraRoutes.map((route) => {
- const component = allComponents[route.code] || null;
- const _route: IRouteProps = {
- key: route.url,
- name: route.name,
- path: route.url,
- };
- if (route.children && route.children.length) {
- const flatRoutes = getRoutes(flatRoute(route.children || []), level + 1);
- const redirect = flatRoutes.filter((r) => r.component)[0]?.path;
- _route.children = redirect
- ? [
- ...flatRoutes,
- {
- path: _route.path,
- exact: true,
- redirect: redirect,
- },
- ]
- : flatRoutes;
- } else if (component) {
- _route.component = component;
- }
- if (level !== 1) {
- _route.exact = true;
- }
- return _route;
- });
- };
- export const getMenus = (extraRoutes: IRouteProps[]): any[] => {
- return extraRoutes.map((route) => {
- const children = route.children && route.children.length ? route.children : [];
- return {
- key: route.url,
- name: route.name,
- path: route.url,
- icon: route.icon,
- hideInMenu: !!route.hideInMenu,
- exact: route.level !== 1,
- children: getMenus(children),
- };
- });
- };
- /** 缓存路由数据,格式为 [{ code: url }] */
- export const saveMenusCache = (routes: MenuItem[]) => {
- const list: MenuItem[] = flatRoute(routes);
- const listObject = {};
- const buttons = {};
- list.forEach((route) => {
- listObject[route.code] = route.url;
- });
- // 过滤按钮权限
- list
- .filter((item) => item.buttons)
- .forEach((item) => {
- buttons[item.code] = item.buttons.map((btn) => btn.id);
- });
- try {
- localStorage.setItem(MENUS_DATA_CACHE, JSON.stringify(listObject));
- localStorage.setItem(MENUS_BUTTONS_CACHE, JSON.stringify(buttons));
- } catch (e) {
- console.warn(e);
- }
- };
- /**
- * 匹配按钮权限
- * @param code 路由code
- * @param permission {string | string[]} 权限名称
- */
- export const getButtonPermission = (
- code: MENUS_CODE_TYPE,
- permission: BUTTON_PERMISSION | BUTTON_PERMISSION[],
- ): boolean => {
- if (!code) {
- return false;
- }
- let buttons = {};
- try {
- const buttonString = localStorage.getItem(MENUS_BUTTONS_CACHE);
- buttons = JSON.parse(buttonString || '{}');
- } catch (e) {
- console.warn(e);
- }
- if (!!Object.keys(buttons).length && permission) {
- const _buttonArray = buttons[code];
- if (!_buttonArray) {
- return true;
- }
- return !_buttonArray.some((btnId: string) => {
- if (typeof permission === 'string') {
- return permission === btnId;
- } else {
- return permission.includes(btnId);
- }
- return false;
- });
- }
- return true;
- };
- /**
- * 通过缓存的数据取出相应的路由url
- * @param code
- */
- export const getMenuPathByCode = (code: MENUS_CODE_TYPE): string => {
- const menusStr = localStorage.getItem(MENUS_DATA_CACHE) || '{}';
- const menusData = JSON.parse(menusStr);
- return menusData[code];
- };
- /**
- * 通过缓存的数据取出相应的路由url
- * @param code 路由Code
- * @param id 路由携带参数
- * @param regStr 路由参数code
- */
- export const getMenuPathByParams = (code: string, id?: string, regStr: string = ':id') => {
- const menusData = getMenuPathByCode(code);
- if (!menusData) {
- console.warn('menusData is', menusData);
- }
- return id && menusData ? menusData.replace(regStr, id) : menusData;
- };
- export default getRoutes;
- export { MENUS_CODE };
|