You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
7.2 KiB

import { axios, Tools } from 'platform-core';
10 months ago
class AutoCompletionManager {
6 months ago
parameters: any;
valueTypes: any;
10 months ago
constructor() {
6 months ago
this.parameters = {};
this.valueTypes = {};
}
public setParameters(parameters: any) {
10 months ago
this.parameters = parameters;
}
public setValueTypes(valueTypes: any) {
10 months ago
this.valueTypes = valueTypes;
}
public getOptions(path: string): any {
6 months ago
// 如果没有路径, 返回参数列表
10 months ago
if (!path) {
return this.getParameterOptions();
}
6 months ago
// 以 . 结束表示对象属性
10 months ago
if (path.endsWith('.')) {
path = path.substring(0, path.length - 1);
}
const names = path.split('.');
if (!names) {
return this.getParameterOptions();
}
6 months ago
//查找参数
5 months ago
const parameter = this.findParmeterByName(names[0]);
10 months ago
if (!parameter) {
return null;
}
5 months ago
let valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion);
10 months ago
if (!valueType || !valueType.properties || valueType.properties.length <= 0) {
return null;
}
let index = 1;
while (index < names.length) {
5 months ago
valueType = this.findValueTypeByPropertyName(valueType.code, valueType.version, names[index++]);
10 months ago
}
const options: any[] = [];
10 months ago
for (const property of valueType.properties) {
6 months ago
const option = this.getOptionItem(property);
if (option) {
options.push(option);
6 months ago
}
10 months ago
}
return options;
}
5 months ago
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;
10 months ago
}
6 months ago
public findValueType(valueType: string, valueTypeVersion: number): any {
5 months ago
if (Tools.isNill(valueType)) {
return null;
}
const key = valueType + (Tools.isNill(valueTypeVersion) ? '' : ':' + valueTypeVersion);
return this.valueTypes[key];
10 months ago
}
5 months ago
public findValueTypeByPropertyName(valueTypeString: string, valueTypeVersion: number, propertyName: string) {
10 months ago
const valueType = this.findValueType(valueTypeString, valueTypeVersion);
6 months ago
if (!valueType || !valueType.properties || valueType.properties.length <= 0) {
10 months ago
return null;
}
for (const property of valueType.properties) {
if (property.name === propertyName) {
return this.findValueType(property.valueType, property.valueTypeVersion);
}
}
6 months ago
return null;
10 months ago
}
5 months ago
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;
}
10 months ago
public getParameterOptions(): any {
const options: any[] = [];
6 months ago
Object.values(this.parameters).forEach((parameter: any) => {
const option = this.getOptionItem(parameter);
if (option) {
options.push(option);
7 months ago
}
6 months ago
});
10 months ago
return options;
}
6 months ago
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 };
10 months ago
}
}
6 months ago
return null;
10 months ago
}
public autoCompletionParameters(to: any, matchedText?: any): any {
10 months ago
return {
from: to,
options: this.getParameterOptions(),
validFor: /(.*)?/,
};
}
public autoCompletionProperties(to: any, matchedText?: any): any {
10 months ago
const matchedTextReverse = Tools.reverseString(matchedText);
const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{[$#])+/g; //匹配 '.]n[}xxx{$#' 模式
5 months ago
// -- -- --- -- -- --- ----
// . ] n [ } xxx {$#
const matcheds: any = matchedTextReverse.match(regReverse);
10 months ago
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');
5 months ago
// ---- --- -- -- --- --
// $ { xxx } [ n ]
10 months ago
if (Tools.isUndefinedOrNull(parameterName)) {
parameterName = matched.replace(/\$\{(.+?)\}(\[(.+?)\])?/g, '$1');
if (Tools.isUndefinedOrNull(parameterName)) {
return null;
}
10 months ago
}
*/
10 months ago
const options = this.getOptions(parameterName);
if (Tools.isUndefinedOrNull(options)) {
return null;
}
return {
from: to,
options: options,
validFor: /^(.*)?$/,
};
}
public doAutoCompletion(context: any): any {
10 months ago
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) => {
6 months ago
this.setParameters(response.data?.parameters);
this.setValueTypes(response.data?.valueTypes);
});
}
public autoCompletion(): any {
5 months ago
return (context: any) => {
return this.doAutoCompletion(context);
};
}
10 months ago
}
export { AutoCompletionManager };