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.findParmeterByName(names[0]); if (!parameter) { return null; } let valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion); if (!valueType || !valueType.properties || valueType.properties.length <= 0) { return null; } let index = 1; while (index < names.length) { valueType = this.findValueTypeByPropertyName(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 findParmeterByCode(parameterCode: string) { return this.parameters[parameterCode]; } public findParmeterByName(parameterName: string) { const values = Object.values(this.parameters); for (const value of values) { if (value.name === parameterName) { return value; } } return null; } public findValueType(valueType: string, valueTypeVersion: number): any { if (Tools.isNill(valueType)) { return null; } const key = valueType + (Tools.isNill(valueTypeVersion) ? '' : ':' + valueTypeVersion); return this.valueTypes[key]; } public findValueTypeByPropertyName(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 findValueTypeByPropertyCode(valueTypeString: string, valueTypeVersion: number, propertyCode: 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.code === propertyCode) { 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.type === 'parameter') { 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 }; } } else if (parameter.type === 'enum') { return { label: parameter.name, type: 'enum', 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 = /(\.(\](.+?)\[)?\}(.+?)\{[$#])+/g; //匹配 '.]n[}xxx{$#' 模式 // -- -- --- -- -- --- ---- // . ] n [ } xxx {$# 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(/[#$]\{(.+?)\}(\[(.+?)\])?/g, '$1'); if (Tools.isUndefinedOrNull(parameterName)) { return null; } /* const enumRegReverse = /(\.(\](.+?)\[)?\}(.+?)\{#)+/g; //匹配 '.]n[}xxx{#' 模式 // -- -- --- -- -- --- ---- // . ] n [ } xxx {# let matcheds: any = matchedTextReverse.match(enumRegReverse); if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) { const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{\$)+/g; //匹配 '.]n[}xxx{$' 模式 // -- -- --- -- -- --- ---- // . ] n [ } xxx {$ matcheds = matchedTextReverse.match(regReverse); if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) { return null; } } const matched = Tools.reverseString(matcheds[0]); let parameterName = matched.replace(/#\{(.+?)\}(\[(.+?)\])?/g, '$1'); // ---- --- -- -- --- -- // $ { xxx } [ n ] if (Tools.isUndefinedOrNull(parameterName)) { parameterName = matched.replace(/\$\{(.+?)\}(\[(.+?)\])?/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: /^(.*)?$/, }; } 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 { return (context: any) => { return this.doAutoCompletion(context); }; } } export { AutoCompletionManager };