Files
SaaS-lib/lib/paas/store/modules/authorization-service.ts
xuziqiang d0155dbe3c push
2024-05-15 17:29:42 +08:00

547 lines
20 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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];
}
},
},
});