push
This commit is contained in:
46
lib/paas/store/modules/app-config.ts
Normal file
46
lib/paas/store/modules/app-config.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
interface AppConfig {
|
||||
projectType: string;
|
||||
baseApi: string;
|
||||
timeout: number;
|
||||
pagePermission: boolean;
|
||||
actionPermission: boolean;
|
||||
customAppTitle?: boolean;
|
||||
layout?: Function;
|
||||
headerBellInfo?: object;
|
||||
customInitMessageCount?: Function | Boolean; // 自定义消息数量获取事件
|
||||
}
|
||||
export const appConfigStore = defineStore({
|
||||
id: 'appConfig',
|
||||
/**
|
||||
* module 测试用
|
||||
* @returns
|
||||
*/
|
||||
state(): AppConfig {
|
||||
return {
|
||||
projectType: 'web',
|
||||
baseApi: '/api',
|
||||
timeout: 15 * 1000,
|
||||
pagePermission: true,
|
||||
actionPermission: true,
|
||||
customAppTitle: false,
|
||||
customInitMessageCount: false,
|
||||
headerBellInfo: {
|
||||
isShow: false,
|
||||
api: '',
|
||||
toRouterName: '',
|
||||
},
|
||||
};
|
||||
},
|
||||
getters: {
|
||||
getHeaderBellInfo: (state: any) => state.headerBellInfo,
|
||||
},
|
||||
actions: {
|
||||
setConfig(config: AppConfig) {
|
||||
Object.keys(config).forEach((key) => {
|
||||
this[key] = config[key];
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
546
lib/paas/store/modules/authorization-service.ts
Normal file
546
lib/paas/store/modules/authorization-service.ts
Normal file
@@ -0,0 +1,546 @@
|
||||
|
||||
|
||||
import { defineStore } from 'pinia';
|
||||
import { http } from '/nerv-lib/util/http';
|
||||
import { stringUtil } from '/nerv-lib/util/string-util';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { toRaw } from 'vue';
|
||||
import { log } from '/nerv-lib/util/log';
|
||||
|
||||
export const authorizationService = defineStore({
|
||||
id: 'authorizationService',
|
||||
/**
|
||||
* token 测试用
|
||||
* userinfo 用户信息
|
||||
* itemMap 权限树
|
||||
* @returns
|
||||
*/
|
||||
state(): {
|
||||
token: boolean;
|
||||
userInfo: any;
|
||||
itemMap: any;
|
||||
defaultRegion: { value: string; label: string; isDefault: any };
|
||||
currentRegion: { value: string; label: string; isDefault: any };
|
||||
regionArray: Array<any>;
|
||||
ModulesRes: Array<any>;
|
||||
permissionMap: Recordable;
|
||||
switches: Recordable;
|
||||
} {
|
||||
return {
|
||||
token: false,
|
||||
userInfo: {},
|
||||
itemMap: {},
|
||||
defaultRegion: { label: '', value: '', isDefault: '' },
|
||||
currentRegion: { label: '', value: '', isDefault: '' },
|
||||
regionArray: [],
|
||||
ModulesRes: [],
|
||||
permissionMap: {},
|
||||
switches: {},
|
||||
};
|
||||
},
|
||||
actions: {
|
||||
login() {},
|
||||
logout() {
|
||||
window.location.href = '/login';
|
||||
},
|
||||
loadAuthorization() {
|
||||
return http.post('/api/passport/passport/objs/Authorization/CheckAuthorization');
|
||||
},
|
||||
loadModules() {
|
||||
return http.get('/api/webui/webui/objs/GetModules');
|
||||
},
|
||||
loadRegion() {
|
||||
return http.get('/api/passport/objs/GetRegionsInfo');
|
||||
},
|
||||
loadSwitch() {
|
||||
return http.get('/api/webui/webui/objs/GetSwitchs');
|
||||
},
|
||||
getAuthMap() {
|
||||
const requestArr = [
|
||||
this.loadAuthorization(),
|
||||
this.loadModules(),
|
||||
this.loadRegion(),
|
||||
this.loadSwitch(),
|
||||
];
|
||||
return Promise.all(requestArr).then((result) => {
|
||||
if (result && result.length >= 2) {
|
||||
log.info('权限加载完成');
|
||||
const authResponse = result[0];
|
||||
const menusResponse = result[1];
|
||||
this.ModulesRes = cloneDeep(result[1]);
|
||||
result[2] ? this.setRegionInfo(result[2]) : '';
|
||||
this.itemMap = this.convertResponse2ItemMap(authResponse, menusResponse);
|
||||
this.permissionMap = this.getPermissionMap(authResponse, menusResponse);
|
||||
this.switches = result[3]?.switchs;
|
||||
|
||||
log.info('生成权限树', toRaw(this.permissionMap));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 是否有权限
|
||||
*
|
||||
* @param moduleName 模块名
|
||||
*
|
||||
* @param subModuleName 子模块名
|
||||
*
|
||||
* @param operationName 操作名
|
||||
*
|
||||
* @returns {boolean} true: 有权限, false: 没有权限
|
||||
*/
|
||||
exists(moduleName: string, subModuleName?: string, operationName?: string): boolean {
|
||||
/**(1)访问主模块*/
|
||||
let key = moduleName;
|
||||
if (subModuleName) {
|
||||
/**(2)访问子模块*/
|
||||
key = key + '_' + subModuleName;
|
||||
}
|
||||
/**(3)某个具体操作*/
|
||||
if (operationName) {
|
||||
key = key + '_' + operationName;
|
||||
}
|
||||
// this.checkAuthMap()
|
||||
return this.itemMap[key] != null || this.isAdmin();
|
||||
},
|
||||
|
||||
// 递归遍历权限树方法
|
||||
traverseMenus(menusItem: any, subMenus: any, itemMap: any, module: any) {
|
||||
if (menusItem['submenus'] && menusItem['submenus'].length > 0) {
|
||||
menusItem['submenus'].forEach((subMenu: any) => {
|
||||
if (subMenu['isGlobalDisplay']) {
|
||||
if (!subMenu['isOperation']) {
|
||||
// 如果是自定义资源且是操作,就不用按照菜单权限写入
|
||||
if (subMenu['operation'] && subMenu['operation']['resource']) {
|
||||
const subMenusName = subMenu['operation']['resource'];
|
||||
subMenus.push(subMenusName);
|
||||
itemMap[module['name'] + '_' + subMenusName] = true;
|
||||
if (subMenu['operations'] && subMenu['operations'].length) {
|
||||
subMenu['operations'].forEach((op: any) => {
|
||||
itemMap[module['name'] + '_' + subMenusName + '__' + op['name']] = true;
|
||||
itemMap[
|
||||
module['name'] + '_' + subMenusName + stringUtil.firstToUpper(op['name'])
|
||||
] = true; //操作对应的页面权限
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 如果是自定义资源且是操作,如【管理】按钮,将它写入父节点的操作里
|
||||
const opName = subMenu?.operation.resource;
|
||||
itemMap[module['name'] + '_' + menusItem['name'] + '__' + opName] = true; // xxApp_xxMenus__xxOpName
|
||||
itemMap[module['name'] + '_' + menusItem['name'] + stringUtil.firstToUpper(opName)] =
|
||||
true; //操作对应的页面权限,如:xxApp_xxMenusXxOpName
|
||||
}
|
||||
this.traverseMenus(subMenu, subMenus, itemMap, module);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
//处理权限树
|
||||
convertResponse2ItemMap(authResponse: any, menusResponse: any) {
|
||||
const itemMap: any = {};
|
||||
/** 如果是具有admin权限用户*/
|
||||
if (authResponse['accountname'] == 'admin' || authResponse['isAdmin']) {
|
||||
itemMap['*'] = '';
|
||||
return itemMap;
|
||||
}
|
||||
/***默认显示的模块或者菜单 如:监控下面的指标监控
|
||||
* 先处理默认显示的模块权限,再处理授权的权限,注意顺序
|
||||
*/
|
||||
if (menusResponse instanceof Array) {
|
||||
menusResponse.forEach((module) => {
|
||||
if (module['isGlobalDisplay']) {
|
||||
let menus: Array<any> = [];
|
||||
if (itemMap[module['name']] == null) {
|
||||
itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
|
||||
}
|
||||
itemMap[module['name']] = '';
|
||||
if (module['menus'] && module['menus'].length > 0) {
|
||||
module['menus'].forEach((menusItem: any) => {
|
||||
if (menusItem['isGlobalDisplay']) {
|
||||
if (menusItem['isGlobal']) {
|
||||
// 1. 全局开放模块又是独立模块
|
||||
itemMap[menusItem['name']] = '';
|
||||
const globalMenus: Array<any> = [];
|
||||
if (menusItem['submenus'] && menusItem['submenus'].length > 0) {
|
||||
menusItem['submenus'].forEach((subMenu: any) => {
|
||||
if (subMenu['isGlobalDisplay']) {
|
||||
if (subMenu['operation'] && subMenu['operation']['resource']) {
|
||||
const globalMenuName = subMenu['operation']['resource'];
|
||||
globalMenus.push(globalMenuName);
|
||||
itemMap[menusItem['name'] + '_' + globalMenuName] = '';
|
||||
if (subMenu['operations'] && subMenu['operations'].length) {
|
||||
subMenu['operations'].forEach((op: any) => {
|
||||
itemMap[
|
||||
menusItem['name'] + '_' + globalMenuName + '_' + op['name']
|
||||
] = '';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (menusItem['isDir']) {
|
||||
itemMap[module['name'] + '_' + subMenu['name']] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
itemMap[menusItem['name']] = globalMenus;
|
||||
}
|
||||
} else if (menusItem['isDir']) {
|
||||
// 2. 文件夹下的模块
|
||||
const subMenus: Array<any> = [];
|
||||
this.traverseMenus(menusItem, subMenus, itemMap, module);
|
||||
menus = [...menus, ...subMenus];
|
||||
} else {
|
||||
//3. 普通全局开放模块
|
||||
menus.push(menusItem['name']);
|
||||
itemMap[module['name'] + '_' + menusItem['name']] = '';
|
||||
if (menusItem.operations && menusItem.operations.length) {
|
||||
menusItem.operations.forEach((op: any) => {
|
||||
itemMap[module['name'] + '_' + menusItem['name'] + '_' + op['name']] = '';
|
||||
});
|
||||
}
|
||||
// 处理下层菜单
|
||||
const subMenus: Array<any> = [];
|
||||
this.traverseMenus(menusItem, subMenus, itemMap, module);
|
||||
menus = [...menus, ...subMenus];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
itemMap[module['name']] = menus;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!authResponse) {
|
||||
return itemMap;
|
||||
}
|
||||
const projects = authResponse['projects'];
|
||||
if (!projects.length) {
|
||||
return itemMap;
|
||||
}
|
||||
projects.forEach((project: any) => {
|
||||
// if (project['projectname'] == 'systemProject') {
|
||||
const modules = project['modules'];
|
||||
if (!modules.length) {
|
||||
return;
|
||||
}
|
||||
modules.forEach((module: any) => {
|
||||
let menus = [];
|
||||
if (itemMap[module['name']] == null) {
|
||||
itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
|
||||
}
|
||||
if (!module['resources'].length) {
|
||||
return;
|
||||
}
|
||||
module['resources'].forEach((subModule: any) => {
|
||||
menus.push(subModule['name']);
|
||||
itemMap[module['name'] + '_' + subModule['name']] = ''; //当该资源在系统项目下,即受角色管理
|
||||
itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] = '';
|
||||
if (!subModule['operations'].length) {
|
||||
return;
|
||||
}
|
||||
const ops: Array<any> = [];
|
||||
subModule['operations'].forEach((op: any) => {
|
||||
/**权限合并修改:
|
||||
* 1.后端注册权限将查看(detail)和列表(list)权限合并为查看(list)权限后,
|
||||
* 2.前端:用户勾选查看(list),即表示有查看列表和详情权限。
|
||||
*/
|
||||
if (op['name'] == subModule['name'] + '_list') {
|
||||
op['name'] = subModule['name'] + '_detail';
|
||||
}
|
||||
itemMap[module['name'] + '_' + subModule['name'] + '_' + op['name']] = '';
|
||||
itemMap[
|
||||
module['name'] +
|
||||
'_' +
|
||||
subModule['name'] +
|
||||
'_' +
|
||||
project['projectname'] +
|
||||
'_' +
|
||||
op['name']
|
||||
] = '';
|
||||
ops.push(op['name']);
|
||||
});
|
||||
itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] =
|
||||
ops.join(',');
|
||||
});
|
||||
if (itemMap[module['name']] && itemMap[module['name']] instanceof Array) {
|
||||
//如果上个项目在该模块有菜单
|
||||
menus.push(...itemMap[module['name']]); //合并
|
||||
menus = Array.from(new Set(menus)); //去重
|
||||
}
|
||||
itemMap[module['name']] = menus;
|
||||
});
|
||||
// }
|
||||
});
|
||||
return itemMap;
|
||||
},
|
||||
|
||||
//判断是否在当前项目内
|
||||
isCurrentApp(app: string) {
|
||||
const url = window.location.href;
|
||||
const reg = /[http|https]+:\/\/.+?\/([^/]+)/gi;
|
||||
let currentApp;
|
||||
const result = reg.exec(url);
|
||||
if (result != null) {
|
||||
currentApp = result[1];
|
||||
}
|
||||
return currentApp === app;
|
||||
},
|
||||
|
||||
getValidFirstMenuName(moduleName: string | number) {
|
||||
if (!this.itemMap) {
|
||||
return [];
|
||||
}
|
||||
// let menuName = null;
|
||||
const menus: any[] = this.itemMap[moduleName];
|
||||
// if(!menus||menus.length==0)return;
|
||||
// menuName = menus[0];
|
||||
return menus;
|
||||
},
|
||||
|
||||
isAdmin() {
|
||||
return this.itemMap['*'] != null;
|
||||
},
|
||||
|
||||
//设置region信息
|
||||
setRegionInfo(response: any) {
|
||||
if (response) {
|
||||
const item: { label: any; value: any; isDefault: any }[] = [];
|
||||
const regions = response['regions'];
|
||||
regions.forEach((region: { isDefault: any; name: any; label: any }) => {
|
||||
region.isDefault
|
||||
? (this.defaultRegion = {
|
||||
label: region.label,
|
||||
value: region.name,
|
||||
isDefault: region.isDefault,
|
||||
})
|
||||
: '';
|
||||
item.push({
|
||||
label: region.label,
|
||||
value: region.name,
|
||||
isDefault: region.isDefault,
|
||||
});
|
||||
});
|
||||
this.regionArray = item;
|
||||
}
|
||||
},
|
||||
|
||||
setCurrentRegion(currentRegion: { value: string; label: string; isDefault: any }) {
|
||||
this.currentRegion = currentRegion;
|
||||
},
|
||||
|
||||
getApp() {
|
||||
return ((import.meta.env.VITE_PUBLIC_PATH || '') as string).replace(/\//g, '');
|
||||
},
|
||||
|
||||
getPermissionMap(authResponse: any, menusResponse: any) {
|
||||
const itemMap: any = {};
|
||||
// itemMap['*'] = true;
|
||||
// return itemMap;
|
||||
/** 如果是具有admin权限用户*/
|
||||
if (authResponse['accountname'] == 'admin' || authResponse['isAdmin']) {
|
||||
itemMap['*'] = true;
|
||||
return itemMap;
|
||||
}
|
||||
|
||||
/***默认显示的模块或者菜单 如:监控下面的指标监控
|
||||
* 先处理默认显示的模块权限,再处理授权的权限,注意顺序
|
||||
*/
|
||||
if (menusResponse instanceof Array) {
|
||||
menusResponse.forEach((module) => {
|
||||
if (module['isGlobalDisplay']) {
|
||||
let menus: Array<any> = [];
|
||||
if (itemMap[module['name']] == null) {
|
||||
itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
|
||||
}
|
||||
itemMap[module['name']] = '';
|
||||
if (module['menus'] && module['menus'].length > 0) {
|
||||
module['menus'].forEach((menusItem: any) => {
|
||||
if (menusItem['isGlobalDisplay']) {
|
||||
if (menusItem['isGlobal']) {
|
||||
//全局开放模块又是独立模块
|
||||
itemMap[menusItem['name']] = '';
|
||||
const globalMenus: Array<any> = [];
|
||||
if (menusItem['submenus'] && menusItem['submenus'].length > 0) {
|
||||
menusItem['submenus'].forEach((subMenu: any) => {
|
||||
if (subMenu['isGlobalDisplay']) {
|
||||
if (subMenu['operation'] && subMenu['operation']['resource']) {
|
||||
const globalMenuName = subMenu['operation']['resource'];
|
||||
globalMenus.push(globalMenuName);
|
||||
itemMap[menusItem['name'] + '_' + globalMenuName] = true;
|
||||
if (subMenu['operations'] && subMenu['operations'].length) {
|
||||
subMenu['operations'].forEach((op: any) => {
|
||||
itemMap[
|
||||
menusItem['name'] + '_' + globalMenuName + '__' + op['name']
|
||||
] = true;
|
||||
itemMap[
|
||||
menusItem['name'] +
|
||||
'_' +
|
||||
globalMenuName +
|
||||
stringUtil.firstToUpper(op['name'])
|
||||
] = true; //权限对应页面
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
itemMap[menusItem['name']] = globalMenus;
|
||||
}
|
||||
} else if (menusItem['isDir']) {
|
||||
// 2. 文件夹下的模块
|
||||
const subMenus: Array<any> = [];
|
||||
this.traverseMenus(menusItem, subMenus, itemMap, module);
|
||||
menus = [...menus, ...subMenus];
|
||||
} else {
|
||||
//3. 普通全局开放模块
|
||||
menus.push(menusItem['name']);
|
||||
itemMap[module['name'] + '_' + menusItem['name']] = true;
|
||||
if (menusItem.operations && menusItem.operations.length) {
|
||||
menusItem.operations.forEach((op: any) => {
|
||||
itemMap[module['name'] + '_' + menusItem['name'] + '__' + op['name']] =
|
||||
true;
|
||||
itemMap[
|
||||
module['name'] +
|
||||
'_' +
|
||||
menusItem['name'] +
|
||||
stringUtil.firstToUpper(op['name'])
|
||||
] = true; //权限对应页面
|
||||
});
|
||||
}
|
||||
// 处理下层菜单
|
||||
const subMenus: Array<any> = [];
|
||||
this.traverseMenus(menusItem, subMenus, itemMap, module);
|
||||
menus = [...menus, ...subMenus];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
itemMap[module['name']] = menus;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!authResponse) {
|
||||
return itemMap;
|
||||
}
|
||||
const projects = authResponse['projects'];
|
||||
if (!projects.length) {
|
||||
return itemMap;
|
||||
}
|
||||
projects.forEach((project: any) => {
|
||||
const modules = project['modules'];
|
||||
if (!modules.length) {
|
||||
return;
|
||||
}
|
||||
modules.forEach((module: any) => {
|
||||
let menus = [];
|
||||
if (itemMap[module['name']] == null) {
|
||||
itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
|
||||
}
|
||||
if (!module['resources'].length) {
|
||||
return;
|
||||
}
|
||||
module['resources'].forEach((subModule: any) => {
|
||||
menus.push(subModule['name']);
|
||||
if (project['projectname'] === 'systemProject') {
|
||||
itemMap[module['name'] + '_' + subModule['name']] = 'systemProject'; //当该资源在系统项目下,即受角色管理
|
||||
} else {
|
||||
itemMap[module['name'] + '_' + subModule['name']] = true; //当该资源在系统项目下,即受角色管理
|
||||
itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] =
|
||||
true;
|
||||
}
|
||||
if (!subModule['operations'].length) {
|
||||
return;
|
||||
}
|
||||
const ops: Array<any> = [];
|
||||
subModule['operations'].forEach((op: any) => {
|
||||
/**权限合并修改:
|
||||
* 1.后端注册权限将查看(detail)和列表(list)权限合并为查看(list)权限后,
|
||||
* 2.前端:用户勾选查看(list),即表示有查看列表和详情权限。
|
||||
*/
|
||||
if (op['name'] == 'list') {
|
||||
op['name'] = 'detail';
|
||||
}
|
||||
itemMap[module['name'] + '_' + subModule['name'] + '__' + op['name']] = true;
|
||||
itemMap[
|
||||
module['name'] + '_' + subModule['name'] + stringUtil.firstToUpper(op['name'])
|
||||
] = true; //权限对应页面
|
||||
if (project['projectname'] !== 'systemProject') {
|
||||
itemMap[
|
||||
module['name'] +
|
||||
'_' +
|
||||
subModule['name'] +
|
||||
'_' +
|
||||
project['projectname'] +
|
||||
'__' +
|
||||
op['name']
|
||||
] = true;
|
||||
}
|
||||
ops.push(op['name']);
|
||||
});
|
||||
if (project['projectname'] !== 'systemProject') {
|
||||
itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] =
|
||||
ops.join(',');
|
||||
}
|
||||
});
|
||||
if (itemMap[module['name']] && itemMap[module['name']] instanceof Array) {
|
||||
//如果上个项目在该模块有菜单
|
||||
menus.push(...itemMap[module['name']]); //合并
|
||||
menus = Array.from(new Set(menus)); //去重
|
||||
}
|
||||
itemMap[module['name']] = menus;
|
||||
});
|
||||
// }
|
||||
});
|
||||
return itemMap;
|
||||
},
|
||||
async checkAuthMap() {
|
||||
if (this.ModulesRes.length === 0) {
|
||||
await this.getAuthMap();
|
||||
}
|
||||
},
|
||||
checkPermission(
|
||||
moduleName: string,
|
||||
subModuleName?: string | undefined,
|
||||
operationName?: string | undefined,
|
||||
projectName?: string | undefined,
|
||||
): boolean {
|
||||
if (this.permissionMap['*']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let key = moduleName;
|
||||
if (!subModuleName) {
|
||||
// console.log(1, key);
|
||||
return !!this.permissionMap[key];
|
||||
}
|
||||
key = `${key}_${subModuleName}`;
|
||||
|
||||
if (!projectName) {
|
||||
if (operationName) {
|
||||
key = `${key}__${operationName}`;
|
||||
}
|
||||
|
||||
|
||||
return !!this.permissionMap[key];
|
||||
}
|
||||
if (this.permissionMap[key] === 'systemProject') {
|
||||
if (operationName) {
|
||||
key = `${key}__${operationName}`;
|
||||
}
|
||||
// console.log(3, key, operationName);
|
||||
|
||||
return !!this.permissionMap[key];
|
||||
} else {
|
||||
key = `${key}_${projectName}`;
|
||||
if (operationName) {
|
||||
key = `${key}__${operationName}`;
|
||||
}
|
||||
|
||||
return !!this.permissionMap[key];
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
342
lib/paas/store/modules/catalog-config.ts
Normal file
342
lib/paas/store/modules/catalog-config.ts
Normal file
@@ -0,0 +1,342 @@
|
||||
|
||||
|
||||
// import { message } from 'ant-design-vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { authorizationService } from './authorization-service';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
// import { router } from '/nerv-lib/paas/router';
|
||||
// import { http } from '/nerv-lib/util/http';
|
||||
|
||||
export interface Catalog {
|
||||
label: string;
|
||||
name?: string;
|
||||
items: CatalogItem[];
|
||||
}
|
||||
|
||||
export interface CatalogItem {
|
||||
label: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
url: string;
|
||||
dock?: boolean;
|
||||
queryParams?: QueryParams;
|
||||
isRedirect?: boolean;
|
||||
app?: string;
|
||||
authModuleNames?: any[]; //权限控制所需的所有模块名
|
||||
splitMenuModule?: string; //某个菜单单独拆分出去放在一个app中,权限照旧
|
||||
splitModule?: boolean; //被拆分的模块
|
||||
}
|
||||
// QueryParams修改声明view和region都为非必选
|
||||
export interface QueryParams {
|
||||
view?: string;
|
||||
region?: string;
|
||||
}
|
||||
|
||||
export const CatalogConfigService = defineStore({
|
||||
id: 'CatalogConfigService',
|
||||
/**
|
||||
* sideMenu 侧边栏菜单
|
||||
* @returns
|
||||
*/
|
||||
state(): { region: any; data: any[] } {
|
||||
return { region: '', data: [] };
|
||||
},
|
||||
getters: {},
|
||||
actions: {
|
||||
getCatalogs() {
|
||||
if (this.data.length != 0) {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const { ModulesRes } = authorizationService();
|
||||
const modules = cloneDeep(ModulesRes);
|
||||
this.data = this.convert2Catalog(modules);
|
||||
return this.data;
|
||||
},
|
||||
|
||||
convert2Catalog(modules: any): any {
|
||||
const authService = authorizationService();
|
||||
let catalogs: Array<Catalog> = [];
|
||||
let sort: any[] = [];
|
||||
const storage = JSON.parse((window.localStorage.docks as string) || '[]');
|
||||
// console.log('storage', storage);
|
||||
|
||||
modules.forEach((module: any) => {
|
||||
if (module.hasOwnProperty('sort')) {
|
||||
sort = module.sort;
|
||||
} else {
|
||||
const catalogName = module.catalog;
|
||||
let catalog: Catalog;
|
||||
catalogs.forEach((cl) => {
|
||||
if (cl.name == catalogName) {
|
||||
catalog = cl;
|
||||
}
|
||||
});
|
||||
if (!catalog) {
|
||||
catalog = {
|
||||
label: catalogName,
|
||||
name: catalogName,
|
||||
items: [],
|
||||
};
|
||||
catalogs.push(catalog);
|
||||
}
|
||||
|
||||
const catalogItem: CatalogItem = {
|
||||
label: module.label,
|
||||
name: module.name,
|
||||
icon: module.icon,
|
||||
url: module.url,
|
||||
app: module.app,
|
||||
dock: storage.includes(module.name),
|
||||
};
|
||||
let catalogItemName = module.name;
|
||||
if (module['authModuleNames']) {
|
||||
catalogItem['authModuleNames'] = module.authModuleNames;
|
||||
}
|
||||
if (module['splitMenuModule']) {
|
||||
catalogItemName = catalogItem['splitMenuModule'] = module['splitMenuModule'];
|
||||
}
|
||||
if (module['splitModule']) {
|
||||
catalogItem['splitModule'] = module['splitModule'];
|
||||
}
|
||||
if (module.queryParams) {
|
||||
catalogItem['queryParams'] = {
|
||||
view: module.queryParams.view,
|
||||
};
|
||||
}
|
||||
|
||||
const isCurrentApp = authService.isCurrentApp(module.app);
|
||||
catalogItem['isRedirect'] = !isCurrentApp;
|
||||
|
||||
let firstMenuName;
|
||||
|
||||
/**
|
||||
* 如果module.json最外层没有指定url 并且 当前登录是admin账号, 则取module.json中menus的第0个
|
||||
*/
|
||||
if (!catalogItem.url && authService.isAdmin()) {
|
||||
if (module['menus'] && module['menus'].length > 0) {
|
||||
firstMenuName = module['menus'][0]['name'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果module.json中的最外层没有指定url 且 当前登陆非admin, 则取menus中有权限的第0个
|
||||
*/
|
||||
const menusForAppMap: any = {};
|
||||
if (!catalogItem.url && !authService.isAdmin()) {
|
||||
/**
|
||||
* 将独立模块的子菜单menu['submenus']加进一级菜单里 module['menus']
|
||||
* 将文件夹模块的菜单处理和独立模块处理成同一种逻辑
|
||||
*/
|
||||
const globalMenus: Array<any> = []; //保留独立模块的子菜单
|
||||
if (module['menus'] && module['menus'].length > 0) {
|
||||
module['menus'].forEach((menu: { [x: string]: any[] }) => {
|
||||
if ((menu['isGlobal'] || menu['isDir']) && menu['submenus'].length > 0) {
|
||||
menu['submenus'].forEach((subMenu) => {
|
||||
module['menus'].push({
|
||||
name: subMenu['operation']['resource'],
|
||||
url: subMenu['url'],
|
||||
label: subMenu['label'],
|
||||
});
|
||||
});
|
||||
globalMenus.push(menu);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 独立模块下的资源与菜单顺序不一致时候,需要重新对菜单按照menusSort排序
|
||||
*/
|
||||
if (module['menusSort'] && module['menusSort'] instanceof Array) {
|
||||
if (module['menus'] && module['menus'].length > 0) {
|
||||
let sortMenus: any[] = [];
|
||||
module['menusSort'].forEach((sortMenuName) => {
|
||||
module['menus'].forEach((menu: { [x: string]: any }) => {
|
||||
//独立模块下的菜单
|
||||
if (menu['isGlobal'] && menu['submenus'].length > 0) {
|
||||
menu['submenus'].forEach((subMenu: { [x: string]: any }) => {
|
||||
if (!subMenu['operation']['resource']) return;
|
||||
const menuName = subMenu['operation']['resource'];
|
||||
if (menuName == sortMenuName) {
|
||||
sortMenus.push({
|
||||
name: subMenu['operation']['resource'],
|
||||
url: subMenu['url'],
|
||||
label: subMenu['label'],
|
||||
});
|
||||
}
|
||||
});
|
||||
//普通菜单
|
||||
} else if (menu['name'] == sortMenuName) {
|
||||
sortMenus.push(menu);
|
||||
}
|
||||
});
|
||||
});
|
||||
sortMenus = [...sortMenus, ...globalMenus];
|
||||
module['menus'] = sortMenus;
|
||||
}
|
||||
}
|
||||
/***如果app下一级菜单属于不同后端注册模块:authModuleNames存放所有的模块**/
|
||||
let authMenus: any[] = [];
|
||||
if (catalogItem['authModuleNames'] && catalogItem['authModuleNames'].length > 0) {
|
||||
const authModuleNames: any[] = catalogItem['authModuleNames'];
|
||||
authModuleNames.forEach((moduleName) => {
|
||||
const tempAuthMenus = authService.getValidFirstMenuName(moduleName); //每个模块有权限的菜单
|
||||
if (tempAuthMenus && tempAuthMenus.length > 0) {
|
||||
tempAuthMenus.forEach((menu) => {
|
||||
menusForAppMap[menu] = moduleName;
|
||||
});
|
||||
}
|
||||
// authMenus = [...authMenus, ...tempAuthMenus];
|
||||
if (tempAuthMenus) {
|
||||
authMenus = [...authMenus, ...tempAuthMenus];
|
||||
} else {
|
||||
authMenus = [...authMenus];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
/***如果app下所有资源属于同一个后端注册模块:没有authModuleNames字段**/
|
||||
authMenus = authService.getValidFirstMenuName(catalogItemName);
|
||||
if (authMenus && authMenus.length > 0) {
|
||||
authMenus.forEach((menu) => {
|
||||
menusForAppMap[menu] = catalogItemName;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (module['menus'] && module['menus'].length > 0) {
|
||||
if (authMenus && authMenus.length > 0) {
|
||||
let count = 0;
|
||||
module['menus'].forEach((menusItem: { [x: string]: any }) => {
|
||||
if (authMenus.indexOf(menusItem['name']) != -1) {
|
||||
count++;
|
||||
if (count == 1) {
|
||||
firstMenuName = menusItem['name'];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第0个子菜单的url以及queryParams
|
||||
*/
|
||||
if (firstMenuName) {
|
||||
let moduleName = catalogItemName;
|
||||
if (menusForAppMap && menusForAppMap[firstMenuName]) {
|
||||
moduleName = menusForAppMap[firstMenuName];
|
||||
}
|
||||
let urlObj = {};
|
||||
let isSubModule = false;
|
||||
if (moduleName == catalogItemName) {
|
||||
urlObj = this.getUrlObj(firstMenuName, module['menus']);
|
||||
} else {
|
||||
isSubModule = true;
|
||||
let globalModule: any = {};
|
||||
if (module['menus'] && module['menus'].length > 0) {
|
||||
module['menus'].forEach((subMenusModule: { [x: string]: any }) => {
|
||||
if (subMenusModule['name'] == moduleName) {
|
||||
globalModule = subMenusModule;
|
||||
}
|
||||
});
|
||||
}
|
||||
urlObj = this.getUrlObj(firstMenuName, globalModule['submenus'], isSubModule);
|
||||
}
|
||||
const url: any = urlObj['url'];
|
||||
const queryParams = urlObj['queryParams'];
|
||||
|
||||
if (url) {
|
||||
catalogItem['url'] = url;
|
||||
}
|
||||
|
||||
if (queryParams) {
|
||||
catalogItem['queryParams'] = queryParams;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果不是当前应用的url 并且 不是http开头的url, 则加上应用名
|
||||
*/
|
||||
if (catalogItem.url && catalogItem.url.toLowerCase().indexOf('http') != 0) {
|
||||
catalogItem.url = '/' + module.app + catalogItem.url;
|
||||
|
||||
/* 如果存在queryParams, 则在url中追加 */
|
||||
const queryParams = catalogItem['queryParams'];
|
||||
if (queryParams) {
|
||||
const paramStringArr = [];
|
||||
for (const k in queryParams) {
|
||||
const paramString = k + '=' + queryParams[k];
|
||||
paramStringArr.push(paramString);
|
||||
}
|
||||
if (catalogItem.url.indexOf('http') == 0 || catalogItem['isRedirect']) {
|
||||
catalogItem.url = catalogItem.url + '?' + paramStringArr.join('&');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!catalogItem.url) {
|
||||
catalogItem.url = '';
|
||||
}
|
||||
|
||||
catalog.items.push(catalogItem);
|
||||
}
|
||||
});
|
||||
// console.log(catalogs);
|
||||
if (sort) {
|
||||
catalogs = this.sortcatalogs(catalogs, sort);
|
||||
}
|
||||
// console.log(catalogs);
|
||||
return catalogs;
|
||||
},
|
||||
getUrlObj(menuName: any, menus: any[], isSubModule?: boolean) {
|
||||
let url = null;
|
||||
let queryParams = null;
|
||||
if (menus && menus instanceof Array) {
|
||||
menus.forEach((mu) => {
|
||||
if (isSubModule) {
|
||||
if (mu['operation']['resource'] != menuName) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (mu['name'] != menuName) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.region) {
|
||||
if (mu['queryParams']) {
|
||||
mu['queryParams']['region'] = this.region.value;
|
||||
} else {
|
||||
mu['queryParams'] = { region: this.region.value };
|
||||
}
|
||||
} else {
|
||||
if (mu['queryParams']) {
|
||||
delete mu['queryParams']['region'];
|
||||
}
|
||||
}
|
||||
url = mu['url'];
|
||||
queryParams = mu['queryParams'];
|
||||
});
|
||||
}
|
||||
return {
|
||||
url: url,
|
||||
queryParams: queryParams,
|
||||
};
|
||||
},
|
||||
|
||||
sortcatalogs(orginCatalogs: any[], sort: string | any[]) {
|
||||
let destCatalogs = [];
|
||||
for (let index = 0; index < sort.length; index++) {
|
||||
for (let idx = 0; idx < orginCatalogs.length; idx++) {
|
||||
if (orginCatalogs[idx].label == sort[index]) {
|
||||
destCatalogs.push(orginCatalogs[idx]);
|
||||
orginCatalogs.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (orginCatalogs) {
|
||||
destCatalogs = destCatalogs.concat(orginCatalogs);
|
||||
}
|
||||
// console.log(destCatalogs);
|
||||
return destCatalogs;
|
||||
},
|
||||
},
|
||||
});
|
||||
83
lib/paas/store/modules/config-service.ts
Normal file
83
lib/paas/store/modules/config-service.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
// import { message } from 'ant-design-vue';
|
||||
import { defineStore } from 'pinia';
|
||||
// import { router } from '/nerv-lib/paas/router';
|
||||
// import { http } from '/nerv-lib/util/http';
|
||||
export const configRegist = defineStore({
|
||||
id: 'configRegist',
|
||||
/**
|
||||
* sideMenu 侧边栏菜单
|
||||
* @returns
|
||||
*/
|
||||
state(): { sideMenu: { [k: string]: SideMenu }; activateUrls: { [k: string]: number } } {
|
||||
return { sideMenu: {}, activateUrls: {} };
|
||||
},
|
||||
getters: {},
|
||||
actions: {
|
||||
setSideMenu(menu: SideMenu) {
|
||||
if (menu.name) {
|
||||
this.sideMenu[menu.name] = menu;
|
||||
}
|
||||
},
|
||||
getSidMenu(name: any) {
|
||||
return this.sideMenu[name];
|
||||
},
|
||||
setUrl(url: string, index: number) {
|
||||
this.activateUrls[url] = index;
|
||||
},
|
||||
removeUrl(url: string) {
|
||||
delete this.activateUrls[url];
|
||||
},
|
||||
hasUrl(url: string) {
|
||||
let isExist = false;
|
||||
Object.keys(this.activateUrls).some((el) => {
|
||||
el === url ? (isExist = true) : '';
|
||||
});
|
||||
return isExist;
|
||||
},
|
||||
isLaster(url: string) {
|
||||
let isCurr = true;
|
||||
const ind = this.activateUrls[url];
|
||||
const indexMap = Object.values(this.activateUrls).sort();
|
||||
isCurr = ind >= indexMap[indexMap.length - 1];
|
||||
return isCurr;
|
||||
},
|
||||
},
|
||||
});
|
||||
export interface SideMenuItem {
|
||||
authMap?: Array<string>; //侧边栏显示文字
|
||||
isOpen?: boolean; //侧边栏权限标记
|
||||
ifShow?: Boolean | Function; //dom隐藏
|
||||
label: string; //侧边栏路由
|
||||
module: string; //菜单所属模块
|
||||
name: string; //是否属于项目权限
|
||||
projectName?: boolean; //是否根据多个模块授权,默认是&&连接符
|
||||
url: string; //是否是全局开放的模块
|
||||
app?: string; //
|
||||
bindView?: string;
|
||||
openPermission?: boolean;
|
||||
submenus?: SideMenuItem[];
|
||||
}
|
||||
|
||||
export interface SideMenu {
|
||||
backTo?: string; //通过匹配路由的name,获取菜单信息
|
||||
ifShow?: Boolean | Function; //dom隐藏
|
||||
|
||||
menus: SideMenuItem[]; //显示标题名称
|
||||
name: string; //返回的路径
|
||||
root?: boolean; //是否是根目录
|
||||
title?: string;
|
||||
backToHandle?: Function
|
||||
}
|
||||
export interface ModuleResItem {
|
||||
label: string;
|
||||
name: string;
|
||||
operations: [];
|
||||
url: string;
|
||||
}
|
||||
export interface ModuleRes {
|
||||
app: string;
|
||||
catalog: string;
|
||||
icon: string;
|
||||
label: string;
|
||||
menus: ModuleResItem[];
|
||||
}
|
||||
83
lib/paas/store/modules/login-service.ts
Normal file
83
lib/paas/store/modules/login-service.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
// import { message } from 'ant-design-vue';
|
||||
import { defineStore } from 'pinia';
|
||||
// import { router } from '/nerv-lib/paas/router';
|
||||
import { http } from '/nerv-lib/util/http';
|
||||
import Cookies from 'js-cookie';
|
||||
import { appConfigStore } from '/nerv-base/store/modules/app-config';
|
||||
import { isArray } from 'lodash-es';
|
||||
export const loginService = defineStore({
|
||||
id: 'loginService',
|
||||
/**
|
||||
* module 测试用
|
||||
* @returns
|
||||
*/
|
||||
state(): { currentUser: string; currentUserTenant: string; userName: string; isAdmin: boolean } {
|
||||
return { currentUser: '', currentUserTenant: '', userName: '', isAdmin: false };
|
||||
},
|
||||
getters: {},
|
||||
actions: {
|
||||
isLogin(): boolean {
|
||||
const authToken = appConfigStore()?.headers?.extraAuth;
|
||||
if (authToken && authToken.includes('nervsid')) {
|
||||
const tokenArr = authToken.split('=');
|
||||
return !!(isArray(tokenArr) && tokenArr.length > 0 && tokenArr[1]);
|
||||
}
|
||||
return !!Cookies.get('nervsid');
|
||||
},
|
||||
|
||||
/**
|
||||
* Get userInfo from nginx
|
||||
*/
|
||||
asyncFetchUserInfo(): Promise<any> {
|
||||
return http
|
||||
.get('/api/webui/webui/objs/PassportUserInfo')
|
||||
.then((body) => {
|
||||
const { name, tenant, tenantAlias, isAdmin } = body;
|
||||
this.currentUser = name;
|
||||
this.currentUserTenant = tenant;
|
||||
this.isAdmin = isAdmin;
|
||||
http.setHeaders({
|
||||
'NERV-TENANT': tenant,
|
||||
});
|
||||
if (tenantAlias) {
|
||||
this.userName = `${name}@${tenantAlias}`;
|
||||
} else {
|
||||
if (tenant && tenant !== 'nerv') {
|
||||
this.userName = `${name}@${tenant}`;
|
||||
} else {
|
||||
this.userName = name;
|
||||
}
|
||||
}
|
||||
return body;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get logoutUrl from nginx, then redirect to passport
|
||||
*
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
logout(): Promise<any> {
|
||||
if (appConfigStore().layout) {
|
||||
return appConfigStore().layout();
|
||||
} else {
|
||||
return http.get('/api/webui/webui/objs/PassportLogout').then((body) => {
|
||||
Cookies.remove('nervsid');
|
||||
window.location.href = body.url;
|
||||
const user = this.currentUser;
|
||||
this.currentUser = '';
|
||||
return user;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async checkUserInfo() {
|
||||
if (this.currentUser === '') {
|
||||
await this.asyncFetchUserInfo();
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
9
lib/paas/store/modules/lowCodeMyApp.ts
Normal file
9
lib/paas/store/modules/lowCodeMyApp.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { defineStore } from 'pinia';
|
||||
export const configRegister = defineStore({
|
||||
id: 'lowCodeMyApp',
|
||||
state(): { module: any } {
|
||||
return { module: {} };
|
||||
},
|
||||
getters: {},
|
||||
actions: {},
|
||||
});
|
||||
16
lib/paas/store/modules/project-auth..ts
Normal file
16
lib/paas/store/modules/project-auth..ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// import { message } from 'ant-design-vue';
|
||||
import { defineStore } from 'pinia';
|
||||
// import { router } from '/nerv-lib/paas/router';
|
||||
// import { http } from '/nerv-lib/util/http';
|
||||
export const configRegister = defineStore({
|
||||
id: 'configRegister',
|
||||
/**
|
||||
* module 测试用
|
||||
* @returns
|
||||
*/
|
||||
state(): { module: any } {
|
||||
return { module: {} };
|
||||
},
|
||||
getters: {},
|
||||
actions: {},
|
||||
});
|
||||
Reference in New Issue
Block a user