oak-frontend-base/lib/features/console.js

247 lines
8.3 KiB
JavaScript
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.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Feature_1 = require("../types/Feature");
const assert_1 = require("oak-domain/lib/utils/assert");
const lodash_1 = require("oak-domain/lib/utils/lodash");
const constant_1 = require("../constant/constant");
const relation_1 = require("oak-domain/lib/store/relation");
;
;
;
class Console extends Feature_1.Feature {
cache;
localStorage;
user;
userId;
isRoot;
consoleContext;
availMenus;
unsubFns;
initialize() {
this.unsubFns.push(this.user.subscribe(() => this.onUserChanged()));
}
saveContext(context) {
if (this.consoleContext !== context) {
this.consoleContext = context;
if (context) {
this.localStorage.save(constant_1.LOCAL_STORAGE_KEYS.consoleContext, context);
}
else {
this.localStorage.remove(constant_1.LOCAL_STORAGE_KEYS.consoleContext);
}
this.checkAvailMenus();
}
}
async onUserChanged() {
this.isRoot = this.user.isRoot();
const userId = this.user.getUserId(true);
if (userId !== this.userId) {
this.userId = userId;
}
if (this.userId && !this.isRoot) {
await this.cache.exec('loadRelations', {
entities: this.entities,
});
}
else if (!this.userId) {
this.saveContext(undefined);
return;
}
this.checkAvailMenus();
}
initAvailMenus() {
const schema = this.cache.getSchema();
this.availMenus = this.menus.map((menu) => {
const { destEntity, path, ...rest } = menu;
if (destEntity) {
let sourceEntity = destEntity;
if (path) {
const paths = path.split('.');
paths.forEach((ele) => {
const rel = (0, relation_1.judgeRelation)(schema, sourceEntity, ele);
if (rel === 2) {
sourceEntity = ele;
}
else if (typeof rel === 'string') {
sourceEntity = rel;
}
else {
(0, assert_1.assert)(rel instanceof Array);
sourceEntity = rel[0];
}
});
return {
destEntity,
path,
sourceEntity,
available: null,
...rest,
};
}
else {
return {
destEntity,
path,
sourceEntity,
available: null,
...rest,
};
}
}
return {
...menu,
available: null,
};
});
}
checkAvailMenus() {
if (this.consoleContext && this.userId) {
const { entity, entityId } = this.consoleContext;
// 这个不能放在constructor里面因为this.menus是后初始化的
if (this.availMenus.length < this.menus.length) {
this.initAvailMenus();
}
const actionAuths = this.userId && !this.isRoot && this.cache.get('actionAuth', {
data: {
id: 1,
path: {
destEntity: 1,
sourceEntity: 1,
value: 1,
},
deActions: 1,
},
filter: {
relation: {
entity: entity,
$or: [
{
entityId,
},
{
entityId: {
$exists: false,
},
}
],
userRelation$relation: {
userId: this.userId
}
},
}
});
this.availMenus.forEach((menu) => {
let { destEntity, path, actions, sourceEntity } = menu;
let available = false;
switch (destEntity) {
// 如果是空字符串,表示对任何用户可见
case '': {
available = true;
break;
}
case 'userRelation': {
available = !!this.cache.checkOperation(destEntity, {
action: 'create',
data: {
entity: entity,
entityId
},
}, [
'relation'
]);
break;
}
case undefined: {
available = !!this.isRoot;
break;
}
default: {
(0, assert_1.assert)(actions?.length);
(0, assert_1.assert)(typeof path === 'string');
if (sourceEntity === entity) {
if (this.isRoot) {
available = true;
}
else if (this.userId) {
(0, assert_1.assert)(actionAuths);
available = !!actionAuths.find(actionAuth => (0, lodash_1.intersection)(actionAuth.deActions, actions).length > 0 && actionAuth.path.destEntity === destEntity && path === actionAuth.path.value);
}
}
else {
available = null;
}
}
}
menu.available = available;
});
}
else {
this.availMenus.forEach(ele => ele.available = null);
}
this.publish();
}
constructor(cache, localStorage, user, getEntityProjection) {
super();
this.cache = cache;
this.localStorage = localStorage;
this.user = user;
this.availMenus = [];
this.unsubFns = [];
this.initialize();
this.loadContext(getEntityProjection);
}
async loadContext(getEntityProjection) {
const context = await this.localStorage.load(constant_1.LOCAL_STORAGE_KEYS.consoleContext);
this.consoleContext = context;
if (this.consoleContext) {
const { entity, entityId } = this.consoleContext;
await this.cache.refresh(entity, {
data: getEntityProjection(entity),
filter: {
id: entityId,
},
});
this.checkAvailMenus();
}
}
setContext(entity, entityId) {
(0, assert_1.assert)(this.entities.includes(entity));
if (entity !== this.consoleContext?.entity || entityId !== this.consoleContext.entityId) {
this.saveContext({
entity,
entityId,
});
}
}
getContext() {
return this.consoleContext;
}
getAvailMenus() {
return this.availMenus.filter(ele => ele.available === true);
}
/**
* 检查当前url是否可以访问
* @param url
* @returns
* true: 可以访问
* false: 无权访问
* null: 上下文不匹配
* undefined: menu中没有此url
*/
checkUrlAvailable(url) {
let result = undefined;
for (const menu of this.availMenus) {
if (menu.url === url) {
if (menu.available) {
return true;
}
else {
result = menu.available;
}
}
}
return result;
}
}
exports.default = Console;