@lcap/asl
Version:
NetEase Application Specific Language
307 lines (299 loc) • 10.5 kB
text/typescript
import { immutable, circular, action, excludedInJSON } from '../decorators';
import { config, history, LEVEL_ENUM, Vertex, MicroService, ProcessComponent, ProcessParam, ProcessReturn, ProcessProperty, ProcessInterface, vertexsMap, LogicItem, typeCheck, ActionOptions } from '..';
import processService from '../../service/process';
/**
* 流程类
*/
export class Process extends Vertex {
/**
* 概念类型
*/
()
public readonly level: LEVEL_ENUM = LEVEL_ENUM.process;
/**
* 流程 Id
*/
()
public readonly id: string = undefined;
/**
* 流程名称
*/
()
public readonly name: string = undefined;
/**
* 流程标题
*/
()
public readonly title: string = undefined;
/**
* 流程描述
*/
()
public readonly description: string = undefined;
/**
* 流程组件集合
*/
()
public readonly childShapes: Array<ProcessComponent> = [];
/**
* 流程输入参数
*/
()
public readonly params: Array<any> = [];
/**
* 流程输出参数
*/
()
public readonly returns: Array<any> = [];
/**
* 流程内置参数
*/
()
public readonly properties: Array<any> = [];
/**
* 启动流程接口
*/
()
public readonly launchProcessInterface: ProcessInterface = undefined;
/**
* 后端服务类型
*/
()
public readonly serviceType: string = 'MICROSERVICE';
/**
* 所属后端服务 Id
*/
()
public readonly serviceId: string = undefined;
/**
* 所属后端服务
*/
()
()
public readonly service: MicroService = undefined;
/**
* 树组件的子节点字段
*/
()
()
public readonly childrenField: string = 'childShapes';
/**
* 树组件的子节点字段
*/
()
()
public readonly moreChildrenFields: Array<string> = ['params', 'returns', 'properties', 'interfaces'];
/**
* 已存在名称集合
*/
()
()
public readonly existingNames: Array<string> = [];
/**
* 接口列表,单纯用于 tree 展示
*/
()
()
public readonly interfaces: Array<ProcessInterface> = [];
/**
* @param source 需要合并的部分参数
*/
constructor(source?: Partial<Process>) {
super();
this.assign(source);
}
/**
* 添加流程
*/
('添加流程')
async create(none?: void, actionOptions?: ActionOptions) {
config.defaultApp?.emit('saving');
this.assign({ editing: false, loading: true });
const body = this.toJSON();
const result = await processService.add({
headers: {
appId: config.defaultApp?.id,
operationAction: actionOptions?.actionName || 'Process.create',
operationDesc: actionOptions?.actionDesc || `添加流程"${this.name}${this.title ? `(${this.title})` : ''}"`,
},
body,
});
this.assign(Process.from(result, this.service));
this.service.emit('interfacesChange');
await config.defaultApp?.history.load();
config.defaultApp?.emit('saved');
return this;
}
/**
* 删除流程
*/
('删除流程')
async delete(none?: void, actionOptions?: ActionOptions) {
config.defaultApp?.emit('saving');
await processService.delete({
headers: {
appId: config.defaultApp?.id,
operationAction: actionOptions?.actionName || 'Process.delete',
operationDesc: actionOptions?.actionDesc || `删除流程"${this.name}${this.title ? `(${this.title})` : ''}"`,
},
path: {
id: this.id,
},
});
typeCheck.deleteByProcess(this.id);
const index = this.service.processes.indexOf(this);
~index && this.service.processes.splice(index, 1);
this.destroy();
this.service.emit('interfacesChange');
await config.defaultApp?.history.load();
config.defaultApp?.emit('saved');
}
/**
* 修改流程
*/
async update(deep?: boolean, actionOptions?: ActionOptions, then?: () => Promise<any>) {
config.defaultApp?.emit('saving');
const body = this.toPlainJSON();
const result = await processService.update({
headers: {
appId: config.defaultApp?.id,
operationAction: actionOptions?.actionName || 'Process.update',
operationDesc: actionOptions?.actionDesc || `修改流程"${this.name}${this.title ? `(${this.title})` : ''}"`,
},
body,
});
// 深度更新,需要同步更新 流程接口 和 UserTask 中的 完成任务接口
if (deep && result) {
const { childShapes = [], launchProcessInterface } = result;
const { name, path, method } = launchProcessInterface;
this.launchProcessInterface.assign({ name, path, method });
this.launchProcessInterface.logic.assign({ name });
this.childShapes.forEach((childShape) => {
const { type, completeTaskInterface } = childShape;
if (type === 'UserTask') {
const newUserTask = childShapes.find((cShape: ProcessComponent) => cShape.id === childShape.id);
const { name, path, method } = newUserTask.completeTaskInterface;
completeTaskInterface.assign({ name, path, method });
completeTaskInterface.logic.assign({ name });
}
});
this.service.emit('interfacesChange');
}
await then?.();
await config.defaultApp?.history.load();
config.defaultApp?.emit('saved');
return this;
}
/**
* 批量修改流程组件
*/
async batchComponents(body: any, actionOptions?: ActionOptions) {
config.defaultApp?.emit('saving');
const result = await processService.batchComponents({
headers: {
appId: config.defaultApp?.id,
operationAction: actionOptions?.actionName || 'Process.batchComponents',
operationDesc: `批量修改流程组件"${this.name}${this.title ? `(${this.title})` : ''}"`,
},
body,
});
let childShapes: Array<ProcessComponent> = [];
this.childShapes.forEach((processComponent) => {
const isDeleted = result.delete.find((node: any) => node.id === processComponent.id);
if (isDeleted) {
return;
}
const isUpdatedComp = result.update.find((node: any) => node.id === processComponent.id);
if (isUpdatedComp) {
childShapes.push(ProcessComponent.from(isUpdatedComp, this));
return;
}
childShapes.push(processComponent);
});
childShapes = childShapes.concat((result.add).map((childShape: any) => ProcessComponent.from(childShape, this)));
this.assign({ childShapes });
this.service.emit('interfacesChange');
this.checkType();
await config.defaultApp?.history.load();
config.defaultApp?.emit('saved');
}
/**
* 流程级别的类型检查
*/
async checkType() {
const result = await processService.checkTypeProcess({
path: { id: this.id },
});
typeCheck.deleteByProcess(this.id);
typeCheck.pushAll(result);
result.forEach((typeCheckResult: any) => {
if (typeCheckResult.processComponentId) {
const processComponent = vertexsMap.get(typeCheckResult.processComponentId);
ProcessComponent.assignTypeCheckResult(processComponent as ProcessComponent, typeCheckResult);
}
if (typeCheckResult.logicId) {
const logicItem = vertexsMap.get(typeCheckResult.id);
LogicItem.assignTypeCheckResult(logicItem as LogicItem, typeCheckResult);
}
});
}
/**
* 设置流程名称
* @param name 名称
*/
('设置流程名称')
async setName(name: string) {
const oldName = this.name;
this.assign({ name });
await this.update(true, {
actionDesc: `设置流程"${oldName}"的名称为"${name}"`,
});
}
/**
* 设置流程标题
* @param title 标题
*/
('设置流程标题')
async setTitle(title: string) {
this.assign({ title });
await this.update(false, {
actionDesc: `设置流程"${this.name}"的标题为"${title}"`,
});
}
/**
* 设置流程描述
* @param description 描述
*/
('设置流程描述')
async setDescription(description: string) {
this.assign({ description });
await this.update(false, {
actionDesc: `设置流程"${this.name}"的描述为"${description}"`,
});
}
/**
* 从后端 JSON 生成规范的 Param 对象
*/
public static from(source: any, service: MicroService) {
const process = new Process(source);
process.assign({ service });
if (source) {
const { params = [], returns = [], properties = [], childShapes = [], launchProcessInterface } = source;
process.assign({
params: params.map((param: any) => ProcessParam.from(param, process)),
returns: returns.map((rn: any) => ProcessReturn.from(rn, process)),
properties: properties.map((property: any) => ProcessProperty.from(property, process)),
childShapes: childShapes.map((childShape: ProcessComponent) => ProcessComponent.from(childShape, process)),
});
if (launchProcessInterface) {
const ifce = ProcessInterface.from(launchProcessInterface, process);
process.assign({
launchProcessInterface: ifce,
interfaces: [ifce],
});
}
}
return process;
}
}
export default Process;