This commit is contained in:
xuziqiang
2024-05-15 17:29:42 +08:00
commit d0155dbe3c
7296 changed files with 1832517 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
import { RouteRecordRaw } from 'vue-router';
import { dynamicImportRoute, getComponent } from '/nerv-base/router/helper/view-helper';
import { routeModule } from '/nerv-base/router/routes';
export interface RouteMenu {
code: string; //组件名
name?: string;
label: string;
sort: number;
parentCode?: string;
backApi?: Recordable[]; //组件内所使用的Api
route?: RouteRecordRaw;
menus?: RouteMenu[];
type?: string; //三种类型 menus菜单 noChildrenMenu不渲染该菜单下的子菜单 op操作
}
/***
* 转换权限菜单到路由
* @param menu
* @param parentCode
*/
export function transformMenuToRoute(menu: RouteMenu, parentCode = '') {
const { route, menus } = menu;
if (route.component) {
route.component = dynamicImportRoute(route.component);
}
const _route: RouteRecordRaw = {
...route,
};
if (menus) {
_route.children = transformMenus(menus);
}
return _route;
}
/***
* 转换权限菜单列表到路由列表
* @param menus
*/
export function transformMenus(menus: RouteMenu[]): RouteRecordRaw[] {
const list = [];
for (let i = 0, l = menus.length; i < l; i++) {
list.push(transformMenuToRoute(menus[i]));
}
return list;
}
export function sortMenu(menus: RouteMenu[]) {
menus.sort((a: RouteMenu, b: RouteMenu) => {
return a.sort - b.sort;
});
return menus;
}
export function dropMenu(menus, info) {
const { dragNode: menu, node: target, dropToGap, dropPosition } = info;
if (
(target.parentCode !== menu.parentCode && target.code !== menu.parentCode) ||
(target.parentCode !== '' && dropToGap === false)
) {
return {
success: false,
msg: '只在栏目内移动',
};
}
const list = getMenusArray(menus, menu);
// 移到当前栏目最顶部
if (target.code === menu.parentCode) {
}
moveMenuItem(list, menu.code, dropPosition, dropToGap);
return {
success: true,
menus,
};
}
/**
* 获得移动的最终数组对象
* @param menus
* @param menu
*/
export function getMenusArray(menus, menu) {
let list: RouteMenu[] = [];
const index = -1;
function _getMenuArray(menus, menu) {
for (let i = 0, l = menus.length; i < l; i++) {
if (menus[i].code === menu.parentCode) {
list = menus[i];
return;
} else if (menus[i].menus) {
_getMenuArray(menus[i].menus, menu);
}
}
}
if (menu.parentCode === '') {
return menus;
}
_getMenuArray(menus, menu);
return list.menus;
}
/**
* 数组内移动
* @param menus
* @param dragNodeCode
* @param dropPosition
* @param dropToGap
*/
function moveMenuItem(menus, dragNodeCode, dropPosition, dropToGap) {
const index = menus.findIndex((item) => dragNodeCode === item.code);
const _menus = menus.splice(index, 1);
if (dropToGap === false) {
menus.unshift(_menus[0]);
} else {
if (index < dropPosition) {
dropPosition--;
}
if (dropPosition === -1) dropPosition = 0;
menus.splice(dropPosition, 0, _menus[0]);
}
for (let i = 0, l = menus.length; i < l; i++) {
menus[i].sort = i + 1;
}
}
export function editMenuLabel(menus: RouteMenu[], code: string, newLabel: string) {
for (let i = 0, l = menus.length; i < l; i++) {
if (menus[i].code === code) {
menus[i].label = newLabel;
// menus[i].route.meta.title = newLabel;
return;
}
if (menus[i].menus) {
editMenuLabel(menus[i].menus as RouteMenu[], code, newLabel);
}
}
}

View File

@@ -0,0 +1,82 @@
import { RouteRecordRaw } from 'vue-router';
import { getComponent } from '/nerv-base/router/helper/view-helper';
import { ModuleMenu } from '/nerv-base/router/types';
import { RouteMenu, sortMenu } from '/nerv-base/router/helper/menu-helper';
import { isNumber } from 'lodash-es';
export function transformRouteToMenu(route: RouteRecordRaw, parentCode = '') {
const { children, ...extend } = route;
if (extend.component) {
const component = getComponent(extend.component.toString());
component && (extend.component = component as any);
}
const code: any = route.meta?.code || route.name || '';
if (!extend.meta) extend.meta = {};
if (extend.meta.index === undefined || !isNumber(extend.meta.index)) {
extend.meta.index = 999;
}
const _menu: ModuleMenu = {
code,
icon: (route.meta?.icon || ' ') as string,
sort: (route.meta?.index || 999) as number,
label: (route.meta?.title || ' ') as string,
type: (route.meta?.type || 'menus') as string,
// name: dealOp(route) as string,
backApi: dealBackApi(route) as Recordable[],
parentCode,
extend: {
keepAlive: (route.meta?.keepAlive || false) as boolean,
// itemList: route.meta?.itemList || null,
},
route: extend,
};
if (children) {
_menu.menus = transformRoutes(children, code);
}
return _menu;
}
function dealBackApi(e: any) {
if (e.meta?.hideChildren) {
if (e.children !== undefined) {
return e.children[0].meta?.backApi || [];
} else {
return e.meta?.backApi ? e.meta?.backApi : [];
}
}
return e.meta?.backApi || [];
}
function dealOp(e: any) {
if (e.meta?.type === 'op') {
return e.name;
} else {
return '';
}
}
export function transformRoutes(routes: RouteRecordRaw[], parentCode = '') {
const list = [];
for (let i = 0, l = routes.length; i < l; i++) {
if (routes[i].meta?.operates && !routes[i].meta?.hideResource) {
routes[i].meta?.operates.forEach((item) => {
const info = {
sort: 999,
type: 'op',
code: item.code,
name: '',
label: item.title,
backApi: item.backApi,
parentCode: parentCode,
};
list.push(info);
});
}
if (routes[i].name !== `${parentCode}Index` && !routes[i].meta?.hideResource) {
list.push(transformRouteToMenu(routes[i], parentCode));
}
}
return sortMenu(list);
}

View File

@@ -0,0 +1,33 @@
const viewsModules: Recordable<() => Promise<Recordable>> = import.meta.glob(
'/src/view/**/*.{vue,tsx}'
);
viewsModules['/saas/view/system/application.vue'] = () =>
import('/nerv-lib/saas/view/system/application.vue');
viewsModules['/saas/view/system/layout/content.vue'] = () =>
import('/nerv-lib/saas/view/system/layout/content.vue');
viewsModules['/saas/view/menuManage/index.vue'] = () =>
import('/nerv-lib/saas/view/menuManage/index.vue');
const viewsModulesKeys = Object.keys(viewsModules);
function getComponent(component: string): string | undefined {
const key = viewsModulesKeys.find((key) => {
return component.includes(key);
});
// !key && console.log('key', component);
return key;
}
function dynamicImportRoute(component: string) {
const dynamicComponent = viewsModules[component];
if (dynamicComponent) {
return dynamicComponent;
} else {
console.error(`can't find ${component}`);
return viewsModules['/saas/view/system/layout/content.vue'];
}
}
export { viewsModules, getComponent, dynamicImportRoute };