Browse Source

1. 更新前端 8.2.28

2. 规则引擎支持枚举类型
main
wangshaoping 2 months ago
parent
commit
659cf413f9
  1. 1
      erm.frontend/.eslintrc.cjs
  2. 2
      erm.frontend/package.json
  3. 2
      gradle.properties
  4. 1
      io.sc.engine.mv.frontend/.eslintrc.cjs
  5. 2
      io.sc.engine.mv.frontend/package.json
  6. 56
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/DictionaryGenerator.java
  7. 10
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/EnumDictionaryItemValueType.java
  8. 8
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/dictionary/Dictionary.java
  9. 54
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/dictionary/EnumItem.java
  10. 2
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/GroovyExpressionReplacer.java
  11. 174
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/PlaceHolderEnumExpressionUtil.java
  12. 10
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/dictionary_render.tpl
  13. 6
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/impl/lib.tpl
  14. 10
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/impl/resource.tpl
  15. 7
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums.properties
  16. 7
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_tw_CN.properties
  17. 7
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_zh_CN.properties
  18. 1
      io.sc.engine.rule.frontend/.eslintrc.cjs
  19. 2
      io.sc.engine.rule.frontend/package.json
  20. 1
      io.sc.engine.rule.frontend/src/i18n/messages.json
  21. 1
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  22. 1
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  23. 15
      io.sc.engine.rule.frontend/src/utils/PlaceHolder.ts
  24. 41
      io.sc.engine.rule.frontend/src/views/dictionary/dictionary.vue
  25. 43
      io.sc.engine.rule.frontend/src/views/resources/designer/DecisionTreeDialog.vue
  26. 63
      io.sc.engine.rule.frontend/src/views/resources/designer/ExecutionFlowDialog.vue
  27. 48
      io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue
  28. 44
      io.sc.engine.rule.frontend/src/views/shared/AutoCompletionManager.ts
  29. 6
      io.sc.engine.rule.frontend/src/views/shared/Processor.ts
  30. 16
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/controller/ParameterAndValueTypeWebController.java
  31. 63
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/impl/AutoCompletionServiceImpl.java
  32. 141
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/impl/ParameterAndValueTypeServiceImpl.java
  33. 9
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/support/Parameter.java
  34. 25
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/support/ParameterAndValueType.java
  35. 9
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/support/Property.java
  36. 48
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/converter/DictionaryEntityConverter.java
  37. 10
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/converter/EnumItemConverter.java
  38. 1
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/EnumDictionaryEntity.java
  39. 96
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/EnumItemEntity.java
  40. 4
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/repository/DictionaryRepository.java
  41. 26
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/impl/DictionaryServiceImpl.java
  42. 30
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/impl/EnumItemServiceImpl.java
  43. 65
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/vo/EnumItemVo.java
  44. 31
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterServiceImpl.java
  45. 6180
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎示例(元数据).json
  46. 1753
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎示例.json
  47. 5
      io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule Engine Database Schema DDL.xml
  48. 1
      io.sc.engine.st.frontend/.eslintrc.cjs
  49. 2
      io.sc.engine.st.frontend/package.json
  50. 2
      io.sc.platform.core.frontend/package.json
  51. 22
      io.sc.platform.core.frontend/src/platform/components/code-mirror/WCodeMirror.vue
  52. 60
      io.sc.platform.core.frontend/src/platform/components/code-mirror/w-code-mirror/PlaceholderPlugin.ts
  53. 14
      io.sc.platform.core.frontend/src/platform/components/graph/WGraph.vue
  54. 23
      io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformSelectedCellHandler.ts
  55. 48
      io.sc.platform.core.frontend/src/views/testcase/code-mirror/AutoCompletionManager.ts
  56. 7
      io.sc.platform.core.frontend/src/views/testcase/code-mirror/code-mirror.vue
  57. 226
      io.sc.platform.core.frontend/src/views/testcase/maxgraph/AutoCompletionManager.ts
  58. 18
      io.sc.platform.core.frontend/src/views/testcase/maxgraph/PlaceHolder.ts
  59. 23
      io.sc.platform.core.frontend/src/views/testcase/maxgraph/UserDefinedFunctionsManager.ts
  60. 136
      io.sc.platform.core.frontend/src/views/testcase/maxgraph/maxgraph.vue
  61. 1
      io.sc.platform.core.frontend/template-project/.eslintrc.cjs
  62. 4
      io.sc.platform.core.frontend/template-project/package.json
  63. 48
      io.sc.platform.core.frontend/template-project/src/views/testcase/code-mirror/AutoCompletionManager.ts
  64. 7
      io.sc.platform.core.frontend/template-project/src/views/testcase/code-mirror/code-mirror.vue
  65. 226
      io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/AutoCompletionManager.ts
  66. 136
      io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/Maxgraph.vue
  67. 18
      io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/PlaceHolder.ts
  68. 23
      io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/UserDefinedFunctionsManager.ts
  69. 2
      io.sc.platform.developer.doc/package.json
  70. 1
      io.sc.platform.developer.frontend/.eslintrc.cjs
  71. 2
      io.sc.platform.developer.frontend/package.json
  72. 2
      io.sc.platform.gradle/templates/pgp/setup/gradle.properties
  73. 1
      io.sc.platform.lcdp.frontend/.eslintrc.cjs
  74. 2
      io.sc.platform.lcdp.frontend/package.json
  75. 1
      io.sc.platform.license.keygen.frontend/.eslintrc.cjs
  76. 2
      io.sc.platform.license.keygen.frontend/package.json
  77. 1
      io.sc.platform.mvc.frontend/.eslintrc.cjs
  78. 2
      io.sc.platform.mvc.frontend/package.json
  79. 1
      io.sc.platform.scheduler.manager.frontend/.eslintrc.cjs
  80. 2
      io.sc.platform.scheduler.manager.frontend/package.json
  81. 1
      io.sc.platform.system.frontend/.eslintrc.cjs
  82. 2
      io.sc.platform.system.frontend/package.json
  83. 11
      io.sc.platform.util/src/main/java/io/sc/platform/util/PlaceHolderExpressionUtil.java
  84. 1
      io.sc.standard.frontend/.eslintrc.cjs
  85. 2
      io.sc.standard.frontend/package.json
  86. 2
      io.sc.website/package.json

1
erm.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
erm.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

2
gradle.properties

@ -38,7 +38,7 @@ application_version=1.0.0
platform_group=io.sc
platform_version=8.2.5
platform_plugin_version=8.2.5
platform_core_frontend_version=8.2.24
platform_core_frontend_version=8.2.28
###########################################################
# dependencies version

1
io.sc.engine.mv.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.engine.mv.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

56
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/DictionaryGenerator.java

@ -1,7 +1,7 @@
package io.sc.engine.rule.core.code.generator.impl;
import io.sc.engine.rule.core.po.dictionary.Dictionary;
import io.sc.engine.rule.core.po.dictionary.UserDefinedJavaClassField;
import io.sc.engine.rule.core.enums.EnumDictionaryItemValueType;
import io.sc.engine.rule.core.po.dictionary.*;
import io.sc.engine.rule.core.po.model.Parameter;
import io.sc.engine.rule.core.util.GroovyExpressionReplacer;
import io.sc.engine.rule.core.util.IdReplacer;
@ -15,10 +15,29 @@ import java.util.List;
import java.util.Map;
public class DictionaryGenerator {
public String generateFields(List<UserDefinedJavaClassField> fields){
if(!CollectionUtil.hasElements(fields)){ return null; }
public String generateFields(Dictionary dictionary){
if(dictionary instanceof UserDefinedJavaClassDictionary){
return generateUserDefinedJavaClassFields((UserDefinedJavaClassDictionary)dictionary);
}else if(dictionary instanceof EnumDictionary){
return generateEnumFields((EnumDictionary)dictionary);
}
return null;
}
public String generateFieldInits(Dictionary dictionary){
if(dictionary instanceof UserDefinedJavaClassDictionary){
return generateUserDefinedJavaClassFieldInits((UserDefinedJavaClassDictionary)dictionary);
}else if(dictionary instanceof EnumDictionary){
}
return null;
}
private String generateUserDefinedJavaClassFields(UserDefinedJavaClassDictionary userDefinedJavaClassDictionary){
if(userDefinedJavaClassDictionary==null || !CollectionUtil.hasElements(userDefinedJavaClassDictionary.getFields())){ return null; }
StringBuilder sb =new StringBuilder("");
for(UserDefinedJavaClassField field : fields){
for(UserDefinedJavaClassField field : userDefinedJavaClassDictionary.getFields()){
String code =field.getCode();
String name =field.getName();
String valueType =field.getValueType();
@ -52,10 +71,31 @@ public class DictionaryGenerator {
return sb.toString();
}
public String generateInits(List<UserDefinedJavaClassField> fields){
if(!CollectionUtil.hasElements(fields)){ return null; }
public String generateEnumFields(EnumDictionary enumDictionary){
if(enumDictionary==null || !CollectionUtil.hasElements(enumDictionary.getItems())){ return null; }
StringBuilder sb =new StringBuilder("");
for(EnumItem item : enumDictionary.getItems()){
if(EnumDictionaryItemValueType.STRING.equals(item.getValueType())) {
sb.append("public static final String ").append(item.getCode()).append(" =").append("'").append(item.getValue()).append("';");
}else if(EnumDictionaryItemValueType.INTEGER.equals(item.getValueType())){
sb.append("public static final Long ").append(item.getCode()).append(" =").append(item.getValue()).append(";");
}else if(EnumDictionaryItemValueType.DECIMAL.equals(item.getValueType())){
sb.append("public static final BigDecimal ").append(item.getCode()).append(" =").append(item.getValue()).append(";");
}
sb.append(" //").append(item.getName()).append("\n");
}
if(sb.length()>0){
sb.setLength(sb.length()-1);
}
return sb.toString();
}
public String generateUserDefinedJavaClassFieldInits(UserDefinedJavaClassDictionary userDefinedJavaClassDictionary){
if(userDefinedJavaClassDictionary==null || !CollectionUtil.hasElements(userDefinedJavaClassDictionary.getFields())){ return null; }
StringBuilder sb =new StringBuilder("");
for(UserDefinedJavaClassField field : fields){
for(UserDefinedJavaClassField field : userDefinedJavaClassDictionary.getFields()){
String code =field.getCode();
String name =field.getName();
String valueCalculation =field.getValueCalculation();

10
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/EnumDictionaryItemValueType.java

@ -0,0 +1,10 @@
package io.sc.engine.rule.core.enums;
/**
* 枚举元数据项值类型枚举
*/
public enum EnumDictionaryItemValueType {
STRING, //字符串
INTEGER, //整数
DECIMAL; //小数
}

8
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/dictionary/Dictionary.java

@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.sc.engine.rule.core.enums.DeployStatus;
import io.sc.engine.rule.core.enums.DictionaryType;
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",defaultImpl=FolderDictionary.class)
@ -18,6 +19,7 @@ import io.sc.engine.rule.core.enums.DeployStatus;
})
public abstract class Dictionary {
protected String id; //Id
protected DictionaryType type; //类型
protected String code; //代码
protected String name; //名称
protected String namec; //名称(字母)
@ -37,6 +39,12 @@ public abstract class Dictionary {
public void setId(String id) {
this.id = id;
}
public DictionaryType getType() {
return type;
}
public void setType(DictionaryType type) {
this.type = type;
}
public String getCode() {
return code;
}

54
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/dictionary/EnumItem.java

@ -1,52 +1,72 @@
package io.sc.engine.rule.core.po.dictionary;
import io.sc.engine.rule.core.enums.EnumDictionaryItemValueType;
/**
* 枚举项
* @author wangshaoping
*
*/
public class EnumItem {
protected String id; //ID
protected String code; //代码
protected String name; //名称
protected EnumDictionaryItemValueType valueType;//值类型
protected String value; //值
protected String title; //标题
protected String description; //描述
protected Integer order; //排序
protected String config; //配置
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EnumDictionaryItemValueType getValueType() {
return valueType;
}
public void setValueType(EnumDictionaryItemValueType valueType) {
this.valueType = valueType;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
public String getConfig() {
return config;
}
public void setConfig(String config) {
this.config = config;
}
}

2
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/GroovyExpressionReplacer.java

@ -58,6 +58,7 @@ public class GroovyExpressionReplacer {
}
// 再处理 xxx
content =PlaceHolderExpressionUtil.replace(content,"${arg.","}");
content =PlaceHolderEnumExpressionUtil.replace(content,"","");
// 最后处理 `xxx`, 替换回正确的值
for(String key : sortedCache.keySet()){
@ -65,6 +66,7 @@ public class GroovyExpressionReplacer {
}
return "\"\"\"" + content + "\"\"\"";
}else{
content =PlaceHolderEnumExpressionUtil.replace(content,"","");
return PlaceHolderExpressionUtil.replace(content,"arg.","");
}
}

174
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/PlaceHolderEnumExpressionUtil.java

@ -0,0 +1,174 @@
package io.sc.engine.rule.core.util;
import io.sc.platform.util.CollectionUtil;
import io.sc.platform.util.support.PlaceholderExpression;
import io.sc.platform.util.support.PlaceholderExpressionPart;
import io.sc.platform.util.support.StringLengthDescComparator;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 占位符表达式工具类
*/
public class PlaceHolderEnumExpressionUtil {
// 占位符表达式的模式匹配
// 可匹配以下模式
// 1. #{aaa}
// 2. #{bbb}[1]
// 3. #{ccc}[1].#{ddd}
// 4. #{eee}[1].#{fff}[2]
// 5. #{ggg}[1].#{hhh}[2].#{iii}
private static final String PH_EXPRESSION_REG_PATTERN_STR = "(# \\{ (.+?) \\})(\\[ (.+?) \\])?((\\[ (.+?) \\])?(\\.? (# \\{ (.+?) \\})(\\[ (.+?) \\])?)+?)*";
// --- --- ----- --- --- ----- --- --- ----- --- --- --- --- ----- --- --- ----- ---
// (# { xxx } )([ nnn ] )?(([ nnn ] )?(.? (# { xxx } )([ nnn ] )?)+?)*
// (#{xxx} )([nnn] )?(([nnn] )?(.? (#{xxx} )([nnn ] )?)+?)*
// (#{xxx})([nnn])?(([nnn])?(.?(#{xxx})([nnn])?)+?)*
// -------- ------- ? ------- - ------ -------
// (变量)([下标])?(([下标])?(.?(变量)([下标])?)+?)*
private static final Pattern PH_EXPRESSION_REG_PATTERN =Pattern.compile(StringUtils.trimAllWhitespace(PH_EXPRESSION_REG_PATTERN_STR));
private static final String PH_EXPRESSION_PART_REG_PATTERN_STR = "(# \\{ (.+?) \\})(\\[ (.+?) \\])?";
// --- --- ----- --- --- ----- --- --- ----- --- --- --- --- ----- --- --- ----- ---
// (# { xxx } )([ nnn ] )?
// (#{xxx})([nnn])?
private static final Pattern PH_EXPRESSION_PART_REG_PATTERN =Pattern.compile(StringUtils.trimAllWhitespace(PH_EXPRESSION_PART_REG_PATTERN_STR));
private static final Pattern PH_VARIABLE_REG_PATTERN =Pattern.compile("#\\{(.+?)\\}");
private static final Pattern PH_VARIABLE_ARRAY_INDEX_REG_PATTERN =Pattern.compile("\\[(.+?)\\]");
/**
* 将占位符表达式替换为非占位符表达式,示例:
* PlaceHolderExpressionUtil.replace("(#{aaa} + #{bbb}[1] - #{ccc}['some.key'].#{xxx}) / (#{ddd}[1].#{eee}[2] + #{fff}[1].#{ggg}[2].#{hhh})","","");
* 替换结果为: (aaa + bbb[1] - ccc['some.key'].xxx) / (ddd[1].eee[2] + fff[1].ggg[2].hhh)
* PlaceHolderExpressionUtil.replace("(#{aaa} + #{bbb}[1] - #{ccc}['some.key'].#{xxx}) / (#{ddd}[1].#{eee}[2] + #{fff}[1].#{ggg}[2].#{hhh})","arg.");
* 替换结果为: (arg.aaa + arg.bbb[1] - arg.ccc['some.key'].xxx) / (arg.ddd[1].eee[2] + arg.fff[1].ggg[2].hhh)
* PlaceHolderExpressionUtil.replace("(#{aaa} + #{bbb}[1] - #{ccc}['some.key'].#{xxx}) / (#{ddd}[1].#{eee}[2] + #{fff}[1].#{ggg}[2].#{hhh})","#{arg.","}");
* 替换结果为: (#{arg.aaa} + #{arg.bbb[1]} - #{arg.ccc['some.key'].xxx}) / (#{arg.ddd[1].eee[2]} + #{arg.fff[1].ggg[2].hhh})
* @param content 字符串
* @param prefix 前缀
* @param suffix 后缀
* @returns 替换后的字符串
*/
public static String replace(String content,String prefix,String suffix) {
if (!StringUtils.hasText(content)) {
return content;
}
List<PlaceholderExpression> expressions =parse(content);
if(!CollectionUtil.hasElements(expressions)){
return content;
}
// 在替换时, 需要先替换长度较长的, 避免替换错误
Map<String,String> sortedCache =new TreeMap<>(new StringLengthDescComparator());
String result =content;
for(PlaceholderExpression expression : expressions){
List<PlaceholderExpressionPart> parts =expression.getParts();
StringBuilder sb =new StringBuilder();
sb.append(prefix);
int size =parts.size();
for(int i=0;i<size;i++){
PlaceholderExpressionPart part =parts.get(i);
if(StringUtils.hasText(part.getArrayIndex())){
sb.append(part.getName()).append("[").append(part.getArrayIndex()).append("]");
}else{
sb.append(part.getName());
}
if(i<size-1){
sb.append(".");
}
}
sb.append(suffix);
sortedCache.put(expression.getExpression(),sb.toString());
}
for(String key : sortedCache.keySet()){
result =result.replace(key,sortedCache.get(key));
}
return result;
}
/**
* 解析占位符表达式
* PlaceHolderExpressionUtil.parse("(#{aaa} + #{bbb}[1] - #{ccc}['some.key'].#{xxx}) / (#{ddd}[1].#{eee}[2] + #{fff}[1].#{ggg}[2].#{hhh})","","");
* 解析结果如下:
* [{
* "expression" : "#{aaa}",
* "parts" : [ { "name" : "aaa", "arrayIndex" : null } ]
* }, {
* "expression" : "#{bbb}[1]",
* "parts" : [ { "name" : "bbb", "arrayIndex" : "1" } ]
* }, {
* "expression" : "#{ccc}['some.key'].#{xxx}",
* "parts" : [
* { "name" : "ccc", "arrayIndex" : "'some.key'" },
* { "name" : "xxx", "arrayIndex" : null }
* ]
* }, {
* "expression" : "#{ddd}[1].#{eee}[2]",
* "parts" : [
* { "name" : "ddd", "arrayIndex" : "1" },
* { "name" : "eee", "arrayIndex" : "2" }
* ]
* }, {
* "expression" : "#{fff}[1].#{ggg}[2].#{hhh}",
* "parts" : [
* { "name" : "fff", "arrayIndex" : "1" },
* { "name" : "ggg", "arrayIndex" : "2" },
* { "name" : "hhh", "arrayIndex" : null }
* ]
* }]
* @param content 表达式字符串内容
* @return 解析后的占位符表达式列表
*/
public static List<PlaceholderExpression> parse(String content) {
Set<PlaceholderExpression> expressions =new TreeSet<>(new Comparator<PlaceholderExpression>() {
@Override
public int compare(PlaceholderExpression o1, PlaceholderExpression o2) {
return o2.getExpression().compareTo(o1.getExpression());
}
});
Matcher matcher =PH_EXPRESSION_REG_PATTERN.matcher(content);
while(matcher.find()){
String group =matcher.group();
PlaceholderExpression expression =parseExpression(group);
if(!expression.isEmpty()) {
expressions.add(expression);
}
}
return CollectionUtil.set2List(expressions);
}
/**
* PlaceHolderExpressionUtil.parseExpression("#{fff}[1].#{ggg}[2].#{hhh})");
* 解析结果如下:
* {
* "expression" : "#{fff}[1].#{ggg}[2].#{hhh}",
* "parts" : [
* { "name" : "fff", "arrayIndex" : "1" },
* { "name" : "ggg", "arrayIndex" : "2" },
* { "name" : "hhh", "arrayIndex" : null }
* ]
* }
* 解析占位符表达式
* @param content 表达式
* @return 解析后的表达式对象
*/
public static PlaceholderExpression parseExpression(String content){
PlaceholderExpression expression =new PlaceholderExpression();
expression.setExpression(content);
Matcher matcher =PH_EXPRESSION_PART_REG_PATTERN.matcher(content);
while(matcher.find()){
String group =matcher.group();
Matcher variableMatcher =PH_VARIABLE_REG_PATTERN.matcher(group);
if(variableMatcher.find()){
PlaceholderExpressionPart part =new PlaceholderExpressionPart();
part.setName(variableMatcher.group(1));
Matcher variableArrayIndexMatcher =PH_VARIABLE_ARRAY_INDEX_REG_PATTERN.matcher(group);
if(variableArrayIndexMatcher.find()){
part.setArrayIndex(variableArrayIndexMatcher.group(1));
}
expression.addPart(part);
}
}
return expression;
}
}

10
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/dictionary_render.tpl

@ -2,12 +2,16 @@
/**
* #(dictionary.name)
*/
#if("UD_JAVA_CLASS"==dictionary.type.toString())
@JsonIgnoreProperties(ignoreUnknown=true)
#end
class #(className(dictionary.code,dictionary.version)) {
#(tabs(DictionaryGenerator.generateFields(dictionary.getFields()),1))
#(tabs(DictionaryGenerator.generateFields(dictionary),1))
#if("UD_JAVA_CLASS"==dictionary.type.toString())
public void init(){
#(tabs(DictionaryGenerator.generateInits(dictionary.getFields()),2))
#(tabs(DictionaryGenerator.generateFieldInits(dictionary),2))
}
#end
}
#end

6
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/impl/lib.tpl

@ -4,11 +4,11 @@
#######################################
### 模版函数
#######################################
#include("/io/sc/engine/rule/core/code/template/package_render.tpl")
#include("/io/sc/engine/rule/core/code/template/import_render.tpl")
#include("/io/sc/engine/rule/core/code/template/functions_render.tpl")
#include("/io/sc/engine/rule/core/code/template/dictionary_render.tpl")
#include("/io/sc/engine/rule/core/code/template/functions_render.tpl")
#include("/io/sc/engine/rule/core/code/template/import_render.tpl")
#include("/io/sc/engine/rule/core/code/template/lib_render.tpl")
#include("/io/sc/engine/rule/core/code/template/package_render.tpl")
#@renderPackage(packageName)

10
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/impl/resource.tpl

@ -6,14 +6,14 @@
#######################################
### 模版函数
#######################################
#include("/io/sc/engine/rule/core/code/template/package_render.tpl")
#include("/io/sc/engine/rule/core/code/template/import_render.tpl")
#include("/io/sc/engine/rule/core/code/template/functions_render.tpl")
#include("/io/sc/engine/rule/core/code/template/parameter_render.tpl")
#include("/io/sc/engine/rule/core/code/template/model_render.tpl")
#include("/io/sc/engine/rule/core/code/template/argument_render.tpl")
#include("/io/sc/engine/rule/core/code/template/dictionary_render.tpl")
#include("/io/sc/engine/rule/core/code/template/functions_render.tpl")
#include("/io/sc/engine/rule/core/code/template/import_render.tpl")
#include("/io/sc/engine/rule/core/code/template/lib_render.tpl")
#include("/io/sc/engine/rule/core/code/template/model_render.tpl")
#include("/io/sc/engine/rule/core/code/template/package_render.tpl")
#include("/io/sc/engine/rule/core/code/template/parameter_render.tpl")
#@renderPackage(packageName)

7
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums.properties

@ -99,6 +99,13 @@ io.sc.engine.rule.core.enums.DictionaryType.JAVA_CLASS=Java Class
io.sc.engine.rule.core.enums.DictionaryType.UD_JAVA_CLASS=Structure
io.sc.engine.rule.core.enums.DictionaryType.ENUM=Enumerate
#================================================
# \u679A\u4E3E\u5143\u6570\u636E\u9879\u503C\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.STRING=String
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.INTEGER=Integer
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.DECIMAL=Decimal
#================================================
# \u5E93\u7C7B\u578B\u679A\u4E3E
#================================================

7
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_tw_CN.properties

@ -99,6 +99,13 @@ io.sc.engine.rule.core.enums.DictionaryType.JAVA_CLASS=Java \u985E
io.sc.engine.rule.core.enums.DictionaryType.UD_JAVA_CLASS=\u7D50\u69CB\u9AD4
io.sc.engine.rule.core.enums.DictionaryType.ENUM=\u679A\u8209
#================================================
# \u679A\u4E3E\u5143\u6570\u636E\u9879\u503C\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.STRING=\u5B57\u7B26\u4E32
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.INTEGER=\u6574\u6578
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.DECIMAL=\u5C0F\u6578
#================================================
# \u5E93\u7C7B\u578B\u679A\u4E3E
#================================================

7
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_zh_CN.properties

@ -99,6 +99,13 @@ io.sc.engine.rule.core.enums.DictionaryType.JAVA_CLASS=Java \u7C7B
io.sc.engine.rule.core.enums.DictionaryType.UD_JAVA_CLASS=\u7ED3\u6784\u4F53
io.sc.engine.rule.core.enums.DictionaryType.ENUM=\u679A\u4E3E
#================================================
# \u679A\u4E3E\u5143\u6570\u636E\u9879\u503C\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.STRING=\u5B57\u7B26\u4E32
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.INTEGER=\u6574\u6570
io.sc.engine.rule.core.enums.EnumDictionaryItemValueType.DECIMAL=\u5C0F\u6570
#================================================
# \u5E93\u7C7B\u578B\u679A\u4E3E
#================================================

1
io.sc.engine.rule.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.engine.rule.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

1
io.sc.engine.rule.frontend/src/i18n/messages.json

@ -76,6 +76,7 @@
"re.parameter.grid.entity.libVersion": "Library Version",
"re.parameter.grid.entity.indicatorCode": "Indicator",
"re.parameter.tip.indicatorParameterCanNotEditable": "Indicator parameter can NOT editable!",
"re.parameter.tip.subModelParameterCanNotEditable": "Sub model parameter can NOT editable!",
"re.parameter.dialog.moveParameter.title": "Select Target Location of Parameter",

1
io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json

@ -76,6 +76,7 @@
"re.parameter.grid.entity.libVersion": "指標庫版本",
"re.parameter.grid.entity.indicatorCode": "指標",
"re.parameter.tip.indicatorParameterCanNotEditable": "類型為指標的參數不能進行編輯!",
"re.parameter.tip.subModelParameterCanNotEditable": "子模型參數不能進行編輯!",
"re.parameter.dialog.moveParameter.title": "選擇參數移動的目標位置",

1
io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json

@ -76,6 +76,7 @@
"re.parameter.grid.entity.libVersion": "指标库版本",
"re.parameter.grid.entity.indicatorCode": "指标",
"re.parameter.tip.indicatorParameterCanNotEditable": "类型为指标的参数不能进行编辑!",
"re.parameter.tip.subModelParameterCanNotEditable": "子模型参数不能进行编辑!",
"re.parameter.dialog.moveParameter.title": "选择参数移动的目标位置",

15
io.sc.engine.rule.frontend/src/utils/PlaceHolder.ts

@ -1,18 +1,15 @@
import { Tools } from 'platform-core';
class PlaceHolder {
static #prefix: string = '<span class="p-0.5"><span class="p-0.5 border border-gray-800 rounded-md">';
static #parameterPrefix: string = '<span class="p-0.5"><span class="p-0.5 border border-gray-800 rounded-md">';
static #enumPrefix: string = '<span class="p-0.5"><span class="p-0.5 border border-orange-400 rounded-md">';
static #suffix: string = '</span></span>';
public static replace(str: string, prefix?: string, suffix?: string) {
public static replace(str: string) {
if (Tools.isString(str)) {
str = str.replace('<', '&lt;');
if (Tools.isUndefinedOrNull(prefix)) {
prefix = PlaceHolder.#prefix;
}
if (Tools.isUndefinedOrNull(suffix)) {
suffix = PlaceHolder.#suffix;
}
return str.replace(/\$\{(.+?)\}/g, prefix + '$1' + suffix);
str = str.replace(/#\{(.+?)\}/g, PlaceHolder.#enumPrefix + '$1' + PlaceHolder.#suffix);
str = str.replace(/\$\{(.+?)\}/g, PlaceHolder.#parameterPrefix + '$1' + PlaceHolder.#suffix);
}
return str;
}

41
io.sc.engine.rule.frontend/src/views/dictionary/dictionary.vue

@ -457,6 +457,7 @@
<w-grid
ref="enumGridRef"
:title="$t('re.dictionary.enum.grid.title')"
dnd-mode="server"
dense-body
hide-bottom
:config-button="true"
@ -472,8 +473,14 @@
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view']"
:columns="[
{ width: 150, name: 'name', label: $t('name') },
{ width: 100, name: 'value', label: $t('value') },
{ width: 250, name: 'title', label: $t('title') },
{
width: 80,
name: 'valueType',
label: $t('valueType'),
format: Formater.enum(ValueTypeEnums),
},
{ width: '100%', name: 'description', label: $t('description') },
]"
:editor="{
@ -484,15 +491,17 @@
colsNum: 1,
fields: [
{ name: 'dictionary', label: $t('dictionary'), type: 'w-text', showIf: false, defaultValue: currentSelectedDictionaryIdRef },
{ name: 'value', label: $t('value'), type: 'w-text', requiredIf: true },
{ name: 'name', label: $t('name'), type: 'w-text', requiredIf: true },
{
name: 'title',
label: $t('title'),
type: 'w-text',
name: 'valueType',
label: $t('valueType'),
type: 'w-select',
options: Options.enum(ValueTypeEnums),
defaultValue: 'STRING',
requiredIf: true,
},
{ name: 'value', label: $t('value'), type: 'w-text', requiredIf: true },
{ name: 'description', label: $t('description'), type: 'w-text' },
{ name: 'order', label: $t('order'), type: 'w-number' },
],
},
}"
@ -519,7 +528,20 @@
<script setup lang="ts">
import 'tailwindcss/utilities.css';
import { ref, reactive } from 'vue';
import { i18n, eventBus, $t, axios, Environment, Formater, Tools, EnumTools, DialogManager, Downloader, CorporationAuditorEntityManager } from 'platform-core';
import {
i18n,
eventBus,
$t,
axios,
Environment,
Formater,
Tools,
EnumTools,
DialogManager,
Downloader,
CorporationAuditorEntityManager,
Options,
} from 'platform-core';
import UserDefinedJavaClassDictionaryJsonDialog from './UserDefinedJavaClassDictionaryJsonDialog.vue';
import ImportDialog from './ImportDialog.vue';
import ImportSampleDialog from './ImportSampleDialog.vue';
@ -544,12 +566,17 @@ const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
const templateImportAndExportDialogRef = ref();
const templateImportAndExportManager = new TemplateImportAndExportManager(templateImportAndExportDialogRef);
const valueTypeOptions = [
{ label: $t('java.lang.String'), value: 'java.lang.String' },
{ label: $t('java.lang.Long'), value: 'java.lang.Long' },
];
const divStatus = reactive({
isShowFieldGrid: false,
isShowEnumGrid: false,
});
const ValueTypeEnums = await EnumTools.fetch('io.sc.engine.rule.core.enums.EnumDictionaryItemValueType');
await EngineEnums.init();
await valueTypeManager.init();
</script>

43
io.sc.engine.rule.frontend/src/views/resources/designer/DecisionTreeDialog.vue

@ -5,7 +5,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { $t, axios, Environment, NotifyManager, Formater, EnumTools } from 'platform-core';
import { $t, axios, Environment, NotifyManager } from 'platform-core';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
import { PlaceHolder } from '@/utils/PlaceHolder';
@ -24,10 +24,10 @@ const edgeDefines = [
type: 'EdgeConditionBranch',
fromVertexType: 'Condition',
toVertexType: null,
getLabel: (value) => {
getLabel: (value: any) => {
return value.value || '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
valueType: dom.getAttribute('valueType') || '',
@ -68,7 +68,6 @@ const edgeDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -93,10 +92,10 @@ const vertexDefines = [
shape: 'ellipse',
size: [50, 50],
},
getLabel: (value) => {
getLabel: (value: any) => {
return value.label;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
label: dom.getAttribute('label') || '',
@ -128,10 +127,10 @@ const vertexDefines = [
shape: 'rhombus',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
return value.condition ? PlaceHolder.replace(value.condition) : '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
condition: dom.getAttribute('condition') || '',
@ -153,7 +152,6 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: false,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -173,14 +171,14 @@ const vertexDefines = [
shape: 'rectangle',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
let html = '';
html += '<div style="text-align:center;">' + PlaceHolder.replace(value.expression || '') + '</div>';
html += '<hr size="0.5"/>';
html += '<div style="text-align:left;">' + PlaceHolder.replace(value.commands || '') + '</div>';
return html;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
expression: dom.getAttribute('expression') || '',
@ -205,7 +203,6 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -227,14 +224,14 @@ const vertexDefines = [
shape: 'ellipse',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
return resourceAbstract.name + '(V' + resourceAbstract.version + ')';
}
return '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
const code = dom.getAttribute('code');
const version = dom.getAttribute('version');
@ -254,7 +251,7 @@ const vertexDefines = [
};
}
},
setValue: (dom, value) => {
setValue: (dom: any, value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
dom.setAttribute('code', resourceAbstract.code);
@ -270,7 +267,7 @@ const vertexDefines = [
name: 'resourceAbstractId',
label: $t('re.graph.vertex.resourceAbstract.entity.resourceAbstractId'),
type: 'w-grid-select',
displayValue: (args) => {
displayValue: (args: any) => {
return args.data.name + '(V' + args.data.version + ')';
},
grid: {
@ -280,7 +277,7 @@ const vertexDefines = [
configButton: true,
checkboxSelection: false,
tree: true,
treeIcon: (row) => {
treeIcon: (row: any) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
@ -302,7 +299,7 @@ const vertexDefines = [
width: 80,
name: 'type',
label: $t('type'),
format: (value, row) => {
format: (value: any, row: any) => {
if (value !== 'FOLDER') {
return EngineEnums.ResourceType.formater(value);
}
@ -324,7 +321,7 @@ const vertexDefines = [
},
];
const findResourceAbstractById = (id) => {
const findResourceAbstractById = (id: string) => {
for (const item of resourceAbstractsRef.value) {
if (item.id === id) {
return item;
@ -333,7 +330,7 @@ const findResourceAbstractById = (id) => {
return null;
};
const findResourceAbstractByCodeAndVersion = (code, version) => {
const findResourceAbstractByCodeAndVersion = (code: string, version: number) => {
for (const item of resourceAbstractsRef.value) {
if (item.code === code && item.version.toString() === version) {
return item;
@ -342,8 +339,8 @@ const findResourceAbstractByCodeAndVersion = (code, version) => {
return null;
};
const open = async (parameterId, processorId) => {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByParameterId/' + parameterId));
const open = async (parameterId: string, processorId: string) => {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByParameterId/' + parameterId));
userDefinedFunctionsManager.load();
processorIdRef.value = processorId;
@ -363,7 +360,7 @@ const close = () => {
dialogRef.value.hide();
};
const save = (xml) => {
const save = (xml: string) => {
axios.post(Environment.apiContextPath('api/re/model/parameter/processor/saveDecisionTreeById/' + processorIdRef.value), { xml }).then((response) => {
NotifyManager.info($t('operationSuccess'));
});

63
io.sc.engine.rule.frontend/src/views/resources/designer/ExecutionFlowDialog.vue

@ -5,7 +5,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { $t, axios, Environment, NotifyManager, Formater, EnumTools } from 'platform-core';
import { $t, axios, Environment, NotifyManager } from 'platform-core';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
import { PlaceHolder } from '@/utils/PlaceHolder';
@ -25,10 +25,10 @@ const edgeDefines = [
type: 'EdgeConditionBranch',
fromVertexType: 'Condition',
toVertexType: null,
getLabel: (value) => {
getLabel: (value: any) => {
return value.value || '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
valueType: dom.getAttribute('valueType') || '',
@ -69,7 +69,6 @@ const edgeDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -94,10 +93,10 @@ const vertexDefines = [
shape: 'ellipse',
size: [50, 50],
},
getLabel: (value) => {
getLabel: (value: any) => {
return value.label;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
label: dom.getAttribute('label') || '',
@ -129,10 +128,10 @@ const vertexDefines = [
shape: 'rhombus',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
return value.condition ? PlaceHolder.replace(value.condition) : '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
condition: dom.getAttribute('condition') || '',
@ -154,7 +153,6 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: false,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -174,12 +172,12 @@ const vertexDefines = [
shape: 'rectangle',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
let html = '';
html += '<div style="text-align:left;">' + value.commands + '</div>';
return html;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
commands: dom.getAttribute('commands') || '',
@ -201,7 +199,6 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -223,14 +220,14 @@ const vertexDefines = [
shape: 'ellipse',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
return resourceAbstract.name + '(V' + resourceAbstract.version + ')';
}
return '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
const code = dom.getAttribute('code');
const version = dom.getAttribute('version');
@ -250,7 +247,7 @@ const vertexDefines = [
};
}
},
setValue: (dom, value) => {
setValue: (dom: any, value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
dom.setAttribute('code', resourceAbstract.code);
@ -266,7 +263,7 @@ const vertexDefines = [
name: 'resourceAbstractId',
label: $t('re.graph.vertex.resourceAbstract.entity.resourceAbstractId'),
type: 'w-grid-select',
displayValue: (args) => {
displayValue: (args: any) => {
return args.data.name + '(V' + args.data.version + ')';
},
grid: {
@ -276,7 +273,7 @@ const vertexDefines = [
configButton: true,
checkboxSelection: false,
tree: true,
treeIcon: (row) => {
treeIcon: (row: any) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
@ -298,7 +295,7 @@ const vertexDefines = [
width: 80,
name: 'type',
label: $t('type'),
format: (value, row) => {
format: (value: any, row: any) => {
if (value !== 'FOLDER') {
return EngineEnums.ResourceType.formater(value);
}
@ -335,7 +332,7 @@ const vertexDefines = [
shape: 'doubleEllipse',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
let html = '<div style="text-align:left;">' + (value?.inputCommands || '') + '</div>';
html += '<hr/>';
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
@ -346,7 +343,7 @@ const vertexDefines = [
html += '<div style="text-align:left;">' + (value?.outputCommands || '') + '</div>';
return html;
},
getValue: (dom) => {
getValue: (dom: any) => {
let result = { resourceAbstractId: '', inputCommands: '', outputCommands: '' };
if (dom) {
const code = dom.getAttribute('code');
@ -360,7 +357,7 @@ const vertexDefines = [
}
return result;
},
setValue: (dom, value) => {
setValue: (dom: any, value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
dom.setAttribute('code', resourceAbstract.code);
@ -378,7 +375,7 @@ const vertexDefines = [
name: 'resourceAbstractId',
label: $t('re.graph.vertex.configurableResourceAbstract.entity.resourceAbstractId'),
type: 'w-grid-select',
displayValue: (args) => {
displayValue: (args: any) => {
return args.data.name + (args.data.version ? '(V' + args.data.version + ')' : '');
},
grid: {
@ -388,7 +385,7 @@ const vertexDefines = [
configButton: true,
checkboxSelection: false,
tree: true,
treeIcon: (row) => {
treeIcon: (row: any) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
@ -410,7 +407,7 @@ const vertexDefines = [
width: 80,
name: 'type',
label: $t('type'),
format: (value, row) => {
format: (value: any, row: any) => {
if (value !== 'FOLDER') {
return EngineEnums.ResourceType.formater(value);
}
@ -436,7 +433,6 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -449,7 +445,6 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
@ -471,7 +466,7 @@ const vertexDefines = [
shape: 'hexagon',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
for (const item of modeAbstractsRef.value) {
if (item.value === value.code) {
return item.label;
@ -479,7 +474,7 @@ const vertexDefines = [
}
return '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
code: dom.getAttribute('code') || '',
@ -503,7 +498,7 @@ const vertexDefines = [
},
];
const findResourceAbstractById = (id) => {
const findResourceAbstractById = (id: string) => {
for (const item of resourceAbstractsRef.value) {
if (item.id === id) {
return item;
@ -512,7 +507,7 @@ const findResourceAbstractById = (id) => {
return null;
};
const findResourceAbstractByCodeAndVersion = (code, version) => {
const findResourceAbstractByCodeAndVersion = (code: string, version: number) => {
for (const item of resourceAbstractsRef.value) {
if (item.code === code && item.version.toString() === version) {
return item;
@ -521,8 +516,8 @@ const findResourceAbstractByCodeAndVersion = (code, version) => {
return null;
};
const open = async (parameterId, processorId) => {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByParameterId/' + parameterId));
const open = async (parameterId: string, processorId: string) => {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByParameterId/' + parameterId));
userDefinedFunctionsManager.load();
processorIdRef.value = processorId;
@ -532,7 +527,7 @@ const open = async (parameterId, processorId) => {
//
const modelResponse = await axios.get(Environment.apiContextPath('/api/re/model/getModeAbstractByParameterProcessor/' + processorId));
const modelOptions = [];
const modelOptions = <any>[];
for (const item of modelResponse?.data || []) {
modelOptions.push({ label: item.name, value: item.code });
}
@ -550,7 +545,7 @@ const close = () => {
dialogRef.value.hide();
};
const save = (xml) => {
const save = (xml: string) => {
axios.post(Environment.apiContextPath('api/re/model/parameter/processor/saveExecutionFlowById/' + processorIdRef.value), { xml }).then((response) => {
NotifyManager.info($t('operationSuccess'));
});

48
io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue

@ -23,7 +23,7 @@
{
extend: 'add',
click: undefined,
enableIf: (args) => {
enableIf: (args: any) => {
return !readOnly;
},
},
@ -32,7 +32,7 @@
name: 'constant',
label: $t('re.parameter.grid.toolbar.add.constant'),
icon: 'bi-tag',
afterClick: (args) => {
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'CONSTANT');
},
},
@ -42,7 +42,7 @@
name: 'in',
label: $t('re.parameter.grid.toolbar.add.in'),
icon: 'bi-terminal',
afterClick: (args) => {
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'IN');
},
},
@ -51,7 +51,7 @@
name: 'inOption',
label: $t('re.parameter.grid.toolbar.add.inOption'),
icon: 'bi-list-check',
afterClick: (args) => {
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'IN_OPTION');
args.grid.getEditorForm().setFieldValue('valueTypeSelect', 'java.lang.String');
},
@ -60,7 +60,7 @@
name: 'indicator',
label: $t('re.parameter.grid.toolbar.add.indicator'),
icon: 'bi-link',
click: (args) => {
click: (args: any) => {
selectIndicatorDialogRef.open();
},
},
@ -70,7 +70,7 @@
name: 'intermediate',
label: $t('re.parameter.grid.toolbar.add.intermediate'),
icon: 'bi-superscript',
afterClick: (args) => {
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'INTERMEDIATE');
},
},
@ -79,7 +79,7 @@
name: 'out',
label: $t('re.parameter.grid.toolbar.add.out'),
icon: 'bi-shuffle',
afterClick: (args) => {
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'OUT');
},
},
@ -97,15 +97,9 @@
[
{
extend: 'clone',
name: 'clone',
enableIf: (args: any) => {
return args.selected;
},
click: undefined,
},
{
extend: 'clone',
enableIf: (args) => {
return !readOnly && args.selected && args.selected.type !== 'INDICATOR';
return !readOnly && args.selected && args.selected.type !== 'INDICATOR' && args.selected.type !== 'IN_SUB_OUT';
},
},
{
@ -113,10 +107,10 @@
name: 'deepClone',
label: $t('deepClone'),
icon: 'bi-copy',
enableIf: (args) => {
return !readOnly && args.selected && args.selected.type !== 'INDICATOR';
enableIf: (args: any) => {
return !readOnly && args.selected && args.selected.type !== 'INDICATOR' && args.selected.type !== 'IN_SUB_OUT';
},
click: (args) => {
click: (args: any) => {
DialogManager.confirm($t('re.parameter.grid.toolbar.deepClone.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/model/parameter/deepClone/' + args.selected.id)).then(() => {
gridRef.refresh();
@ -127,22 +121,24 @@
],
{
extend: 'edit',
enableIf: (args) => {
return !readOnly && args.selected && args.selected.type !== 'INDICATOR';
enableIf: (args: any) => {
return !readOnly && args.selected && args.selected.type !== 'INDICATOR' && args.selected.type !== 'IN_SUB_OUT';
},
click: (args: any) => {
disableTip: (args: any) => {
const row = args.selected;
if (row.type === 'INDICATOR') {
NotifyManager.warn($t('re.parameter.tip.indicatorParameterCanNotEditable'));
return;
} else if (row.type === 'IN_SUB_OUT') {
NotifyManager.warn($t('re.parameter.tip.subModelParameterCanNotEditable'));
return;
}
args._click(args);
},
},
{
extend: 'remove',
enableIf: (args) => {
return !readOnly && args.selected;
enableIf: (args: any) => {
return !readOnly && args.selected && args.selected.type !== 'IN_SUB_OUT';
},
},
'separator',
@ -150,8 +146,8 @@
name: 'move',
label: $t('re.parameter.grid.toolbar.move'),
icon: 'bi-share-fill',
enableIf: (args) => {
return !readOnly && args.selected;
enableIf: (args: any) => {
return !readOnly && args.selected && args.selected.type !== 'IN_SUB_OUT';
},
click: (args) => {
moveParameterDialogRef.open();

44
io.sc.engine.rule.frontend/src/views/shared/AutoCompletionManager.ts

@ -116,10 +116,14 @@ class AutoCompletionManager {
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 };
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;
@ -135,20 +139,44 @@ class AutoCompletionManager {
public autoCompletionProperties(to: any, matchedText?: any): any {
const matchedTextReverse = Tools.reverseString(matchedText);
const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{\$)+/g; //匹配 '.]n[}xxx{$' 模式
const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{[$#])+/g; //匹配 '.]n[}xxx{$#' 模式
// -- -- --- -- -- --- ----
// . ] 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');
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)) {
return null;
parameterName = matched.replace(/\$\{(.+?)\}(\[(.+?)\])?/g, '$1');
if (Tools.isUndefinedOrNull(parameterName)) {
return null;
}
}
*/
const options = this.getOptions(parameterName);
if (Tools.isUndefinedOrNull(options)) {
return null;

6
io.sc.engine.rule.frontend/src/views/shared/Processor.ts

@ -64,9 +64,11 @@ abstract class Processor {
*/
initAutoCompletionManager() {
if (this.targetType === Processor.PARAMETER || this.targetType === Processor.SCORE_CARD) {
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByParameterId/' + this.context.target.id));
//this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByParameterId/' + this.context.target.id));
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByParameterId/' + this.context.target.id));
} else if (this.targetType === Processor.INDICATOR) {
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByIndicatorId/' + this.context.target.id));
//this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByIndicatorId/' + this.context.target.id));
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByIndicatorId/' + this.context.target.id));
}
}

16
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/controller/ParameterAndValueTypeWebController.java

@ -17,15 +17,20 @@ import java.util.Locale;
public class ParameterAndValueTypeWebController {
@Autowired private ParameterAndValueTypeService service;
@GetMapping("findByModeId/{modelId}")
public ParameterAndValueType findByModeId(@PathVariable(name="modelId",required=true)String modelId, Locale locale) throws Exception{
return service.findByModelId(modelId,locale);
}
@GetMapping("findByParameterId/{parameterId}")
public ParameterAndValueType findByParameterId(@PathVariable(name="parameterId",required=true)String parameterId, Locale locale) throws Exception{
//Thread.sleep(3000);
return service.findByParameterId(parameterId,locale);
}
@GetMapping("findByModeId/{modelId}")
public ParameterAndValueType findByModeId(@PathVariable(name="modelId",required=true)String modelId, Locale locale) throws Exception{
return service.findByModelId(modelId,locale);
@GetMapping("findByLibId/{libId}")
public ParameterAndValueType findByLibId(@PathVariable(name="libId",required=true)String libId, Locale locale) throws Exception{
return service.findByLibId(libId,locale);
}
@GetMapping("findByIndicatorId/{indicatorId}")
@ -33,11 +38,6 @@ public class ParameterAndValueTypeWebController {
return service.findByIndicatorId(indicatorId,locale);
}
@GetMapping("findByLibId/{libId}")
public ParameterAndValueType findByLibId(@PathVariable(name="libId",required=true)String libId, Locale locale) throws Exception{
return service.findByLibId(libId,locale);
}
@GetMapping("findByDictionaryId/{dictionaryId}")
public ParameterAndValueType findByDictionaryId(@PathVariable(name="dictionaryId",required=true)String dictionaryId, Locale locale) throws Exception{
return service.findByDictionaryId(dictionaryId,locale);

63
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/impl/AutoCompletionServiceImpl.java

@ -1,16 +1,13 @@
package io.sc.engine.rule.server.common.service.impl;
import io.sc.engine.rule.core.enums.DictionaryType;
import io.sc.engine.rule.core.enums.EnumDictionaryItemValueType;
import io.sc.engine.rule.core.util.IdReplacer;
import io.sc.engine.rule.core.util.ValueTypeUtil;
import io.sc.engine.rule.server.common.service.AutoCompletionService;
import io.sc.engine.rule.server.common.service.DictionaryItemPluginsService;
import io.sc.engine.rule.server.common.service.support.AutoCompletion;
import io.sc.engine.rule.server.common.service.support.Parameter;
import io.sc.engine.rule.server.common.service.support.Property;
import io.sc.engine.rule.server.common.service.support.ValueType;
import io.sc.engine.rule.server.dictionary.entity.DictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.UserDefinedJavaClassDictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.UserDefinedJavaClassFieldEntity;
import io.sc.engine.rule.server.common.service.support.*;
import io.sc.engine.rule.server.dictionary.entity.*;
import io.sc.engine.rule.server.dictionary.service.DictionaryService;
import io.sc.engine.rule.server.lib.entity.IndicatorEntity;
import io.sc.engine.rule.server.lib.entity.IndicatorLibEntity;
@ -56,6 +53,8 @@ public class AutoCompletionServiceImpl implements AutoCompletionService {
return null;
}
AutoCompletion autoCompletion =new AutoCompletion();
buildEnumParameters(autoCompletion);
buildEnumValueTypes(autoCompletion);
buildAutoCompletion(autoCompletion,modelEntity,locale);
return autoCompletion;
}
@ -70,6 +69,8 @@ public class AutoCompletionServiceImpl implements AutoCompletionService {
return null;
}
AutoCompletion autoCompletion =new AutoCompletion();
buildEnumParameters(autoCompletion);
buildEnumValueTypes(autoCompletion);
buildAutoCompletion(autoCompletion,indicatorLibEntity,locale);
return autoCompletion;
}
@ -84,6 +85,8 @@ public class AutoCompletionServiceImpl implements AutoCompletionService {
return null;
}
AutoCompletion autoCompletion =new AutoCompletion();
buildEnumParameters(autoCompletion);
buildEnumValueTypes(autoCompletion);
buildAutoCompletion(autoCompletion,dictionaryEntity,locale);
return autoCompletion;
}
@ -218,6 +221,52 @@ public class AutoCompletionServiceImpl implements AutoCompletionService {
}
}
private void buildEnumParameters(AutoCompletion autoCompletion){
List<EnumDictionaryEntity> enumDictionaryEntities =dictionaryService.getRepository().findAllEnumDictionaryEntities();
if(CollectionUtil.hasElements(enumDictionaryEntities)){
for(EnumDictionaryEntity enumDictionary : enumDictionaryEntities){
Parameter parameter =new Parameter();
parameter.setCode(IdReplacer.className(enumDictionary.getCode(),enumDictionary.getVersion()));
parameter.setName(enumDictionary.getName());
parameter.setType("enum");
parameter.setValueType(enumDictionary.getCode());
parameter.setValueTypeVersion(enumDictionary.getVersion());
parameter.setValueTypeIsList(false);
autoCompletion.addParameter(parameter);
}
}
}
private void buildEnumValueTypes(AutoCompletion autoCompletion){
List<EnumDictionaryEntity> enumDictionaryEntities =dictionaryService.getRepository().findAllEnumDictionaryEntities();
if(CollectionUtil.hasElements(enumDictionaryEntities)){
for(EnumDictionaryEntity enumDictionary : enumDictionaryEntities){
ValueType valueType =new ValueType();
valueType.setCode(enumDictionary.getCode());
valueType.setName(enumDictionary.getName());
valueType.setVersion(enumDictionary.getVersion());
List<EnumItemEntity> items =enumDictionary.getItems();
if(CollectionUtil.hasElements(items)){
for(EnumItemEntity item : items){
Property property =new Property();
property.setCode(item.getCode());
property.setName(item.getName());
property.setType("enum");
if(EnumDictionaryItemValueType.STRING.equals(item.getValueType())){
property.setValueType("java.lang.String");
}else if(EnumDictionaryItemValueType.INTEGER.equals(item.getValueType())){
property.setValueType("java.lang.Long");
}else if(EnumDictionaryItemValueType.DECIMAL.equals(item.getValueType())){
property.setValueType("java.math.BigDecimal");
}
valueType.addProperty(property);
}
}
autoCompletion.addValueType(valueType);
}
}
}
private void buildJavaClassValueTypes(AutoCompletion autoCompletion,String className,String valueTypeCode, String valueTypeName,Integer valueTypeVersion,Locale locale) throws Exception {
Class<?> clazz =Class.forName(className);
buildJavaClassValueTypes(autoCompletion,clazz,valueTypeCode,valueTypeName,valueTypeVersion,locale);

141
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/impl/ParameterAndValueTypeServiceImpl.java

@ -1,16 +1,17 @@
package io.sc.engine.rule.server.common.service.impl;
import io.sc.engine.rule.core.enums.DictionaryType;
import io.sc.engine.rule.core.enums.EnumDictionaryItemValueType;
import io.sc.engine.rule.core.util.IdReplacer;
import io.sc.engine.rule.core.util.ValueTypeUtil;
import io.sc.engine.rule.server.common.plugins.item.DictionaryItem;
import io.sc.engine.rule.server.common.service.DictionaryItemPluginsService;
import io.sc.engine.rule.server.common.service.ParameterAndValueTypeService;
import io.sc.engine.rule.server.common.service.support.Parameter;
import io.sc.engine.rule.server.common.service.support.ParameterAndValueType;
import io.sc.engine.rule.server.common.service.support.Property;
import io.sc.engine.rule.server.common.service.support.ValueType;
import io.sc.engine.rule.server.dictionary.entity.DictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.UserDefinedJavaClassDictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.UserDefinedJavaClassFieldEntity;
import io.sc.engine.rule.server.dictionary.entity.*;
import io.sc.engine.rule.server.dictionary.service.DictionaryService;
import io.sc.engine.rule.server.lib.entity.IndicatorEntity;
import io.sc.engine.rule.server.lib.entity.IndicatorLibEntity;
@ -22,7 +23,6 @@ import io.sc.engine.rule.server.model.entity.parameter.OutParameterEntity;
import io.sc.engine.rule.server.model.service.ModelService;
import io.sc.engine.rule.server.model.service.ParameterProcessorService;
import io.sc.engine.rule.server.model.service.ParameterService;
import io.sc.engine.rule.server.common.plugins.item.DictionaryItem;
import io.sc.platform.util.CollectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
@ -49,79 +49,60 @@ public class ParameterAndValueTypeServiceImpl implements ParameterAndValueTypeSe
@Override
public ParameterAndValueType findByModelId(String modelId, Locale locale) throws Exception {
if(!StringUtils.hasText(modelId)){
return null;
}
if(!StringUtils.hasText(modelId)){ return null; }
ModelEntity modelEntity =modelService.findById(modelId);
if(modelEntity==null){
return null;
}
if(modelEntity==null){ return null; }
ParameterAndValueType parameterAndValueType =new ParameterAndValueType();
buildAutoCompletion(parameterAndValueType,modelEntity,locale);
buildByModel(parameterAndValueType,modelEntity,locale);
return parameterAndValueType;
}
@Override
public ParameterAndValueType findByParameterId(String parameterId, Locale locale) throws Exception {
if(!StringUtils.hasText(parameterId)){
return null;
}
if(!StringUtils.hasText(parameterId)){ return null; }
ParameterEntity parameterEntity =parameterService.findById(parameterId);
if(parameterEntity==null){
return null;
}
if(parameterEntity==null){ return null; }
ModelEntity modelEntity =parameterEntity.getModel();
if(modelEntity==null){
return null;
}
if(modelEntity==null){ return null; }
return findByModelId(modelEntity.getId(),locale);
}
@Override
public ParameterAndValueType findByLibId(String libId, Locale locale) throws Exception {
if(!StringUtils.hasText(libId)){
return null;
}
if(!StringUtils.hasText(libId)){ return null; }
IndicatorLibEntity indicatorLibEntity =libService.getRepository().findIndicatorLibEntityById(libId);
if(indicatorLibEntity==null){
return null;
}
if(indicatorLibEntity==null){ return null; }
ParameterAndValueType parameterAndValueType =new ParameterAndValueType();
buildAutoCompletion(parameterAndValueType,indicatorLibEntity,locale);
buildByLib(parameterAndValueType,indicatorLibEntity,locale);
return parameterAndValueType;
}
@Override
public ParameterAndValueType findByIndicatorId(String indicatorId, Locale locale) throws Exception {
if(!StringUtils.hasText(indicatorId)){
return null;
}
if(!StringUtils.hasText(indicatorId)){ return null; }
IndicatorEntity entity =indicatorService.findById(indicatorId);
if(entity==null){
return null;
}
if(entity==null){ return null; }
IndicatorLibEntity indicatorLibEntity =libService.getRepository().findIndicatorLibEntityById(entity.getLib().getId());
if(indicatorLibEntity==null){
return null;
}
if(indicatorLibEntity==null){ return null; }
return findByLibId(indicatorLibEntity.getId(),locale);
}
@Override
public ParameterAndValueType findByDictionaryId(String dictionaryId, Locale locale) throws Exception {
if(!StringUtils.hasText(dictionaryId)){
return null;
}
if(!StringUtils.hasText(dictionaryId)){ return null; }
UserDefinedJavaClassDictionaryEntity dictionaryEntity =dictionaryService.getRepository().findUserDefinedJavaClassDictionaryEntityById(dictionaryId);
if(dictionaryEntity==null){
return null;
}
if(dictionaryEntity==null){ return null; }
ParameterAndValueType parameterAndValueType =new ParameterAndValueType();
buildAutoCompletion(parameterAndValueType,dictionaryEntity,locale);
buildByUserDefinedJavaClassDictionary(parameterAndValueType,dictionaryEntity,locale);
return parameterAndValueType;
}
private void buildAutoCompletion(ParameterAndValueType parameterAndValueType,ModelEntity modelEntity, Locale locale) throws Exception{
private void buildByModel(ParameterAndValueType parameterAndValueType,ModelEntity modelEntity, Locale locale) throws Exception{
if(modelEntity==null || !StringUtils.hasText(modelEntity.getId())){ return; }
//枚举类型
buildByEnumDictionary(parameterAndValueType,locale);
//子模型结果值参数作为本模型输入值参数
List<OutParameterEntity> subModelOutParameters =parameterService.findOutParameterEntitiesOfSubModels(modelEntity.getId());
if(subModelOutParameters!=null && subModelOutParameters.size()>0) {
@ -136,6 +117,7 @@ public class ParameterAndValueTypeServiceImpl implements ParameterAndValueTypeSe
buildValueType(parameterAndValueType,entity.getValueType(),entity.getValueTypeVersion(),locale);
}
}
//本模型其他参数
List<ParameterEntity> parameterEntities =modelEntity.getParameters();
if(parameterEntities!=null && parameterEntities.size()>0) {
@ -178,14 +160,14 @@ public class ParameterAndValueTypeServiceImpl implements ParameterAndValueTypeSe
}
}
private void buildAutoCompletion(ParameterAndValueType parameterAndValueType,IndicatorLibEntity indicatorLibEntity, Locale locale) throws Exception{
if(indicatorLibEntity==null){
return;
}
private void buildByLib(ParameterAndValueType parameterAndValueType,IndicatorLibEntity indicatorLibEntity, Locale locale) throws Exception{
if(indicatorLibEntity==null){ return; }
//枚举类型
buildByEnumDictionary(parameterAndValueType,locale);
//指标库中的所有指标
List<IndicatorEntity> indicators =indicatorLibEntity.getIndicators();
if(indicators==null || indicators.isEmpty()){
return;
}
if(indicators==null || indicators.isEmpty()){ return; }
for(IndicatorEntity entity : indicators) {
Parameter parameter =new Parameter();
parameter.setCode(entity.getCode());
@ -198,14 +180,10 @@ public class ParameterAndValueTypeServiceImpl implements ParameterAndValueTypeSe
}
}
private void buildAutoCompletion(ParameterAndValueType parameterAndValueType,UserDefinedJavaClassDictionaryEntity dictionaryEntity, Locale locale) throws Exception{
if(dictionaryEntity==null){
return;
}
private void buildByUserDefinedJavaClassDictionary(ParameterAndValueType parameterAndValueType,UserDefinedJavaClassDictionaryEntity dictionaryEntity, Locale locale) throws Exception{
if(dictionaryEntity==null){ return; }
List<UserDefinedJavaClassFieldEntity> fields =dictionaryEntity.getFields();
if(fields==null || fields.isEmpty()){
return;
}
if(fields==null || fields.isEmpty()){ return; }
for(UserDefinedJavaClassFieldEntity entity : fields) {
Parameter parameter =new Parameter();
parameter.setCode(entity.getCode());
@ -218,6 +196,53 @@ public class ParameterAndValueTypeServiceImpl implements ParameterAndValueTypeSe
}
}
private void buildByEnumDictionary(ParameterAndValueType parameterAndValueType,Locale locale) throws Exception{
if(parameterAndValueType==null){ return; }
List<EnumDictionaryEntity> enumDictionaryEntities =dictionaryService.getRepository().findAllEnumDictionaryEntities();
if(CollectionUtil.hasElements(enumDictionaryEntities)){
// 将枚举作为参数添加到 ParameterAndValueType 中
for(EnumDictionaryEntity enumDictionary : enumDictionaryEntities){
Parameter parameter =new Parameter();
parameter.setCode(IdReplacer.className(enumDictionary.getCode(),enumDictionary.getVersion()));
parameter.setName(enumDictionary.getName());
parameter.setType("enum");
parameter.setValueType(enumDictionary.getCode());
parameter.setValueTypeVersion(enumDictionary.getVersion());
parameter.setValueTypeIsList(false);
parameterAndValueType.addParameter(parameter);
}
// 将枚举作为值类型添加到 ParameterAndValueType 中
for(EnumDictionaryEntity enumDictionary : enumDictionaryEntities){
ValueType valueType =new ValueType();
valueType.setCode(enumDictionary.getCode());
valueType.setName(enumDictionary.getName());
valueType.setVersion(enumDictionary.getVersion());
List<EnumItemEntity> items =enumDictionary.getItems();
if(CollectionUtil.hasElements(items)){
for(EnumItemEntity item : items){
Property property =new Property();
property.setCode(item.getCode());
property.setName(item.getName());
property.setType("enum");
if(EnumDictionaryItemValueType.STRING.equals(item.getValueType())){
property.setValueType("java.lang.String");
}else if(EnumDictionaryItemValueType.INTEGER.equals(item.getValueType())){
property.setValueType("java.lang.Long");
}else if(EnumDictionaryItemValueType.DECIMAL.equals(item.getValueType())){
property.setValueType("java.math.BigDecimal");
}
// 添加枚举类型的枚举项的数据类型
buildValueType(parameterAndValueType,property.getValueType(),property.getValueTypeVersion(),locale);
valueType.addProperty(property);
}
}
parameterAndValueType.addValueType(valueType);
}
}
}
private void buildValueType(ParameterAndValueType parameterAndValueType,String valueTypeCode, Integer valueTypeVersion, Locale locale) throws Exception{
if(dictionaryItemPluginsService.contains(valueTypeCode)){
// 引擎内置类型

9
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/support/Parameter.java

@ -3,6 +3,7 @@ package io.sc.engine.rule.server.common.service.support;
public class Parameter {
private String code;
private String name;
private String type ="parameter";
private String valueType;
private Integer valueTypeVersion;
private Boolean valueTypeIsList =false;
@ -23,6 +24,14 @@ public class Parameter {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValueType() {
return valueType;
}

25
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/support/ParameterAndValueType.java

@ -1,6 +1,7 @@
package io.sc.engine.rule.server.common.service.support;
import io.sc.engine.rule.core.enums.ReplaceMode;
import io.sc.engine.rule.core.util.PlaceHolderEnumExpressionUtil;
import io.sc.platform.util.CollectionUtil;
import io.sc.platform.util.PlaceHolderExpressionUtil;
import io.sc.platform.util.support.PlaceholderExpression;
@ -29,16 +30,23 @@ public class ParameterAndValueType {
if(!StringUtils.hasText(content)){
return content;
}
List<PlaceholderExpression> expressions = PlaceHolderExpressionUtil.parse(content);
List<PlaceholderExpression> expressions = PlaceHolderEnumExpressionUtil.parse(content);
if(CollectionUtil.hasElements(expressions)){
for(PlaceholderExpression expression : expressions){
content =content.replace(expression.getExpression(),replaceExpression(expression,mode));
content =content.replace(expression.getExpression(),replaceExpression(expression,"#",mode));
}
}
expressions = PlaceHolderExpressionUtil.parse(content);
if(CollectionUtil.hasElements(expressions)){
for(PlaceholderExpression expression : expressions){
content =content.replace(expression.getExpression(),replaceExpression(expression,"$",mode));
}
}
return content;
}
private String replaceExpression(PlaceholderExpression expression, ReplaceMode mode) {
private String replaceExpression(PlaceholderExpression expression, String prefix,ReplaceMode mode) {
PlaceholderExpressionPart parameterPart =expression.getParts().get(0);
Parameter parameter =null;
switch (mode){
@ -48,7 +56,8 @@ public class ParameterAndValueType {
if(parameter==null){
return expression.getExpression();
}
StringBuilder sb =new StringBuilder("${");
StringBuilder sb =new StringBuilder();
sb.append(prefix).append("{");
switch (mode){
case CODE_TO_NAME: sb.append(parameter.getName()); break;
case NAME_TO_CODE: sb.append(parameter.getCode()); break;
@ -70,21 +79,21 @@ public class ParameterAndValueType {
String variableArrayIndex =expressionPart.getArrayIndex();
if(valueType==null || valueType.getProperties()==null || valueType.getProperties().isEmpty()) {
if(StringUtils.hasText(variableArrayIndex)){
sb.append(".${").append(variableName).append("}[").append(variableArrayIndex).append("]");
sb.append(".").append(prefix).append("{").append(variableName).append("}[").append(variableArrayIndex).append("]");
}else{
sb.append(".${").append(variableName).append("}");
sb.append(".").append(prefix).append("{").append(variableName).append("}");
}
continue;
}
for(Property property : valueType.getProperties()){
if(ReplaceMode.CODE_TO_NAME.equals(mode)){
if(property.getCode().equals(variableName)){
sb.append(".${").append(property.getName()).append("}");
sb.append(".").append(prefix).append("{").append(property.getName()).append("}");
break;
}
}else{
if(property.getName().equals(variableName)){
sb.append(".${").append(property.getCode()).append("}");
sb.append(".").append(prefix).append("{").append(property.getCode()).append("}");
break;
}
}

9
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/service/support/Property.java

@ -3,6 +3,7 @@ package io.sc.engine.rule.server.common.service.support;
public class Property {
private String code;
private String name;
private String type ="parameter";
private String valueType;
private Integer valueTypeVersion;
private Boolean valueTypeIsList =false;
@ -23,6 +24,14 @@ public class Property {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValueType() {
return valueType;
}

48
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/converter/DictionaryEntityConverter.java

@ -14,52 +14,6 @@ import java.util.List;
*
*/
public class DictionaryEntityConverter {
/**
* 将实体转换成实体主要目的解决实体获取懒加载属性值时发生数据库查询(通过spring data 查询的实体其实是一个动态代理对象对于实体懒加载属性的获取时会发生数据库查询)
* @param entity 实体对象
* @return 实体对象 spring data 实体解耦的实体对象
*/
public static DictionaryEntity toEntity(DictionaryEntity entity) {
if(entity!=null) {
DictionaryEntity clone =null;
if(entity instanceof FolderDictionaryEntity) {//文件夹
clone =new FolderDictionaryEntity();
}else if(entity instanceof UserDefinedJavaClassDictionaryEntity) {//用户定义 Java Class
clone =new UserDefinedJavaClassDictionaryEntity();
}else if(entity instanceof EnumDictionaryEntity) {//枚举类型
clone =new EnumDictionaryEntity();
}else {
clone =new FolderDictionaryEntity();
}
clone.setId(entity.getId());
clone.setCode(entity.getCode());
clone.setName(entity.getName());
clone.setDescription(entity.getDescription());
clone.setVersion(entity.getVersion());
clone.setStatus(entity.getStatus());
return clone;
}
return null;
}
/**
* 将实体转换成实体主要目的解决实体获取懒加载属性值时发生数据库查询(通过spring data 查询的实体其实是一个动态代理对象对于实体懒加载属性的获取时会发生数据库查询)
* @param entities 实体对象集合
* @return 实体对象集合 spring data 实体解耦的实体对象集合
*/
public static List<DictionaryEntity> toEntity(List<? extends DictionaryEntity> entities){
if(entities!=null && entities.size()>0) {
List<DictionaryEntity> clones =new ArrayList<DictionaryEntity>(entities.size());
for(DictionaryEntity entity : entities) {
clones.add(toEntity(entity));
}
return clones;
}
return null;
}
/**
* 将实体转换成 PO 对象
* @param entity 实体对象
@ -85,6 +39,7 @@ public class DictionaryEntityConverter {
}
po.setId(entity.getId());
po.setType(entity.getType());
po.setCode(entity.getCode());
po.setName(entity.getName());
po.setNamec(entity.getNamec());
@ -153,6 +108,7 @@ public class DictionaryEntityConverter {
}
entity.setId(po.getId());
entity.setType(po.getType());
entity.setCode(po.getCode());
entity.setName(po.getName());
entity.setNamec(po.getNamec());

10
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/converter/EnumItemConverter.java

@ -20,11 +20,12 @@ public class EnumItemConverter {
if(entity!=null) {
EnumItem po =new EnumItem();
po.setId(entity.getId());
po.setCode(entity.getCode());
po.setName(entity.getName());
po.setValueType(entity.getValueType());
po.setValue(entity.getValue());
po.setTitle(entity.getTitle());
po.setDescription(entity.getDescription());
po.setOrder(entity.getOrder());
po.setConfig(entity.getConfig());
return po;
}
return null;
@ -57,11 +58,12 @@ public class EnumItemConverter {
if(po!=null) {
EnumItemEntity entity =new EnumItemEntity();
entity.setId(po.getId());
entity.setCode(po.getCode());
entity.setName(po.getName());
entity.setValueType(po.getValueType());
entity.setValue(po.getValue());
entity.setTitle(po.getTitle());
entity.setDescription(po.getDescription());
entity.setOrder(po.getOrder());
entity.setConfig(po.getConfig());
return entity;
}
return null;

1
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/EnumDictionaryEntity.java

@ -19,6 +19,7 @@ import java.util.List;
public class EnumDictionaryEntity extends DictionaryEntity {
//包含的枚举项列表
@OneToMany(mappedBy="dictionary",cascade= {CascadeType.PERSIST},fetch= FetchType.LAZY)
@OrderBy("order")
protected List<EnumItemEntity> items =new ArrayList<EnumItemEntity>();
@Override

96
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/EnumItemEntity.java

@ -1,5 +1,6 @@
package io.sc.engine.rule.server.dictionary.entity;
import io.sc.engine.rule.core.enums.EnumDictionaryItemValueType;
import io.sc.engine.rule.server.dictionary.vo.EnumItemVo;
import io.sc.platform.orm.DeepClone;
import io.sc.platform.orm.IdClearable;
@ -23,43 +24,54 @@ public class EnumItemEntity extends CorporationAuditorEntity<EnumItemVo> impleme
@Column(name="ID_", length=36)
@Size(max=36)
protected String id;
//代码
@Column(name="CODE_", length=255)
protected String code;
//名称
@Column(name="NAME_", length=255)
protected String name;
//值类型
@Column(name="VALUE_TYPE_")
@Enumerated(EnumType.STRING)
protected EnumDictionaryItemValueType valueType;
//值
@Column(name="VALUE_")
protected String value;
//标题
@Column(name="TITLE_", length=1024)
protected String title;
//描述
@Column(name="DESCRIPTION_", length=1024)
@Size(max=255)
@Size(max=1024)
protected String description;
//排序
@Column(name="ORDER_")
protected Integer order;
//配置
@Column(name="CONFIG_")
protected String config;
//所属选项字典
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="DICTIONARY_ID_")
protected DictionaryEntity dictionary;
public EnumItemEntity() {}
public EnumItemEntity(String id) {
this.id =id;
}
@Override
public EnumItemVo toVo() {
EnumItemVo vo =new EnumItemVo();
super.toVo(vo);
vo.setId(this.getId());
vo.setCode(this.getCode());
vo.setName(this.getName());
vo.setValueType(this.getValueType());
vo.setValue(this.getValue());
vo.setTitle(this.getTitle());
vo.setDescription(this.getDescription());
vo.setOrder(this.getOrder());
vo.setConfig(this.getConfig());
vo.setDictionary(this.getDictionary()==null?null:this.getDictionary().getId());
return vo;
}
@ -67,49 +79,66 @@ public class EnumItemEntity extends CorporationAuditorEntity<EnumItemVo> impleme
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EnumDictionaryItemValueType getValueType() {
return valueType;
}
public void setValueType(EnumDictionaryItemValueType valueType) {
this.valueType = valueType;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
public String getConfig() {
return config;
}
public void setConfig(String config) {
this.config = config;
}
public DictionaryEntity getDictionary() {
return dictionary;
}
public void setDictionary(DictionaryEntity dictionary) {
this.dictionary = dictionary;
}
public EnumItemEntity() {}
public EnumItemEntity(String id) {
this.id =id;
}
public Object deepClone() {
EnumItemEntity entity =new EnumItemEntity();
@ -121,15 +150,4 @@ public class EnumItemEntity extends CorporationAuditorEntity<EnumItemVo> impleme
public void clearId() {
this.setId(null);
}
@Override
public String toString() {
return "EnumItemEntity ["
+ "id=" + id
+ ", value=" + value
+ ", title=" + title
+ ", description=" + description
+ ", order=" + order
+ ", config=" + config
+ "]";
}
}

4
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/repository/DictionaryRepository.java

@ -2,6 +2,7 @@ package io.sc.engine.rule.server.dictionary.repository;
import io.sc.engine.rule.core.enums.DeployStatus;
import io.sc.engine.rule.server.dictionary.entity.DictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.EnumDictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.FolderDictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.UserDefinedJavaClassDictionaryEntity;
import io.sc.engine.rule.server.lib.entity.IndicatorLibEntity;
@ -44,6 +45,9 @@ public interface DictionaryRepository extends DaoRepository<DictionaryEntity,Str
@Query("select e from io.sc.engine.rule.server.dictionary.entity.UserDefinedJavaClassDictionaryEntity e where e.id=:id")
public UserDefinedJavaClassDictionaryEntity findUserDefinedJavaClassDictionaryById(@Param("id") String id);
@Query("select e from io.sc.engine.rule.server.dictionary.entity.EnumDictionaryEntity e")
public List<EnumDictionaryEntity> findAllEnumDictionaryEntities();
@Query("select max(e.version)+1 from io.sc.engine.rule.server.dictionary.entity.DictionaryEntity e where e.code=:code")
public Integer getNextVersionByCode(@Param("code") String code);

26
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/impl/DictionaryServiceImpl.java

@ -3,6 +3,7 @@ package io.sc.engine.rule.server.dictionary.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.sc.engine.rule.core.code.SourceCode;
import io.sc.engine.rule.core.enums.DeployStatus;
import io.sc.engine.rule.core.enums.DictionaryType;
import io.sc.engine.rule.core.enums.LibType;
import io.sc.engine.rule.core.enums.ResourceType;
import io.sc.engine.rule.core.po.dictionary.Dictionary;
@ -75,7 +76,11 @@ public class DictionaryServiceImpl extends DaoServiceImpl<DictionaryEntity, Stri
}
//规范代码和名称
if(!StringUtils.hasText(entity.getCode())) {
entity.setCode("D"+System.currentTimeMillis());
if(DictionaryType.ENUM.equals(entity.getType())) {
entity.setCode("E" + System.currentTimeMillis());
}else{
entity.setCode("D" + System.currentTimeMillis());
}
}
entity.setName(StringUtils.trimAllWhitespace(entity.getName()));
@ -105,7 +110,11 @@ public class DictionaryServiceImpl extends DaoServiceImpl<DictionaryEntity, Stri
//规范代码和名称
if(!StringUtils.hasText(entity.getCode())) {
entity.setCode("D"+System.currentTimeMillis());
if(DictionaryType.ENUM.equals(entity.getType())) {
entity.setCode("E" + System.currentTimeMillis());
}else{
entity.setCode("D" + System.currentTimeMillis());
}
}
entity.setName(StringUtils.trimAllWhitespace(entity.getName()));
@ -276,8 +285,11 @@ public class DictionaryServiceImpl extends DaoServiceImpl<DictionaryEntity, Stri
@Override
public List<DictionaryEntity> findDictionaryEntitiesByResourceId(String resourceId) throws Exception {
Set<DictionaryEntity> result =new HashSet<DictionaryEntity>();
//先添加枚举数据字典
result.addAll(repository.findAllEnumDictionaryEntities());
if(StringUtils.hasText(resourceId)) {
//先添加资源所需的数据字典
//添加资源所需的数据字典
ResourceEntity resourceEntity =resourceService.findById(resourceId);
if(ResourceType.MODEL.equals(resourceEntity.getType())) {
ModelResourceEntity modelResourceEntity =resourceService.getRepository().findModelResourceById(resourceId);
@ -315,13 +327,16 @@ public class DictionaryServiceImpl extends DaoServiceImpl<DictionaryEntity, Stri
@Override
public List<DictionaryEntity> findDictionaryEntitiesByLibId(String libId) throws Exception {
Set<DictionaryEntity> result =new HashSet<DictionaryEntity>();
//先添加枚举数据字典
result.addAll(repository.findAllEnumDictionaryEntities());
if(StringUtils.hasText(libId)) {
LibEntity libEntity =libService.findById(libId);
if(LibType.INDICATOR.equals(libEntity.getType())) {
IndicatorLibEntity indicatorLibEntity =(IndicatorLibEntity)libService.findById(libEntity.getId());
List<IndicatorEntity> indicators =indicatorLibEntity.getIndicators();
if(indicators!=null && indicators.size()>0) {
Set<DictionaryEntity> result =new HashSet<>();
for(IndicatorEntity indicator : indicators) {
if(!ValueTypeUtil.isBase(indicator.getValueType())) {
String code =indicator.getValueType();
@ -332,11 +347,10 @@ public class DictionaryServiceImpl extends DaoServiceImpl<DictionaryEntity, Stri
}
}
}
return new ArrayList<DictionaryEntity>(result);
}
}
}
return null;
return new ArrayList<DictionaryEntity>(result);
}
@Override

30
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/impl/EnumItemServiceImpl.java

@ -10,6 +10,7 @@ import io.sc.platform.orm.service.impl.DaoServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Optional;
@ -24,6 +25,12 @@ public class EnumItemServiceImpl extends DaoServiceImpl<EnumItemEntity, String,
if(entity==null){
throw exceptionProvider.getCreateNullObjectException();
}
//规范代码和名称
if(!StringUtils.hasText(entity.getCode())) {
entity.setCode("E"+System.currentTimeMillis());
}
entity.setName(StringUtils.trimAllWhitespace(entity.getName()));
String dictionaryId =entity.getDictionary().getId();
Optional<EnumDictionaryEntity> optional =enumDictionaryRepository.findById(dictionaryId);
if(optional.isPresent()){
@ -32,20 +39,15 @@ public class EnumItemServiceImpl extends DaoServiceImpl<EnumItemEntity, String,
List<EnumItemEntity> items =dictionaryEntity.getItems();
if(items!=null && items.size()>0) {
for(EnumItemEntity item : items) {
if(item.getValue().equals(entity.getValue()) || item.getTitle().equals(entity.getTitle())) {
if(item.getCode().equals(entity.getCode()) || item.getName().equals(entity.getName()) || item.getValue().equals(entity.getValue())) {
throw new EnumItemAlreadyExistsException();
}
}
}
}
}
Integer nextOrder =repository.getNextOrder(entity.getDictionary().getId());
if(nextOrder!=null) {
entity.setOrder(nextOrder);
}else {
entity.setOrder(1);
}
entity.setOrder(nextOrder==null?1:nextOrder);
return super.add(entity);
}
@ -58,6 +60,12 @@ public class EnumItemServiceImpl extends DaoServiceImpl<EnumItemEntity, String,
if(entity==null){
throw exceptionProvider.getUpdateNullNewObjectException();
}
//规范代码和名称
if(!StringUtils.hasText(entity.getCode())) {
entity.setCode("E"+System.currentTimeMillis());
}
entity.setName(StringUtils.trimAllWhitespace(entity.getName()));
String dictionaryId =entity.getDictionary().getId();
Optional<EnumDictionaryEntity> optional =enumDictionaryRepository.findById(dictionaryId);
if(optional.isPresent()) {
@ -67,7 +75,7 @@ public class EnumItemServiceImpl extends DaoServiceImpl<EnumItemEntity, String,
if (items != null && items.size() > 0) {
for (EnumItemEntity item : items) {
if (!item.getId().equals(entity.getId())) {
if (item.getValue().equals(entity.getValue()) || item.getTitle().equals(entity.getTitle())) {
if(item.getCode().equals(entity.getCode()) || item.getName().equals(entity.getName()) || item.getValue().equals(entity.getValue())) {
throw new EnumItemAlreadyExistsException();
}
}
@ -75,6 +83,12 @@ public class EnumItemServiceImpl extends DaoServiceImpl<EnumItemEntity, String,
}
}
}
//如果没有顺序则自动生成顺序
if(entity.getOrder()==null) {
Integer nextOrder =repository.getNextOrder(entity.getDictionary().getId());
entity.setOrder(nextOrder==null?1:nextOrder);
}
return super.update(primaryKey, entity);
}
}

65
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/vo/EnumItemVo.java

@ -1,5 +1,6 @@
package io.sc.engine.rule.server.dictionary.vo;
import io.sc.engine.rule.core.enums.EnumDictionaryItemValueType;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
/**
@ -9,68 +10,88 @@ public class EnumItemVo extends CorporationAuditorVo {
//ID,主键
protected String id;
//代码
protected String code;
//名称
protected String name;
//值类型
protected EnumDictionaryItemValueType valueType;
//值
protected String value;
//标题
protected String title;
//描述
protected String description;
//排序
protected Integer order;
//配置
protected String config;
//所属选项字典
protected String dictionary;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EnumDictionaryItemValueType getValueType() {
return valueType;
}
public void setValueType(EnumDictionaryItemValueType valueType) {
this.valueType = valueType;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
public String getConfig() {
return config;
}
public void setConfig(String config) {
this.config = config;
}
public String getDictionary() {
return dictionary;
}
public void setDictionary(String dictionary) {
this.dictionary = dictionary;
}
public EnumItemVo() {}
public EnumItemVo(String id) {
this.id =id;
}
}

31
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterServiceImpl.java

@ -155,7 +155,12 @@ public class ParameterServiceImpl extends DaoServiceImpl<ParameterEntity, String
if(entity==null){
throw exceptionProvider.getUpdateNullNewObjectException();
}
// 对于子模型输入参数,不处理
if(entity.getType()==null || ParameterType.IN_SUB_OUT.equals(entity.getType())){
return entity;
}
//规范代码和名称
if(!StringUtils.hasText(entity.getCode())) {
entity.setCode("P"+System.currentTimeMillis());
@ -177,24 +182,24 @@ public class ParameterServiceImpl extends DaoServiceImpl<ParameterEntity, String
if(!StringUtils.hasText(entity.getCode())) {
entity.setCode("P"+System.currentTimeMillis());
}
String modelId =entity.getModel().getId();
String modelId = entity.getModel().getId();
//检查在整个模型结构树中是否存在相同代码和名称的模型或子模型
List<ModelEntity> modelEntities =modelService.findModelByParentIdAndCodeOrName(modelId, entity.getCode(), entity.getName());
if(modelEntities!=null && modelEntities.size()>0) {
List<ModelEntity> modelEntities = modelService.findModelByParentIdAndCodeOrName(modelId, entity.getCode(), entity.getName());
if (modelEntities != null && modelEntities.size() > 0) {
throw new ModelEntityAlreadyExistsException();
}
//检查在整个模型结构树中是否存在相同代码和名称的参数
ModelEntity rootModelEntity =modelService.findRootModelByModelId(modelId);
if(rootModelEntity==null) {
ModelEntity rootModelEntity = modelService.findRootModelByModelId(modelId);
if (rootModelEntity == null) {
throw new RootModelEntityNotExistsException();
}
List<ParameterEntity> parameters =modelService.getAllParameters(rootModelEntity.getId());
if(parameters!=null && parameters.size()>0) {
for(ParameterEntity parameter : parameters) {
if(!parameter.getId().equals(entity.getId())) {//排除自己
if(parameter.getCode().equals(entity.getCode()) || parameter.getName().equals(entity.getName())) {
List<ParameterEntity> parameters = modelService.getAllParameters(rootModelEntity.getId());
if (parameters != null && parameters.size() > 0) {
for (ParameterEntity parameter : parameters) {
if (!parameter.getId().equals(entity.getId())) {//排除自己
if (parameter.getCode().equals(entity.getCode()) || parameter.getName().equals(entity.getName())) {
throw new ParameterEntityAlreadyExistsException();
}
}

6180
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎示例(元数据).json

File diff suppressed because it is too large

1753
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎示例.json

File diff suppressed because one or more lines are too long

5
io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule Engine Database Schema DDL.xml

@ -509,11 +509,10 @@
</column>
<column name="CODE_" type="NVARCHAR(255)" remarks="代码"/>
<column name="NAME_" type="NVARCHAR(255)" remarks="名称"/>
<column name="DESCRIPTION_" type="NVARCHAR(1024)" remarks="描述"/>
<column name="VALUE_TYPE_" type="NVARCHAR(20)" remarks="值类型(STRING:字符串; INTEGER:整数; DECIMAL:小数)"/>
<column name="VALUE_" type="NVARCHAR(255)" remarks="值"/>
<column name="TITLE_" type="NVARCHAR(1024)" remarks="文本"/>
<column name="DESCRIPTION_" type="NVARCHAR(1024)" remarks="描述"/>
<column name="ORDER_" type="INTEGER" remarks="顺序"/>
<column name="CONFIG_" type="CLOB" remarks="配置"/>
<column name="DICTIONARY_ID_" type="NVARCHAR(36)" remarks="所属数据字典ID"/>
<!-- 审计字段 -->

1
io.sc.engine.st.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.engine.st.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

2
io.sc.platform.core.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.2.24",
"version": "8.2.28",
"description": "前端核心包,用于快速构建前端的脚手架",
"//main": "库的主文件",
"main": "dist/platform-core.js",

22
io.sc.platform.core.frontend/src/platform/components/code-mirror/WCodeMirror.vue

@ -86,8 +86,6 @@ interface FieldProps extends FormFieldProps {
toolbar?: boolean;
//
editable?: boolean;
//
forceUpdate?: boolean;
//
lineWrap?: boolean;
// tab size
@ -115,7 +113,6 @@ const props = withDefaults(defineProps<FieldProps>(), {
rows: 4,
toolbar: true,
editable: true,
forceUpdate: false,
lineWrap: false,
tabSize: 2,
lineNumber: false,
@ -130,7 +127,7 @@ const props = withDefaults(defineProps<FieldProps>(), {
});
class FieldMethods extends FormFieldMethods {
updateValue = (value_) => {
updateValue = (value_: any) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({
value: value_,
@ -141,7 +138,7 @@ class FieldMethods extends FormFieldMethods {
validate = () => {
return fieldRef.value.validate();
};
setValue = (value_) => {
setValue = (value_: any) => {
editorView.dispatch({ changes: { from: 0, to: editorView.state.doc.length, insert: value_ } });
};
getValue = () => {
@ -259,13 +256,6 @@ onMounted(() => {
if (!props.lineBreak) {
content = content?.replace(/[\r\n]/g, '');
}
//
// if (props.placeholder) {
// const reg = /\$\{(.+?)\}\.\$\{(.+?)\}/g;
// while (reg.test(content)) {
// content = content.replace(reg, '${$1.$2}');
// }
// }
//
modelValue.value = Tools.trim(content);
}
@ -280,8 +270,8 @@ onMounted(() => {
() => modelValue.value,
() => {
// , , 便
// , , modelValue,
if (props.forceUpdate || !editorView.hasFocus) {
// , , modelValue
if (!editorView.hasFocus) {
let content = modelValue.value;
if (!props.lineBreak && !Tools.isEmpty(content)) {
content = content.replace(/[\r\n]/g, '');
@ -296,11 +286,11 @@ onUnmounted(() => {
editorView.destroy();
});
const configure = (values) => {
const configure = (values: any) => {
editorView.dispatch({ effects: StateEffect.reconfigure.of(values) });
};
const buttonClick = (button) => {
const buttonClick = (button: any) => {
if (button.click) {
button.click({
value: modelValue.value,

60
io.sc.platform.core.frontend/src/platform/components/code-mirror/w-code-mirror/PlaceholderPlugin.ts

@ -1,14 +1,14 @@
import { Dialog } from 'quasar';
import { $t } from '@/platform';
import { EditorView, ViewPlugin, ViewUpdate, MatchDecorator, Decoration, DecorationSet, WidgetType } from '@codemirror/view';
class PlaceholderWidget extends WidgetType {
constructor(name) {
name: string;
constructor(name: string) {
super();
this.name = name;
this.name = name.trim();
}
eq(other) {
eq(other: PlaceholderWidget) {
return this.name == other.name;
}
@ -18,9 +18,13 @@ class PlaceholderWidget extends WidgetType {
const elt = document.createElement('span');
elt.setAttribute('placeholder', true);
elt.className = 'p-0.5 border border-gray-800 rounded-md';
elt.textContent = this.name;
elt.className = 'p-0.5 border rounded-md';
if (this.name.startsWith('#')) {
elt.className += ' border-orange-400';
} else {
elt.className += ' border-gray-800';
}
elt.textContent = this.name.replace(/[$#]\{(.+?)\}/g, '$1');
container.appendChild(elt);
return container;
}
@ -31,11 +35,12 @@ class PlaceholderWidget extends WidgetType {
}
const placeholderMatcher = new MatchDecorator({
regexp: /\$\{(.+?)\}/g,
decoration: (match) =>
Decoration.replace({
widget: new PlaceholderWidget(match[1]),
}),
regexp: /[$#]\{(.+?)\}/g,
decoration: (match) => {
return Decoration.replace({
widget: new PlaceholderWidget(match[0]),
});
},
});
const placeholderPlugin = ViewPlugin.fromClass(
@ -58,43 +63,18 @@ const placeholderPlugin = ViewPlugin.fromClass(
mouseover: (e, view) => {
const target = e.target as HTMLElement;
if (target.tagName.toLowerCase() === 'span' && target.getAttribute('placeholder')) {
target.className = 'p-0.5 border border-orange-400 rounded-md';
target.className = target.className.replace('border', 'border border-dashed');
}
},
mouseout: (e, view) => {
const target = e.target as HTMLElement;
if (target.tagName.toLowerCase() === 'span' && target.getAttribute('placeholder')) {
target.className = 'p-0.5 border border-gray-800 rounded-md';
target.className = target.className.replace('border-dashed', '');
}
},
contextmenu: (e, view) => {
e.preventDefault();
},
/*
dblclick: (e, view) => {
e.stopPropagation();
e.preventDefault();
Dialog.create({
title: $t('edit'),
style: 'max-width: 600px;width: 600px;',
message: null,
prompt: {
model: e.target.textContent,
type: 'text',
outlined: true,
},
persistent: true,
ok: {
color: 'primary',
},
cancel: {
color: 'primary',
},
}).onOk((data) => {
e.target.textContent = data;
});
},
*/
},
},
);

14
io.sc.platform.core.frontend/src/platform/components/graph/WGraph.vue

@ -106,10 +106,10 @@ const emit = defineEmits<{
}>();
class FieldMethods extends FormFieldMethods {
updateValue = (value_) => {
updateValue = (value: any) => {
if (props['onUpdateValue']) {
props['onUpdateValue']({
value: value_,
value: value,
form: props['form'],
});
}
@ -117,8 +117,8 @@ class FieldMethods extends FormFieldMethods {
validate = () => {
return true;
};
setValue = (value_) => {
modelValueRef.value = value_;
setValue = (value: any) => {
modelValueRef.value = value;
};
getValue = () => {
return modelValueRef.value;
@ -143,7 +143,7 @@ const xmlDialogRef = ref();
let graph: PlatformGraph;
const generateSvg = (vertexDefine) => {
const generateSvg = (vertexDefine: any) => {
let svg = '<svg viewBox="0 0 24 24">';
if (vertexDefine.shape === 'ellipse') {
//
@ -210,7 +210,7 @@ const remove = () => {
graph.remove();
};
const dragstart = (event, thumbnail) => {
const dragstart = (event: any, thumbnail: any) => {
const data = {
type: thumbnail.type,
shape: thumbnail.cell.shape,
@ -219,7 +219,7 @@ const dragstart = (event, thumbnail) => {
event.dataTransfer.setData('data', Tools.object2Json(data));
};
const updateValue = (arg) => {
const updateValue = (arg: any) => {
const selectedCellHandler = graph.getPlugin<PlatformSelectedCellHandler>('PlatformSelectedCellHandler');
if (selectedCellHandler) {
selectedCellHandler.updateCell(arg);

23
io.sc.platform.core.frontend/src/platform/components/graph/handler/PlatformSelectedCellHandler.ts

@ -1,8 +1,7 @@
import { Graph, GraphPlugin, InternalEvent, CellAttributeChange, ValueChange } from '@maxgraph/core';
import { Graph, GraphPlugin, InternalEvent, ValueChange } from '@maxgraph/core';
import { PlatformVertexDefineHandler } from './PlatformVertexDefineHandler';
import { PlatformEdgeDefineHandler } from './PlatformEdgeDefineHandler';
import { Tools } from '@/platform';
import { nextTick } from 'vue';
export class PlatformSelectedCellHandler implements GraphPlugin {
public static pluginId: string = 'PlatformSelectedCellHandler';
@ -27,8 +26,13 @@ export class PlatformSelectedCellHandler implements GraphPlugin {
if (vertexDefineHandler) {
const value = vertexDefineHandler.getValue(type, cell);
const fields = vertexDefineHandler.getFormFields(type);
this.selectedCellReactive.modelValue = value;
this.selectedCellReactive.fields = fields;
//以下操作是先清空表单字段,等界面渲染后,再设置表单字段, 避免出现以下问题:
//在画图面板中存在两个相同组件时, 选择其中一个, 编辑其属性, 再选择另外一个时, 属性值不能更新
this.selectedCellReactive.fields = [];
nextTick(() => {
this.selectedCellReactive.modelValue = value;
this.selectedCellReactive.fields = fields;
});
} else {
this.selectedCellReactive.modelValue = {};
this.selectedCellReactive.fields = [];
@ -40,8 +44,13 @@ export class PlatformSelectedCellHandler implements GraphPlugin {
if (edgeDefineHandler) {
const value = edgeDefineHandler.getValue(type, cell);
const fields = edgeDefineHandler.getFormFields(type);
this.selectedCellReactive.modelValue = value;
this.selectedCellReactive.fields = fields;
//以下操作是先清空表单字段,等界面渲染后,再设置表单字段, 避免出现以下问题:
//在画图面板中存在两个相同组件时, 选择其中一个, 编辑其属性, 再选择另外一个时, 属性值不能更新
this.selectedCellReactive.fields = [];
nextTick(() => {
this.selectedCellReactive.modelValue = value;
this.selectedCellReactive.fields = fields;
});
} else {
this.selectedCellReactive.modelValue = {};
this.selectedCellReactive.fields = [];

48
io.sc.platform.core.frontend/src/views/testcase/code-mirror/AutoCompletionManager.ts

@ -116,10 +116,14 @@ class AutoCompletionManager {
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 };
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;
@ -135,20 +139,44 @@ class AutoCompletionManager {
public autoCompletionProperties(to: any, matchedText?: any): any {
const matchedTextReverse = Tools.reverseString(matchedText);
const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{\$)+/g; //匹配 '.]n[}xxx{$' 模式
const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{[$#])+/g; //匹配 '.]n[}xxx{$#' 模式
// -- -- --- -- -- --- ----
// . ] 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');
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)) {
return null;
parameterName = matched.replace(/\$\{(.+?)\}(\[(.+?)\])?/g, '$1');
if (Tools.isUndefinedOrNull(parameterName)) {
return null;
}
}
*/
const options = this.getOptions(parameterName);
if (Tools.isUndefinedOrNull(options)) {
return null;
@ -161,7 +189,10 @@ class AutoCompletionManager {
}
public doAutoCompletion(context: any): any {
console.log('>>>>');
const beforeMatched = context.matchBefore(/(.+?)/g);
console.log(beforeMatched);
if (Tools.isUndefinedOrNull(beforeMatched)) {
return null;
}
@ -185,6 +216,7 @@ class AutoCompletionManager {
}
public autoCompletion(): any {
console.log('????');
return (context: any) => {
return this.doAutoCompletion(context);
};

7
io.sc.platform.core.frontend/src/views/testcase/code-mirror/code-mirror.vue

@ -20,7 +20,7 @@ import { axios, Environment, EnumTools, Tools, Formater } from '@/platform';
import { UserDefinedFunctionsManager } from './UserDefinedFunctionsManager';
import { AutoCompletionManager } from './AutoCompletionManager';
const modelValue = ref('${个人征信报告.报告头.报告头信息单元.报告标识信息段.报告编号}');
const modelValue = ref('${个人征信报告.报告头.报告头信息单元.报告标识信息段.报告编号} #{枚举}');
const click = () => {
//console.log(modelValue.value);
@ -30,7 +30,10 @@ const click = () => {
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByIndicatorId/34e7391f-ba76-4e14-b152-ae0da917fd20'));
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByParameterId/34e7391f-ba76-4e14-b152-ae0da917fd20'));
userDefinedFunctionsManager.load();
console.log(Tools.escapeHtml('<xml>&</xml>'));
const matcheds = '${kdsf} #{aaa}'.match(/\$\{(.+?)\}|#\{(.+?)\}/g);
//console.log(matcheds);
</script>

226
io.sc.platform.core.frontend/src/views/testcase/maxgraph/AutoCompletionManager.ts

@ -0,0 +1,226 @@
import { axios, Tools } from '@/platform';
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 {
console.log('>>>>');
const beforeMatched = context.matchBefore(/(.+?)/g);
console.log(beforeMatched);
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 {
console.log('????');
return (context: any) => {
return this.doAutoCompletion(context);
};
}
}
export { AutoCompletionManager };

18
io.sc.platform.core.frontend/src/views/testcase/maxgraph/PlaceHolder.ts

@ -0,0 +1,18 @@
import { Tools } from '@/platform';
class PlaceHolder {
static #parameterPrefix: string = '<span class="p-0.5"><span class="p-0.5 border border-gray-800 rounded-md">';
static #enumPrefix: string = '<span class="p-0.5"><span class="p-0.5 border border-orange-400 rounded-md">';
static #suffix: string = '</span></span>';
public static replace(str: string) {
if (Tools.isString(str)) {
str = str.replace('<', '&lt;');
str = str.replace(/#\{(.+?)\}/g, PlaceHolder.#enumPrefix + '$1' + PlaceHolder.#suffix);
str = str.replace(/\$\{(.+?)\}/g, PlaceHolder.#parameterPrefix + '$1' + PlaceHolder.#suffix);
}
return str;
}
}
export { PlaceHolder };

23
io.sc.platform.core.frontend/src/views/testcase/maxgraph/UserDefinedFunctionsManager.ts

@ -0,0 +1,23 @@
import { ref } from 'vue';
import { axios, Environment, Tools } from '@/platform';
class UserDefinedFunctionsManager {
#functions: any;
constructor() {
this.#functions = ref([]);
}
public userDefinedFunctions(): any {
return this.#functions;
}
public async load() {
const response = await axios.get(Environment.apiContextPath('/api/re/function?pageable=false&sortBy=name'));
this.#functions.value = Tools.objects2Objects(response.data?.content, null, (obj: any) => {
return obj.enable;
});
}
}
export { UserDefinedFunctionsManager };

136
io.sc.platform.core.frontend/src/views/testcase/maxgraph/maxgraph.vue

@ -3,29 +3,29 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, NotifyManager, Formater, EnumTools, $t } from '@/platform';
import { $t, axios, Environment, NotifyManager } from '@/platform';
import { AutoCompletionManager } from './AutoCompletionManager';
import { UserDefinedFunctionsManager } from './UserDefinedFunctionsManager';
import { PlaceHolder } from './PlaceHolder';
const dialogRef = ref();
const processorIdRef = ref();
const modelValueRef = ref('');
const userDefinedFunctionsRef = ref();
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
const resourceAbstractsRef = ref();
const modeAbstractsRef = ref();
const autoCompletion = (context) => {
return [];
};
const edgeDefines = [
{
type: 'EdgeConditionBranch',
fromVertexType: 'Condition',
toVertexType: null,
getLabel: (value) => {
getLabel: (value: any) => {
return value.value || '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
valueType: dom.getAttribute('valueType') || '',
@ -66,8 +66,9 @@ const edgeDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -90,10 +91,10 @@ const vertexDefines = [
shape: 'ellipse',
size: [50, 50],
},
getLabel: (value) => {
getLabel: (value: any) => {
return value.label;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
label: dom.getAttribute('label') || '',
@ -125,10 +126,10 @@ const vertexDefines = [
shape: 'rhombus',
size: [120, 60],
},
getLabel: (value) => {
return value.condition ? value.condition : '';
getLabel: (value: any) => {
return value.condition ? PlaceHolder.replace(value.condition) : '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
condition: dom.getAttribute('condition') || '',
@ -150,8 +151,9 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -169,12 +171,12 @@ const vertexDefines = [
shape: 'rectangle',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
let html = '';
html += '<div style="text-align:left;">' + value.commands + '</div>';
return html;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
commands: dom.getAttribute('commands') || '',
@ -197,8 +199,8 @@ const vertexDefines = [
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -218,14 +220,14 @@ const vertexDefines = [
shape: 'ellipse',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
return resourceAbstract.name + '(V' + resourceAbstract.version + ')';
}
return '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
const code = dom.getAttribute('code');
const version = dom.getAttribute('version');
@ -245,7 +247,7 @@ const vertexDefines = [
};
}
},
setValue: (dom, value) => {
setValue: (dom: any, value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
dom.setAttribute('code', resourceAbstract.code);
@ -261,7 +263,7 @@ const vertexDefines = [
name: 'resourceAbstractId',
label: $t('re.graph.vertex.resourceAbstract.entity.resourceAbstractId'),
type: 'w-grid-select',
displayValue: (args) => {
displayValue: (args: any) => {
return args.data.name + '(V' + args.data.version + ')';
},
grid: {
@ -271,7 +273,7 @@ const vertexDefines = [
configButton: true,
checkboxSelection: false,
tree: true,
treeIcon: (row) => {
treeIcon: (row: any) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
@ -284,7 +286,7 @@ const vertexDefines = [
},
dataUrl: Environment.apiContextPath('/api/re/resource'),
pageable: false,
sortBy: ['order', '-lastModifyDate'],
sortBy: ['type', 'namec', '-lastModifyDate'],
toolbarConfigure: { noIcon: false },
toolbarActions: ['refresh', 'expand'],
columns: [
@ -293,11 +295,6 @@ const vertexDefines = [
width: 80,
name: 'type',
label: $t('type'),
format: (value, row) => {
if (value !== 'FOLDER') {
return Formater.enum(Enums.ResourceType)(value);
}
},
},
{ width: 60, name: 'version', label: $t('version') },
{
@ -329,7 +326,7 @@ const vertexDefines = [
shape: 'doubleEllipse',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
let html = '<div style="text-align:left;">' + (value?.inputCommands || '') + '</div>';
html += '<hr/>';
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
@ -340,7 +337,7 @@ const vertexDefines = [
html += '<div style="text-align:left;">' + (value?.outputCommands || '') + '</div>';
return html;
},
getValue: (dom) => {
getValue: (dom: any) => {
let result = { resourceAbstractId: '', inputCommands: '', outputCommands: '' };
if (dom) {
const code = dom.getAttribute('code');
@ -354,7 +351,7 @@ const vertexDefines = [
}
return result;
},
setValue: (dom, value) => {
setValue: (dom: any, value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
dom.setAttribute('code', resourceAbstract.code);
@ -372,7 +369,7 @@ const vertexDefines = [
name: 'resourceAbstractId',
label: $t('re.graph.vertex.configurableResourceAbstract.entity.resourceAbstractId'),
type: 'w-grid-select',
displayValue: (args) => {
displayValue: (args: any) => {
return args.data.name + (args.data.version ? '(V' + args.data.version + ')' : '');
},
grid: {
@ -382,7 +379,7 @@ const vertexDefines = [
configButton: true,
checkboxSelection: false,
tree: true,
treeIcon: (row) => {
treeIcon: (row: any) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
@ -395,7 +392,7 @@ const vertexDefines = [
},
dataUrl: Environment.apiContextPath('/api/re/resource'),
pageable: false,
sortBy: ['order', '-lastModifyDate'],
sortBy: ['type', 'namec', '-lastModifyDate'],
toolbarConfigure: { noIcon: false },
toolbarActions: ['refresh', 'expand'],
columns: [
@ -404,11 +401,6 @@ const vertexDefines = [
width: 80,
name: 'type',
label: $t('type'),
format: (value, row) => {
if (value !== 'FOLDER') {
return Formater.enum(Enums.ResourceType)(value);
}
},
},
{ width: 60, name: 'version', label: $t('version') },
{
@ -429,8 +421,9 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
{
name: 'outputCommands',
@ -441,8 +434,9 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -462,7 +456,7 @@ const vertexDefines = [
shape: 'hexagon',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
for (const item of modeAbstractsRef.value) {
if (item.value === value.code) {
return item.label;
@ -470,7 +464,7 @@ const vertexDefines = [
}
return '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
code: dom.getAttribute('code') || '',
@ -494,7 +488,7 @@ const vertexDefines = [
},
];
const findResourceAbstractById = (id) => {
const findResourceAbstractById = (id: string) => {
for (const item of resourceAbstractsRef.value) {
if (item.id === id) {
return item;
@ -503,70 +497,48 @@ const findResourceAbstractById = (id) => {
return null;
};
const findResourceAbstractByCodeAndVersion = (code, version) => {
const findResourceAbstractByCodeAndVersion = (code: string, version: number) => {
for (const item of resourceAbstractsRef.value) {
if (item.code === code && item.version?.toString() === version) {
if (item.code === code && item.version.toString() === version) {
return item;
}
}
return null;
};
const open = async (parameterId, processorId) => {
const open = async (parameterId: string, processorId: string) => {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByParameterId/' + parameterId));
userDefinedFunctionsManager.load();
processorIdRef.value = processorId;
//
const resourceAbstractResponse = await axios.get(Environment.apiContextPath('/api/re/resource/getAllReleasableResourceAbstract'));
const resourceAbstractResponse = await axios.get(Environment.apiContextPath('/api/re/resource/getAllResourceAbstract'));
resourceAbstractsRef.value = resourceAbstractResponse?.data;
//
const modelResponse = await axios.get(Environment.apiContextPath('/api/re/model/getModeAbstractByParameterProcessor/' + processorId));
const modelOptions = [];
const modelOptions = <any>[];
for (const item of modelResponse?.data || []) {
modelOptions.push({ label: item.name, value: item.code });
}
modeAbstractsRef.value = modelOptions;
//
const functionResponse = await axios.get(Environment.apiContextPath('/api/re/function?pageable=false'));
const functionOptions = [];
for (const item of functionResponse?.data?.content || []) {
if (item.enable) {
functionOptions.push(item);
}
}
userDefinedFunctionsRef.value = functionOptions;
//
const tipResponse = await axios.get(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + parameterId));
// autoCompletionManager.setParameters(tipResponse?.data?.parameters);
// autoCompletionManager.setValueTypes(tipResponse?.data?.valueTypes);
// graph xml
const graphResponse = await axios.get(Environment.apiContextPath('api/re/model/parameter/processor/getExecutionFlowById/' + processorIdRef.value));
modelValueRef.value = graphResponse?.data;
//
//dialogRef.value.show();
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
const save = (xml) => {
axios.post(Environment.apiContextPath('api/re/model/parameter/processor/saveExecutionFlowById/' + processorIdRef.value), { xml }).then((response) => {
NotifyManager.info($t('operationSuccess'));
});
};
const save = (xml: string) => {};
defineExpose({
open,
close,
});
const parameterId = '3b2e9e42-3e3e-4cd4-8071-a15fdfab54f3';
const processorId = '54d16aa3-1a2e-4c87-9f7a-e78ccbca5cdb';
open(parameterId, processorId);
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ResourceType', 'io.sc.engine.rule.core.enums.DeployStatus']);
</script>

1
io.sc.platform.core.frontend/template-project/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

4
io.sc.platform.core.frontend/template-project/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.2.24",
"version": "8.2.28",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -110,7 +110,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

48
io.sc.platform.core.frontend/template-project/src/views/testcase/code-mirror/AutoCompletionManager.ts

@ -116,10 +116,14 @@ class AutoCompletionManager {
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 };
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;
@ -135,20 +139,44 @@ class AutoCompletionManager {
public autoCompletionProperties(to: any, matchedText?: any): any {
const matchedTextReverse = Tools.reverseString(matchedText);
const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{\$)+/g; //匹配 '.]n[}xxx{$' 模式
const regReverse = /(\.(\](.+?)\[)?\}(.+?)\{[$#])+/g; //匹配 '.]n[}xxx{$#' 模式
// -- -- --- -- -- --- ----
// . ] 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');
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)) {
return null;
parameterName = matched.replace(/\$\{(.+?)\}(\[(.+?)\])?/g, '$1');
if (Tools.isUndefinedOrNull(parameterName)) {
return null;
}
}
*/
const options = this.getOptions(parameterName);
if (Tools.isUndefinedOrNull(options)) {
return null;
@ -161,7 +189,10 @@ class AutoCompletionManager {
}
public doAutoCompletion(context: any): any {
console.log('>>>>');
const beforeMatched = context.matchBefore(/(.+?)/g);
console.log(beforeMatched);
if (Tools.isUndefinedOrNull(beforeMatched)) {
return null;
}
@ -185,6 +216,7 @@ class AutoCompletionManager {
}
public autoCompletion(): any {
console.log('????');
return (context: any) => {
return this.doAutoCompletion(context);
};

7
io.sc.platform.core.frontend/template-project/src/views/testcase/code-mirror/code-mirror.vue

@ -20,7 +20,7 @@ import { axios, Environment, EnumTools, Tools, Formater } from '@/platform';
import { UserDefinedFunctionsManager } from './UserDefinedFunctionsManager';
import { AutoCompletionManager } from './AutoCompletionManager';
const modelValue = ref('${个人征信报告.报告头.报告头信息单元.报告标识信息段.报告编号}');
const modelValue = ref('${个人征信报告.报告头.报告头信息单元.报告标识信息段.报告编号} #{枚举}');
const click = () => {
//console.log(modelValue.value);
@ -30,7 +30,10 @@ const click = () => {
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/autoCompletionByIndicatorId/34e7391f-ba76-4e14-b152-ae0da917fd20'));
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByParameterId/34e7391f-ba76-4e14-b152-ae0da917fd20'));
userDefinedFunctionsManager.load();
console.log(Tools.escapeHtml('<xml>&</xml>'));
const matcheds = '${kdsf} #{aaa}'.match(/\$\{(.+?)\}|#\{(.+?)\}/g);
//console.log(matcheds);
</script>

226
io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/AutoCompletionManager.ts

@ -0,0 +1,226 @@
import { axios, Tools } from '@/platform';
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 {
console.log('>>>>');
const beforeMatched = context.matchBefore(/(.+?)/g);
console.log(beforeMatched);
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 {
console.log('????');
return (context: any) => {
return this.doAutoCompletion(context);
};
}
}
export { AutoCompletionManager };

136
io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/Maxgraph.vue

@ -3,29 +3,29 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, NotifyManager, Formater, EnumTools, $t } from '@/platform';
import { $t, axios, Environment, NotifyManager } from '@/platform';
import { AutoCompletionManager } from './AutoCompletionManager';
import { UserDefinedFunctionsManager } from './UserDefinedFunctionsManager';
import { PlaceHolder } from './PlaceHolder';
const dialogRef = ref();
const processorIdRef = ref();
const modelValueRef = ref('');
const userDefinedFunctionsRef = ref();
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
const resourceAbstractsRef = ref();
const modeAbstractsRef = ref();
const autoCompletion = (context) => {
return [];
};
const edgeDefines = [
{
type: 'EdgeConditionBranch',
fromVertexType: 'Condition',
toVertexType: null,
getLabel: (value) => {
getLabel: (value: any) => {
return value.value || '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
valueType: dom.getAttribute('valueType') || '',
@ -66,8 +66,9 @@ const edgeDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -90,10 +91,10 @@ const vertexDefines = [
shape: 'ellipse',
size: [50, 50],
},
getLabel: (value) => {
getLabel: (value: any) => {
return value.label;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
label: dom.getAttribute('label') || '',
@ -125,10 +126,10 @@ const vertexDefines = [
shape: 'rhombus',
size: [120, 60],
},
getLabel: (value) => {
return value.condition ? value.condition : '';
getLabel: (value: any) => {
return value.condition ? PlaceHolder.replace(value.condition) : '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
condition: dom.getAttribute('condition') || '',
@ -150,8 +151,9 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -169,12 +171,12 @@ const vertexDefines = [
shape: 'rectangle',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
let html = '';
html += '<div style="text-align:left;">' + value.commands + '</div>';
return html;
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
commands: dom.getAttribute('commands') || '',
@ -197,8 +199,8 @@ const vertexDefines = [
lineWrap: true,
lineBreak: true,
forceUpdate: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -218,14 +220,14 @@ const vertexDefines = [
shape: 'ellipse',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
return resourceAbstract.name + '(V' + resourceAbstract.version + ')';
}
return '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
const code = dom.getAttribute('code');
const version = dom.getAttribute('version');
@ -245,7 +247,7 @@ const vertexDefines = [
};
}
},
setValue: (dom, value) => {
setValue: (dom: any, value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
dom.setAttribute('code', resourceAbstract.code);
@ -261,7 +263,7 @@ const vertexDefines = [
name: 'resourceAbstractId',
label: $t('re.graph.vertex.resourceAbstract.entity.resourceAbstractId'),
type: 'w-grid-select',
displayValue: (args) => {
displayValue: (args: any) => {
return args.data.name + '(V' + args.data.version + ')';
},
grid: {
@ -271,7 +273,7 @@ const vertexDefines = [
configButton: true,
checkboxSelection: false,
tree: true,
treeIcon: (row) => {
treeIcon: (row: any) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
@ -284,7 +286,7 @@ const vertexDefines = [
},
dataUrl: Environment.apiContextPath('/api/re/resource'),
pageable: false,
sortBy: ['order', '-lastModifyDate'],
sortBy: ['type', 'namec', '-lastModifyDate'],
toolbarConfigure: { noIcon: false },
toolbarActions: ['refresh', 'expand'],
columns: [
@ -293,11 +295,6 @@ const vertexDefines = [
width: 80,
name: 'type',
label: $t('type'),
format: (value, row) => {
if (value !== 'FOLDER') {
return Formater.enum(Enums.ResourceType)(value);
}
},
},
{ width: 60, name: 'version', label: $t('version') },
{
@ -329,7 +326,7 @@ const vertexDefines = [
shape: 'doubleEllipse',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
let html = '<div style="text-align:left;">' + (value?.inputCommands || '') + '</div>';
html += '<hr/>';
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
@ -340,7 +337,7 @@ const vertexDefines = [
html += '<div style="text-align:left;">' + (value?.outputCommands || '') + '</div>';
return html;
},
getValue: (dom) => {
getValue: (dom: any) => {
let result = { resourceAbstractId: '', inputCommands: '', outputCommands: '' };
if (dom) {
const code = dom.getAttribute('code');
@ -354,7 +351,7 @@ const vertexDefines = [
}
return result;
},
setValue: (dom, value) => {
setValue: (dom: any, value: any) => {
const resourceAbstract = findResourceAbstractById(value.resourceAbstractId);
if (resourceAbstract) {
dom.setAttribute('code', resourceAbstract.code);
@ -372,7 +369,7 @@ const vertexDefines = [
name: 'resourceAbstractId',
label: $t('re.graph.vertex.configurableResourceAbstract.entity.resourceAbstractId'),
type: 'w-grid-select',
displayValue: (args) => {
displayValue: (args: any) => {
return args.data.name + (args.data.version ? '(V' + args.data.version + ')' : '');
},
grid: {
@ -382,7 +379,7 @@ const vertexDefines = [
configButton: true,
checkboxSelection: false,
tree: true,
treeIcon: (row) => {
treeIcon: (row: any) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
@ -395,7 +392,7 @@ const vertexDefines = [
},
dataUrl: Environment.apiContextPath('/api/re/resource'),
pageable: false,
sortBy: ['order', '-lastModifyDate'],
sortBy: ['type', 'namec', '-lastModifyDate'],
toolbarConfigure: { noIcon: false },
toolbarActions: ['refresh', 'expand'],
columns: [
@ -404,11 +401,6 @@ const vertexDefines = [
width: 80,
name: 'type',
label: $t('type'),
format: (value, row) => {
if (value !== 'FOLDER') {
return Formater.enum(Enums.ResourceType)(value);
}
},
},
{ width: 60, name: 'version', label: $t('version') },
{
@ -429,8 +421,9 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
{
name: 'outputCommands',
@ -441,8 +434,9 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
forceUpdate: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -462,7 +456,7 @@ const vertexDefines = [
shape: 'hexagon',
size: [120, 60],
},
getLabel: (value) => {
getLabel: (value: any) => {
for (const item of modeAbstractsRef.value) {
if (item.value === value.code) {
return item.label;
@ -470,7 +464,7 @@ const vertexDefines = [
}
return '';
},
getValue: (dom) => {
getValue: (dom: any) => {
if (dom) {
return {
code: dom.getAttribute('code') || '',
@ -494,7 +488,7 @@ const vertexDefines = [
},
];
const findResourceAbstractById = (id) => {
const findResourceAbstractById = (id: string) => {
for (const item of resourceAbstractsRef.value) {
if (item.id === id) {
return item;
@ -503,70 +497,48 @@ const findResourceAbstractById = (id) => {
return null;
};
const findResourceAbstractByCodeAndVersion = (code, version) => {
const findResourceAbstractByCodeAndVersion = (code: string, version: number) => {
for (const item of resourceAbstractsRef.value) {
if (item.code === code && item.version?.toString() === version) {
if (item.code === code && item.version.toString() === version) {
return item;
}
}
return null;
};
const open = async (parameterId, processorId) => {
const open = async (parameterId: string, processorId: string) => {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/parameterAndValueType/findByParameterId/' + parameterId));
userDefinedFunctionsManager.load();
processorIdRef.value = processorId;
//
const resourceAbstractResponse = await axios.get(Environment.apiContextPath('/api/re/resource/getAllReleasableResourceAbstract'));
const resourceAbstractResponse = await axios.get(Environment.apiContextPath('/api/re/resource/getAllResourceAbstract'));
resourceAbstractsRef.value = resourceAbstractResponse?.data;
//
const modelResponse = await axios.get(Environment.apiContextPath('/api/re/model/getModeAbstractByParameterProcessor/' + processorId));
const modelOptions = [];
const modelOptions = <any>[];
for (const item of modelResponse?.data || []) {
modelOptions.push({ label: item.name, value: item.code });
}
modeAbstractsRef.value = modelOptions;
//
const functionResponse = await axios.get(Environment.apiContextPath('/api/re/function?pageable=false'));
const functionOptions = [];
for (const item of functionResponse?.data?.content || []) {
if (item.enable) {
functionOptions.push(item);
}
}
userDefinedFunctionsRef.value = functionOptions;
//
const tipResponse = await axios.get(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + parameterId));
// autoCompletionManager.setParameters(tipResponse?.data?.parameters);
// autoCompletionManager.setValueTypes(tipResponse?.data?.valueTypes);
// graph xml
const graphResponse = await axios.get(Environment.apiContextPath('api/re/model/parameter/processor/getExecutionFlowById/' + processorIdRef.value));
modelValueRef.value = graphResponse?.data;
//
//dialogRef.value.show();
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
const save = (xml) => {
axios.post(Environment.apiContextPath('api/re/model/parameter/processor/saveExecutionFlowById/' + processorIdRef.value), { xml }).then((response) => {
NotifyManager.info($t('operationSuccess'));
});
};
const save = (xml: string) => {};
defineExpose({
open,
close,
});
const parameterId = '3b2e9e42-3e3e-4cd4-8071-a15fdfab54f3';
const processorId = '54d16aa3-1a2e-4c87-9f7a-e78ccbca5cdb';
open(parameterId, processorId);
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ResourceType', 'io.sc.engine.rule.core.enums.DeployStatus']);
</script>

18
io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/PlaceHolder.ts

@ -0,0 +1,18 @@
import { Tools } from '@/platform';
class PlaceHolder {
static #parameterPrefix: string = '<span class="p-0.5"><span class="p-0.5 border border-gray-800 rounded-md">';
static #enumPrefix: string = '<span class="p-0.5"><span class="p-0.5 border border-orange-400 rounded-md">';
static #suffix: string = '</span></span>';
public static replace(str: string) {
if (Tools.isString(str)) {
str = str.replace('<', '&lt;');
str = str.replace(/#\{(.+?)\}/g, PlaceHolder.#enumPrefix + '$1' + PlaceHolder.#suffix);
str = str.replace(/\$\{(.+?)\}/g, PlaceHolder.#parameterPrefix + '$1' + PlaceHolder.#suffix);
}
return str;
}
}
export { PlaceHolder };

23
io.sc.platform.core.frontend/template-project/src/views/testcase/maxgraph/UserDefinedFunctionsManager.ts

@ -0,0 +1,23 @@
import { ref } from 'vue';
import { axios, Environment, Tools } from '@/platform';
class UserDefinedFunctionsManager {
#functions: any;
constructor() {
this.#functions = ref([]);
}
public userDefinedFunctions(): any {
return this.#functions;
}
public async load() {
const response = await axios.get(Environment.apiContextPath('/api/re/function?pageable=false&sortBy=name'));
this.#functions.value = Tools.objects2Objects(response.data?.content, null, (obj: any) => {
return obj.enable;
});
}
}
export { UserDefinedFunctionsManager };

2
io.sc.platform.developer.doc/package.json

@ -28,7 +28,7 @@
"vuepress": "2.0.0-rc.15"
},
"dependencies": {
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"vue": "3.5.13",
"vue-i18n": "10.0.4"

1
io.sc.platform.developer.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.platform.developer.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

2
io.sc.platform.gradle/templates/pgp/setup/gradle.properties

@ -38,7 +38,7 @@ application_version=1.0.0
platform_group=io.sc
platform_version=8.2.5
platform_plugin_version=8.2.5
platform_core_frontend_version=8.2.22
platform_core_frontend_version=8.2.24
###########################################################
# dependencies version

1
io.sc.platform.lcdp.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.platform.lcdp.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

1
io.sc.platform.license.keygen.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.platform.license.keygen.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

1
io.sc.platform.mvc.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.platform.mvc.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

1
io.sc.platform.scheduler.manager.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.platform.scheduler.manager.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

1
io.sc.platform.system.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.platform.system.frontend/package.json

@ -110,7 +110,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

11
io.sc.platform.util/src/main/java/io/sc/platform/util/PlaceHolderExpressionUtil.java

@ -20,8 +20,8 @@ public class PlaceHolderExpressionUtil {
// 3. ${ccc}[1].${ddd}
// 4. ${eee}[1].${fff}[2]
// 5. ${ggg}[1].${hhh}[2].${iii}
private static final String PH_EXPRESSION_REG_PATTERN_STR = "(\\$ \\{ (.+?) \\})(\\[ (.+?) \\])?((\\[ (.+?) \\])?(\\.? (\\$ \\{ (.+?) \\})(\\[ (.+?) \\])?)+?)*";
//private static final String PH_EXPRESSION_REG_PATTERN_STR = "(\\$ \\{ (\\S+?) \\})(\\[ (\\S+?) \\])?((\\[ (\\S+?) \\])?(\\.? (\\$ \\{ (\\S+?) \\})(\\[ (\\S+?) \\])?)+?)*";
private static final String PH_EXPRESSION_REG_PATTERN_STR = "(\\$ \\{ (.+?) \\})(\\[ (.+?) \\])?((\\[ (.+?) \\])?(\\.? (\\$ \\{ (.+?) \\})(\\[ (.+?) \\])?)+?)*";
// --- --- ----- --- --- ----- --- --- ----- --- --- --- --- ----- --- --- ----- ---
// ($ { xxx } )([ nnn ] )?(([ nnn ] )?(.? ($ { xxx } )([ nnn ] )?)+?)*
// (${xxx} )([nnn] )?(([nnn] )?(.? (${xxx} )([nnn ] )?)+?)*
@ -29,16 +29,13 @@ public class PlaceHolderExpressionUtil {
// -------- ------- ? ------- - ------ -------
// (变量)([下标])?(([下标])?(.?(变量)([下标])?)+?)*
private static final Pattern PH_EXPRESSION_REG_PATTERN =Pattern.compile(StringUtils.trimAllWhitespace(PH_EXPRESSION_REG_PATTERN_STR));
private static final String PH_EXPRESSION_PART_REG_PATTERN_STR = "(\\$ \\{ (.+?) \\})(\\[ (.+?) \\])?";
//private static final String PH_EXPRESSION_PART_REG_PATTERN_STR = "(\\$ \\{ (\\S+?) \\})(\\[ (\\S+?) \\])?";
// --- --- ----- --- --- ----- --- --- ----- --- --- --- --- ----- --- --- ----- ---
private static final String PH_EXPRESSION_PART_REG_PATTERN_STR = "(\\$ \\{ (.+?) \\})(\\[ (.+?) \\])?";
// --- --- ----- --- --- ----- ---
// ($ { xxx } )([ nnn ] )?
// (${xxx})([nnn])?
private static final Pattern PH_EXPRESSION_PART_REG_PATTERN =Pattern.compile(StringUtils.trimAllWhitespace(PH_EXPRESSION_PART_REG_PATTERN_STR));
private static final Pattern PH_VARIABLE_REG_PATTERN =Pattern.compile("\\$\\{(.+?)\\}");
private static final Pattern PH_VARIABLE_ARRAY_INDEX_REG_PATTERN =Pattern.compile("\\[(.+?)\\]");
//private static final Pattern PH_VARIABLE_REG_PATTERN =Pattern.compile("\\$\\{(\\S+?)\\}");
//private static final Pattern PH_VARIABLE_ARRAY_INDEX_REG_PATTERN =Pattern.compile("\\[(\\S+?)\\]");
/**
* 将占位符表达式替换为非占位符表达式,示例:

1
io.sc.standard.frontend/.eslintrc.cjs

@ -66,5 +66,6 @@ module.exports = {
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
'vue/no-v-html': 'off'
},
};

2
io.sc.standard.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.4",
"pinia": "2.2.6",
"pinia-undo": "0.2.4",
"platform-core": "8.2.24",
"platform-core": "8.2.28",
"quasar": "2.17.4",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.5",

2
io.sc.website/package.json

@ -28,6 +28,6 @@
},
"dependencies": {
"vue": "3.5.13",
"platform-core": "8.2.24"
"platform-core": "8.2.28"
}
}
Loading…
Cancel
Save