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.
288 lines
8.2 KiB
288 lines
8.2 KiB
import { axios, Tools } from 'platform-core';
|
|
|
|
class ParameterMapping {
|
|
/**
|
|
* 显示顺序映射
|
|
*/
|
|
static #Boost = {
|
|
//指标类型
|
|
INTERFACE: 100, //接口
|
|
INDICATOR: 100 - 1, //指标
|
|
|
|
// 参数类型
|
|
CONSTANT: 100, //常量
|
|
IN: 100 - 1, //输入
|
|
IN_OPTION: 100 - 1, //输入(选项)
|
|
IN_SUB_OUT: 100 - 1, //输入(子模型输出)
|
|
INTERMEDIATE: 100 - 2, //中间值
|
|
OUT: 100 - 2, //输出
|
|
|
|
// 元数据类型
|
|
ENUM: 0, //枚举
|
|
UD_JAVA_CLASS: 200 - 1, //自定义Java类
|
|
};
|
|
|
|
/**
|
|
* 获取变量替换符前缀
|
|
* @param type 类型
|
|
* @returns 变量替换符前缀
|
|
*/
|
|
public static getPlaceholderPrefix(type: string) {
|
|
if (type === 'ENUM') {
|
|
return '#';
|
|
} else {
|
|
return '$';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取自动完成项的优先级, 数值越大越优先
|
|
* @param type 类型
|
|
* @returns 自动完成项的优先级
|
|
*/
|
|
public static getBoost(type: string) {
|
|
return ParameterMapping.#Boost[type];
|
|
}
|
|
|
|
/**
|
|
* 获取自动完成项的类型
|
|
* @param type 类型
|
|
* @returns 自动完成项的类型
|
|
*/
|
|
public static getAutoCompletionType(type: string) {
|
|
if (type === 'ENUM') {
|
|
return 'enum';
|
|
} else if (type === 'CONSTANT') {
|
|
return 'constant';
|
|
} else if (type === 'INDICATOR' || type === 'INTERMEDIATE' || type === 'OUT') {
|
|
return 'variable';
|
|
} else {
|
|
return 'interface';
|
|
}
|
|
}
|
|
}
|
|
|
|
class AutoCompletionManager {
|
|
parameters: any;
|
|
valueTypes: any;
|
|
|
|
constructor() {
|
|
this.parameters = {};
|
|
this.valueTypes = {};
|
|
}
|
|
|
|
public getParameters() {
|
|
return this.parameters;
|
|
}
|
|
|
|
public setParameters(parameters: any) {
|
|
this.parameters = parameters;
|
|
}
|
|
|
|
public getValueTypes() {
|
|
return this.valueTypes;
|
|
}
|
|
|
|
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 cache = {};
|
|
const options: any[] = [];
|
|
Object.values(this.parameters).forEach((parameter: any) => {
|
|
const option = this.getOptionItem(parameter);
|
|
if (option) {
|
|
if (!cache[option.label]) {
|
|
cache[option.label] = option;
|
|
options.push(option);
|
|
}
|
|
}
|
|
});
|
|
for (const option of options) {
|
|
option.boost = ParameterMapping.getBoost(option.category);
|
|
}
|
|
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;
|
|
return {
|
|
category: parameter.type,
|
|
type: ParameterMapping.getAutoCompletionType(parameter.type),
|
|
label: parameter.name,
|
|
apply: ParameterMapping.getPlaceholderPrefix(parameter.type) + '{' + parameter.name + '}' + (parameter.valueTypeIsList ? '[0]' : ''),
|
|
info: info,
|
|
};
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public autoCompletionParameters(to: any, matchedText?: any): any {
|
|
return {
|
|
from: to,
|
|
options: this.getParameterOptions(),
|
|
validFor: /(.*)?/,
|
|
};
|
|
}
|
|
|
|
public autoCompletionProperties(to: any, matchedText?: any, subText?: string): 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 options = this.getOptions(parameterName);
|
|
if (Tools.isUndefinedOrNull(options)) {
|
|
return null;
|
|
}
|
|
let filteredOptions: any[] = [];
|
|
if (!Tools.isUndefinedOrNull(subText)) {
|
|
options.forEach((item: any) => {
|
|
if (item.label.indexOf(subText) > -1) {
|
|
filteredOptions.push(item);
|
|
}
|
|
});
|
|
} else {
|
|
filteredOptions = options;
|
|
}
|
|
return {
|
|
from: to,
|
|
options: filteredOptions,
|
|
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.autoCompletionParameters(beforeMatched.to);
|
|
} else if (beforeText.endsWith('.')) {
|
|
//匹配所有属性
|
|
return this.autoCompletionProperties(beforeMatched.to, beforeText);
|
|
} else {
|
|
//匹配部分属性
|
|
const lastIndexOf = beforeText.lastIndexOf('.');
|
|
const matchedText = beforeText.substring(0, lastIndexOf + 1);
|
|
const subText = beforeText.substring(lastIndexOf + 1);
|
|
if (lastIndexOf > -1) {
|
|
return this.autoCompletionProperties(beforeMatched.to - subText.length, matchedText, subText);
|
|
}
|
|
}
|
|
}
|
|
|
|
public load(url: string) {
|
|
axios.get(url).then((response: any) => {
|
|
this.setParameters(response.data?.parameters);
|
|
this.setValueTypes(response.data?.valueTypes);
|
|
});
|
|
}
|
|
|
|
public autoCompletion(): any {
|
|
return (context: any) => {
|
|
return this.doAutoCompletion(context);
|
|
};
|
|
}
|
|
}
|
|
|
|
export { AutoCompletionManager };
|
|
|