import { axios, Tools } from 'platform-core'; class AutoCompletionManager { parameters: any; valueTypes: any; constructor() { this.parameters = {}; this.valueTypes = {}; } public setParameters(parameters: any) { this.parameters = parameters; } public setValueTypes(valueTypes: any) { this.valueTypes = valueTypes; } public getOptions(path: string): any { // 如果没有路径, 返回参数列表 if (!path) { return this.getParameterOptions(); } // 以 . 结束表示对象属性 if (path.endsWith('.')) { path = path.substring(0, path.length - 1); } const names = path.split('.'); if (!names) { return this.getParameterOptions(); } //查找参数 const parameter = this.findParmeter(names[0]); if (!parameter) { return null; } const valueTypeString = parameter.valueType; const valueTypeVersion = parameter.valueTypeVersion; let valueType = this.findValueType(valueTypeString, valueTypeVersion); if (!valueType || !valueType.properties || valueType.properties.length <= 0) { return null; } let index = 1; while (index < names.length) { valueType = this.findValueTypeByProperty(valueType.code, valueType.version, names[index++]); } const options: any[] = []; for (const property of valueType.properties) { const option = this.getOptionItem(property); if (option) { options.push(option); } } return options; } public findParmeter(parameterName: string) { return this.parameters[parameterName]; } public findValueType(valueType: string, valueTypeVersion: number): any { return this.valueTypes[this.getValueTypeAndVersionKey(valueType, valueTypeVersion)]; } public findValueTypeByProperty(valueTypeString: string, valueTypeVersion: number, propertyName: string) { const valueType = this.findValueType(valueTypeString, valueTypeVersion); if (!valueType || !valueType.properties || valueType.properties.length <= 0) { return null; } for (const property of valueType.properties) { if (property.name === propertyName) { return this.findValueType(property.valueType, property.valueTypeVersion); } } return null; } public getParameterOptions(): any { const options: any[] = []; Object.values(this.parameters).forEach((parameter: any) => { const option = this.getOptionItem(parameter); if (option) { options.push(option); } }); return options; } public getOptionItem(parameter: any) { const valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion); if (!Tools.isNill(valueType)) { const version = valueType.version ? valueType.name + '(V' + valueType.version + ')' : valueType.name; const info = parameter.valueTypeIsList ? 'List<' + version + '>' : version; if (parameter.valueTypeIsList) { return { label: parameter.name, type: 'variable', apply: '${' + parameter.name + '}[0]', info: info }; } else { return { label: parameter.name, type: 'variable', apply: '${' + parameter.name + '}', info: info }; } } return null; } public autoCompletionParameters(to: any, matchedText?: any): any { return { from: to, options: this.getParameterOptions(), validFor: /(.*)?/, }; } public autoCompletionProperties(to: any, matchedText?: any): any { const matchedTextReverse = Tools.reverseString(matchedText); const regReverse = /(\.(\]\S*(.+?)\S*\[)?\}(.+?)\{\$)+/g; //匹配 '.]xxx[}yyy{$' 模式 //const regReverse = /(\.\}(.+?)\{\$)+/g; //匹配 '.}]xxx[yyy{$' 模式 const matcheds: any = matchedTextReverse.match(regReverse); if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) { return null; } const matched = Tools.reverseString(matcheds[0]); const parameterName = matched.replace(/\$\{(.+?)\}(\[\S*(.+?)\S*\])?/g, '$1'); if (Tools.isUndefinedOrNull(parameterName)) { return null; } const options = this.getOptions(parameterName); if (Tools.isUndefinedOrNull(options)) { return null; } return { from: to, options: options, validFor: /^(.*)?$/, }; } private getValueTypeAndVersionKey(valueType: string, valueTypeVersion: number): string { if (Tools.isNill(valueType)) { return ''; } return valueType + (Tools.isNill(valueTypeVersion) ? '' : ':' + valueTypeVersion); } public doAutoCompletion(context: any): any { const beforeMatched = context.matchBefore(/(.+?)/g); if (Tools.isUndefinedOrNull(beforeMatched)) { return null; } const beforeText = beforeMatched.text || ''; if (beforeText.endsWith('.')) { //匹配属性 return this.autoCompletionProperties(beforeMatched.to, beforeText); } else if (beforeText.endsWith(' ')) { //匹配参数 return this.autoCompletionParameters(beforeMatched.to); } else { return null; } } public load(url: string) { axios.get(url).then((response) => { this.setParameters(response.data?.parameters); this.setValueTypes(response.data?.valueTypes); }); } public autoCompletion(): any { const THIS = this; return function (context: any) { return THIS.doAutoCompletion(context); }; } } export { AutoCompletionManager };