import { Feature } from 'oak-frontend-base/es/types/Feature'; import { assert } from 'oak-domain/lib/utils/assert'; import { cloneDeep, merge } from 'oak-domain/lib/utils/lodash'; import { traverseProjection } from 'oak-domain/lib/utils/projection'; import { applicationProjection } from '../types/Projection'; import { OakApplicationLoadingException, } from '../types/Exception'; export class Application extends Feature { version; applicationId; application; cache; storage; projection; sensitiveEntities = []; constructor(cache, storage, version) { super(); this.cache = cache; this.version = version; this.storage = storage; this.projection = cloneDeep(applicationProjection); // this.application做一层缓存,有时候更新了一些相关的属性还是要更新的 traverseProjection('application', this.cache.getSchema(), this.projection, (entity) => this.sensitiveEntities.push(entity)); this.cache.bindOnSync((opRecords) => { for (const record of opRecords) { if (record.a !== 's') { if (this.sensitiveEntities.includes(record.e)) { this.application = undefined; } else { const { d } = record; for (const e2 in d) { if (this.sensitiveEntities.includes(e2)) { this.application = undefined; } } } } } }); } getApplicationFromCache() { if (this.application) { return this.application; } const data = this.cache.get('application', { data: this.projection, filter: { id: this.applicationId, }, }); assert(data.length === 1, `cache:applicationId${this.applicationId}没有取到有效数据`); this.application = data[0]; return this.application; } async loadApplicationInfo(version, domain) { let applicationId; let appType = 'web'; if (process.env.OAK_PLATFORM === 'wechatMp') { appType = 'wechatMp'; } else if (process.env.OAK_PLATFORM === 'native') { appType = 'native'; } else { const url = new URL(window.location.href); const param = url.searchParams.get('appType'); if (/MicroMessenger/i.test(window.navigator.userAgent)) { appType = param || 'wechatPublic'; } } const { result } = await this.cache.exec('getApplication', { version, type: appType, domain, data: this.projection, appId: this.applicationId }, undefined, true, true); applicationId = result; this.applicationId = applicationId; this.getApplicationFromCache(); // 如果取得的type和当前环境不同,则不缓存id(未来可能有type相同的application上线) // if (this.application?.type === type) { // this.storage.save(LOCAL_STORAGE_KEYS.appId, applicationId); // } this.publish(); } async initialize(version, domain, appId, projection) { // const applicationId = await this.storage.load(LOCAL_STORAGE_KEYS.appId); // this.applicationId = applicationId; //接收外层注入的projection this.version = version; this.projection = merge(this.projection, projection); if (process.env.NODE_ENV === 'development' && appId) { // development环境下允许注入一个线上的appId this.applicationId = appId; } return await this.loadApplicationInfo(version, domain); } getApplication() { if (this.applicationId === undefined) { throw new OakApplicationLoadingException(); } return this.getApplicationFromCache(); } getApplicationId(allowUnInitialized) { if (this.applicationId === undefined) { if (!allowUnInitialized) { throw new OakApplicationLoadingException(); } } return this.applicationId; } async uploadWechatMedia(params) { const { applicationId, type, file, description, isPermanent = false, } = params; const formData = new FormData(); formData.append('applicationId', applicationId); formData.append('type', type); formData.append('file', file); if (description) { formData.append('description', JSON.stringify(description)); } if (isPermanent) { formData.append('isPermanent', `${isPermanent}`); } const callBack = await this.cache.exec('uploadWechatMedia', formData); return callBack.result; } getVersion() { return this.version; } }