UNPKG

@lcap/asl

Version:

NetEase Application Specific Language

1,065 lines 41.1 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.View = void 0; const decorators_1 = require("../decorators"); const __1 = require(".."); const Block_1 = __importDefault(require("./Block")); const page_1 = require("../../service/page"); const Logic_1 = __importDefault(require("../logic/Logic")); const assets_1 = require("../../service/assets"); const translator_1 = __importDefault(require("../logic/translator")); const lodash_1 = require("lodash"); const utils_1 = require("../utils"); const Entity_1 = __importDefault(require("../data/Entity")); const preprocess_1 = require("../../service/common/preprocess"); /** * 子页面类,前端路由控制 */ class View extends Block_1.default { /** * @param source 需要合并的部分参数 */ constructor(source) { super(); /** * 概念类型 */ this.level = __1.LEVEL_ENUM.view; /** * 子页面 Id */ this.id = undefined; /** * 子页面名称 */ this.name = undefined; /** * 前端路径,不带 page 名 */ this.path = undefined; /** * 前后端路径 * 由于 name 会改的关系,尽量不要用 * @deprecated */ this.tempPath = undefined; /** * 唯一标识码 */ this.code = undefined; /** * 标题 */ this.title = undefined; /** * 面包屑 */ this.crumb = undefined; /** * 是否为默认跳转页 */ this.first = undefined; /** * 子页面 Id */ this.parentId = undefined; /** * 附加的 script */ this.script = undefined; /** * 页面 Id */ this.pageId = undefined; /** * 页面模板 Id */ this.pageTemplateId = undefined; /** * 所属页面 */ this.page = undefined; /** * 父级子页面 */ this.parent = undefined; /** * 子页面 */ this.children = []; /** * 正在请求的 Promise * 前端 UI 状态 */ this.contentPromise = undefined; /** * 输入参数 */ // @immutable() // public readonly params: Array<Param> = []; /** * 逻辑列表 */ // @immutable() // public readonly logics: Array<Logic> = []; // vueFile: VueFile; /** * 树组件的子节点字段 */ this.moreChildrenFields = ['$def.params', '$def.variables', '$def.logics']; source && this.assign(source); this.on('change', lodash_1.throttle(this._onChange.bind(this), __1.config.throttleWait, { leading: true, trailing: true })); } async _onChange() { // 在子页面修改时生成缓存,注意不需要 await if (__1.config.webFileCache) { const tasks = []; // 保存 cache 之前需要保证 view 和下面的 logic 全部 load 完成 if (!this.isContentLoaded()) tasks.push(this.load()); this.$def.logics.forEach((logic) => { if (!logic.isContentLoaded()) tasks.push(logic.load()); }); await Promise.all(tasks); try { __1.generator.saveViewCache(this); } catch (e) { this.emit('translate-error'); } } __1.generator.saveViewDetailCache(this); } /** * 在 mergeBlock 的情况下使用 * 在 loadDetail 的情况下使用 * @returns */ load() { // 如果有正在进行的 Promise,则直接返回它 if (this.contentPromise) return this.contentPromise; return this.contentPromise = (async () => { try { const result = await page_1.viewService.load({ path: { id: this.id, }, }); const $def = result.$def; delete result.$def; delete result.children; const temp = View.from(result, this.parent, this.page, this); this.assign({ $html: temp.$html, script: temp.script, // style: temp.style, definition: temp.definition, }); // def 情况比较特殊,需要单独处理,防止逻辑重新加载 this._syncDef($def); this.attachNodePath(true); return this; } catch (err) { } })().finally(() => this.contentPromise = undefined); } loadAll() { // 如果有正在进行的 Promise,则直接返回它 if (this.contentPromise) return this.contentPromise; return this.contentPromise = (async () => { try { const result = await page_1.viewService.load({ path: { id: this.id, }, }); const temp = View.from(result, this.parent, this.page, this); this.assign(temp); __1.utils.traverse((current) => { current.node.attachNodePath(true); }, { node: this }); return this; } catch (err) { } })().finally(() => this.contentPromise = undefined); } isContentLoaded() { return !!this.$html; } /** * 后续改为根据 id 查找 Element */ attachNodePath(clear) { if (!this.$html) return; __1.utils.traverse((current) => { current.node.nodePath = current.nodePath; if (clear && current.node.tag === 'd-progress') { current.parent.children.splice(current.index, 1); } }, { node: this.$html }); } /** * 根据路径查找子节点 * @param nodePath 节点路径,/1/2 表示根节点的第1个子节点的第2个子节点 * @param node 查找的起始节点 * @examples * - findElementByNodePath('', root) 指根节点本身 * - findElementByNodePath('/', root) 指根节点本身 * - findElementByNodePath('/0', root) 指第0个子节点 * - findElementByNodePath('/2/1', root) 指第2个子节点的第1个子节点 */ findElementByNodePath(nodePath, node = this.$html) { if (nodePath[0] === '/') // 这个里边相对和绝对是一样的 nodePath = nodePath.slice(1); const arr = nodePath.split('/'); if (!nodePath || !arr.length) return node; else { const parent = node; return this.findElementByNodePath(arr.slice(1).join('/'), parent.children[+arr[0]]); } } /** * 根据标签查找元素 * @param tag */ findElementByTag(tag) { return this.$html.findElementByTag(tag); } /** * 根据属性查找元素 * @param name * @param value */ findElementByAttr(name, value) { return this.$html.findElementByAttr(name, value); } /* 绑定数据结构和接口 */ addData(res) { const microService = this.parent.page.service.app.firstMicroService; const interfaces = res.interfaces; if (interfaces && interfaces.length) { interfaces.forEach((item, index) => { const itface = interfaces[index] = __1.Interface.from(item, microService); preprocess_1.postServiceType(itface); }); microService.interfaces.unshift(...interfaces); microService.emit('interfacesChange'); } const enums = res.enums; if (enums && enums.length) { enums.forEach((item, index) => enums[index] = __1.Enum.from(item, microService)); microService.data.enums.unshift(...enums); __1.updateDataTypeList(); } const entities = res.entities; if (entities && entities.length) { entities.forEach((item, index) => entities[index] = Entity_1.default.from(item, microService)); microService.data.entities.unshift(...entities); __1.updateDataTypeList(); } const structures = res.structures; if (structures && structures.length) { structures.forEach((item, index) => structures[index] = __1.Structure.from(item, microService)); microService.data.structures.unshift(...structures); __1.updateDataTypeList(); } } async importViewCreate(none, actionOptions, then) { __1.config.defaultApp?.emit('saving'); const body = this.toJSON(); __1.utils.logger.debug('添加子页面', body); const result = await page_1.viewService.importView({ headers: { appId: __1.config.defaultApp?.id, operationAction: actionOptions?.actionName || 'View.create', operationDesc: actionOptions?.actionDesc || `添加子页面"${this.name}${this.title ? `(${this.title})` : ''}"`, }, body, }); this.deepPick(result.view, ['id']); // 添加数据 this.addData(result); if (result.view) { const temp = View.from(result.view, this.parent, this.parent.page); this.assign({ $html: temp.$html, script: temp.script, $def: temp.$def, tempPath: temp.tempPath, code: temp.code, parent: temp.parent, page: temp.page, children: temp.children, definition: temp.definition, }); __1.utils.traverse((current) => { current.node.attachNodePath(true); }, { node: this }); } this.attachNodePath(); await then?.(); // 在子页面修改时生成缓存,注意不需要 await this.page.service.emit('pageTreeChange'); const microService = this.page.service.app.firstMicroService; microService.emit('dataTypesChange'); microService.emit('enumsChange'); microService.emit('vertexIdToNameChange'); this.emit('change'); await __1.config.defaultApp?.history.load(); __1.config.defaultApp?.emit('saved'); return this; } /** * 添加子页面 */ async create(none, actionOptions, then) { __1.config.defaultApp?.emit('saving'); const body = this.toJSON(); body.serviceId = this.page.service.id; __1.utils.logger.debug('添加子页面', body); const result = await page_1.viewService.create({ headers: { appId: __1.config.defaultApp?.id, operationAction: actionOptions?.actionName || 'View.create', operationDesc: actionOptions?.actionDesc || `添加子页面"${this.name}${this.title ? `(${this.title})` : ''}"`, }, body, }); this.deepPick(result, ['id']); this.assign({ tempPath: this.parent ? `${this.parent.tempPath}/${this.name}` : `/${this.page.rootView.name}`, code: this.parent ? `${this.parent.code}/ID_${this.id}` : `/ID_${this.page.rootView.id}`, }); this.attachNodePath(); await then?.(); // 在子页面修改时生成缓存,注意不需要 await this.page.service.emit('pageTreeChange'); this.emit('change'); await __1.config.defaultApp?.history.load(); __1.config.defaultApp?.emit('saved'); return this; } /** * 删除子页面 */ async delete(none, actionOptions) { __1.config.defaultApp?.emit('saving'); if (!this.parent) throw Error('该子页面为根节点!'); try { await page_1.viewService.delete({ headers: { appId: __1.config.defaultApp?.id, operationAction: actionOptions?.actionName || 'View.delete', operationDesc: actionOptions?.actionDesc || `删除子页面"${this.name}${this.title ? `(${this.title})` : ''}"`, }, path: { id: this.id, }, }); } catch (err) { await __1.config.defaultApp?.history.load(); throw err; } const index = this.parent.children.indexOf(this); ~index && this.parent.children.splice(index, 1); // 删除的子页面为默认跳转页时,取消默认跳转页面 if (this.parent.first && this.parent.first === this.name) { this.parent.assign({ first: null }); await this.parent.update(undefined, { actionDesc: `取消子页面"${this.name}"为默认跳转页`, }); } this.destroy(); this.page.service.emit('pageTreeChange'); await __1.config.defaultApp?.history.load(); __1.config.defaultApp?.emit('saved'); } /** * 修改子页面 */ async update(none, actionOptions, then) { __1.config.defaultApp?.emit('saving'); const body = this.toPlainJSON(); __1.utils.logger.debug('修改页面', body); const result = await page_1.viewService.update({ headers: { appId: __1.config.defaultApp?.id, operationAction: actionOptions?.actionName || 'View.update', operationDesc: actionOptions?.actionDesc || `修改子页面"${this.name}${this.title ? `(${this.title})` : ''}"`, }, body, }); await then?.(); await __1.config.defaultApp?.history.load(); __1.config.defaultApp?.emit('saved'); return this; } /** * 设置子页面名称 * 如果为顶级子页面,会同时设置 Page 的属性 * @param name 名称 */ async setName(name) { const oldName = this.name; const oldTempPath = this.tempPath; this.assign({ name }); this.assign({ tempPath: this.parent ? `${this.parent.tempPath}/${name}` : `/${name}`, }); await this.update(undefined, { actionDesc: `设置页面"${oldName}"的名称为"${name}"`, }); if (this.page.rootView === this) { this.page.assign({ name }); await this.page.update(); } // 同步权限 new __1.Nuims({ domainName: this.page.service.app.name, view: this, }).editResourceFromResourceValue(oldTempPath); this.page.service.emit('pageTreeChange'); this.emit('change'); } /** * 设置子页面标题 * 如果为顶级子页面,会同时设置 Page 的属性 * @param title 标题 */ async setTitle(title) { const oldTitle = this.title; this.assign({ title }); await this.update(undefined, { actionDesc: `设置页面"${oldTitle}"的标题为"${title}"`, }); if (this.page.rootView === this) { this.page.assign({ title }); await this.page.update(); } this.page.service.emit('pageTreeChange'); this.emit('change'); } /** * 设置子页面面包屑 * @param crumb 面包屑 */ async setCrumb(crumb) { const oldCrumb = this.crumb; this.assign({ crumb }); await this.update(undefined, { actionDesc: `设置页面"${oldCrumb}"的面包屑为"${crumb}"`, }); this.page.service.emit('pageTreeChange'); this.emit('change'); } /** * 设置该子页面为默认跳转页 */ async setAsFirst() { if (!this.parent) return; this.parent.assign({ first: this.name }); await this.parent.update(undefined, { actionDesc: `设置子页面"${this.name}"为默认跳转页`, }); this.page.service.emit('pageTreeChange'); this.parent.emit('change'); } canCancelFirst() { return this.parent.first === this.name; } async setAsFirstFalse() { if (!this.parent) return; if (this.parent.first && this.parent.first === this.name) { this.parent.assign({ first: null }); await this.parent.update(undefined, { actionDesc: `设置子页面"${this.name}"为取消默认跳转页`, }); this.page.service.emit('pageTreeChange'); this.parent.emit('change'); } } /** * 添加子页面 * @param view */ async importView(view) { view.assign({ pageId: this.page && this.page.id, parentId: this.id, parent: this, }); await view.importViewCreate(undefined, undefined, async () => { this.children.unshift(view); }); return view; } /** * 添加子页面 * @param view */ async addView(view) { view.assign({ pageId: this.page && this.page.id, parentId: this.id, parent: this, }); await view.create(undefined, undefined, async () => { this.children.unshift(view); }); return view; } /** * 从模板添加子页面 * @param view 页面名称或页面 Options * @param templateId 页面模板 Id */ async addViewFromTemplate(viewName, templateId) { let view; if (typeof viewName === 'string') { view = new View({ name: viewName, title: viewName, pageId: this.page.id, page: this.page, parentId: this.id, parent: this, pageTemplateId: templateId, }); } else { view = new View(Object.assign({ pageId: this.page.id, page: this.page, parentId: this.id, parent: this, pageTemplateId: templateId, }, viewName)); } await view.importViewCreate(undefined, undefined, async () => { this.children.unshift(view); }); return view; } /** * 添加页面事件 */ async addLifecycle(data, actionOptions) { // (data as any).element = this; let lifecycle = new __1.Lifecycle(data); await lifecycle.create(undefined, Object.assign({ actionDesc: `添加页面"${this.name}"事件"${lifecycle.name}"`, }, actionOptions)); lifecycle = __1.Lifecycle.from(lifecycle, this); this.$def.lifecycles.push(lifecycle); this.emit('change'); return lifecycle; } /** * 删除页面属性 */ async removeLifecycle(lifecycle, actionOptions) { if (!lifecycle) throw Error(`该页面"${this.name}"没有事件"${lifecycle.name}"`); if (lodash_1.isPlainObject(lifecycle)) lifecycle = this.$def.lifecycles.find((item) => item.id === lifecycle.id); await lifecycle.delete(undefined, Object.assign({ actionDesc: `删除页面"${this.name}"事件"${lifecycle.name}"`, }, actionOptions)); const index = this.$def.lifecycles.indexOf(lifecycle); ~index && this.$def.lifecycles.splice(index, 1); this.emit('change'); } /** * 转换成 Vue 中需要的 JS 代码 * @TODO 这一版先做成 componentOptions 式的,后面再美化 */ toScript(options) { let componentOptions = 'const componentOptions = {};'; if (this.script) componentOptions = this.script.trim().replace(/export default |module\.exports +=/, 'const componentOptions = '); const $def = JSON.parse(JSON.stringify(this.$def)); $def.title = this.title; $def.crumb = this.crumb; $def.first = this.first; // utils.traverse((current) => { // const node = current.node; // if (node.type === 'Unparsed') { // // 借 Identifier 的鸡下个蛋 // node.type = 'Identifier'; // node.name = node.code; // }else if (node.type === 'BuiltInFunction') { // Object.assign( // node, // ((babel.parse(`this.$utils['${node.calleeCode}']()`, { // filename: 'file.js', // })as babel.types.File).program.body[0] as babel.types.ExpressionStatement).expression, // { // arguments: (node.builtInFuncParams || []).map((param: any) => { // return param.builtInFuncParamValue; // }), // }, // ); // } // }, { node: $def }, { mode: 'anyObject' }); return `${componentOptions} ${__1.genFinalCode(translator_1.default($def), options && options.finalCode)} export default componentOptions; `; } /** * 转换成 Vue 文件 */ toVue(options) { let result = ''; if (this.$html) result += `<template>\n${this.$html.toVue(options)}\n</template>\n`; if (this.script || this.$def) result += `<script>\n${this.toScript(options)}\n</script>\n`; // if (this.$def) // result += ''; // `<script>\n${this.$html.toVue()}\n</script>\n`; return result; } /** * 转换成设计器中使用的 Vue 文件 * @param options */ toDesignerVue(options) { let result = ''; if (this.$html) result += `<template>\n${this.$html.toDesignerVue(options)}\n</template>\n`; // if (this.script) // result += `<script>\n${this.script}\n</script>\n`; if (this.$def) result += ''; // `<script>\n${this.$html.toVue()}\n</script>\n`; return result; } /** * 转换成 VueOptions * @TODO 后面 template 可以优化成 render 函数 */ toVueOptions(options) { return { template: this.$html.toVue(options), script: this.toScript(options), }; } /** * 合并代码 */ async mergeBlock({ code, nodePath, position, parentNodePath }, actionOptions, then) { __1.config.defaultApp?.emit('saving', true); /** * 本来的 Name 相关的集合 */ const thisNameSets = { viewVariables: new Set(), logics: new Set(), elements: new Set(), }; /** * 需要替换的 Map */ const replacements = { viewVariables: {}, logics: {}, elements: {}, }; this.$def.params.forEach((param) => thisNameSets.viewVariables.add(param.name)); this.$def.variables.forEach((param) => thisNameSets.viewVariables.add(param.name)); this.$def.logics.forEach((logic) => thisNameSets.logics.add(logic.name)); __1.utils.traverse((current) => { if (current.node.level === 'element' && current.node.name) thisNameSets.elements.add(current.node.name); }, { node: this.$html }); const setNewNameIfNotUnique = (obj, key, type) => { // name 去重 const newName = __1.utils.unique(obj[key], thisNameSets[type]); if (newName !== obj[key]) obj[key] = replacements[type][obj[key]] = newName; }; const body = {}; const template = __1.utils.sliceTagContent(code, 'template'); const parentNode = this.findElementByNodePath(parentNodePath); const viewId = parentNode.view.id; const parentId = parentNode.id; body.id = viewId; const definition = __1.utils.sliceTagContent(code, 'definition'); if (definition) { const $def = JSON.parse(definition); body.$def = $def; } if (template) { const newNode = __1.Element.parse(template, body.$def); const paramObj = { viewId, parentId, }; newNode.assign(paramObj); body.$html = newNode.toJSON(); if (position === 'append') { // 父节点最后追加 body.$html._posIndex = parentNode.children && parentNode.children.length || 0; } else { // 添加目标标节点的位置 const posIndex = nodePath.split('/').pop(); body.$html._posIndex = +posIndex; } utils_1.traverse((current) => { if (current.node.level === 'element' && current.node.name) setNewNameIfNotUnique(current.node, 'name', 'elements'); }, { node: body.$html }); } if (definition) { // Element 需要逻辑变量没改名字时处理 const $def = body.$def; delete $def.dataSchema; if ($def.interfaces) { body.interfaces = $def.interfaces; delete $def.interfaces; } if ($def.structures) { body.structures = $def.structures; delete $def.structures; } [].concat($def.params || [], $def.variables || []).forEach((param) => { param.viewId = viewId; setNewNameIfNotUnique(param, 'name', 'viewVariables'); }); $def.lifecycles = $def.lifecycles || []; $def.lifecycles.filter((lifecycle) => !this.$def.lifecycles.find((thisLifecycle) => thisLifecycle.name === lifecycle.name)); $def.lifecycles.forEach((lifecycle) => { lifecycle.viewId = viewId; }); ($def.logics || []).forEach((logic) => { logic.moduleType = 'view'; logic.moduleId = viewId; setNewNameIfNotUnique(logic, 'name', 'logics'); }); } const hasKeyThenReplace = (obj, key, test, replacement) => { if (obj[key] === undefined || !Object.keys(replacement).length) return; if (!test) test = /^(\w+)$/; const cap = obj[key].match(test); if (!cap) return; const oldName = cap[1]; const newName = replacement[oldName]; if (newName) obj[key] = obj[key].replace(test, () => test.toString().replace(/[\^\\/]/g, '').replace(/\$$/, '').replace(/\(w\+\)/, newName)); }; const { interfaces } = body; delete body.interfaces; utils_1.traverse((current) => { if (current.node.level === 'lifecycle' || current.node.level === 'event') { hasKeyThenReplace(current.node, 'logicId', null, replacements.logics); hasKeyThenReplace(current.node, 'value', null, replacements.logics); hasKeyThenReplace(current.node, 'value', /^\$refs\.(\w+)\./, replacements.elements); } else if (current.node.level === 'logicNode' && current.node.type === 'CallLogic') { hasKeyThenReplace(current.node, 'callee', null, replacements.logics); hasKeyThenReplace(current.node, 'calleeCode', null, replacements.logics); hasKeyThenReplace(current.node, 'calleeCode', /^\$refs\.(\w+)\./, replacements.elements); } else if (current.node.level === 'expressionNode' && current.node.type === 'Identifier') { if (current.parent && (current.parent.type !== 'MemberExpression' || current.node === current.parent.object)) { hasKeyThenReplace(current.node, 'code', null, replacements.viewVariables); hasKeyThenReplace(current.node, 'name', null, replacements.viewVariables); hasKeyThenReplace(current.node, 'name', null, replacements.logics); // 处理表格 data-source 的问题 } } // else if (current.node.level === 'expressionNode') }, { node: body }, { mode: 'anyObject' }); body.interfaces = interfaces; const res = await page_1.viewService.mergeBlock({ body, headers: { appId: __1.config.defaultApp?.id, operationAction: 'View.mergeBlock', operationDesc: '根据实体自动生成组件和逻辑', }, }); await then?.(); this.redoMergeBlock(res); // await config.defaultApp?.history.load(); // config.defaultApp?.emit('saved'); } _removeDef($def) { const removedParams = this.$def.params.filter((param) => $def.params?.find((item) => param.id === item.id)); this.$def.params = this.$def.params.filter((param) => !$def.params?.find((item) => param.id === item.id)); removedParams.forEach((param) => { param.destroy(); }); const removedVariables = this.$def.variables.filter((param) => $def.variables?.find((item) => param.id === item.id)); this.$def.variables = this.$def.variables.filter((variable) => !$def.variables?.find((item) => variable.id === item.id)); removedVariables.forEach((variable) => { variable.destroy(); }); const removedLifecycles = this.$def.lifecycles.filter((param) => $def.lifecycles?.find((item) => param.id === item.id)); this.$def.lifecycles = this.$def.lifecycles.filter((lifecycle) => !$def.lifecycles?.find((item) => lifecycle.id === item.id)); removedLifecycles.forEach((lifecycle) => { lifecycle.destroy(); }); const removedLogics = this.$def.logics.filter((logic) => $def.logics?.find((item) => logic.id === item.id)); this.$def.logics = this.$def.logics.filter((logic) => !$def.logics?.find((item) => logic.id === item.id)); removedLogics.forEach((logic) => { // @TODO: 目前只做 logic 的 remove,后面页面中的可以切过来 __1.config.defaultApp?.emit('some-remove', logic); logic.destroy(); }); } async undoMergeBlock(res) { const microService = this.page.service.app.firstMicroService; const structures = res.structures; if (structures && structures.length) { const allStructures = microService.data.structures; for (let i = allStructures.length - 1; i >= 0; i--) { if (structures.find((item) => item.id === allStructures[i].id)) allStructures.splice(i, 1); } __1.updateDataTypeList(); } const interfaces = res.interfaces; if (interfaces && interfaces.length) { const allInterfaces = microService.interfaces; for (let i = interfaces.length - 1; i >= 0; i--) { if (allInterfaces.find((item) => item.id === interfaces[i].id)) allInterfaces.splice(i, 1); } const allglobalLogics = microService.globalLogic.globalLogics; for (let i = interfaces.length - 1; i >= 0; i--) { if (allglobalLogics.find((item) => item.id === interfaces[i].id)) allglobalLogics.splice(i, 1); } microService.emit('interfacesChange'); } const parent = __1.vertexsMap.get(res.$html.parentId); parent.removeChild(res.$html, { actionMode: __1.ACTION_MODE.undoRedo, loadHistory: false }); this._removeDef(res.$def); this.page.service.emit('pageTreeChange'); this.emit('change'); this.page.service.emit('vertexIdToNameChange'); await __1.config.defaultApp?.history.load(); __1.config.defaultApp?.emit('saved'); } _addDef($def) { $def.params?.forEach((param) => { this.$def.params.push(__1.ViewParam.from(param, this)); }); $def.variables?.forEach((variable) => { this.$def.variables.push(__1.ViewVariable.from(variable, this)); }); $def.lifecycles?.forEach((lifecycle) => { this.$def.lifecycles.push(__1.Lifecycle.from(lifecycle, this)); }); $def.logics?.forEach((logic) => { this.$def.logics.push(Logic_1.default.from(logic, this)); }); } async redoMergeBlock(res) { const microService = this.page.service.app.firstMicroService; const structures = res.structures; if (structures && structures.length) { structures.forEach((item, index) => structures[index] = __1.Structure.from(item, microService)); microService.data.structures.unshift(...structures); __1.updateDataTypeList(); } const interfaces = res.interfaces; if (interfaces && interfaces.length) { interfaces.forEach((item, index) => { const itface = interfaces[index] = __1.Interface.from(item, microService); itface.assign({ serviceType: 'micro' }); }); microService.interfaces.unshift(...interfaces); microService.globalLogic.globalLogics.unshift(...interfaces); microService.emit('interfacesChange'); } const parent = __1.vertexsMap.get(res.$html.parentId); parent.addChild(res.$html, { actionMode: __1.ACTION_MODE.undoRedo, loadHistory: false }); this._addDef(res.$def); this.page.service.emit('pageTreeChange'); this.emit('change'); this.page.service.emit('vertexIdToNameChange'); await __1.config.defaultApp?.history.load(); __1.config.defaultApp?.emit('saved'); } _syncDef($def) { $def.params?.forEach((param) => { if (!this.$def.params.find((thisParam) => thisParam.id === param.id)) this.$def.params.push(__1.ViewParam.from(param, this)); }); $def.variables?.forEach((variable) => { if (!this.$def.variables.find((thisVariable) => thisVariable.id === variable.id)) this.$def.variables.push(__1.ViewVariable.from(variable, this)); }); $def.lifecycles?.forEach((lifecycle) => { if (!this.$def.lifecycles.find((thisLifecycle) => thisLifecycle.id === lifecycle.id)) this.$def.lifecycles.push(__1.Lifecycle.from(lifecycle, this)); }); $def.logics?.forEach((logic) => { if (!this.$def.logics.find((thisLogic) => thisLogic.id === logic.id)) this.$def.logics.push(Logic_1.default.from(logic, this)); }); } /** * 从后端 JSON 生成规范的 View 对象 * @param currentView 方便构建子对象时关联,主要在 load 中使用 */ static from(source, parent, page, currentView) { const view = new View(source); currentView = currentView || view; if (page && page.rootView) { view.assign({ tempPath: parent ? `${parent.tempPath}/${view.name}` : `/${page.rootView.name}`, code: parent ? `${parent.code}/ID_${view.id}` : `/ID_${page.rootView.id}`, }); } view.assign({ parent, page, children: view.children?.map((child) => View.from(child, currentView, page)), }); view.$html && view.assign({ $html: __1.Element.from(view.$html, null, currentView) }); view.$def.params = view.$def.params.map((param) => __1.ViewParam.from(param, currentView)); view.$def.variables = view.$def.variables.map((param) => __1.ViewVariable.from(param, currentView)); view.$def.lifecycles = view.$def.lifecycles.map((lifecycle) => __1.Lifecycle.from(lifecycle, currentView)); view.$def.logics = view.$def.logics.map((param) => Logic_1.default.from(param, currentView)); return view; } /** * 按照模板创建 */ static async fromTemplate(templateName, source, parent, page, scope) { // const template = TEMPLATE_MAP[templateName]; // @TODO: 后面改到资产中心 const { rows } = await assets_1.blockService.loadList({ query: { keyword: (scope || __1.config.scope) === 'h5' ? `@lcap/mobile-ui/${templateName}.vue` : `@cloud-ui/s-${templateName}.vue`, }, }); if (!rows[0]) throw new Error('Cannot find block ' + templateName); const content = rows[0].content.replace(/https:\/\/static-vusion\.163yun\.com/g, __1.config.staticURL); const html = __1.utils.sliceTagContent(content, 'template'); const script = __1.utils.sliceTagContent(content, 'script'); const view = this.from(source, parent, page); view.assign({ $html: __1.Element.fromHTML(html, null, view), script, }); return view; } } __decorate([ decorators_1.immutable() ], View.prototype, "level", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "id", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "name", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "path", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "tempPath", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "code", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "title", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "crumb", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "first", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "parentId", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "script", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "pageId", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "pageTemplateId", void 0); __decorate([ decorators_1.circular(), decorators_1.immutable() ], View.prototype, "page", void 0); __decorate([ decorators_1.circular(), decorators_1.immutable() ], View.prototype, "parent", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "children", void 0); __decorate([ decorators_1.excludedInJSON() ], View.prototype, "contentPromise", void 0); __decorate([ decorators_1.immutable() ], View.prototype, "moreChildrenFields", void 0); __decorate([ decorators_1.action('添加子页面') ], View.prototype, "importViewCreate", null); __decorate([ decorators_1.action('添加子页面') ], View.prototype, "create", null); __decorate([ decorators_1.action('删除子页面') ], View.prototype, "delete", null); __decorate([ decorators_1.action('设置子页面名称') ], View.prototype, "setName", null); __decorate([ decorators_1.action('设置子页面标题') ], View.prototype, "setTitle", null); __decorate([ decorators_1.action('设置子页面面包屑') ], View.prototype, "setCrumb", null); __decorate([ decorators_1.action('设置该子页面为默认跳转页') ], View.prototype, "setAsFirst", null); __decorate([ decorators_1.action('是否是默认跳转页') ], View.prototype, "canCancelFirst", null); __decorate([ decorators_1.action('设置该子页面为取消默认跳转页') ], View.prototype, "setAsFirstFalse", null); __decorate([ decorators_1.action('添加页面事件') ], View.prototype, "addLifecycle", null); __decorate([ decorators_1.action('删除页面事件') ], View.prototype, "removeLifecycle", null); __decorate([ decorators_1.action('根据实体自动生成组件和逻辑') ], View.prototype, "mergeBlock", null); exports.View = View; exports.default = View; //# sourceMappingURL=View.js.map