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

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 };