@lcap/asl
Version:
NetEase Application Specific Language
301 lines (274 loc) • 8.81 kB
text/typescript
import { immutable, circular, excludedInJSON, action } from '../decorators';
import {
config, utils, LEVEL_ENUM, Vertex, DataNode,
ObjectSchema, Service, dataTypesMap, updateDataTypeList,
StructureProperty, ActionOptions,
} from '..';
import { structureService } from '../../service/data';
import { convert2RefType } from './dataTypeUtils';
import { updateAllVariablesChildrenSchema } from '../index';
/**
* 数据结构类
*/
export class Structure extends Vertex implements ObjectSchema {
/**
* 概念类型
*/
public readonly level: LEVEL_ENUM = LEVEL_ENUM.structure;
/**
* Id
*/
public readonly id: string = undefined;
/**
* dataTypes 中的唯一标识
*/
public readonly schemaRef: string = undefined;
/**
* 名称
*/
public readonly name: string = undefined;
/**
* 描述
*/
public readonly description: string = undefined;
/**
* 类型
*/
public readonly type: 'object' = 'object';
/**
* 属性列表
*/
readonly propertyList: Array<StructureProperty> = [];
public readonly resolvers: string = undefined;
/**
* 所属服务 Id
*/
public readonly serviceId: string = undefined;
/**
* catogory Name
*/
public readonly category: string = undefined;
/**
* 所属服务类型
*/
public readonly serviceType: string = undefined;
/**
* 所属实体 Id
*/
public readonly entityId: string = undefined;
/**
* 所属服务
*/
public readonly service: Service = undefined;
/**
* 父节点
*/
public readonly dataNode: DataNode = undefined;
/**
* 周边存在的名称
*/
public existingNames: Array<string> = [];
/**
* 周边存在的名称
*/
constructor(source?: Partial<Structure>) {
super();
source && this.assign(source);
}
/**
* 按当前 id 加载数据结构数据
* @requires this.id
*/
async load() {
const result = await structureService.loadDetail({
query: {
id: this.id,
},
config: {
mock: config.mock,
},
});
this.assign(result);
return this;
}
/**
* 按当前 id 加载数据结构数据
* @requires this.id
*/
async loadPro() {
const result = await structureService.loadDetail({
query: {
id: this.id,
},
});
Object.assign(result, result.definition);
delete result.definition;
convert2RefType(result);
const structure = new Structure(result);
const propertyList = structure.propertyList as Array<StructureProperty>;
propertyList.forEach((property, index) => {
property = propertyList[index] = new StructureProperty(property);
property.assign({ root: structure });
});
const service = this.dataNode.service;
structure.assign({
schemaRef: `#/${service.id}/${structure.id}`,
dataNode: service.data,
expanded: true,
});
dataTypesMap[structure.schemaRef] = structure;
this.assign(structure);
const pos = this.dataNode.structures.findIndex((item) => item.id === this.id);
if (pos === -1)
this.dataNode.structures.unshift(this);
else {
this.dataNode.structures.splice(pos, 1, structure);
}
updateDataTypeList();
updateAllVariablesChildrenSchema();
this.dataNode.service.emit('dataTypesChange');
this.dataNode.service.emit('vertexIdToNameChange', this.id, this.name);
return this;
}
/**
* 添加数据结构
*/
async create(none?: void, actionOptions?: ActionOptions, then?: () => Promise<any>) {
config.defaultApp?.emit('saving');
const body = this.toJSON();
utils.logger.debug('添加数据结构', body);
const result: Structure = await structureService.create({
headers: {
appId: config.defaultApp?.id,
operationAction: actionOptions?.actionName || 'Structure.create',
operationDesc: actionOptions?.actionDesc || `添加数据结构"${this.name}"`,
},
body,
});
this.deepPick(result, ['id']);
this.assign({
schemaRef: `#/${this.dataNode.service.id}/${result.id}`,
});
dataTypesMap[this.schemaRef] = this;
await then?.();
updateDataTypeList();
this.dataNode.service.emit('dataTypesChange');
this.dataNode.service.emit('vertexIdToNameChange', this.id, this.name);
await config.defaultApp?.history.load();
config.defaultApp?.emit('saved');
return this;
}
/**
* 删除数据结构
*/
async delete(none?: void, actionOptions?: ActionOptions) {
config.defaultApp?.emit('saving');
if (this.id) {
await structureService.delete({
headers: {
appId: config.defaultApp?.id,
operationAction: actionOptions?.actionName || 'Structure.delete',
operationDesc: actionOptions?.actionDesc || `删除数据结构"${this.name}"`,
},
query: {
id: this.id,
},
});
}
const index = this.dataNode.structures.indexOf(this);
~index && this.dataNode.structures.splice(index, 1);
this.dataNode.service.globalLogic.removeCategoryStructure(this);
delete dataTypesMap[this.schemaRef];
updateDataTypeList();
this.destroy();
this.dataNode.service.emit('dataTypesChange');
await config.defaultApp?.history.load();
config.defaultApp?.emit('saved');
}
/**
* 修改数据结构
*/
async update(none?: void, actionOptions?: ActionOptions, then?: () => Promise<any>) {
config.defaultApp?.emit('saving');
const body = this.toJSON('', ['propertyList']);
utils.logger.debug('修改数据结构', body);
const result: Structure = await structureService.update({
headers: {
appId: config.defaultApp?.id,
operationAction: actionOptions?.actionName || 'Structure.update',
operationDesc: actionOptions?.actionDesc || `修改数据结构"${this.name}"`,
},
body,
});
convert2RefType(result);
this.plainAssign(result);
await then?.();
await config.defaultApp?.history.load();
config.defaultApp?.emit('saved');
return this;
}
/**
* 设置数据结构名称
* @param name 名称
*/
async setName(name: string) {
const oldName = this.name;
this.assign({ name });
await this.update(undefined, {
actionDesc: `设置数据结构"${oldName}"的名称为"${name}"`,
});
updateDataTypeList();
this.dataNode.service.emit('dataTypesChange');
this.dataNode.service.emit('vertexIdToNameChange', this.id, this.name);
}
/**
* 设置数据结构描述
* @param description 描述
*/
async setDescription(description: string) {
this.assign({ description });
await this.update(undefined, {
actionDesc: `设置数据结构"${this.name}"的描述为"${description}"`,
});
}
/**
* 从后端 JSON 生成规范的 Structure 对象
*/
public static from(source: any, service: Service) {
convert2RefType(source);
const structure = new Structure(source);
structure.assign({
dataNode: service.data,
schemaRef: `#/${service.id}/${structure.id}`,
});
const propertyList = structure.propertyList as Array<StructureProperty>;
propertyList.forEach((property, index) => {
property = propertyList[index] = new StructureProperty(property);
property.assign({ root: structure });
});
structure.assign({ resolvers: undefined });
dataTypesMap[structure.schemaRef] = structure;
return structure;
}
}
export default Structure;