import { immutable, excludedInJSON, action } from '../decorators'; import { config, history, LEVEL_ENUM, Logic, Param, Process, ProcessInterface, Schema, ActionOptions } from '..'; import { convert2RefType } from '../data/dataTypeUtils'; import { getBasicTypeDefaultValue } from '../data/basicTypes'; import { schemaService } from '../../service/common'; import processService from '../../service/process'; /** * 流程输入参数 */ export class ProcessParam extends Param { /** * 概念类型 */ @immutable() public readonly level: LEVEL_ENUM = LEVEL_ENUM.processParam; /** * 流程 Id */ @immutable() public readonly parentId: string = undefined; /** * 视图 */ @excludedInJSON() @immutable() public readonly process: Process = undefined; /** * 默认值 * 按 JSON string 处理 * - string: 666 -> '666' * - string: true -> 'true' * - number: 666 -> 666 * - boolean: true -> true */ public defaultValue: string = undefined; /** * @param source 需要合并的部分参数 */ constructor(source?: Partial) { super(); source && this.assign(source); } genCode() { return `ID_${this.process.id}.ID_${this.id}`; } /** * 添加流程输入参数 */ @action('添加流程输入参数') async create(none?: void, actionOptions?: ActionOptions) { config.defaultApp?.emit('saving'); this.assign({ loading: true, editing: false }); const body = this.toJSON(); const result = await processService.addProcessVal({ headers: { appId: config.defaultApp?.id, operationAction: actionOptions?.actionName || 'ProcessParam.create', operationDesc: actionOptions?.actionDesc || `添加流程"${this.process.name}"输入参数"${this.name}"`, }, body, }); this.assign(ProcessParam.from(result, this.process)); this.updateInterface(); await config.defaultApp?.history.load(); config.defaultApp?.emit('saved'); return this; } /** * 删除流程输入参数 */ @action('删除流程输入参数') async delete(none?: void, actionOptions?: ActionOptions) { if (this.id) { config.defaultApp?.emit('saving'); const body = this.toJSON(); await processService.deleteProcessVal({ headers: { appId: config.defaultApp?.id, operationAction: actionOptions?.actionName || 'ProcessParam.delete', operationDesc: actionOptions?.actionDesc || `删除流程"${this.process.name}"输入参数"${this.name}"`, }, body, }); const index = this.process.params.indexOf(this); ~index && this.process.params.splice(index, 1); this.destroy(); this.updateInterface(); await config.defaultApp?.history.load(); config.defaultApp?.emit('saved'); } } /** * 修改流程输入参数 */ async update(none?: void, actionOptions?: ActionOptions, then?: () => Promise) { config.defaultApp?.emit('saving'); const body = this.toJSON(); const result = await processService.updateProcessVal({ headers: { appId: config.defaultApp?.id, operationAction: actionOptions?.actionName || 'ProcessParam.update', operationDesc: actionOptions?.actionDesc || `修改流程"${this.process.name}"输入参数"${this.name}"`, }, body, }); this.assign(ProcessParam.from(result, this.process)); this.updateInterface(); await then?.(); await config.defaultApp?.history.load(); config.defaultApp?.emit('saved'); return this; } /** * 设置流程输入参数名称 * @param name 名称 */ @action('设置流程输入参数名称') async setName(name: string) { const oldName = this.name; this.assign({ name }); await this.update(undefined, { actionDesc: `设置流程"${this.process.name}"的输入参数"${oldName}"的名称为"${name}"`, }); } /** * 设置流程输入参数描述 * @param description 描述 */ @action('设置流程输入参数描述') async setDescription(description: string) { this.assign({ description }); await this.update(undefined, { actionDesc: `设置流程"${this.process.name}"的输入参数"${this.name}"的描述为"${description}"`, }); } /** * 设置流程输入参数的数据类型 * @param $ref 数据类型 */ @action('设置流程输入参数的数据类型') async setDataType(schema: Schema) { // 用于update失败后还原数据 const originalData = { schema: Object.assign({}, this.schema), defaultValue: this.defaultValue, }; Object.assign(this.schema, { $ref: undefined, //引用到Entity或者structure type: undefined, format: undefined, typeInstantiation: undefined, }); Object.assign(this.schema, schema); this.assign({ defaultValue: getBasicTypeDefaultValue() }); try { await this.update(undefined, { actionDesc: `设置流程"${this.process.name}"的输入参数"${this.name}"的数据类型为"${this.schema.typeKey}"`, }); this.genSchemaChildren(); this.process.checkType(); } catch (err) { this.assign(originalData); config.defaultApp?.emit('saved'); throw err; } } /** * 设置流程输入参数的默认值 * @param defaultValue 默认值 */ @action('设置流程输入参数的默认值') async setDefaultValue(defaultValue: string) { this.assign({ defaultValue }); await this.update(undefined, { actionDesc: `设置流程"${this.process.name}"的输入参数"${this.name}"的默认值为"${defaultValue}"`, }); } /** * 查找schema 顶点被引用的流程输入参数顶点列表 */ async getSchemaUsage() { if (this.schema) { const schemaId = this.schema.type === 'genericType' ? this.id : this.schema.id; const result = await schemaService.getSchemaUsage({ query: { schemaId, valSource: 'process_param', }, }); return result; } } /** * 流程接口会自动根据输入输出参数变更,更新流程接口的输入输出 */ async updateInterface() { const { launchProcessInterface } = this.process; if (launchProcessInterface) { const ifce = await processService.getInterface({ path: { id: launchProcessInterface.id } }); const { logic } = launchProcessInterface; const oldParams = logic?.params || []; const newParams = (ifce?.logic?.params || []).map((param: Param) => { const existParam = oldParams.find((oldParam: Param) => oldParam.id === param.id); if (existParam) { existParam.assign(Param.from(param, logic)); return existParam; } return Param.from(param, logic); }); logic.assign({ params: newParams }); } } /** * 从后端 JSON 生成规范的 ProcessParam 对象 */ public static from(source: any, process: Process | Logic) { convert2RefType(source.schema); source.process = process; source.code = `ID_${process.id}.ID_${source.id}`; source.parentId = process.id; const processParam = new ProcessParam(source); processParam.genSchemaChildren(); return processParam; } } export default ProcessParam;