@lcap/asl
Version:
NetEase Application Specific Language
1,065 lines • 41.1 kB
JavaScript
"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' ? `/mobile-ui/${templateName}.vue` : `-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