"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;