import Vue from 'vue'; import qs from 'qs'; import { DynamicInstanceConfig, IPSAppView } from '@ibizstudio/runtime'; import { AppServiceBase, GetModelService, SandboxInstance, Util } from '@ibizstudio/runtime'; import { AppComponentService, AppNavHistory } from '../app-service'; // import { CommunicationService } from '@ibiz/model-location'; /** * 视图容器基类 * * @export * @class ViewContainerBase * @extends {Vue} */ export class ViewContainerBase extends Vue { /** * 部件静态参数 * * @memberof ViewContainerBase */ declare staticProps: any; /** * 部件动态参数 * * @memberof ViewContainerBase */ declare dynamicProps: any; /** * 动态模型文件路径 * * @public * @type {StringConstructor} * @memberof ViewContainerBase */ dynaModelFilePath: string = ''; /** * 视图标识 * * @type {string} * @memberof ViewContainerBase */ viewtag: string = ''; /** * 视图容器 * * @type {any} * @memberof ViewContainerBase */ viewContainerName: string = ''; /** * 临时动态视图上下文环境参数 * * @type {ViewContext} * @memberof ViewBase */ tempViewContext: any = {}; /** * 动态视图上下文环境参数 * * @type {*} * @memberof ViewBase */ viewContext: any = {}; /** * 模型数据实例 * * @type {boolean} * @memberof ViewContainerBase */ modeldata!: IPSAppView; /** * 应用上下文 * * @type {*} * @memberof ViewContainerBase */ context: any = {}; created(): void { const env = AppServiceBase.getInstance().getAppEnvironment(); if (env.devMode) { this.selfPreview = this.selfPreview.bind(this); // const m = CommunicationService.getInstance(); // m.evt.on('preview-view', this.selfPreview); } } destroyed(): void { const env = AppServiceBase.getInstance().getAppEnvironment(); if (env.devMode) { // const m = CommunicationService.getInstance(); // m.evt.off('preview-view', this.selfPreview); } } protected async selfPreview(res: any): Promise { const model = res.model; if (model.dynaModelFilePath === this.dynaModelFilePath) { const s = await GetModelService(this.context); s.store.modelObject.delete(model.dynaModelFilePath); const view = (await s.getPSAppView(model)) as any; this.initViewContext({ modeldata: view }); this.viewContainerName = ''; setTimeout(() => { if (view) { this.viewContainerName = AppComponentService.getViewComponents(view.viewType, view.viewStyle, view.getPSSysPFPlugin?.pluginCode); } this.$forceUpdate(); }, 100); this.$forceUpdate(); } } /** * 视图容器初始化 * * @memberof ViewContainerBase */ async ViewContainerInit() { if (this.dynamicProps && this.dynamicProps.viewdata) { if (typeof this.dynamicProps.viewdata == 'string') { this.context = JSON.parse(this.dynamicProps.viewdata); } else { this.context = Util.deepCopy(this.dynamicProps.viewdata); } // 初始化沙箱实例 if (this.context && this.context.hasOwnProperty('srfsandboxtag')) { await this.initSandBoxInst(this.context); } if (this.context && this.context.srfinsttag && this.context.srfinsttag2) { let dynainstParam: DynamicInstanceConfig = ( await GetModelService({ srfsandboxtag: this.context.srfsandboxtag, instTag: this.context.srfinsttag, instTag2: this.context.srfinsttag2 }) ).getDynaInsConfig(); Object.assign(this.context, { srfdynainstid: dynainstParam.id }); } await this.computeDynaModelFilePath(); this.loadDynamicModelData(); return; } await this.computeDynaModelFilePath(); // 路由打开 if (this.$route && this.$route.fullPath && this.$route.fullPath.indexOf('?') > -1) { let tempViewParam: any = {}; const tempViewparam: any = this.$route.fullPath.slice(this.$route.fullPath.indexOf('?') + 1); const viewparamArray: Array = decodeURIComponent(tempViewparam).split(';'); if (viewparamArray.length > 0) { viewparamArray.forEach((item: any) => { Object.assign(tempViewParam, qs.parse(item)); }); } // 初始化沙箱实例 if (tempViewParam && tempViewParam.hasOwnProperty('srfsandboxtag')) { await this.initSandBoxInst(tempViewParam); } if (tempViewParam.srfinsttag && tempViewParam.srfinsttag2) { let dynainstParam: DynamicInstanceConfig = ( await GetModelService({ srfsandboxtag: tempViewParam.srfsandboxtag, instTag: tempViewParam.srfinsttag, instTag2: tempViewParam.srfinsttag2 }) ).getDynaInsConfig(); this.context = { srfdynainstid: dynainstParam.id }; } if (tempViewParam.srfdynainstid) { this.context = { srfdynainstid: tempViewParam.srfdynainstid }; } // 补充沙箱实例参数(路由) if (tempViewParam && tempViewParam.hasOwnProperty('srfsandboxtag')) { Object.assign(this.context, { srfsandboxtag: tempViewParam.srfsandboxtag }); } } this.loadDynamicModelData(); } /** * 初始化沙箱实例 * * @memberof ViewContainerBase */ async initSandBoxInst(args: any) { if (args && args.srfsandboxtag) { const tempSandboxInst: SandboxInstance = new SandboxInstance(args); await tempSandboxInst.initSandBox(); } } /** * 加载动态模型数据 * * @type {Array<*>} * @memberof ViewContainerBase */ async loadDynamicModelData() { if (this.staticProps && this.staticProps.viewModelData) { this.modeldata = this.staticProps.viewModelData; } else { if (this.dynaModelFilePath) { const modelService = await GetModelService(this.context); this.modeldata = await modelService.getPSAppView(this.dynaModelFilePath); } } // 未找到模型数据跳转404页面 if (Util.isEmpty(this.modeldata)) { console.warn(`未找到模型 ${this.dynaModelFilePath}, 跳转 404 界面`); this.$router.push('/404'); return; } // 视图壳加载视图数据 await this.modeldata?.fill?.(true); this.initViewContext({ modeldata: this.modeldata }); this.initViewMateInfo(this.modeldata); this.viewContainerName = AppComponentService.getViewComponents(this.modeldata?.viewType, this.modeldata?.viewStyle, this.modeldata?.getPSSysPFPlugin()?.pluginCode); this.$forceUpdate(); } /** * 初始化动态视图上下文环境参数 * * @type {*} opts * @memberof ViewContainerBase */ initViewContext(opts: any) { let temp: any = {}; Object.defineProperty(temp, 'modeldata', { enumerable: false, writable: true }); Object.assign(temp, this.tempViewContext, opts, { viewtag: this.viewtag, viewcontainer: this.context, ...this.staticProps, }); // 删除viewModelData,避免递归 if (temp.viewModelData) { delete temp.viewModelData; } this.viewContext = temp; } /** * 初始化视图容器元数据 * * @type {*} opts * @memberof ViewContainerBase */ initViewMateInfo(opts: any) { if (!this.dynamicProps || !this.dynamicProps.viewdata) { const initNavData: Function = () => { if (this.$route.meta && !this.$route.meta.ignoreAddPage) { let navHistory: AppNavHistory = AppServiceBase.getInstance().getAppNavDataService(); if (!navHistory) { AppServiceBase.getInstance().setAppNavDataService(new AppNavHistory()); navHistory = AppServiceBase.getInstance().getAppNavDataService(); } navHistory.add(this.$route); } }; // 设置路由meta数据 let activedView: any = this.$route.meta.parameters.find((item: any) => { return item.pathName === 'views'; }); if (Object.is(activedView.parameterName, 'view') && Object.is(activedView.pathName, 'views')) { this.$route.meta.captionTag = opts.getCapPSLanguageRes()?.lanResTag; this.$route.meta.caption = opts?.caption; this.$route.meta.title = opts?.title; this.$route.meta.imgPath = opts?.getPSSysImage()?.imagePath; this.$route.meta.iconCls = opts?.getPSSysImage()?.cssClass; if (opts.accUserMode && (opts.accUserMode == 0 || opts.accUserMode == 3)) { this.$route.meta.requireAuth = false; } else { this.$route.meta.requireAuth = true; } this.$store.commit('setCurPageCaption', { route: this.$route, caption: this.$route.meta.caption, info: '', }); initNavData(); } else { initNavData(); } } } /** * 处理部件事件 * * @memberof ViewContainerBase */ handleViewEvent(opts: any) { if (opts.action) { this.$emit(opts.action, opts.data ? opts.data : null, opts.viewName); } } /** * 计算视图动态路径 * * @memberof ViewContainerBase */ async computeDynaModelFilePath() { if (this.dynamicProps && this.dynamicProps.viewdata) { // 嵌入视图 if (this.context.viewpath) { this.dynaModelFilePath = this.context.viewpath; delete this.context.viewpath; } } else { // 路由打开 if (this.$route && this.$route.meta && this.$route.meta.parameters) { let resource: string = this.$route.meta.resource ? this.$route.meta.resource.toLowerCase() : ''; let activedView: any = this.$route.meta.parameters.find((item: any) => { return item.pathName === 'views'; }); let localActivedView: any = Util.deepCopy(activedView); if (Object.is(localActivedView.parameterName, 'view') && Object.is(localActivedView.pathName, 'views')) { localActivedView.parameterName = this.parseUrlDynamicParam().view; } if (localActivedView && localActivedView.parameterName) { const modelService = await GetModelService(this.context); const path = modelService.getPSAppViewPath(`${resource}${localActivedView.parameterName}`); if (path) { this.dynaModelFilePath = path; } } } } } /** * 解析路由动态参数 * * @memberof ViewContainerBase */ parseUrlDynamicParam(): any { const path = this.$route.matched[this.$route.matched.length - 1].path; const keys: Array = []; const curReg = this.$pathToRegExp.pathToRegexp(path, keys); const matchArray = curReg.exec(this.$route.path); let tempValue: Object = {}; keys.forEach((item: any, index: number) => { if (matchArray[index + 1]) { Object.defineProperty(tempValue, item.name, { enumerable: true, value: decodeURIComponent(matchArray[index + 1]), }); } }); return tempValue; } }