Browse Source

后端发布: 8.2.11

前端发布: 8.2.65
main
wangshaoping 3 weeks ago
parent
commit
c78e556515
  1. 3
      app.engine.rule/build.gradle
  2. 4
      erm.frontend/package.json
  3. 11
      erm.frontend/webpack.config.mf.cjs
  4. 4
      gradle.properties
  5. 8
      io.sc.creditreport.core/src/main/java/io/sc/creditreport/core/CreditReportParser.java
  6. 4
      io.sc.engine.mv.frontend/package.json
  7. 11
      io.sc.engine.mv.frontend/webpack.config.mf.cjs
  8. 1
      io.sc.engine.rule.core/build.gradle
  9. 88
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/WebRequest.java
  10. 40
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/WebResponse.java
  11. 1
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/ExecuteUnit4LibGenerator.java
  12. 2
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/ExecuteUnit4ResourceGenerator.java
  13. 55
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/IndicatorGenerator.java
  14. 68
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/ParameterGenerator.java
  15. 77
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/processor/HttpRequest.java
  16. 9
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/processor/SqlFieldMapping.java
  17. 23
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/impl/resource.tpl
  18. 1
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/lib_render.tpl
  19. 22
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/parameter_render.tpl
  20. 1
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/processor/http_request.tpl
  21. 13
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/ValueTypeUtil.java
  22. 89
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/WebRequestUtil.java
  23. 10
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/dictionary_render.tpl
  24. 33
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/dictionary/dictionary.ftl
  25. 6
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/functions.ftl
  26. 115
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/groovy.ftl
  27. 115
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib/lib.ftl
  28. 201
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib_groovy.ftl
  29. 153
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/argument.ftl
  30. 228
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/model.ftl
  31. 25
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/sub-model.ftl
  32. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/ARITHMETIC.ftl
  33. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/CONDITION_RANGE.ftl
  34. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TABLE.ftl
  35. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TABLE_2C.ftl
  36. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TREE.ftl
  37. 13
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TREE_FUNCTION.ftl
  38. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/EXECUTION_FLOW.ftl
  39. 13
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/EXECUTION_FLOW_FUNCTION.ftl
  40. 3
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/GROOVY_SCRIPT.ftl
  41. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/MATH_FORMULA.ftl
  42. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/NUMBER_RANGE.ftl
  43. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/OBJECT_PROPERTIES.ftl
  44. 34
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/OPTION_VALUE.ftl
  45. 3
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/PMML.ftl
  46. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/RULE.ftl
  47. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/SINGLE_RULE.ftl
  48. 17
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/SQL.ftl
  49. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/TERNARY.ftl
  50. 12
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/WHEN_THEN.ftl
  51. 11
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/resource_groovy.ftl
  52. 89
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/scorecard/argument.ftl
  53. 147
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/scorecard/score_card.ftl
  54. 6
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/impl/lib.tpl
  55. 33
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/impl/resource.tpl
  56. 22
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/import_render.tpl
  57. 1
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/lib_render.tpl
  58. 22
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/parameter_render.tpl
  59. 1
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/processor/http_request.tpl
  60. 4
      io.sc.engine.rule.frontend/package.json
  61. 317
      io.sc.engine.rule.frontend/src/views/shared/processors/HttpRequest.ts
  62. 15
      io.sc.engine.rule.frontend/src/views/shared/processors/Sql.ts
  63. 11
      io.sc.engine.rule.frontend/webpack.config.mf.cjs
  64. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/controller/ParameterAndValueTypeWebController.java
  65. 16
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/controller/IndicatorProcessorWebController.java
  66. 5
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/IndicatorProcessorService.java
  67. 30
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/IndicatorProcessorServiceImpl.java
  68. 15
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/HttpRequestParameterProcessorEntity.java
  69. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ParameterProcessorService.java
  70. 20
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterProcessorServiceImpl.java
  71. 7
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/support/processor/SqlQueryRequest.java
  72. 4
      io.sc.engine.st.frontend/package.json
  73. 11
      io.sc.engine.st.frontend/webpack.config.mf.cjs
  74. 4
      io.sc.platform.ai.frontend/package.json
  75. 11
      io.sc.platform.ai.frontend/webpack.config.mf.cjs
  76. 9
      io.sc.platform.core.frontend/.bin/sync.js
  77. 2
      io.sc.platform.core.frontend/package.json
  78. 4
      io.sc.platform.core.frontend/src/components/index.ts
  79. 1
      io.sc.platform.core.frontend/src/i18n/messages.json
  80. 1
      io.sc.platform.core.frontend/src/i18n/messages_tw_CN.json
  81. 1
      io.sc.platform.core.frontend/src/i18n/messages_zh_CN.json
  82. 9
      io.sc.platform.core.frontend/src/menus/menus.json
  83. 35
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/Topper.vue
  84. 12
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/ViewTaskDialog.vue
  85. 215
      io.sc.platform.core.frontend/src/platform/plugin/environment/default-configure.json
  86. 1
      io.sc.platform.core.frontend/src/platform/types/ConfigureType.ts
  87. 10
      io.sc.platform.core.frontend/src/routes/routes.json
  88. 4
      io.sc.platform.core.frontend/src/views/testcase/global-route/GlobalRoute.vue
  89. 4
      io.sc.platform.core.frontend/template-project/package.json
  90. 2
      io.sc.platform.core.frontend/template-project/src/components/index.ts
  91. 1
      io.sc.platform.core.frontend/template-project/src/i18n/messages.json
  92. 1
      io.sc.platform.core.frontend/template-project/src/i18n/messages_tw_CN.json
  93. 1
      io.sc.platform.core.frontend/template-project/src/i18n/messages_zh_CN.json
  94. 9
      io.sc.platform.core.frontend/template-project/src/menus/menus.json
  95. 12
      io.sc.platform.core.frontend/template-project/src/routes/routes.json
  96. 11
      io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs
  97. 11
      io.sc.platform.core.frontend/webpack.config.mf.cjs
  98. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  99. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  100. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties

3
app.engine.rule/build.gradle

@ -13,6 +13,7 @@ dependencies {
implementation (
project(":io.sc.platform.app"),
project(":io.sc.platform.developer"),
project(":io.sc.standard"),
project(":io.sc.platform.scheduler.manager"),
project(":io.sc.platform.scheduler.executor"),
@ -26,6 +27,8 @@ dependencies {
project(":io.sc.engine.rule.core"),
project(":io.sc.engine.rule.server"),
project(":io.sc.engine.rule.sample"),
project(":io.sc.platform.ai"),
)
}

4
erm.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "erm.frontend",
"version": "8.2.11",
"version": "8.2.13",
"description": "",
"private": false,
"keywords": [],
@ -112,7 +112,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.65",
"platform-core": "8.2.70",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

11
erm.frontend/webpack.config.mf.cjs

@ -9,13 +9,20 @@ const projectName = packageJson.name; // 项目名称
const deps = packageJson.dependencies; // 项目依赖
// 读取本地路由配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const data = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(data);
const routesJson = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(routesJson);
const mfExposes = {};
for (const route of routes) {
mfExposes[route.component] = route.componentPath;
}
// 读取远程组件配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const remoteComponentsJson = fs.readFileSync('./src/remote-components/remote-components.json', 'utf8');
const remoteComponents = Json5.parse(remoteComponentsJson);
for (const remoteComponent of remoteComponents) {
mfExposes[remoteComponent.component] = remoteComponent.componentPath;
}
// 导出 webapck 配置的模块联邦部分
module.exports = {
plugins: [

4
gradle.properties

@ -37,9 +37,9 @@ application_version=1.0.0
# platform
###########################################################
platform_group=io.sc
platform_version=8.2.11
platform_version=8.2.13
platform_plugin_version=8.2.10
platform_core_frontend_version=8.2.65
platform_core_frontend_version=8.2.70
###########################################################
# dependencies version

8
io.sc.creditreport.core/src/main/java/io/sc/creditreport/core/CreditReportParser.java

@ -2,13 +2,21 @@ package io.sc.creditreport.core;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.sc.platform.util.ObjectMapperUtil;
import org.springframework.util.StringUtils;
public class CreditReportParser {
public static io.sc.creditreport.core.person.Document parsePersonCreditReport(String xml) throws JsonProcessingException {
if(StringUtils.hasText(xml)) {
return ObjectMapperUtil.xml().readValue(xml, io.sc.creditreport.core.person.Document.class);
}
return null;
}
public static io.sc.creditreport.core.company.Document parseCompanyCreditReport(String xml) throws JsonProcessingException {
System.out.println(">>>>>>>>>>>>" + xml);
if(StringUtils.hasText(xml)) {
return ObjectMapperUtil.xml().readValue(xml, io.sc.creditreport.core.company.Document.class);
}
return null;
}
}

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.mv.frontend",
"version": "8.2.11",
"version": "8.2.13",
"description": "",
"private": false,
"keywords": [],
@ -112,7 +112,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.65",
"platform-core": "8.2.70",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

11
io.sc.engine.mv.frontend/webpack.config.mf.cjs

@ -9,13 +9,20 @@ const projectName = packageJson.name; // 项目名称
const deps = packageJson.dependencies; // 项目依赖
// 读取本地路由配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const data = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(data);
const routesJson = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(routesJson);
const mfExposes = {};
for (const route of routes) {
mfExposes[route.component] = route.componentPath;
}
// 读取远程组件配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const remoteComponentsJson = fs.readFileSync('./src/remote-components/remote-components.json', 'utf8');
const remoteComponents = Json5.parse(remoteComponentsJson);
for (const remoteComponent of remoteComponents) {
mfExposes[remoteComponent.component] = remoteComponent.componentPath;
}
// 导出 webapck 配置的模块联邦部分
module.exports = {
plugins: [

1
io.sc.engine.rule.core/build.gradle

@ -28,5 +28,6 @@ dependencies {
"org.jpmml:pmml-evaluator:${jpmml_version}",
"org.jpmml:pmml-evaluator-extension:${jpmml_version}",
"com.belerweb:pinyin4j:${pinyin4j_version}",
"com.squareup.okhttp3:okhttp:${okhttp_version}"
)
}

88
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/WebRequest.java

@ -0,0 +1,88 @@
package io.sc.engine.rule.core;
import io.sc.engine.rule.core.enums.HttpAuthorizationType;
import io.sc.engine.rule.core.enums.HttpMethodType;
public class WebRequest {
private HttpMethodType httpMethod;
private String httpUrl;
private HttpAuthorizationType httpAuthType;
private String httpAuthApikey;
private String httpAuthApiValue;
private String httpAuthBasicUsername;
private String httpAuthBasicPassword;
private String httpAuthBearerToken;
private String httpRequestBody;
public HttpMethodType getHttpMethod() {
return httpMethod;
}
public void setHttpMethod(HttpMethodType httpMethod) {
this.httpMethod = httpMethod;
}
public String getHttpUrl() {
return httpUrl;
}
public void setHttpUrl(String httpUrl) {
this.httpUrl = httpUrl;
}
public HttpAuthorizationType getHttpAuthType() {
return httpAuthType;
}
public void setHttpAuthType(HttpAuthorizationType httpAuthType) {
this.httpAuthType = httpAuthType;
}
public String getHttpAuthApikey() {
return httpAuthApikey;
}
public void setHttpAuthApikey(String httpAuthApikey) {
this.httpAuthApikey = httpAuthApikey;
}
public String getHttpAuthApiValue() {
return httpAuthApiValue;
}
public void setHttpAuthApiValue(String httpAuthApiValue) {
this.httpAuthApiValue = httpAuthApiValue;
}
public String getHttpAuthBasicUsername() {
return httpAuthBasicUsername;
}
public void setHttpAuthBasicUsername(String httpAuthBasicUsername) {
this.httpAuthBasicUsername = httpAuthBasicUsername;
}
public String getHttpAuthBasicPassword() {
return httpAuthBasicPassword;
}
public void setHttpAuthBasicPassword(String httpAuthBasicPassword) {
this.httpAuthBasicPassword = httpAuthBasicPassword;
}
public String getHttpAuthBearerToken() {
return httpAuthBearerToken;
}
public void setHttpAuthBearerToken(String httpAuthBearerToken) {
this.httpAuthBearerToken = httpAuthBearerToken;
}
public String getHttpRequestBody() {
return httpRequestBody;
}
public void setHttpRequestBody(String httpRequestBody) {
this.httpRequestBody = httpRequestBody;
}
}

40
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/WebResponse.java

@ -0,0 +1,40 @@
package io.sc.engine.rule.core;
public class WebResponse {
private boolean successful;
private int status;
private String error;
private String content;
public boolean getSuccessful() {
return successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

1
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/ExecuteUnit4LibGenerator.java

@ -53,6 +53,7 @@ public class ExecuteUnit4LibGenerator extends ExecuteUnitGenerator {
engine.addSharedObject("ObjectProperty",new ObjectProperty());
engine.addSharedObject("OptionValue",new OptionValue());
engine.addSharedObject("SqlFieldMapping",new SqlFieldMapping());
engine.addSharedObject("HttpRequest",new HttpRequest());
engine.addSharedObject("Ternary",new Ternary());
engine.addSharedObject("WhenThen",new WhenThen());

2
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/ExecuteUnit4ResourceGenerator.java

@ -24,6 +24,7 @@ public class ExecuteUnit4ResourceGenerator extends ExecuteUnitGenerator {
if(resource instanceof ModelResource){
((ModelResource)resource).getModel().buildFullName();
}
}
@Override
@ -58,6 +59,7 @@ public class ExecuteUnit4ResourceGenerator extends ExecuteUnitGenerator {
engine.addSharedObject("ObjectProperty",new ObjectProperty());
engine.addSharedObject("OptionValue",new OptionValue());
engine.addSharedObject("SqlFieldMapping",new SqlFieldMapping());
engine.addSharedObject("HttpRequest",new HttpRequest());
engine.addSharedObject("Ternary",new Ternary());
engine.addSharedObject("WhenThen",new WhenThen());
engine.addSharedObject("ScoreCard",new ScoreCard());

55
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/IndicatorGenerator.java

@ -29,29 +29,43 @@ public class IndicatorGenerator {
String name =indicator.getName();
String valueType =indicator.getValueType();
Integer valueTypeVersion =indicator.getValueTypeVersion();
Boolean valueTypeIsList =indicator.getValueTypeIsList();
String defaultValue =indicator.getDefaultValue();
Map<String,Object> variables =new HashMap<>();
variables.put("name",name);
variables.put("fieldName", IdReplacer.fieldName(code));
variables.put("defaultValue",defaultValue);
if(ValueTypeUtil.isString(valueType)){
if(StringUtils.hasText(defaultValue)){
if(StringUtils.hasText(defaultValue)) { // 有默认值
if (valueTypeIsList != null && valueTypeIsList) { //列表
variables.put("className", IdReplacer.className(valueType, valueTypeVersion));
String tpl = "List<${className}> ${fieldName} =ObjectMapperUtil.json().readValue(\"\"\"${defaultValue}\"\"\",new TypeReference<List<${className}>>(){}); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
} else { //非列表
if (ValueTypeUtil.isBase(valueType)) { // 基本类型
if (ValueTypeUtil.isString(valueType)) { // 字符串
String tpl ="String ${fieldName} =\"\"\"${defaultValue}\"\"\"; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
}else{
String tpl ="String ${fieldName}; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
} else { // 非字符串
variables.put("className", IdReplacer.className(valueType, valueTypeVersion));
String tpl = "${className} ${fieldName} =${defaultValue}; //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}
}else{
if(StringUtils.hasText(defaultValue)){
} else { // 非基本类型
variables.put("className", IdReplacer.className(valueType, valueTypeVersion));
String tpl = "${className} ${fieldName} =ObjectMapperUtil.json().readValue(\"\"\"${defaultValue}\"\"\",${className}.class); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}
}
}else{ // 无默认值
variables.put("className",IdReplacer.className(valueType,valueTypeVersion));
String tpl ="${className} ${fieldName} =${defaultValue}; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
if (ValueTypeUtil.isBase(valueType)) { // 基本类型
String tpl = "${className} ${fieldName}; //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}else{
variables.put("className",IdReplacer.className(valueType,valueTypeVersion));
String tpl ="${className} ${fieldName}; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
String tpl = "${className} ${fieldName} =new ${className}(); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}
}
}
@ -70,22 +84,25 @@ public class IndicatorGenerator {
Integer valueTypeVersion = indicator.getValueTypeVersion();
Map<String,Object> variables =new HashMap<>();
variables.put("prefix",prefix);
variables.put("code",code);
variables.put("name",name);
variables.put("fieldName",IdReplacer.fieldName(code));
variables.put("className",IdReplacer.className(valueType,valueTypeVersion));
if (indicator.getValueTypeIsList()) {
String tpl ="${prefix}.${fieldName} =TypeConvertor.getValue(map.get('${code}'),new TypeReference<List<${className}>>(){}); //${name}";
sb.append(StringUtil.format("if (map.get('${code}')!=null) {\n",variables));
String tpl ="\targ.${fieldName} =ObjectMapperUtil.json().readValue(map.get('${code}'),new TypeReference<List<${className}>>(){}); //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
sb.append("}").append("\n");
} else {
String tpl ="${prefix}.${fieldName} =TypeConvertor.getValue(map.get('${code}'),${className}.class); //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
}
if (!ValueTypeUtil.isBase(valueType)) {
String tpl ="if(${prefix}.${fieldName}!=null) { ${prefix}.${fieldName}.init(); }";
sb.append(StringUtil.format("if (map.get('${code}')!=null) {\n",variables));
String tpl ="\targ.${fieldName} =TypeConvertor.getValue(map.get('${code}'),${className}.class); //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
sb.append("}").append("\n");
}
// if (!ValueTypeUtil.isBase(valueType)) {
// String tpl ="if(arg.${fieldName}!=null) { arg.${fieldName}.init(); }";
// sb.append(StringUtil.format(tpl,variables)).append("\n");
// }
}
return sb.toString();
}

68
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/ParameterGenerator.java

@ -33,29 +33,41 @@ public class ParameterGenerator {
variables.put("name",name);
variables.put("fieldName",IdReplacer.fieldName(code));
variables.put("defaultValue",defaultValue);
if(ValueTypeUtil.isString(valueType)){
if(StringUtils.hasText(defaultValue)){
String tpl ="String ${fieldName} =\"\"\"${defaultValue}\"\"\"; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
}else{
String tpl ="String ${fieldName}; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
}
}else{
if(StringUtils.hasText(defaultValue)){
if(valueTypeIsList!=null && valueTypeIsList){
if(StringUtils.hasText(defaultValue)) { // 有默认值
if (valueTypeIsList != null && valueTypeIsList) { //列表
variables.put("className", IdReplacer.className(valueType, valueTypeVersion));
String tpl = "List<${className}> ${fieldName} =ObjectMapperUtil.json().readValue(\"\"\"${defaultValue}\"\"\",new TypeReference<List<${className}>>(){}); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}else {
} else { //非列表
if (ValueTypeUtil.isBase(valueType)) { // 基本类型
if (ValueTypeUtil.isString(valueType)) { // 字符串
String tpl ="String ${fieldName} =\"\"\"${defaultValue}\"\"\"; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
} else { // 非字符串
variables.put("className", IdReplacer.className(valueType, valueTypeVersion));
String tpl = "${className} ${fieldName} =${defaultValue}; //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}
}else{
} else { // 非基本类型
variables.put("className", IdReplacer.className(valueType, valueTypeVersion));
String tpl = "${className} ${fieldName} =ObjectMapperUtil.json().readValue(\"\"\"${defaultValue}\"\"\",${className}.class); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}
}
}else{ // 无默认值
variables.put("className",IdReplacer.className(valueType,valueTypeVersion));
String tpl ="${className} ${fieldName}; //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
if (ValueTypeUtil.isBase(valueType)) { // 基本类型
String tpl = "${className} ${fieldName}; //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}else{
if(ValueTypeUtil.isMap(valueType)) {
String tpl = "${className} ${fieldName} =new java.util.HashMap(); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}else{
String tpl = "${className} ${fieldName} =new ${className}(); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
}
}
}
}
@ -82,16 +94,26 @@ public class ParameterGenerator {
variables.put("fieldName",IdReplacer.fieldName(code));
variables.put("className",IdReplacer.className(valueType,valueTypeVersion));
if (parameter.getValueTypeIsList()) {
String tpl ="arg.${fieldName} =TypeConvertor.getValue(map.get('${code}'),new TypeReference<List<${className}>>(){}); //${name}";
sb.append(StringUtil.format("if (map.get('${code}')!=null) {\n",variables));
String tpl ="\targ.${fieldName} =ObjectMapperUtil.json().readValue(map.get('${code}'),new TypeReference<List<${className}>>(){}); //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
sb.append("}").append("\n");
} else {
String tpl ="arg.${fieldName} =TypeConvertor.getValue(map.get('${code}'),${className}.class); //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
sb.append(StringUtil.format("if (map.get('${code}')!=null) {\n",variables));
if (ValueTypeUtil.isBase(valueType)) {
String tpl = "\targ.${fieldName} =TypeConvertor.getValue(map.get('${code}'),${className}.class); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
sb.append("}").append("\n");
}else{
String tpl = "\targ.${fieldName} =ObjectMapperUtil.json().readValue(map.get('${code}'),${className}.class); //${name}";
sb.append(StringUtil.format(tpl, variables)).append("\n");
sb.append("}").append("\n");
}
if (!ValueTypeUtil.isBase(valueType)) {
String tpl ="if(arg.${fieldName}!=null) { arg.${fieldName}.init(); }";
sb.append(StringUtil.format(tpl,variables)).append("\n");
}
// if (!ValueTypeUtil.isBase(valueType)) {
// String tpl ="if(arg.${fieldName}!=null) { arg.${fieldName}.init(); }";
// sb.append(StringUtil.format(tpl,variables)).append("\n");
// }
}
return sb.toString();
}
@ -110,8 +132,8 @@ public class ParameterGenerator {
variables.put("fieldName",IdReplacer.fieldName(code));
variables.put("name",name);
if (!ValueTypeUtil.isBase(valueType)) {
String tpl ="if(arg.${fieldName}!=null) { arg.${fieldName}.init(); } //${name}";
sb.append(StringUtil.format(tpl,variables)).append("\n");
// String tpl ="if(arg.${fieldName}!=null) { arg.${fieldName}.init(); } //${name}";
// sb.append(StringUtil.format(tpl,variables)).append("\n");
}
}
return sb.toString();

77
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/processor/HttpRequest.java

@ -0,0 +1,77 @@
package io.sc.engine.rule.core.code.generator.impl.processor;
import io.sc.engine.rule.core.enums.HttpAuthorizationType;
import io.sc.engine.rule.core.po.lib.Indicator;
import io.sc.engine.rule.core.po.lib.processor.HttpRequestIndicatorProcessor;
import io.sc.engine.rule.core.po.model.Parameter;
import io.sc.engine.rule.core.po.model.processor.HttpRequestParameterProcessor;
import io.sc.engine.rule.core.util.GroovyExpressionReplacer;
import io.sc.platform.util.StringUtil;
public class HttpRequest {
public String groovy(Parameter parameter, HttpRequestParameterProcessor processor) throws Exception{
if(parameter==null || processor==null){ return null; }
try {
StringBuilder sb =new StringBuilder();
sb.append("{").append("\n");
sb.append("\tio.sc.engine.rule.core.WebRequest request =new io.sc.engine.rule.core.WebRequest();\n");
sb.append("\trequest.setHttpMethod(").append("io.sc.engine.rule.core.enums.HttpMethodType.").append(processor.getHttpMethod()).append(");\n");
sb.append("\trequest.setHttpUrl(").append(StringUtil.format("${0}", GroovyExpressionReplacer.groovy(processor.getHttpUrl(),String.class.getName()))).append(");\n");
if(processor.getHttpAuthType()!=null) {
sb.append("\trequest.setHttpAuthType(").append("io.sc.engine.rule.core.enums.HttpAuthorizationType.").append(processor.getHttpAuthType()).append(");\n");
if(HttpAuthorizationType.BASIC_AUTH.equals(processor.getHttpAuthType())){
sb.append("\trequest.setHttpAuthBasicUsername(").append(processor.getHttpAuthBasicUsername()).append(");\n");
sb.append("\trequest.setHttpAuthBasicPassword(").append(processor.getHttpAuthBasicPassword()).append(");\n");
}else if(HttpAuthorizationType.API_KEY.equals(processor.getHttpAuthType())){
sb.append("\trequest.setHttpAuthApikey(").append(processor.getHttpAuthApikey()).append(");\n");
sb.append("\trequest.setHttpAuthApiValue(").append(processor.getHttpAuthApiValue()).append(");\n");
}else if(HttpAuthorizationType.BEARER.equals(processor.getHttpAuthType())){
sb.append("\trequest.setHttpAuthBearerToken(").append(StringUtil.format("${0}", GroovyExpressionReplacer.groovy(processor.getHttpAuthBearerToken(),String.class.getName()))).append(");\n");
}
}else{
sb.append("\trequest.setHttpAuthType(").append("io.sc.engine.rule.core.enums.HttpAuthorizationType.NONE);\n");
}
sb.append("\tio.sc.engine.rule.core.WebResponse response =io.sc.engine.rule.core.util.WebRequestUtil.sendWebRequest(request);\n");
String groovy =StringUtil.tabs(processor.getHttpResponseMapping().replace("${response}","response"),1);
groovy =GroovyExpressionReplacer.groovy(groovy);
sb.append("\t").append(groovy).append("\n");
sb.append("}").append("\n");
return sb.toString();
}catch(Exception e) {
throw new RuntimeException("There was a Error when generate " + parameter.getName()+ "'s HttpRequest groovy source code.", e);
}
}
public String groovy(Indicator indicator, HttpRequestIndicatorProcessor processor) throws Exception{
if(indicator==null || processor==null){ return null; }
try {
StringBuilder sb =new StringBuilder();
sb.append("{").append("\n");
sb.append("\tio.sc.engine.rule.core.WebRequest request =new io.sc.engine.rule.core.WebRequest();\n");
sb.append("\trequest.setHttpMethod(").append("io.sc.engine.rule.core.enums.HttpMethodType.").append(processor.getHttpMethod()).append(");\n");
sb.append("\trequest.setHttpUrl(").append(StringUtil.format("${0}", GroovyExpressionReplacer.groovy(processor.getHttpUrl(),String.class.getName()))).append(");\n");
if(processor.getHttpAuthType()!=null) {
sb.append("\trequest.setHttpAuthType(").append("io.sc.engine.rule.core.enums.HttpAuthorizationType.").append(processor.getHttpAuthType()).append(");\n");
if(HttpAuthorizationType.BASIC_AUTH.equals(processor.getHttpAuthType())){
sb.append("\trequest.setHttpAuthBasicUsername(").append(processor.getHttpAuthBasicUsername()).append(");\n");
sb.append("\trequest.setHttpAuthBasicPassword(").append(processor.getHttpAuthBasicPassword()).append(");\n");
}else if(HttpAuthorizationType.API_KEY.equals(processor.getHttpAuthType())){
sb.append("\trequest.setHttpAuthApikey(").append(processor.getHttpAuthApikey()).append(");\n");
sb.append("\trequest.setHttpAuthApiValue(").append(processor.getHttpAuthApiValue()).append(");\n");
}else if(HttpAuthorizationType.BEARER.equals(processor.getHttpAuthType())){
sb.append("\trequest.setHttpAuthBearerToken(").append(StringUtil.format("${0}", GroovyExpressionReplacer.groovy(processor.getHttpAuthBearerToken(),String.class.getName()))).append(");\n");
}
}else{
sb.append("\trequest.setHttpAuthType(").append("io.sc.engine.rule.core.enums.HttpAuthorizationType.NONE);\n");
}
sb.append("\tio.sc.engine.rule.core.WebResponse response =io.sc.engine.rule.core.util.WebRequestUtil.sendWebRequest(request);\n");
String groovy =StringUtil.tabs(processor.getHttpResponseMapping().replace("${response}","response"),1);
groovy =GroovyExpressionReplacer.groovy(groovy);
sb.append("\t").append(groovy).append("\n");
sb.append("}").append("\n");
return sb.toString();
}catch(Exception e) {
throw new RuntimeException("There was a Error when generate " + indicator.getName()+ "'s HttpRequest groovy source code.", e);
}
}
}

9
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/generator/impl/processor/SqlFieldMapping.java

@ -11,6 +11,7 @@ import io.sc.engine.rule.core.util.GroovyExpressionReplacer;
import io.sc.engine.rule.core.util.IdReplacer;
import io.sc.platform.util.CollectionUtil;
import io.sc.platform.util.ObjectMapperUtil;
import io.sc.platform.util.PlaceHolderExpressionUtil;
import io.sc.platform.util.StringUtil;
import org.springframework.util.StringUtils;
@ -59,10 +60,10 @@ public class SqlFieldMapping {
sb.append("\t").append("db.query(sql) { rs ->").append("\n");
sb.append("\t\t").append("if (rs.next()) {").append("\n");
for(SqlFieldMapping sqlFieldMapping : sqlFieldMappings) {
sb.append("\t\t\t")
.append(ExpressionReplacer.groovy(IdReplacer.fieldName(sqlFieldMapping.parameter), null))
.append(" =")
.append("rs.getObject(\"").append(sqlFieldMapping.getField()).append("\");").append("\n");
sb.append("\t\t\t");
sb.append(PlaceHolderExpressionUtil.replace(sqlFieldMapping.parameter, "arg.",""));
sb.append(" =");
sb.append("rs.getObject(\"").append(sqlFieldMapping.getField()).append("\");").append("\n");
}
sb.append("\t\t}").append("\n");
sb.append("\t}").append("\n");

23
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/impl/resource.tpl

@ -133,6 +133,29 @@ class #(className(resource.code,resource.version)) {
}
#@renderModel(model)
### 决策树函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("DECISION_TREE"==processor.type.toString())
//决策树函数: #(parameter.name)(#(parameter.type))
#(DecisionTree.groovy(parameter,processor))
#end
#end
#end
#end
### 执行流函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("EXECUTION_FLOW"==processor.type.toString())
//执行流函数: #(parameter.name)(#(parameter.type))
#(tabs(ExecutionFlow.groovy(parameter,processor),1))
#end
#end
#end
#end
}
//******************************************************************************

1
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/lib_render.tpl

@ -6,6 +6,7 @@ class #(className(lib.code,lib.version)) {
//通过输入参数构建指标库对象
public void convertArgument(Map<String,Object> map){
#(className(lib.code,lib.version)) arg =this;
#(tabs(IndicatorGenerator.generateConvertorFromMap(lib.indicators,"this"),2))
}

22
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/parameter_render.tpl

@ -100,26 +100,4 @@
#end
#end
### 决策树函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("DECISION_TREE"==processor.type.toString())
//决策树函数: #(parameter.name)(#(parameter.type))
#(DecisionTree.groovy(parameter,processor))
#end
#end
#end
#end
### 执行流函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("EXECUTION_FLOW"==processor.type.toString())
//执行流函数: #(parameter.name)(#(parameter.type))
#(tabs(ExecutionFlow.groovy(parameter,processor),1))
#end
#end
#end
#end
#end

1
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/template/processor/http_request.tpl

@ -0,0 +1 @@
#(tabs(HttpRequest.groovy(parameter,processor),2))

13
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/ValueTypeUtil.java

@ -74,10 +74,23 @@ public class ValueTypeUtil {
return List.class.isAssignableFrom(clazz);
}
public static boolean isList(String type){
try {
return List.class.isAssignableFrom(Class.forName(type));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static boolean isMap(Class<?> clazz){
return Map.class.isAssignableFrom(clazz);
}
public static boolean isMap(String type){
return "java.util.Map".equals(type) || "java.util.HashMap".equals(type);
}
public static String getSimpleName(Class<?> type) {
return getSimpleName(type.getName());
}

89
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/WebRequestUtil.java

@ -0,0 +1,89 @@
package io.sc.engine.rule.core.util;
import groovy.json.JsonSlurper;
import io.sc.engine.rule.core.WebRequest;
import io.sc.engine.rule.core.WebResponse;
import io.sc.engine.rule.core.enums.HttpAuthorizationType;
import io.sc.engine.rule.core.enums.HttpMethodType;
import io.sc.platform.util.StringUtil;
import okhttp3.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Base64;
import java.util.Map;
public class WebRequestUtil {
public static WebResponse sendWebRequest(WebRequest webRequest) {
try {
Headers.Builder headerBuilder = new Headers.Builder().add("Content-Type: application/json");
HttpAuthorizationType httpAuthType =webRequest.getHttpAuthType();
if(httpAuthType==null){
httpAuthType =HttpAuthorizationType.NONE;
}
switch (httpAuthType) {
case NONE:
break;
case API_KEY:
headerBuilder.add(webRequest.getHttpAuthApikey() + "=" + webRequest.getHttpAuthApiValue());
break;
case BASIC_AUTH:
headerBuilder.add("Authorization:Basic " + Base64.getEncoder().encodeToString(webRequest.getHttpAuthBasicUsername().getBytes(StandardCharsets.UTF_8)) + Base64.getEncoder().encodeToString(webRequest.getHttpAuthBasicPassword().getBytes(StandardCharsets.UTF_8)));
break;
case BEARER:
headerBuilder.add("Authorization: Bearer " + webRequest.getHttpAuthBearerToken());
break;
}
Headers headers = headerBuilder.build();
okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder().url(webRequest.getHttpUrl()).headers(headers);
if (HttpMethodType.GET.equals(webRequest.getHttpMethod())) {
requestBuilder.get();
}else if(HttpMethodType.POST.equals(webRequest.getHttpMethod())){
RequestBody body = RequestBody.create(webRequest.getHttpRequestBody(), MediaType.parse("application/json; charset=utf-8"));
requestBuilder.post(body);
}
Request request = requestBuilder.build();
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(Duration.ofSeconds(60))
.readTimeout(Duration.ofSeconds(60))
.writeTimeout(Duration.ofSeconds(60))
.build();
client.dispatcher().setMaxRequests(64);
client.dispatcher().setMaxRequestsPerHost(6);
Call call = client.newCall(request);
Response response = call.execute();
WebResponse result = new WebResponse();
if(response.isSuccessful()) {
result.setSuccessful(response.isSuccessful());
result.setStatus(response.code());
result.setError(null);
result.setContent(response.body().string());
return result;
}else{
result.setSuccessful(response.isSuccessful());
result.setStatus(response.code());
result.setError("Error occured!");
return result;
}
}catch (Exception e){
WebResponse result = new WebResponse();
result.setSuccessful(false);
result.setStatus(500);
result.setError(StringUtil.getStackTrace(e));
return result;
}
}
public static void main(String[] args) {
WebRequest webRequest =new WebRequest();
webRequest.setHttpMethod(HttpMethodType.GET);
webRequest.setHttpUrl("http://localhost:8090/api/re/resource/getDefineByCode?code=M1744084117959");
webRequest.setHttpAuthType(HttpAuthorizationType.BEARER);
webRequest.setHttpAuthBearerToken("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJjb3Jwb3JhdGlvbkNvZGUiOiJfUFJJTUFSWV8iLCJjb3Jwb3JhdGlvbk5hbWUiOiLmsqrooaPllYbmnZHplYfpk7booYwiLCJkZWZhdWx0Um9sZUNvZGUiOiJhZG1pbiIsInVzZXJOYW1lIjoi57O757uf566h55CG5ZGYIiwidXNlcklkIjoiZWYyNTMzYzUtODZiYi00YzI2LTgyYWEtNGFhYTA1NGJkYzk4IiwiYXV0aG9yaXRpZXMiOlt7ImNvZGUiOiJhZG1pbiIsIm5hbWUiOiLns7vnu5_nrqHnkIblkZgiLCJpZCI6IjhiMWM4YTAwLTk4MDEtNDAyMC05ODY1LTA0ZDU2ODcxY2ZiOSJ9XSwiZGVmYXVsdFJvbGVOYW1lIjoi57O757uf566h55CG5ZGYIiwibG9naW5OYW1lIjoiYWRtaW4iLCJleHAiOjE3NDQ3MzkxMzEsImlhdCI6MTc0NDcxMDMzMSwianRpIjoiZWQxNzMwOTMtZTIzMi00OWQ1LWI2ZjItNTRkZDRlYjM5ZmEwIiwiZGVmYXVsdFJvbGVJZCI6IjhiMWM4YTAwLTk4MDEtNDAyMC05ODY1LTA0ZDU2ODcxY2ZiOSJ9.C1pDjMUyf5DAZXTzoys9YfDlXbvPkENIe-XIuSoh1QYJ4SYzaX9n5WaQRvZ793cmcVqyTMNFQKlp5F8sWZZnMft-XmrBtH5FTpo2jxGnoexuGUudPCsdRiFzyNMKCgohIkEs-8lWzG_jcJ-otk7UxmBSQQkOAZU3JkVE-rhDiMRzKa9RIJGiqicQ24-Q5ihGJ9aXX_5CgbvKSdqG59pfNHta0u33gxfqwhozU1L8276f07RrrW4lxoF1rB95_OqEObvzOCpZHqWETf6MAo3rqAfEIPOJFENgjX7wXu6PDla85K9cJHbjKFV_dbjT2DmZn98uPlU_2-iimFrxA4Hp3g");
WebResponse response =sendWebRequest(webRequest);
System.out.println(response.getContent());
Map o =(Map)new JsonSlurper().parseText(response.getContent());
System.out.println(o.get("resource").getClass().getName());
}
}

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

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

33
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/dictionary/dictionary.ftl

@ -1,33 +0,0 @@
<#assign dictionaries=($wrapper.dictionaries)!>
<#list (dictionaries)! as dictionary>
/**
* 数据字典类
* @author auto generated by engine
*/
@JsonIgnoreProperties(ignoreUnknown=true)
class ${CodeReplacer.className(dictionary.code)}_V${dictionary.version}{
<#list (dictionary.getFields())! as field>
<#if field.defaultValue??>
<#if "java.lang.String"==(field.valueType)!>
String ${CodeReplacer.fieldName(field.code)} ="${field.defaultValue}";//${field.name}
<#else>
${ValueType.getSimpleJavaType(field.valueType)} ${CodeReplacer.fieldName(field.code)} =${field.defaultValue};//${field.name}
</#if>
<#else>
<#if (field.valueTypeIsList)!>
List<${ValueType.getSimpleJavaType(field.valueType)}> ${CodeReplacer.fieldName(field.code)};//${field.name}
<#else>
${ValueType.getSimpleJavaType(field.valueType)} ${CodeReplacer.fieldName(field.code)};//${field.name}
</#if>
</#if>
</#list>
public void init(){
<#list (dictionary.getFields())! as field>
<#if field?? && field.valueCalculation?? && field.valueCalculation!="">
${CodeReplacer.fieldName(field.code)} =(${ExpressionReplacer.groovyWithNoArgumentName(field.valueCalculation,null)});
</#if>
</#list>
}
}
</#list>

6
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/functions.ftl

@ -1,6 +0,0 @@
<#assign functions=$wrapper.functions!>
<#list functions! as function>
<#if (function.enable)!>
${function.body}
</#if>
</#list>

115
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/groovy.ftl

@ -1,115 +0,0 @@
<#ftl strip_whitespace=true>
package io.sc.engine.rule.core.code;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.type.TypeReference;
import groovy.transform.Canonical;
import java.math.*;
import java.util.Random;
import java.util.Map;
import io.sc.engine.rule.core.classes.RuleResult;
import io.sc.engine.rule.core.classes.SingleRuleResult;
import io.sc.engine.rule.core.classes.ResourceAbstract;
import io.sc.engine.rule.core.code.impl.support.ResourceResult;
import io.sc.engine.rule.core.code.impl.support.ParameterResult;
import io.sc.engine.rule.core.code.impl.support.FieldValidator;
import io.sc.engine.rule.core.code.impl.support.ValidateResult;
import io.sc.engine.rule.core.enums.ParameterType;
import io.sc.engine.rule.core.enums.RuntimeInputParameterType;
import io.sc.engine.rule.core.util.DateUtil;
import io.sc.engine.rule.core.util.DataTypeConvertor;
import io.sc.engine.rule.core.util.ESql;
import io.sc.engine.rule.core.util.JacksonObjectMapper;
import io.sc.engine.rule.core.util.IdReplacer;
import io.sc.engine.rule.core.util.Strings;
import io.sc.engine.rule.client.Executor;
import static java.lang.Math.PI;
import static java.lang.Math.E;
import static java.lang.Math.abs;
import static java.lang.Math.atan2;
import static java.lang.Math.cbrt;
import static java.lang.Math.ceil;
import static java.lang.Math.exp;
import static java.lang.Math.expm1;
import static java.lang.Math.floor;
import static java.lang.Math.IEEEremainder;
import static java.lang.Math.pow;
import static java.lang.Math.random;
import static java.lang.Math.rint;
import static java.lang.Math.round;
import static java.lang.Math.sqrt;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;
import static java.lang.Math.sin;
import static java.lang.Math.cos;
import static java.lang.Math.tan;
import static java.lang.Math.asin;
import static java.lang.Math.acos;
import static java.lang.Math.atan;
import static java.lang.Math.sinh;
import static java.lang.Math.cosh;
import static java.lang.Math.tanh;
import static io.sc.engine.rule.core.function.ArithmeticFunction.randomInt;
import static io.sc.engine.rule.core.function.ArithmeticFunction.max;
import static io.sc.engine.rule.core.function.ArithmeticFunction.min;
import static io.sc.engine.rule.core.function.ArithmeticFunction.sum;
import static io.sc.engine.rule.core.function.ArithmeticFunction.log;
import static io.sc.engine.rule.core.function.ArithmeticFunction.ln;
import static io.sc.engine.rule.core.function.ArithmeticFunction.lg;
import static io.sc.engine.rule.core.function.ArithmeticFunction.root;
import static io.sc.engine.rule.core.function.ArithmeticFunction.div;
import static io.sc.engine.rule.core.function.ArithmeticFunction.transformSequencing;
import static io.sc.engine.rule.core.function.DateFunction.now;
import static io.sc.engine.rule.core.function.DateFunction.yyyyMMdd;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd;
import static io.sc.engine.rule.core.function.StringFunction.length;
import static io.sc.engine.rule.core.function.StringFunction.trim;
import static io.sc.engine.rule.core.function.StringFunction.upperCase;
import static io.sc.engine.rule.core.function.StringFunction.lowerCase;
import static io.sc.engine.rule.core.function.StringFunction.contains;
import static io.sc.engine.rule.core.function.StringFunction.startsWith;
import static io.sc.engine.rule.core.function.StringFunction.endsWith;
import static io.sc.engine.rule.core.function.StringFunction.join;
import static io.sc.engine.rule.core.function.NormalDistributionFunction.G;
import static io.sc.engine.rule.core.function.NormalDistributionFunction.iG;
import static io.sc.engine.rule.core.function.SpecialValueFunction.isNil;
import static io.sc.engine.rule.core.function.SpecialValueFunction.isZero;
import static io.sc.engine.rule.core.function.SpecialValueFunction.isNan;
import static io.sc.engine.rule.core.function.SpecialValueFunction.isInfinite;
import static io.sc.engine.rule.core.function.SpecialValueFunction.nil;
import static io.sc.engine.rule.core.function.SpecialValueFunction.zero;
import static io.sc.engine.rule.core.function.SpecialValueFunction.nan;
import static io.sc.engine.rule.core.function.SpecialValueFunction.infinite;
import static io.sc.engine.rule.core.util.NumberFormater.decimal;
import static io.sc.engine.rule.core.util.NumberFormater.comma;
import static io.sc.engine.rule.core.util.NumberFormater.money;
import static io.sc.engine.rule.core.util.NumberFormater.percent;
import io.sc.engine.rule.core.function.JpmmlEvaluator;
<#include "/functions.ftl"/>
<#if $wrapper.type=="RESOURCE">
<#include "/resource_groovy.ftl"/>
<#elseif $wrapper.type=="LIB">
<#include "/lib_groovy.ftl"/>
</#if>

115
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib/lib.ftl

@ -1,115 +0,0 @@
<#assign libs=($wrapper.libs)!>
<#list (libs)! as lib>
/**
* 库类
* @author auto generated by engine
*/
@JsonIgnoreProperties(ignoreUnknown=true)
class ${CodeReplacer.className(lib.code,lib.version)}{
private static final Logger log =LoggerFactory.getLogger(${CodeReplacer.className(lib.code,lib.version)}.class);
<#list (lib.indicators)! as indicator>
${indicator.forArgumentField($wrapper)}
</#list>
//通过输入参数构建指标库对象
public void convertArgument(Map<String,Object> map){
Object obj =null;
<#list (lib.indicators)! as indicator>
${indicator.forConvertArgumentFromMap($wrapper,"this")}
</#list>
}
public void convertArgument(String json){
${CodeReplacer.className(lib.code)}_V${lib.version} result =JacksonObjectMapper.getDefaultObjectMapper().readValue(json, ${CodeReplacer.className(lib.code,lib.version)}.class);
<#list (lib.indicators)! as indicator>
<#if "INTERFACE"==(indicator.type)!>
this.${CodeReplacer.fieldName(indicator.code)} =result.${CodeReplacer.fieldName(indicator.code)};
<#if ValueType.isBaseType(indicator.valueType)>
<#else>
this.${CodeReplacer.fieldName(indicator.code)}.init();
</#if>
</#if>
</#list>
}
public void execute() throws Exception{
<#-- 处理指标值 -->
<#list (lib.indicators)! as indicator>
<#if "INDICATOR"==(indicator.type)!>
${CodeReplacer.fieldName(indicator.code)}();//${indicator.name},${indicator.type}
</#if>
</#list>
}
public void validate(ValidateResult result) {
<#list (lib.indicators)! as indicator>
<#list (indicator.validators)! as validator>
<#if "EMPTY"==(validator.type)!>
FieldValidator.empty("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "NOT_EMPTY"==(validator.type)!>
FieldValidator.notEmpty("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "TRUE"==(validator.type)!>
FieldValidator.trueValue("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "FALSE"==(validator.type)!>
FieldValidator.falseValue("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "INTEGER_RANGE"==(validator.type)!>
FieldValidator.integerRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>${validator.minValue}<#else>null</#if>,<#if validator.maxValue??>${validator.maxValue}<#else>null</#if>,result);
<#elseif "DECIMAL_RANGE"==(validator.type)!>
FieldValidator.decimalRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>new Double(${validator.minValue})<#else>null</#if>,<#if validator.maxValue??>new Double(${validator.maxValue})<#else>null</#if>,result);
<#elseif "LENGTH_RANGE"==(validator.type)!>
FieldValidator.lengthRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>${validator.minValue}<#else>null</#if>,<#if validator.maxValue??>${validator.maxValue}<#else>null</#if>,result);
<#elseif "DATE_RANGE"==(validator.type)!>
FieldValidator.dateRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>DateUtil.parseDate("${validator.minValue?string("yyyy-MM-dd HH:mm:ss")}")<#else>null</#if>,<#if validator.maxValue??>DateUtil.parseDate("${validator.maxValue?string("yyyy-MM-dd HH:mm:ss")}")<#else>null</#if>,result);
<#elseif "EMAIL"==(validator.type)!>
FieldValidator.mail("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "PATTERN"==(validator.type)!>
FieldValidator.pattern("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},"${validator.pattern}",result);
</#if>
</#list>
</#list>
}
<#list (lib.indicators)! as indicator>
<#if "INDICATOR"==(indicator.type)!>
<#assign parameter=indicator>
public void ${CodeReplacer.fieldName(indicator.code)}(){
${CodeReplacer.className(lib.code)}_V${lib.version} arg =this;
<#list (indicator.processors)! as processor>
if(log.isDebugEnabled()){log.debug(" {}","${parameter.name}(${parameter.type})");}
<#if "OBJECT_PROPERTIES"==(processor.type)!>
<#include "/processor/OBJECT_PROPERTIES.ftl"/>
<#elseif "OPTION_VALUE"==(processor.type)!>
<#include "/processor/OPTION_VALUE.ftl"/>
<#elseif "MATH_FORMULA"==(processor.type)!>
<#include "/processor/MATH_FORMULA.ftl"/>
<#elseif "ARITHMETIC"==(processor.type)!>
<#include "/processor/ARITHMETIC.ftl"/>
<#elseif "TERNARY"==(processor.type)!>
<#include "/processor/TERNARY.ftl"/>
<#elseif "WHEN_THEN"==(processor.type)!>
<#include "/processor/WHEN_THEN.ftl"/>
<#elseif "NUMBER_RANGE"==(processor.type)!>
<#include "/processor/NUMBER_RANGE.ftl"/>
<#elseif "CONDITION_RANGE"==(processor.type)!>
<#include "/processor/CONDITION_RANGE.ftl"/>
<#elseif "DECISION_TABLE_2C"==(processor.type)!>
<#include "/processor/DECISION_TABLE_2C.ftl"/>
<#elseif "DECISION_TABLE"==(processor.type)!>
<#include "/processor/DECISION_TABLE.ftl"/>
<#elseif "DECISION_TREE"==(processor.type)!>
<#include "/processor/DECISION_TREE.ftl"/>
<#elseif "EXECUTION_FLOW"==(processor.type)!>
<#include "/processor/EXECUTION_FLOW.ftl"/>
<#elseif "PMML"==(processor.type)!>
<#include "/processor/PMML.ftl"/>
<#elseif "GROOVY_SCRIPT"==(processor.type)!>
<#include "/processor/GROOVY_SCRIPT.ftl"/>
<#elseif "SQL"==(processor.type)!>
<#include "/processor/SQL.ftl"/>
</#if>
</#list>
}
</#if>
</#list>
}
</#list>

201
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib_groovy.ftl

@ -1,201 +0,0 @@
<#assign lib=$wrapper.lib>
/**
* 指标库类(name:${lib.name}, code:${lib.code}, version:${lib.version})
* ${(lib.description)!}
* @author auto generated by engine
*/
class ${CodeReplacer.className(lib.code,lib.version)}{
private static final Logger log =LoggerFactory.getLogger(${CodeReplacer.className(lib.code,lib.version)}.class);
/**
* 执行方法(Map作为输入参数,该 Map 封装了调用模型的参数)
* @param map 输入参数封装器
* @return 执行结果
*/
public static ResourceResult execute(Map<String,Object> map) throws Exception{
return execute(map["executor"],map["subModelCode"],map["argument"]);
}
<#-- 执行方法(Map作为输入参数) -->
/**
* 执行方法
* @param executor 执行器对象
* @param subModelCode 子模型代码
* @param data 输入参数
* @return 执行结果
*/
public static ResourceResult execute(Executor executor,String subModelCode,Object data) throws Exception{
if(log.isDebugEnabled()){log.debug("开始执行指标库 : ${CodeReplacer.className(lib.code,lib.version)}");}
if(data instanceof Map){
if(log.isDebugEnabled()){log.debug("显示输入参数(Map)=================================================\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(data));}
}else if(data instanceof String){
if(log.isDebugEnabled()){log.debug("显示输入参数(Json字符串)=================================================\n{}",data);}
}
//初始化模型参数
if(log.isDebugEnabled()){log.debug("初始化指标库参数");}
Argument argument =Argument.convertArgument(data);
//输入参数合法性检查(指标库)
ValidateResult validateResult =new ValidateResult();
//输入参数合法性检查(模型)
if(log.isDebugEnabled()){log.debug("开始检查指标库输入参数数据合法性");}
argument.validate(validateResult);
if(validateResult.hasError()){
if(log.isDebugEnabled()){log.debug("\t检查结果: 失败!");}
ResourceResult result =new ResourceResult();
result.setValidateResult(validateResult);
return result;
}
if(log.isDebugEnabled()){log.debug("\t检查结果: 成功!");}
//执行指标库中的所有指标
<#list (lib.indicators)! as indicator>
<#if "INDICATOR"==(indicator.type)!>
${CodeReplacer.methodName(indicator.code)}(executor,argument);//${indicator.name},${indicator.type}
</#if>
</#list>
//返回结果
ResourceResult result =argument.toResult();
if(log.isDebugEnabled()){log.debug("指标库调用成功,返回结果:\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(result));}
return result;
}
<#list (lib.indicators)! as indicator>
<#if "INDICATOR"==(indicator.type)!>
public static void ${CodeReplacer.methodName(indicator.code)}(Executor executor,Argument arg){
<#list (indicator.processors)! as processor>
<#assign parameter=indicator>
if(log.isDebugEnabled()){log.debug(" {}","${parameter.name}(${parameter.type})");}
<#if "OBJECT_PROPERTIES"==(processor.type)!>
<#include "/processor/OBJECT_PROPERTIES.ftl"/>
<#elseif "OPTION_VALUE"==(processor.type)!>
<#include "/processor/OPTION_VALUE.ftl"/>
<#elseif "MATH_FORMULA"==(processor.type)!>
<#include "/processor/MATH_FORMULA.ftl"/>
<#elseif "ARITHMETIC"==(processor.type)!>
<#include "/processor/ARITHMETIC.ftl"/>
<#elseif "TERNARY"==(processor.type)!>
<#include "/processor/TERNARY.ftl"/>
<#elseif "WHEN_THEN"==(processor.type)!>
<#include "/processor/WHEN_THEN.ftl"/>
<#elseif "NUMBER_RANGE"==(processor.type)!>
<#include "/processor/NUMBER_RANGE.ftl"/>
<#elseif "CONDITION_RANGE"==(processor.type)!>
<#include "/processor/CONDITION_RANGE.ftl"/>
<#elseif "DECISION_TABLE_2C"==(processor.type)!>
<#include "/processor/DECISION_TABLE_2C.ftl"/>
<#elseif "DECISION_TABLE"==(processor.type)!>
<#include "/processor/DECISION_TABLE.ftl"/>
<#elseif "DECISION_TREE"==(processor.type)!>
<#include "/processor/DECISION_TREE.ftl"/>
<#elseif "EXECUTION_FLOW"==(processor.type)!>
<#include "/processor/EXECUTION_FLOW.ftl"/>
<#elseif "PMML"==(processor.type)!>
<#include "/processor/PMML.ftl"/>
<#elseif "GROOVY_SCRIPT"==(processor.type)!>
<#include "/processor/GROOVY_SCRIPT.ftl"/>
<#elseif "SQL"==(processor.type)!>
<#include "/processor/SQL.ftl"/>
</#if>
</#list>
}
</#if>
</#list>
}
/**
* 模型参数类
* @author auto generated by engine
*/
@JsonIgnoreProperties(ignoreUnknown=true)
class Argument{
<#list (lib.indicators)! as indicator>
${indicator.forArgumentField($wrapper)}
</#list>
<#-- 参数转换 -->
public static Argument convertArgument(Map<String,Object> map){
if(map!=null){
Argument argument =new Argument();
Object obj =null;
<#list (lib.indicators)! as indicator>
${indicator.forConvertArgumentFromMap($wrapper,"argument")}
</#list>
return argument;
}
return null;
}
<#-- 参数转换 -->
public static Argument convertArgument(String json){
if(json!=null && !"".equals(json.trim())){
Argument argument =JacksonObjectMapper.getDefaultObjectMapper().readValue(json, Argument.class);
<#list (lib.indicators)! as indicator>
${indicator.forConvertArgumentFromJson($wrapper,"argument")}
</#list>
return argument;
}
return null;
}
public void validate(ValidateResult result) {
<#list (lib.indicators)! as indicator>
<#list (indicator.validators)! as validator>
<#if "EMPTY"==(validator.type)!>
FieldValidator.empty("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "NOT_EMPTY"==(validator.type)!>
FieldValidator.notEmpty("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "TRUE"==(validator.type)!>
FieldValidator.trueValue("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "FALSE"==(validator.type)!>
FieldValidator.falseValue("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "INTEGER_RANGE"==(validator.type)!>
FieldValidator.integerRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>${validator.minValue}<#else>null</#if>,<#if validator.maxValue??>${validator.maxValue}<#else>null</#if>,result);
<#elseif "DECIMAL_RANGE"==(validator.type)!>
FieldValidator.decimalRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>new Double(${validator.minValue})<#else>null</#if>,<#if validator.maxValue??>new Double(${validator.maxValue})<#else>null</#if>,result);
<#elseif "LENGTH_RANGE"==(validator.type)!>
FieldValidator.lengthRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>${validator.minValue}<#else>null</#if>,<#if validator.maxValue??>${validator.maxValue}<#else>null</#if>,result);
<#elseif "DATE_RANGE"==(validator.type)!>
FieldValidator.dateRange("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},<#if validator.minValue??>DateUtil.parseDate("${validator.minValue?string("yyyy-MM-dd HH:mm:ss")}")<#else>null</#if>,<#if validator.maxValue??>DateUtil.parseDate("${validator.maxValue?string("yyyy-MM-dd HH:mm:ss")}")<#else>null</#if>,result);
<#elseif "EMAIL"==(validator.type)!>
FieldValidator.mail("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},result);
<#elseif "PATTERN"==(validator.type)!>
FieldValidator.pattern("${indicator.code}",'''${indicator.name}''',this.${CodeReplacer.fieldName(indicator.code)},"${validator.pattern}",result);
</#if>
</#list>
</#list>
}
public ResourceResult toResult(){
ResourceResult result =new ResourceResult();
<#list (lib.indicators)! as indicator>
<#if "INDICATOR"==(indicator.type)!>
<#if indicator.valueType==ValueType.Decimal.getJavaType()>
result.addParameterResult(new ParameterResult("${indicator.code}","${indicator.name}",ParameterType.${indicator.type},"${indicator.valueType}",${indicator.valueScale!"8"},RoundingMode.${indicator.valueRoundingMode!"HALF_UP"},this.${CodeReplacer.fieldName(indicator.code)}==null?null:${CodeReplacer.fieldName(indicator.code)}.setScale(${indicator.valueScale!"8"},RoundingMode.${indicator.valueRoundingMode!"HALF_UP"}).toString()));
<#elseif
indicator.valueType==ValueType.Boolean.getJavaType()
|| indicator.valueType==ValueType.Long.getJavaType()
|| indicator.valueType==ValueType.String.getJavaType()
|| indicator.valueType==ValueType.Date.getJavaType()
>
result.addParameterResult(new ParameterResult("${indicator.code}","""${indicator.name}""",ParameterType.${indicator.type},"${indicator.valueType}",${indicator.valueScale!"null"},<#if indicator.valueRoundingMode??>RoundingMode.${indicator.valueRoundingMode}<#else>null</#if>,this.${CodeReplacer.fieldName(indicator.code)}==null?null:this.${CodeReplacer.fieldName(indicator.code)}.toString()));
<#else>
result.addParameterResult(new ParameterResult("${indicator.code}","""${indicator.name}""",ParameterType.${indicator.type},"${indicator.valueType}",${indicator.valueScale!"null"},<#if indicator.valueRoundingMode??>RoundingMode.${indicator.valueRoundingMode}<#else>null</#if>,this.${CodeReplacer.fieldName(indicator.code)}==null?null:JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(this.${CodeReplacer.fieldName(indicator.code)})));
</#if>
</#if>
</#list>
return result;
}
}
<#-- 数据字典类 -->
<#include "/dictionary/dictionary.ftl"/>
//执行并返回
${CodeReplacer.className(lib.code)}_V${lib.version}.execute(INPUT_PARAMETER);

153
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/argument.ftl

@ -1,153 +0,0 @@
/**
* 模型参数类
* @author auto generated by engine
*/
@JsonIgnoreProperties(ignoreUnknown=true)
class Argument{
<#list (model.getAllParameters())! as parameter>
${parameter.forArgumentField($wrapper)}
</#list>
<#-- 参数转换 -->
public static Argument convertArgument(Map<String,Object> map){
if(map!=null){
Argument argument =new Argument();
Object obj =null;
<#list (model.getAllParameters())! as parameter>
${parameter.forConvertArgumentFromMap($wrapper,"argument")}
</#list>
return argument;
}
return null;
}
<#-- 参数转换 -->
public static Argument convertArgument(String json){
if(json!=null && !"".equals(json.trim())){
Argument argument =JacksonObjectMapper.getDefaultObjectMapper().readValue(json, Argument.class);
<#list (model.getAllParameters())! as parameter>
${parameter.forConvertArgumentFromJson($wrapper,"argument")}
</#list>
return argument;
}
return null;
}
public void validate(ValidateResult result) {
<#list (model.getAllParameters())! as parameter>
<#list (parameter.getValidators())! as validator>
${validator.type!}
<#if "EMPTY"==(validator.type)!>
FieldValidator.empty("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},result);
<#elseif "NOT_EMPTY"==(validator.type)!>
FieldValidator.notEmpty("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},result);
<#elseif "TRUE"==(validator.type)!>
FieldValidator.trueValue("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},result);
<#elseif "FALSE"==(validator.type)!>
FieldValidator.falseValue("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},result);
<#elseif "INTEGER_RANGE"==(validator.type)!>
FieldValidator.integerRange("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},<#if validator.minValue??>${validator.minValue}<#else>null</#if>,<#if validator.maxValue??>${validator.maxValue}<#else>null</#if>,result);
<#elseif "DECIMAL_RANGE"==(validator.type)!>
FieldValidator.decimalRange("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},<#if validator.minValue??>new Double(${validator.minValue})<#else>null</#if>,<#if validator.maxValue??>new Double(${validator.maxValue})<#else>null</#if>,result);
<#elseif "LENGTH_RANGE"==(validator.type)!>
FieldValidator.lengthRange("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},<#if validator.minValue??>${validator.minValue}<#else>null</#if>,<#if validator.maxValue??>${validator.maxValue}<#else>null</#if>,result);
<#elseif "DATE_RANGE"==(validator.type)!>
FieldValidator.dateRange("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},<#if validator.minValue??>DateUtil.parseDate("${validator.minValue?string("yyyy-MM-dd HH:mm:ss")}")<#else>null</#if>,<#if validator.maxValue??>DateUtil.parseDate("${validator.maxValue?string("yyyy-MM-dd HH:mm:ss")}")<#else>null</#if>,result);
<#elseif "EMAIL"==(validator.type)!>
FieldValidator.mail("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},result);
<#elseif "PATTERN"==(validator.type)!>
FieldValidator.pattern("${parameter.code}",'''${parameter.name}''',this.${CodeReplacer.fieldName(parameter.code)},"${validator.pattern}",result);
</#if>
</#list>
</#list>
}
public void mergeParameterValueFromIndicatorLib(Map<String,Object> libs){
<#list (model.getAllParameters())! as parameter>
<#if "INDICATOR"==(parameter.type)!>
<#-- 如果直接给模型参数(类型为指标)设置过非空值,则直接采用设置过的值,否则采用指标库计算结果值 -->
<#if $wrapper.isExecuteTestCase>
if(this.${CodeReplacer.fieldName(parameter.code)}==null){this.${CodeReplacer.fieldName(parameter.code)} =libs.get("${CodeReplacer.varName(parameter.libCode,parameter.libVersion)}").${CodeReplacer.fieldName(parameter.indicatorCode)};}//${parameter.name}
<#else>
this.${CodeReplacer.fieldName(parameter.code)} =libs.get("${CodeReplacer.varName(parameter.libCode,parameter.libVersion)}").${CodeReplacer.fieldName(parameter.indicatorCode)};//${parameter.name}
</#if>
</#if>
</#list>
}
public ResourceResult toResult(){
ResourceResult result =new ResourceResult();
<#list model.getAllParameters() as parameter>
<#if 'OUT'==(parameter.type)! || 'INTERMEDIATE'==(parameter.type)!>
<#if parameter.valueType==ValueType.Decimal.getJavaType()>
result.addParameterResult(new ParameterResult("${parameter.code}","${parameter.name}",ParameterType.${parameter.type},"${parameter.valueType}",${parameter.valueScale!"8"},RoundingMode.${parameter.valueRoundingMode!"HALF_UP"},this.${CodeReplacer.fieldName(parameter.code)}==null?null:${CodeReplacer.fieldName(parameter.code)}.setScale(${parameter.valueScale!"8"},RoundingMode.${parameter.valueRoundingMode!"HALF_UP"}).toString()));
<#elseif
parameter.valueType==ValueType.Boolean.getJavaType()
|| parameter.valueType==ValueType.Long.getJavaType()
|| parameter.valueType==ValueType.String.getJavaType()
|| parameter.valueType==ValueType.Date.getJavaType()
>
result.addParameterResult(new ParameterResult("${parameter.code}","${parameter.name}",ParameterType.${parameter.type},"${parameter.valueType}",null,null,this.${CodeReplacer.fieldName(parameter.code)}==null?null:this.${CodeReplacer.fieldName(parameter.code)}.toString()));
<#else>
result.addParameterResult(new ParameterResult("${parameter.code}","${parameter.name}",ParameterType.${parameter.type},"${parameter.valueType}",null,null,this.${CodeReplacer.fieldName(parameter.code)}==null?null:JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(this.${CodeReplacer.fieldName(parameter.code)})));
</#if>
<#elseif 'INDICATOR'==(parameter.type)!>
<#assign indicator=LibUtil.findIndicator($wrapper.libs,parameter.libCode,parameter.libVersion,parameter.indicatorCode)>
<#if "INDICATOR"==(indicator.type)!>
<#if parameter.valueType==ValueType.Decimal.getJavaType()>
result.addParameterResult(new ParameterResult("${indicator.code}","${indicator.name}",ParameterType.${parameter.type},"${parameter.valueType}",${parameter.valueScale!"8"},RoundingMode.${parameter.valueRoundingMode!"HALF_UP"},this.${CodeReplacer.fieldName(parameter.code)}==null?null:${CodeReplacer.fieldName(parameter.code)}.setScale(${parameter.valueScale!"8"},RoundingMode.${parameter.valueRoundingMode!"HALF_UP"}).toString()));
<#elseif
parameter.valueType==ValueType.Boolean.getJavaType()
|| parameter.valueType==ValueType.Long.getJavaType()
|| parameter.valueType==ValueType.String.getJavaType()
|| parameter.valueType==ValueType.Date.getJavaType()
>
result.addParameterResult(new ParameterResult("${indicator.code}","${indicator.name}",ParameterType.${parameter.type},"${parameter.valueType}",null,null,this.${CodeReplacer.fieldName(parameter.code)}==null?null:this.${CodeReplacer.fieldName(parameter.code)}.toString()));
<#else>
result.addParameterResult(new ParameterResult("${indicator.code}","${indicator.name}",ParameterType.${parameter.type},"${parameter.valueType}",null,null,this.${CodeReplacer.fieldName(parameter.code)}==null?null:JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(this.${CodeReplacer.fieldName(parameter.code)})));
</#if>
</#if>
<#elseif 'RULE_RESULT'==(parameter.type)!>
result.addParameterResult(new ParameterResult("${parameter.code}","${parameter.name}",ParameterType.${parameter.type},this.${CodeReplacer.fieldName(parameter.code)}));
<#elseif 'SINGLE_RULE_RESULT'==(parameter.type)!>
result.addParameterResult(new ParameterResult("${parameter.code}","${parameter.name}",ParameterType.${parameter.type},this.${CodeReplacer.fieldName(parameter.code)}));
</#if>
</#list>
return result;
}
public Map<String,Object> toMap(){
Map<String,Object> map =new HashMap<String,Object>();
<#list model.getAllParameters() as parameter>
map.put("${parameter.code}",this.${CodeReplacer.fieldName(parameter.code)});//${parameter.type}, ${parameter.name}
</#list>
return map;
}
public void mergeResult(ResourceResult result){
if(result!=null){
<#list model.getAllParameters() as parameter>
<#if
parameter.valueType==ValueType.Boolean.getJavaType()
|| parameter.valueType==ValueType.Long.getJavaType()
|| parameter.valueType==ValueType.Decimal.getJavaType()
|| parameter.valueType==ValueType.String.getJavaType()
|| parameter.valueType==ValueType.Date.getJavaType()
>
if(result.exists("${parameter.code}")){
this.${CodeReplacer.fieldName(parameter.code)} =DataTypeConvertor.convert(result.getValueByParameterCode("${parameter.code}"),${ValueType.getSimpleJavaType(parameter.valueType)}.class);
}
<#else>
if(result.exists("${parameter.code}")){
this.${CodeReplacer.fieldName(parameter.code)} =result.getValueByParameterCode("${parameter.code}");
}
</#if>
</#list>
}
}
}

228
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/model.ftl

@ -1,228 +0,0 @@
<#assign model=resource.model>
/**
* 资源类(name:${resource.name}, code:${resource.code}, version:${resource.version})
* @author auto generated by engine
*/
class ${CodeReplacer.className(resource.code,resource.version)} {
private static final Logger log =LoggerFactory.getLogger(${CodeReplacer.className(resource.code,resource.version)}.class);
/**
* 执行方法(Map作为输入参数,该 Map 封装了调用模型的参数)
* @param map 输入参数封装器
* @return 执行结果
*/
public static ResourceResult execute(Map<String,Object> map) throws Exception{
return execute(map["executor"],map["subModelCode"],map["argument"]);
}
<#-- 执行方法(Map作为输入参数) -->
/**
* 执行方法
* @param executor 执行器对象
* @param subModelCode 子模型代码
* @param data 输入参数
* @return 执行结果
*/
public static ResourceResult execute(Executor executor,String subModelCode,Object data) throws Exception{
if(log.isDebugEnabled()){log.debug("开始执行模型 : ${CodeReplacer.className(resource.code,resource.version)}");}
if(data instanceof Map){
if(log.isDebugEnabled()){log.debug("显示输入参数(Map)=================================================\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(data));}
}else if(data instanceof String){
if(log.isDebugEnabled()){log.debug("显示输入参数(Json字符串)=================================================\n{}",data);}
}
<#if $wrapper.isExecuteTestCase>
<#else>
<#list ($wrapper.libs)! as lib>
if(log.isDebugEnabled()){log.debug("初始化指标库 : ${lib.name}_V${lib.version}");}
${CodeReplacer.className(lib.code,lib.version)} ${CodeReplacer.varName(lib.code,lib.version)} =new ${CodeReplacer.className(lib.code,lib.version)}();
${CodeReplacer.varName(lib.code,lib.version)}.convertArgument(data);
</#list>
</#if>
//初始化模型参数
if(log.isDebugEnabled()){log.debug("从 {} 初始化模型参数","java.lang.String"==data.class?"Json":"Map");}
Argument argument =Argument.convertArgument(data);
//输入参数合法性检查
ValidateResult validateResult =new ValidateResult();
<#if $wrapper.isExecuteTestCase>
<#else>
//输入参数合法性检查(指标库)
<#list ($wrapper.libs)! as lib>
if(log.isDebugEnabled()){log.debug("开始检查输入参数数据合法性(指标库: ${lib.name}_V${lib.version})");}
${CodeReplacer.varName(lib.code,lib.version)}.validate(validateResult);
if(validateResult.hasError()){
if(log.isDebugEnabled()){log.debug("\t检查结果: 失败!");}
ResourceResult result =new ResourceResult();
result.setValidateResult(validateResult);
return result;
}
if(log.isDebugEnabled()){log.debug("\t检查结果: 成功!");}
</#list>
</#if>
//输入参数合法性检查(模型)
if(log.isDebugEnabled()){log.debug("开始检查模型输入参数数据合法性");}
argument.validate(validateResult);
if(validateResult.hasError()){
if(log.isDebugEnabled()){log.debug("\t检查结果: 失败!");}
ResourceResult result =new ResourceResult();
result.setValidateResult(validateResult);
return result;
}
if(log.isDebugEnabled()){log.debug("\t检查结果: 成功!");}
<#if $wrapper.isExecuteTestCase>
<#else>
//执行指标库
<#list ($wrapper.libs)! as lib>
if(log.isDebugEnabled()){log.debug("开始执行指标库: ${lib.name}_V${lib.version}");}
${CodeReplacer.varName(lib.code,lib.version)}.execute();
</#list>
</#if>
<#if $wrapper.isExecuteTestCase>
<#else>
//合并指标库指标
if(log.isDebugEnabled()){log.debug("开始合并指标库指标");}
Map<String,Object> indicatorLibs =new HashMap<String,Object>();
<#list ($wrapper.libs)! as lib>
indicatorLibs.put("${CodeReplacer.varName(lib.code,lib.version)}",${CodeReplacer.varName(lib.code,lib.version)});
</#list>
argument.mergeParameterValueFromIndicatorLib(indicatorLibs);
if(log.isDebugEnabled()){log.debug("显示合并后输入参数:\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(argument));}
</#if>
//执行模型
if(subModelCode){
subModelCode =CodeReplacer.methodName(subModelCode);
"${r'${subModelCode}'}"(executor,argument);//调用子模型
}else{
${CodeReplacer.methodName(model.code)}(executor,argument);//调用顶级模型(${model.name})
}
//返回结果
ResourceResult result =argument.toResult();
if(log.isDebugEnabled()){log.debug("模型调用成功,返回结果:\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(result));}
return result;
}
//顶级模型(${model.fullName})
private static void ${CodeReplacer.methodName(model.code)}(Executor executor,Argument argument){
if(log.isDebugEnabled()){log.debug("开始调用顶级模型: {}","${model.name}");}
<#if (model.enable)!>
<#else>
if(log.isDebugEnabled()){log.debug("开始调用顶级模型: enable==false");}
return;
</#if>
<#if "DOWN_TOP"==(model.executeMode)!>
<#-- 模型的执行模式为:自下而上,首先执行子模型 -->
<#list (model.children)! as subModel>
${CodeReplacer.methodName(subModel.code)}(executor,argument);//${subModel.name}
</#list>
</#if>
<#-- 处理顶级模型的中间值和结果值 -->
<#list (model.parameters)! as parameter>
<#if "INTERMEDIATE"==(parameter.type)! || "OUT"==(parameter.type)! || "RULE_RESULT"==(parameter.type)! || "SINGLE_RULE_RESULT"==(parameter.type)!>
${CodeReplacer.methodName(parameter.code)}(executor,argument);//${parameter.name},${parameter.type}
</#if>
</#list>
}
<#-- 递归生成所有子模型执行方法 -->
<#list (model.children)! as subModel>
//子模型(${subModel.fullName})
private static void ${CodeReplacer.methodName(subModel.code)}(Executor executor,Argument argument){
if(log.isDebugEnabled()){log.debug("开始调用子模型: {}","${subModel.fullName}");}
<#if (subModel.enable)!>
<#else>
if(log.isDebugEnabled()){log.debug("开始调用子模型: enable==false");}
return;
</#if>
<#if "DOWN_TOP"==(subModel.executeMode)!>
<#-- 子模型的执行模式为:自下而上,首先执行子模型的子模型 -->
<#list (subModel.children)! as _subModel>
${CodeReplacer.methodName(_subModel.code)}(executor,argument);//${_subModel.name}
</#list>
</#if>
<#-- 处理子模型的中间值和结果值 -->
<#list (subModel.getParameters())! as parameter>
<#if "INTERMEDIATE"==(parameter.type)! || "OUT"==(parameter.type)! || "RULE_RESULT"==(parameter.type)! || "SINGLE_RULE_RESULT"==(parameter.type)!>
${CodeReplacer.methodName(parameter.code)}(executor,argument);//${parameter.name},${parameter.type}
</#if>
</#list>
}
<#include "/model/sub-model.ftl"/>
</#list>
<#-- 生成所有参数处理器方法 -->
<#list (model.getAllParameters())! as parameter><#-- 循环将每个参数处理生成一个方法 -->
<#if ("INTERMEDIATE"==(parameter.type)! || "OUT"==(parameter.type)! || "RULE_RESULT"==(parameter.type)! || "SINGLE_RULE_RESULT"==(parameter.type)!)>
//参数处理器, ${parameter.name}(${parameter.type})
private static void ${CodeReplacer.methodName(parameter.code)}(Executor executor,Argument ${ExpressionReplacer.ARGUMENT_NAME}){
if(log.isDebugEnabled()){log.debug(" {}","${parameter.name}(${parameter.type})");}
<#list (parameter.processors)! as processor><#-- 循环将每个处理器转换成 java 语句 -->
<#if (processor.enable)!>
<#if "OBJECT_PROPERTIES"==(processor.type)!>
<#include "/processor/OBJECT_PROPERTIES.ftl"/>
<#elseif "OPTION_VALUE"==(processor.type)!>
<#include "/processor/OPTION_VALUE.ftl"/>
<#elseif "MATH_FORMULA"==(processor.type)!>
<#include "/processor/MATH_FORMULA.ftl"/>
<#elseif "ARITHMETIC"==(processor.type)!>
<#include "/processor/ARITHMETIC.ftl"/>
<#elseif "TERNARY"==(processor.type)!>
<#include "/processor/TERNARY.ftl"/>
<#elseif "WHEN_THEN"==(processor.type)!>
<#include "/processor/WHEN_THEN.ftl"/>
<#elseif "RULE"==(processor.type)!>
<#include "/processor/RULE.ftl"/>
<#elseif "SINGLE_RULE"==(processor.type)!>
<#include "/processor/SINGLE_RULE.ftl"/>
<#elseif "NUMBER_RANGE"==(processor.type)!>
<#include "/processor/NUMBER_RANGE.ftl"/>
<#elseif "CONDITION_RANGE"==(processor.type)!>
<#include "/processor/CONDITION_RANGE.ftl"/>
<#elseif "DECISION_TABLE_2C"==(processor.type)!>
<#include "/processor/DECISION_TABLE_2C.ftl"/>
<#elseif "DECISION_TABLE"==(processor.type)!>
<#include "/processor/DECISION_TABLE.ftl"/>
<#elseif "DECISION_TREE"==(processor.type)!>
<#include "/processor/DECISION_TREE.ftl"/>
<#elseif "EXECUTION_FLOW"==(processor.type)!>
<#include "/processor/EXECUTION_FLOW.ftl"/>
<#elseif "PMML"==(processor.type)!>
<#include "/processor/PMML.ftl"/>
<#elseif "GROOVY_SCRIPT"==(processor.type)!>
<#include "/processor/GROOVY_SCRIPT.ftl"/>
<#elseif "SQL"==(processor.type)!>
<#include "/processor/SQL.ftl"/>
</#if>
</#if>
</#list>
if(log.isDebugEnabled()){log.debug(" 参数结果值 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}
}
</#if>
</#list>
<#-- 决策树函数 -->
<#include "/processor/DECISION_TREE_FUNCTION.ftl"/>
<#-- 执行流函数 -->
<#include "/processor/EXECUTION_FLOW_FUNCTION.ftl"/>
}
<#-- 参数类 -->
<#include "/model/argument.ftl"/>
<#-- 库类 -->
<#include "/lib/lib.ftl"/>
<#-- 数据字典类 -->
<#include "/dictionary/dictionary.ftl"/>
//执行并返回
${CodeReplacer.className(resource.code)}_V${resource.version}.execute(INPUT_PARAMETER);

25
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/sub-model.ftl

@ -1,25 +0,0 @@
<#list (subModel.children)! as subModel>
//子模型(${subModel.fullName})
private static void ${subModel.code}(Executor executor,Argument argument){
if(log.isDebugEnabled()){log.debug("开始调用子模型: {}","${subModel.fullName}");}
<#if (subModel.enable)!>
<#else>
if(log.isDebugEnabled()){log.debug("开始调用子模型: enable==false");}
return;
</#if>
<#if "DOWN_TOP"==(subModel.executeMode)!>
<#-- 子模型的执行模式为:自下而上,首先执行子模型的子模型 -->
<#list (subModel.children)! as _subModel>
${_subModel.code}(executor,argument);//${_subModel.name}
</#list>
</#if>
<#-- 处理子模型的中间值和结果值 -->
<#list (subModel.getParameters())! as parameter>
<#if "INTERMEDIATE"==(parameter.type)! || "OUT"==(parameter.type)! || "RULE_RESULT"==(parameter.type)! || "SINGLE_RULE_RESULT"==(parameter.type)!>
${parameter.code}(executor,argument);//${parameter.name},${parameter.type}
</#if>
</#list>
}
<#include "/model/sub-model.ftl"/>
</#list>

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/ARITHMETIC.ftl

@ -1,4 +0,0 @@
//算数运算
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =${ExpressionReplacer.groovy(processor.arithmetic,parameter.valueType<#-- 算数运算,需要进行相关逻辑处理,即使参数类型为字符串也需要执行算数运算表达式 -->)};//${parameter.type}, ${parameter.name}
if(log.isDebugEnabled()){log.debug(" 算数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/CONDITION_RANGE.ftl

@ -1,4 +0,0 @@
//条件分段函数
${ConditionRange.generateGroovyCode(parameter,processor)}
if(log.isDebugEnabled()){log.debug(" 条件分段函数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TABLE.ftl

@ -1,4 +0,0 @@
//决策表
${DecisionTable.generateGroovyCode(parameter,processor)}
if(log.isDebugEnabled()){log.debug(" 决策表运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TABLE_2C.ftl

@ -1,4 +0,0 @@
//简单决策表
${DecisionTable2C.generateGroovyCode(parameter,processor)}
if(log.isDebugEnabled()){log.debug(" 简单决策表运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TREE.ftl

@ -1,4 +0,0 @@
//决策树(此处只是入口,真正的决策树计算逻辑在后面通过一系列方法完成)
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =Tree_${CodeReplacer.fieldName(parameter.code)}_${DecisionTree.parse(processor.decisionTree).id}(executor,${ExpressionReplacer.ARGUMENT_NAME});
if(log.isDebugEnabled()){log.debug(" 决策树运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

13
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/DECISION_TREE_FUNCTION.ftl

@ -1,13 +0,0 @@
/*-------------------------------------------------------------------------------*
* 决策树函数 *
*-------------------------------------------------------------------------------*/
<#list (model.getAllParameters())! as parameter><#-- 循环将每个参数处理生成一个方法 -->
<#if ("INTERMEDIATE"==parameter.type || "OUT"==parameter.type)>
<#list (parameter.processors)! as processor>
<#if "DECISION_TREE"==processor.type>
//${parameter.name}(${parameter.type})
${DecisionTree.generateGroovyCode(parameter,processor)}
</#if>
</#list>
</#if>
</#list>

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/EXECUTION_FLOW.ftl

@ -1,4 +0,0 @@
//执行流(此处只是入口,真正的执行流计算逻辑在后面通过一系列方法完成)
Flow_${CodeReplacer.fieldName(parameter.code)}_${ExecutionFlow.parse(processor.executionFlow).id}(executor,${ExpressionReplacer.ARGUMENT_NAME});
if(log.isDebugEnabled()){log.debug(" 执行流运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

13
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/EXECUTION_FLOW_FUNCTION.ftl

@ -1,13 +0,0 @@
/*-------------------------------------------------------------------------------*
* 执行流函数 *
*-------------------------------------------------------------------------------*/
<#list (model.getAllParameters())! as parameter><#-- 循环将每个参数处理生成一个方法 -->
<#if ("INTERMEDIATE"==parameter.type || "OUT"==parameter.type)>
<#list (parameter.processors)! as processor>
<#if "EXECUTION_FLOW"==processor.type>
//${parameter.name}(${parameter.type})
${ExecutionFlow.generateGroovyCode(parameter,processor)}
</#if>
</#list>
</#if>
</#list>

3
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/GROOVY_SCRIPT.ftl

@ -1,3 +0,0 @@
<#if processor.groovyScript??>
${ExpressionReplacer.groovy(processor.groovyScript,null)}
</#if>

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/MATH_FORMULA.ftl

@ -1,4 +0,0 @@
//数学公式
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =${MathFormula.generateGroovyCode(parameter,processor)};
if(log.isDebugEnabled()){log.debug(" 数学公式运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/NUMBER_RANGE.ftl

@ -1,4 +0,0 @@
//数值分段函数
${NumberRange.generateGroovyCode(parameter,processor)}
if(log.isDebugEnabled()){log.debug(" 数值分段函数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/OBJECT_PROPERTIES.ftl

@ -1,4 +0,0 @@
//对象属性函数
${ObjectProperty.generateGroovyCode(parameter,processor)}
if(log.isDebugEnabled()){log.debug(" 对象属性函数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

34
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/OPTION_VALUE.ftl

@ -1,34 +0,0 @@
//选项值运算
<#assign optionParameter=model.getParameterByOptionParameterCode(processor.optionCode)>
<#if optionParameter??>
if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}!=null){
<#list model.getParameterOptionsByOptionParameterCode(processor.optionCode) as option>
<#if option_index==0>
<#if optionParameter.valueType=='java.lang.String'>
if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}=="""${option.inputValue}"""){
<#else>
if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}==${option.inputValue}){
</#if>
<#else>
<#if optionParameter.valueType=='java.lang.String'>
}else if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}=="""${option.inputValue}"""){
<#else>
}else if(${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(optionParameter.code)}==${option.inputValue}){
</#if>
</#if>
<#if parameter.valueType=='java.lang.String'>
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} ="""${option.value}""";
if(log.isDebugEnabled()){log.debug(" 选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}
<#else>
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =${option.value};
if(log.isDebugEnabled()){log.debug(" 选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}
</#if>
</#list>
}else{
if(log.isDebugEnabled()){log.debug(" !!!未匹配到选项列表,选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}
}
}else{
if(log.isDebugEnabled()){log.debug(" !!!未提供选项输入值,选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}
}
</#if>

3
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/PMML.ftl

@ -1,3 +0,0 @@
<#if processor.pmml??>
arg.${CodeReplacer.fieldName(parameter.code)} =JpmmlEvaluator.evaluate('${parameter.id}_${processor.id}','''${processor.pmml}''',arg.toMap());
</#if>

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/RULE.ftl

@ -1,4 +0,0 @@
//规则运算
${Rule.generateGroovyCode(parameter,processor)}
if(log.isDebugEnabled()){log.debug(" 算数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/SINGLE_RULE.ftl

@ -1,4 +0,0 @@
//单规则运算
${SingleRule.generateGroovyCode(parameter,processor)}
if(log.isDebugEnabled()){log.debug(" 算数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

17
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/SQL.ftl

@ -1,17 +0,0 @@
//SQL 运算
<#if processor.sqlDatasourceName??>
javax.sql.DataSource ds =io.sc.engine.rule.client.spring.util.EngineSpringApplicationContextUtil.getDataSource('${processor.sqlDatasourceName}');
<#else>
javax.sql.DataSource ds =io.sc.engine.rule.client.spring.util.EngineSpringApplicationContextUtil.getDefaultDataSource();
</#if>
String sql =${ExpressionReplacer.groovy("\n"+processor.sql,"java.lang.String")};
<#if processor.sql??>
ESql.withInstance(ds){ db->
db.query(sql) { rs ->
if (rs.next()) {
${SqlFieldMapping.generateGroovyCode(parameter,processor)}
}
}
}
</#if>

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/TERNARY.ftl

@ -1,4 +0,0 @@
//三元运算
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =(${ExpressionReplacer.groovy(processor.ternaryCondition,null)}) ? (${ExpressionReplacer.groovy(processor.ternaryTrue,parameter.valueType)}) : (${ExpressionReplacer.groovy(processor.ternaryFalse,parameter.valueType)});
if(log.isDebugEnabled()){log.debug(" 三元运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

12
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/WHEN_THEN.ftl

@ -1,12 +0,0 @@
//WhenThen 运算
if(${ExpressionReplacer.groovy(processor.when,null)}){
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =${ExpressionReplacer.groovy(processor.then,parameter.valueType)};
if(log.isDebugEnabled()){log.debug(" WhenThen 运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}
<#-- 如果是短路操作,直接结束处理 -->
<#if processor.isWhenThenShorted>
if(log.isDebugEnabled()){log.debug(" WhenThen 短路!!!");}
if(log.isDebugEnabled()){log.debug(" 参数结果值 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}
return;
</#if>
}

11
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/resource_groovy.ftl

@ -1,11 +0,0 @@
<#assign resource=$wrapper.resource>
//外部引入-------------------------------------------------------
<#if resource.imports??>
${resource.imports}
</#if>
<#if resource.type=="MODEL">
<#include "/model/model.ftl"/>
<#elseif resource.type=="SCORE_CARD">
<#include "/scorecard/score_card.ftl"/>
</#if>

89
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/scorecard/argument.ftl

@ -1,89 +0,0 @@
/**********************************************************************************
* 评分卡参数类 *
**********************************************************************************/
@JsonIgnoreProperties(ignoreUnknown=true)
class Argument{
<#list (resource.scoreCardVars)! as scoreCardVar>
<#if 'NUMBER_RANGE'==(scoreCardVar.type)! || 'INDICATOR_NUMBER_RANGE'==(scoreCardVar.type)! || 'INDICATOR_VALUE'==(scoreCardVar.type)!>
BigDecimal ${CodeReplacer.fieldName(scoreCardVar.code)};//${scoreCardVar.name}, ${scoreCardVar.type}
<#elseif 'OPTION'==(scoreCardVar.type)! || 'INDICATOR_OPTION'==(scoreCardVar.type)!>
String ${CodeReplacer.fieldName(scoreCardVar.code)};//${scoreCardVar.name}, ${scoreCardVar.type}
</#if>
</#list>
<#list (resource.scoreCardVars)! as scoreCardVar>
BigDecimal R_${scoreCardVar.code};//${scoreCardVar.name}得分, OUT
</#list>
/* 最终得分 -------------------------------*/
BigDecimal _SCORE_;//最终得分
<#-- 参数转换(Map) -->
public static Argument convertArgument(Map<String,Object> map){
if(map!=null){
Argument argument =new Argument();
Object obj =null;
<#list (resource.scoreCardVars)! as scoreCardVar>
<#if 'NUMBER_RANGE'==(scoreCardVar.type)! || 'INDICATOR_NUMBER_RANGE'==(scoreCardVar.type)! || 'INDICATOR_VALUE'==(scoreCardVar.type)!>
obj =DataTypeConvertor.convert(map.get("${scoreCardVar.code}"),BigDecimal.class);if(obj!=null){argument.${CodeReplacer.fieldName(scoreCardVar.code)} =obj;}//${scoreCardVar.name}
<#elseif 'OPTION'==(scoreCardVar.type)! || 'INDICATOR_OPTION'==(scoreCardVar.type)!>
obj =DataTypeConvertor.convert(map.get("${scoreCardVar.code}"),String.class);if(obj!=null){argument.${CodeReplacer.fieldName(scoreCardVar.code)} =obj;}//${scoreCardVar.name}
</#if>
</#list>
return argument;
}
return null;
}
<#-- 参数转换(json) -->
public static Argument convertArgument(String json){
if(json!=null && !"".equals(json.trim())){
return JacksonObjectMapper.getDefaultObjectMapper().readValue(json, Argument.class);
}
return null;
}
public void validate(ValidateResult result) {
}
public void mergeParameterValueFromIndicatorLib(Map<String,Object> libs){
<#list (resource.scoreCardVars)! as scoreCardVar>
<#if 'INDICATOR_OPTION'==(scoreCardVar.type)! || 'INDICATOR_NUMBER_RANGE'==(scoreCardVar.type)! || 'INDICATOR_VALUE'==(scoreCardVar.type)!>
<#-- 如果直接给模型参数(类型为指标)设置过非空值,则直接采用设置过的值,否则采用指标库计算结果值 -->
<#if $wrapper.isExecuteTestCase>
if(this.${CodeReplacer.fieldName(scoreCardVar.code)}==null){this.${CodeReplacer.fieldName(scoreCardVar.code)} =libs.get("${scoreCardVar.libCode}_${scoreCardVar.libVersion}").${CodeReplacer.fieldName(scoreCardVar.indicatorCode)};}//${scoreCardVar.name}
<#else>
this.${CodeReplacer.fieldName(scoreCardVar.code)} =libs.get("${scoreCardVar.libCode}_${scoreCardVar.libVersion}").${CodeReplacer.fieldName(scoreCardVar.indicatorCode)};//${scoreCardVar.name}
</#if>
</#if>
</#list>
}
public ResourceResult toResult(){
ResourceResult resourceResult =new ResourceResult();
<#list (resource.scoreCardVars)! as scoreCardVar>
resourceResult.addParameterResult(new ParameterResult("R_${scoreCardVar.code}","""${scoreCardVar.name}""",ParameterType.OUT,"java.math.BigDecimal",this.R_${scoreCardVar.code}==null?null:this.R_${scoreCardVar.code}.toString()));
</#list>
resourceResult.addParameterResult(new ParameterResult("_SCORE_","最终得分",ParameterType.OUT,"java.math.BigDecimal",this._SCORE_==null?null:this._SCORE_.toString()));
return resourceResult;
}
public Map<String,Object> toMap(){
Map<String,Object> map =new HashMap<String,Object>();
<#list (resource.scoreCardVars)! as scoreCardVar>
map.put("${scoreCardVar.code}",this.${scoreCardVar.code});
</#list>
<#list (resource.scoreCardVars)! as scoreCardVar>
map.put("R_${scoreCardVar.code}",this.R_${scoreCardVar.code});
</#list>
map.put("_SCORE_",this._SCORE_);
return map;
}
}

147
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/scorecard/score_card.ftl

@ -1,147 +0,0 @@
/**
* 资源类(name:${resource.name}, code:${resource.code}, version:${resource.version})
* ${(resource.description)!}
* @author auto generated by engine
*/
class ${CodeReplacer.className(resource.code)}_V${resource.version}{
private static final Logger log =LoggerFactory.getLogger(${CodeReplacer.className(resource.code)}_V${resource.version}.class);
/**
* 执行方法(Map作为输入参数,该 Map 封装了调用模型的参数)
* @param map 输入参数封装器
* @return 执行结果
*/
public static ResourceResult execute(Map<String,Object> map) throws Exception{
return execute(map["executor"],map["subModelCode"],map["argument"]);
}
<#-- 执行方法(Map作为输入参数) -->
/**
* 执行方法
* @param executor 执行器对象
* @param subModelCode 子模型代码
* @param data 输入参数
* @return 执行结果
*/
public static ResourceResult execute(Executor executor,String subModelCode,Object data) throws Exception{
if(log.isDebugEnabled()){log.debug("开始执行评分卡 : ${resource.name}_${resource.version}");}
if(data instanceof Map){
if(log.isDebugEnabled()){log.debug("显示输入参数(Map)=================================================\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(data));}
}else if(data instanceof String){
if(log.isDebugEnabled()){log.debug("显示输入参数(Json字符串)=================================================\n{}",data);}
}
<#list ($wrapper.libs)! as lib>
//初始化指标库[name:${lib.name}, code:${lib.code}, version:${lib.version}]
if(log.isDebugEnabled()){log.debug("初始化指标库 : ${lib.name}_${lib.version}");}
${CodeReplacer.className(lib.code,lib.version)} ${CodeReplacer.varName(lib.code,lib.version)} =new ${CodeReplacer.className(lib.code,lib.version)}();
${CodeReplacer.varName(lib.code,lib.version)}.convertArgument(data);
</#list>
//初始化评分卡变量
if(log.isDebugEnabled()){log.debug("初始化评分卡变量");}
Argument argument =Argument.convertArgument(data);
//输入参数合法性检查(指标库)
ValidateResult validateResult =new ValidateResult();
<#list ($wrapper.libs)! as lib>
if(log.isDebugEnabled()){log.debug("开始检查输入参数数据合法性(指标库: ${lib.name}_${lib.version})");}
${CodeReplacer.varName(lib.code,lib.version)}.validate(validateResult);
if(validateResult.hasError()){
if(log.isDebugEnabled()){log.debug("\t检查结果: 失败!");}
ResourceResult result =new ResourceResult();
result.setValidateResult(validateResult);
return result;
}
if(log.isDebugEnabled()){log.debug("\t检查结果: 成功!");}
</#list>
//输入参数合法性检查(评分卡)
if(log.isDebugEnabled()){log.debug("开始检查评分卡输入参数数据合法性");}
argument.validate(validateResult);
if(validateResult.hasError()){
if(log.isDebugEnabled()){log.debug("\t检查结果: 失败!");}
ResourceResult result =new ResourceResult();
result.setValidateResult(validateResult);
return result;
}
if(log.isDebugEnabled()){log.debug("\t检查结果: 成功!");}
//执行指标库
<#if $wrapper.isExecuteTestCase>
<#else>
<#list ($wrapper.libs)! as lib>
if(log.isDebugEnabled()){log.debug("开始执行指标库: ${lib.name}_${lib.version}");}
${CodeReplacer.varName(lib.code,lib.version)}.execute();
</#list>
</#if>
//合并指标库指标
if(log.isDebugEnabled()){log.debug("开始合并指标库指标");}
Map<String,Object> indicatorLibs =new HashMap<String,Object>();
<#list ($wrapper.libs)! as lib>
indicatorLibs.put("${lib.code}_${lib.version}",${CodeReplacer.varName(lib.code,lib.version)});
</#list>
argument.mergeParameterValueFromIndicatorLib(indicatorLibs);
if(log.isDebugEnabled()){log.debug("显示合并后输入参数:\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(argument));}
//调用评分卡
${CodeReplacer.fieldName(resource.code)}(executor,argument);//调用评分卡(${resource.name})
//返回结果
ResourceResult result =argument.toResult();
if(log.isDebugEnabled()){log.debug("评分卡调用成功,返回结果:\n{}",JacksonObjectMapper.getDefaultObjectMapper().writeValueAsString(result));}
return result;
}
//${resource.name}
public static void ${CodeReplacer.fieldName(resource.code)}(Executor executor,Argument ${ExpressionReplacer.ARGUMENT_NAME}){
if(log.isDebugEnabled()){log.debug("开始调用评分卡: {}","${resource.name}");}
<#list (resource.scoreCardVars)! as scoreCardVar>
//${scoreCardVar.name}
${CodeReplacer.fieldName(scoreCardVar.code)}(executor,${ExpressionReplacer.ARGUMENT_NAME});
</#list>
//计算最终得分
${ExpressionReplacer.ARGUMENT_NAME}._SCORE_ =0;
<#list (resource.scoreCardVars)! as scoreCardVar>
${ExpressionReplacer.ARGUMENT_NAME}._SCORE_ +=${ExpressionReplacer.ARGUMENT_NAME}.R_${scoreCardVar.code}==null?0:${ExpressionReplacer.ARGUMENT_NAME}.R_${scoreCardVar.code};
</#list>
if(log.isDebugEnabled()){log.debug("评分卡结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}._SCORE_);}
}
<#list (resource.scoreCardVars)! as scoreCardVar>
//计算评分卡变量得分(${scoreCardVar.name})
public static void ${CodeReplacer.fieldName(scoreCardVar.code)}(Executor executor,Argument arg){
<#if "OPTION"==(scoreCardVar.type)! || "INDICATOR_OPTION"==(scoreCardVar.type)!>
//选项
if(log.isDebugEnabled()){log.debug(" {}","${scoreCardVar.name}(OUT)");}
${Option.generateGroovyCode(scoreCardVar)}
if(log.isDebugEnabled()){log.debug(" 选项运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.R_${scoreCardVar.code});}
<#elseif "NUMBER_RANGE"==(scoreCardVar.type)! || "INDICATOR_NUMBER_RANGE"==(scoreCardVar.type)!>
//数值分段函数
if(log.isDebugEnabled()){log.debug(" {}","${scoreCardVar.name}(OUT)");}
${NumberRange.generateGroovyCode(scoreCardVar)}
if(log.isDebugEnabled()){log.debug(" 数值分段函数运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.R_${scoreCardVar.code});}
<#elseif "INDICATOR_VALUE"==(scoreCardVar.type)!>
//指标值
if(log.isDebugEnabled()){log.debug(" {}","${scoreCardVar.name}(OUT)");}
${ExpressionReplacer.ARGUMENT_NAME}.R_${CodeReplacer.fieldName(scoreCardVar.code)} =${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(scoreCardVar.code)};
if(log.isDebugEnabled()){log.debug(" 指标值运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.R_${CodeReplacer.fieldName(scoreCardVar.code)});}
</#if>
}
</#list>
}
<#-- 参数类 -->
<#include "/scorecard/argument.ftl"/>
<#-- 库类 -->
<#include "/lib/lib.ftl"/>
<#-- 数据字典类 -->
<#include "/dictionary/dictionary.ftl"/>
//执行并返回
${CodeReplacer.className(resource.code)}_V${resource.version}.execute(INPUT_PARAMETER);

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/dictionary_render.tpl")
#include("/io/sc/engine/rule/core/code/template/functions_render.tpl")
#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/lib_render.tpl")
#include("/io/sc/engine/rule/core/code/template/package_render.tpl")
#@renderPackage(packageName)

33
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)
@ -133,6 +133,29 @@ class #(className(resource.code,resource.version)) {
}
#@renderModel(model)
### 决策树函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("DECISION_TREE"==processor.type.toString())
//决策树函数: #(parameter.name)(#(parameter.type))
#(DecisionTree.groovy(parameter,processor))
#end
#end
#end
#end
### 执行流函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("EXECUTION_FLOW"==processor.type.toString())
//执行流函数: #(parameter.name)(#(parameter.type))
#(tabs(ExecutionFlow.groovy(parameter,processor),1))
#end
#end
#end
#end
}
//******************************************************************************

22
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/import_render.tpl

@ -35,21 +35,9 @@ import static io.sc.engine.rule.core.function.ArithmeticFunction.randomInt;
import static io.sc.engine.rule.core.function.ArithmeticFunction.root;
import static io.sc.engine.rule.core.function.ArithmeticFunction.sum;
import static io.sc.engine.rule.core.function.ArithmeticFunction.transformSequencing;
import static io.sc.engine.rule.core.function.CollectionFunction.hasElements;
import static io.sc.engine.rule.core.function.CollectionFunction.collectionSize;
import static io.sc.engine.rule.core.function.CollectionFunction.collectionMax;
import static io.sc.engine.rule.core.function.CollectionFunction.collectionMin;
import static io.sc.engine.rule.core.function.DateFunction.now;
import static io.sc.engine.rule.core.function.DateFunction.formatDate;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd_HH_mm_ss_SSS;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd_HH_mm_ss;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd_HH_mm;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd_HH;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd;
import static io.sc.engine.rule.core.function.DateFunction.yyyyMMdd;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM;
import static io.sc.engine.rule.core.function.DateFunction.yyyyMM;
import static io.sc.engine.rule.core.function.DateFunction.yyyy;
import static io.sc.engine.rule.core.function.DateFunction.yyyy_MM_dd;
import static io.sc.engine.rule.core.function.NormalDistributionFunction.G;
import static io.sc.engine.rule.core.function.NormalDistributionFunction.iG;
import static io.sc.engine.rule.core.function.SpecialValueFunction.infinite;
@ -68,6 +56,7 @@ import static io.sc.engine.rule.core.function.StringFunction.lowerCase;
import static io.sc.engine.rule.core.function.StringFunction.startsWith;
import static io.sc.engine.rule.core.function.StringFunction.trim;
import static io.sc.engine.rule.core.function.StringFunction.upperCase;
import static io.sc.platform.util.CollectionUtil.hasElements;
import static io.sc.platform.util.DateUtil.yearsBetween;
import static io.sc.platform.util.DateUtil.monthsBetween;
import static io.sc.platform.util.DateUtil.weeksBetween;
@ -75,13 +64,6 @@ import static io.sc.platform.util.DateUtil.daysBetween;
import static io.sc.platform.util.DateUtil.hoursBetween;
import static io.sc.platform.util.DateUtil.minutesBetween;
import static io.sc.platform.util.DateUtil.secondsBetween;
import static io.sc.platform.util.DateUtil.plusYears;
import static io.sc.platform.util.DateUtil.plusMonths;
import static io.sc.platform.util.DateUtil.plusWeeks;
import static io.sc.platform.util.DateUtil.plusDays;
import static io.sc.platform.util.DateUtil.plusHours;
import static io.sc.platform.util.DateUtil.plusMinutes;
import static io.sc.platform.util.DateUtil.plusSeconds;
import static io.sc.platform.util.NumberUtil.comma;
import static io.sc.platform.util.NumberUtil.decimal;
import static io.sc.platform.util.NumberUtil.money;

1
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/lib_render.tpl

@ -6,6 +6,7 @@ class #(className(lib.code,lib.version)) {
//通过输入参数构建指标库对象
public void convertArgument(Map<String,Object> map){
#(className(lib.code,lib.version)) arg =this;
#(tabs(IndicatorGenerator.generateConvertorFromMap(lib.indicators,"this"),2))
}

22
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/parameter_render.tpl

@ -100,26 +100,4 @@
#end
#end
### 决策树函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("DECISION_TREE"==processor.type.toString())
//决策树函数: #(parameter.name)(#(parameter.type))
#(tabs(DecisionTree.groovy(parameter,processor),1))
#end
#end
#end
#end
### 执行流函数
#for(parameter : model.allParameters)
#if("INTERMEDIATE"==parameter.type.toString() || "OUT"==parameter.type.toString())
#for(processor : parameter.processors)
#if("EXECUTION_FLOW"==processor.type.toString())
//执行流函数: #(parameter.name)(#(parameter.type))
#(tabs(ExecutionFlow.groovy(parameter,processor),1))
#end
#end
#end
#end
#end

1
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/processor/http_request.tpl

@ -0,0 +1 @@
#(tabs(HttpRequest.groovy(parameter,processor),2))

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.rule.frontend",
"version": "8.2.11",
"version": "8.2.13",
"description": "",
"private": false,
"keywords": [],
@ -112,7 +112,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.65",
"platform-core": "8.2.70",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

317
io.sc.engine.rule.frontend/src/views/shared/processors/HttpRequest.ts

@ -4,7 +4,9 @@ import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
class HttpRequest extends Processor {
#HttpMethodTypeEnum: any;
#editorForm: any;
#httpResponseBodyRef = ref(undefined);
#httpMethodTypeEnum: any;
#httpMethodTypeOptionsRef = ref(<any>[]);
#HttpAuthorizationTypeEnum: any;
#httpAuthorizationTypeOptionsRef = ref(<any>[]);
@ -13,12 +15,6 @@ class HttpRequest extends Processor {
super(targetType, context);
this.PROCESSOR_TYPE = 'HTTP_REQUEST';
this.EDITOR_DIALOG_WIDTH = 1024;
EnumTools.fetch(['io.sc.engine.rule.core.enums.HttpMethodType', 'io.sc.engine.rule.core.enums.HttpAuthorizationType']).then((value) => {
this.#HttpMethodTypeEnum = value.HttpMethodType;
this.#httpMethodTypeOptionsRef = Options.enum(this.#HttpMethodTypeEnum);
this.#HttpAuthorizationTypeEnum = value.HttpAuthorizationType;
this.#httpAuthorizationTypeOptionsRef = Options.enum(this.#HttpAuthorizationTypeEnum);
});
}
public getToolbarAction(): any {
@ -44,7 +40,7 @@ class HttpRequest extends Processor {
public getEditorFields(): any {
return [
{
colSpan: 3,
colSpan: 2,
name: 'httpMethod',
label: $t('re.processor.grid.entity.httpMethod'),
type: 'w-select',
@ -55,16 +51,7 @@ class HttpRequest extends Processor {
},
},
{
colSpan: 9,
name: 'httpUrl',
label: $t('re.processor.grid.entity.httpUrl'),
type: 'w-text',
showIf: (args: any) => {
return args.form.getFieldValue('type') === this.PROCESSOR_TYPE;
},
},
{
colSpan: 3,
colSpan: 2,
name: 'httpAuthType',
label: $t('re.processor.grid.entity.httpAuthType'),
type: 'w-select',
@ -74,7 +61,7 @@ class HttpRequest extends Processor {
},
},
{
colSpan: 3,
colSpan: 4,
name: 'httpAuthApikey',
label: $t('re.processor.grid.entity.httpAuthApikey'),
type: 'w-text',
@ -83,7 +70,7 @@ class HttpRequest extends Processor {
},
},
{
colSpan: 6,
colSpan: 4,
name: 'httpAuthApiValue',
label: $t('re.processor.grid.entity.httpAuthApiValue'),
type: 'w-text',
@ -92,7 +79,7 @@ class HttpRequest extends Processor {
},
},
{
colSpan: 3,
colSpan: 4,
name: 'httpAuthBasicUsername',
label: $t('re.processor.grid.entity.httpAuthBasicUsername'),
type: 'w-text',
@ -101,7 +88,7 @@ class HttpRequest extends Processor {
},
},
{
colSpan: 6,
colSpan: 4,
name: 'httpAuthBasicPassword',
label: $t('re.processor.grid.entity.httpAuthBasicPassword'),
type: 'w-text',
@ -110,7 +97,7 @@ class HttpRequest extends Processor {
},
},
{
colSpan: 9,
colSpan: 8,
name: 'httpAuthBearerToken',
label: $t('re.processor.grid.entity.httpAuthBearerToken'),
type: 'w-text',
@ -119,14 +106,134 @@ class HttpRequest extends Processor {
},
},
{
colSpan: 12,
colSpan: 6,
firstCol: true,
name: 'httpUrl',
label: $t('re.processor.grid.entity.httpUrl'),
type: 'w-code-mirror',
lang: 'javascript',
rows: 7,
toolbar: false,
placeholder: true,
lineWrap: true,
lineBreak: true,
lineHeight: '1.3rem',
fontSize: '0.75rem',
autoCompletion: this.autoCompletionManager.autoCompletion(),
showIf: (args: any) => {
return args.form.getFieldValue('type') === this.PROCESSOR_TYPE;
},
},
{
colSpan: 6,
name: 'urlParameterValues',
label: $t('re.processor.grid.entity.sqlParameterValues'),
showIf: (args: any) => {
return args.form.getFieldValue('type') === this.PROCESSOR_TYPE;
},
type: 'w-grid',
height: 110,
title: $t('re.processor.grid.entity.sqlParameterValues'),
localMode: true,
autoFetchData: false,
dense: true,
dbClickOperation: 'edit',
dndMode: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
{
name: 'analyze',
label: $t('analyze'),
icon: 'bi-tag',
click: (args: any) => {
const sql = this.#editorForm.getFieldValue('httpUrl');
const regex = /\$\{[\u0000-\uFFFF]+?\}/g;
const array: any[] = sql.match(regex);
const rows: any[] = [];
array.forEach((item) => {
rows.push({ name: item, value: '' });
});
const grid = this.#editorForm.getFieldComponent('urlParameterValues');
grid.setLocalData(rows);
},
},
'separator',
'add',
'edit',
[
{
extend: 'remove',
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('urlParameterValues');
grid.removeRows(args.selecteds);
},
},
{
extend: 'remove',
name: 'removeAll',
label: $t('deleteAll'),
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('urlParameterValues');
grid.setLocalData([]);
},
},
],
],
columns: [
{
width: '50%',
name: 'name',
label: $t('name'),
align: 'left',
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
{
width: '100%',
name: 'value',
label: $t('value'),
sortable: false,
},
],
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{
name: 'name',
label: $t('name'),
type: 'w-code-mirror',
toolbar: false,
lang: 'java',
rows: 1,
placeholder: true,
autoCompletion: this.autoCompletionManager.autoCompletion(),
},
{
name: 'value',
label: $t('value'),
type: 'w-text',
},
],
},
},
},
{
colSpan: 6,
name: 'httpRequestBody',
label: $t('re.processor.grid.entity.httpRequestBody'),
showIf: (args: any) => {
return args.form.getFieldValue('type') === this.PROCESSOR_TYPE;
},
type: 'w-code-mirror',
rows: 4,
rows: 7,
toolbar: false,
lineNumber: false,
lang: 'json',
@ -136,6 +243,145 @@ class HttpRequest extends Processor {
autoCompletion: this.autoCompletionManager.autoCompletion(),
userDefinedFunctions: this.userDefinedFunctionsManager.userDefinedFunctions(),
},
{
colSpan: 6,
name: 'bodyParameterValues',
label: $t('re.processor.grid.entity.sqlParameterValues'),
showIf: (args: any) => {
return args.form.getFieldValue('type') === this.PROCESSOR_TYPE;
},
type: 'w-grid',
height: 110,
title: $t('re.processor.grid.entity.sqlParameterValues'),
localMode: true,
autoFetchData: false,
dense: true,
dbClickOperation: 'edit',
dndMode: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
{
name: 'send',
label: $t('send'),
icon: 'bi-send',
click: (args: any) => {
const httpMethod = this.#editorForm.getFieldValue('httpMethod');
const httpUrl = this.#editorForm.getFieldValue('httpUrl');
const httpAuthType = this.#editorForm.getFieldValue('httpAuthType');
const httpAuthApikey = this.#editorForm.getFieldValue('httpAuthApikey');
const httpAuthApiValue = this.#editorForm.getFieldValue('httpAuthApiValue');
const httpAuthBasicUsername = this.#editorForm.getFieldValue('httpAuthBasicUsername');
const httpAuthBasicPassword = this.#editorForm.getFieldValue('httpAuthBasicPassword');
const httpAuthBearerToken = this.#editorForm.getFieldValue('httpAuthBearerToken');
const httpRequestBody = this.#editorForm.getFieldValue('httpRequestBody');
axios
.post(Environment.apiContextPath('/api/re/indicator/processor/sendWebRequest'), {
httpMethod,
httpUrl,
httpAuthType,
httpAuthApikey,
httpAuthApiValue,
httpAuthBasicUsername,
httpAuthBasicPassword,
httpAuthBearerToken,
httpRequestBody,
})
.then((response) => {
const result = response.data;
if (result.successful) {
this.#httpResponseBodyRef.value = result.content;
} else {
this.#httpResponseBodyRef.value = result.status + ',' + result.error;
}
});
},
},
'separator',
{
name: 'analyze',
label: $t('analyze'),
icon: 'bi-tag',
click: (args: any) => {
const sql = this.#editorForm.getFieldValue('httpRequestBody');
const regex = /\$\{[\u0000-\uFFFF]+?\}/g;
const array: any[] = sql.match(regex);
const rows: any[] = [];
array.forEach((item) => {
rows.push({ name: item, value: '' });
});
const grid = this.#editorForm.getFieldComponent('bodyParameterValues');
grid.setLocalData(rows);
},
},
'separator',
'add',
'edit',
[
{
extend: 'remove',
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('bodyParameterValues');
grid.removeRows(args.selecteds);
},
},
{
extend: 'remove',
name: 'removeAll',
label: $t('deleteAll'),
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('bodyParameterValues');
grid.setLocalData([]);
},
},
],
],
columns: [
{
width: '50%',
name: 'name',
label: $t('name'),
align: 'left',
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
{
width: '100%',
name: 'value',
label: $t('value'),
sortable: false,
},
],
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{
name: 'name',
label: $t('name'),
type: 'w-code-mirror',
toolbar: false,
lang: 'java',
rows: 1,
placeholder: true,
autoCompletion: this.autoCompletionManager.autoCompletion(),
},
{
name: 'value',
label: $t('value'),
type: 'w-text',
},
],
},
},
},
{
colSpan: 12,
name: 'httpResponseBody',
@ -145,11 +391,14 @@ class HttpRequest extends Processor {
},
type: 'w-code-mirror',
lang: 'json',
rows: 5,
rows: 4,
lineHeight: '1.3rem',
fontSize: '0.75rem',
toolbar: false,
lineNumber: false,
lineWrap: false,
lineBreak: true,
modelValue: this.#httpResponseBodyRef.value,
},
{
colSpan: 12,
@ -159,15 +408,19 @@ class HttpRequest extends Processor {
return args.form.getFieldValue('type') === this.PROCESSOR_TYPE;
},
type: 'w-code-mirror',
rows: 8,
rows: 5,
toolbar: false,
lineNumber: false,
lang: 'json',
lineHeight: '1.3rem',
fontSize: '0.75rem',
lang: 'java',
lineWrap: false,
lineBreak: true,
placeholder: true,
autoCompletion: this.autoCompletionManager.autoCompletion(),
userDefinedFunctions: this.userDefinedFunctionsManager.userDefinedFunctions(),
defaultValue:
'if(${response}.getSuccessful()){\n\t//def object =new groovy.xml.XmlParser().parse(${response}.getContent());\n\tdef object = new groovy.json.JsonSlurper().parseText(${response}.getContent());\n}',
},
];
}
@ -193,6 +446,14 @@ class HttpRequest extends Processor {
args.grid.getEditorDialog().setWidth(this.EDITOR_DIALOG_WIDTH);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
this.#editorForm = args.grid.getEditorForm();
EnumTools.fetch(['io.sc.engine.rule.core.enums.HttpMethodType', 'io.sc.engine.rule.core.enums.HttpAuthorizationType']).then((value) => {
this.#httpMethodTypeEnum = value.HttpMethodType;
this.#httpMethodTypeOptionsRef.value = Options.enum(this.#httpMethodTypeEnum);
this.#HttpAuthorizationTypeEnum = value.HttpAuthorizationType;
this.#httpAuthorizationTypeOptionsRef.value = Options.enum(this.#HttpAuthorizationTypeEnum);
});
}
}

15
io.sc.engine.rule.frontend/src/views/shared/processors/Sql.ts

@ -198,6 +198,7 @@ class Sql extends Processor {
label: $t('execute'),
icon: 'bi-caret-right',
click: (args: any) => {
const datasourceName = this.#editorForm.getFieldValue('sqlDatasourceName');
const sql = this.#editorForm.getFieldValue('sql');
const grid = this.#editorForm.getFieldComponent('sqlParameterValues');
const sqlParameterValues = grid?.getRows();
@ -209,6 +210,7 @@ class Sql extends Processor {
}
noErrorAxios
.post(Environment.apiContextPath(url), {
datasourceName: datasourceName,
sql: sql,
sqlParameterValues: sqlParameterValues,
})
@ -302,8 +304,17 @@ class Sql extends Processor {
{
name: 'parameter',
label: $t('parameterName'),
type: 'w-select',
options: this.#parameterOptionsRef.value,
//type: 'w-select',
//options: this.#parameterOptionsRef.value,
toolbar: false,
type: 'w-code-mirror',
lang: 'java',
rows: 1,
placeholder: true,
lineWrap: false,
lineBreak: false,
autoCompletion: this.autoCompletionManager.autoCompletion(),
userDefinedFunctions: this.userDefinedFunctionsManager.userDefinedFunctions(),
},
{
name: 'field',

11
io.sc.engine.rule.frontend/webpack.config.mf.cjs

@ -9,13 +9,20 @@ const projectName = packageJson.name; // 项目名称
const deps = packageJson.dependencies; // 项目依赖
// 读取本地路由配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const data = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(data);
const routesJson = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(routesJson);
const mfExposes = {};
for (const route of routes) {
mfExposes[route.component] = route.componentPath;
}
// 读取远程组件配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const remoteComponentsJson = fs.readFileSync('./src/remote-components/remote-components.json', 'utf8');
const remoteComponents = Json5.parse(remoteComponentsJson);
for (const remoteComponent of remoteComponents) {
mfExposes[remoteComponent.component] = remoteComponent.componentPath;
}
// 导出 webapck 配置的模块联邦部分
module.exports = {
plugins: [

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

@ -42,7 +42,7 @@ public class ParameterAndValueTypeWebController {
}
@GetMapping("findByDictionaryCodeAndVersion/{code}/{version}")
public ParameterAndValueType findByDictionaryCodeAndVersion(@PathVariable(name="code",required=true)String code, @PathVariable(name="version",required=true)Integer version,Locale locale) throws Exception{
public ParameterAndValueType findByDictionaryCodeAndVersion(@PathVariable(name="code",required=true)String code, @PathVariable(name="version",required=false)Integer version,Locale locale) throws Exception{
return service.findByDictionaryCodeAndVersion(code,version,locale);
}
}

16
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/controller/IndicatorProcessorWebController.java

@ -1,5 +1,9 @@
package io.sc.engine.rule.server.lib.controller;
import io.sc.engine.rule.core.WebRequest;
import io.sc.engine.rule.core.WebResponse;
import io.sc.engine.rule.core.enums.HttpAuthorizationType;
import io.sc.engine.rule.core.enums.HttpMethodType;
import io.sc.engine.rule.core.enums.ReplaceMode;
import io.sc.engine.rule.server.common.service.ParameterAndValueTypeService;
import io.sc.engine.rule.server.common.service.support.ParameterAndValueType;
@ -17,15 +21,22 @@ import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.orm.entity.BaseEntity;
import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.util.ObjectMapperUtil;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 指标处理器 Controller
@ -68,4 +79,9 @@ public class IndicatorProcessorWebController extends RestCrudController<Indicato
public SqlQueryResult executeSql(@RequestBody SqlQueryRequest request) throws Exception{
return service.executeSql(request);
}
@PostMapping("sendWebRequest")
public WebResponse sendWebRequest(@RequestBody WebRequest webRequest) throws Exception {
return service.sendWebRequest(webRequest);
}
}

5
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/IndicatorProcessorService.java

@ -1,5 +1,7 @@
package io.sc.engine.rule.server.lib.service;
import io.sc.engine.rule.core.WebRequest;
import io.sc.engine.rule.core.WebResponse;
import io.sc.engine.rule.server.lib.entity.IndicatorProcessorEntity;
import io.sc.engine.rule.server.lib.repository.IndicatorProcessorRepository;
import io.sc.engine.rule.server.model.service.support.AutoMatchObjectProperties;
@ -16,5 +18,6 @@ import java.util.List;
public interface IndicatorProcessorService extends DaoService<IndicatorProcessorEntity, String, IndicatorProcessorRepository>{
public List<ObjectProperty> listObejctPropertiesByProcessorId(String processorId) throws Exception;
public List<ObjectProperty> autoMatch(AutoMatchObjectProperties autoMatchObjectProperties) throws Exception;
public SqlQueryResult executeSql(SqlQueryRequest request);
public SqlQueryResult executeSql(SqlQueryRequest request) throws Exception;
public WebResponse sendWebRequest(WebRequest webRequest) throws Exception;
}

30
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/IndicatorProcessorServiceImpl.java

@ -1,11 +1,15 @@
package io.sc.engine.rule.server.lib.service.impl;
import com.fasterxml.jackson.core.type.TypeReference;
import io.sc.engine.rule.core.WebRequest;
import io.sc.engine.rule.core.WebResponse;
import io.sc.engine.rule.core.enums.ReplaceMode;
import io.sc.engine.rule.core.util.ExpressionReplacer;
import io.sc.engine.rule.core.util.ValueTypeUtil;
import io.sc.engine.rule.core.util.WebRequestUtil;
import io.sc.engine.rule.server.common.service.ParameterAndValueTypeService;
import io.sc.engine.rule.server.common.service.support.ParameterAndValueType;
import io.sc.engine.rule.server.common.util.VariableCodeAndNameReplacer;
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;
@ -24,9 +28,9 @@ import io.sc.engine.rule.server.model.service.support.AutoMatchObjectProperties;
import io.sc.engine.rule.server.model.service.support.ObjectProperty;
import io.sc.engine.rule.server.model.support.processor.SqlQueryRequest;
import io.sc.engine.rule.server.model.support.processor.SqlQueryResult;
import io.sc.engine.rule.server.common.util.VariableCodeAndNameReplacer;
import io.sc.platform.core.response.ValidationErrorBuilder;
import io.sc.platform.core.util.ValidatorUtil;
import io.sc.platform.jdbc.service.DatasourceService;
import io.sc.platform.jdbc.util.SqlValidator;
import io.sc.platform.orm.entity.support.EntityChangedEventType;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
@ -40,6 +44,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
@ -49,6 +54,7 @@ public class IndicatorProcessorServiceImpl extends DaoServiceImpl<IndicatorProce
@Autowired private IndicatorService indicatorService;
@Autowired private DictionaryService dictionaryService;
@Autowired private ParameterAndValueTypeService parameterAndValueTypeService;
@Autowired private DatasourceService datasourceService;
@Autowired private JdbcTemplate jdbcTemplate;
@Override
@ -278,7 +284,7 @@ public class IndicatorProcessorServiceImpl extends DaoServiceImpl<IndicatorProce
return result;
}
public SqlQueryResult executeSql(SqlQueryRequest request) {
public SqlQueryResult executeSql(SqlQueryRequest request) throws Exception {
if(request!=null) {
String sql =request.getSql();
if(StringUtils.hasText(sql)) {
@ -287,14 +293,32 @@ public class IndicatorProcessorServiceImpl extends DaoServiceImpl<IndicatorProce
}
Map<String,String> mapping =request.getSqlParameterValueMap();
String replacedSql = ExpressionReplacer.replace(sql, mapping);
if(StringUtils.hasText(request.getDatasourceName())){
DataSource ds =datasourceService.getDatasource(request.getDatasourceName());
if(ds!=null){
JdbcTemplate jd =new JdbcTemplate(ds);
return jd.query(replacedSql, new ResultSetExtractor<SqlQueryResult>() {
@Override
public SqlQueryResult extractData(ResultSet rs) throws SQLException, DataAccessException {
return SqlQueryResult.from(rs);
}
}, new Object[]{});
}
}else {
return jdbcTemplate.query(replacedSql, new ResultSetExtractor<SqlQueryResult>() {
@Override
public SqlQueryResult extractData(ResultSet rs) throws SQLException, DataAccessException {
return SqlQueryResult.from(rs);
}
},new Object[] {});
}, new Object[]{});
}
}
}
return null;
}
@Override
public WebResponse sendWebRequest(WebRequest webRequest) throws Exception {
return WebRequestUtil.sendWebRequest(webRequest);
}
}

15
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/HttpRequestParameterProcessorEntity.java

@ -55,6 +55,7 @@ public class HttpRequestParameterProcessorEntity extends ParameterProcessorEntit
@Column(name="HTTP_PARAMS_")
private String httpParams;
@Column(name="HTTP_REQUEST_BODY_")
private String httpRequestBody;
@ -220,6 +221,20 @@ public class HttpRequestParameterProcessorEntity extends ParameterProcessorEntit
result =true;
}
this.httpResponseMapping =replaced;
replaced =parameterAndValueType.replace(this.httpUrl, mode);
replaced =(replaced==null?"":replaced);
if(!replaced.equals(this.httpUrl)) {
result =true;
}
this.httpUrl =replaced;
replaced =parameterAndValueType.replace(this.httpRequestBody, mode);
replaced =(replaced==null?"":replaced);
if(!replaced.equals(this.httpRequestBody)) {
result =true;
}
this.httpRequestBody =replaced;
return result;
}
}

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ParameterProcessorService.java

@ -28,5 +28,5 @@ public interface ParameterProcessorService extends DaoService<ParameterProcessor
public List<ObjectProperty> listObejctPropertiesByProcessorId(String processorId) throws Exception;
public List<ObjectProperty> autoMatch(AutoMatchObjectProperties autoMatchObjectProperties) throws Exception;
public void importFromCsv(String parameterId,String csvContent, String splitChar) throws Exception;
public SqlQueryResult executeSql(SqlQueryRequest request);
public SqlQueryResult executeSql(SqlQueryRequest request) throws Exception;
}

20
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterProcessorServiceImpl.java

@ -29,6 +29,7 @@ import io.sc.engine.rule.server.model.support.processor.SqlQueryResult;
import io.sc.engine.rule.server.model.vo.ParameterProcessorVo;
import io.sc.engine.rule.server.model.vo.processor.ObjectPropertiesParameterProcessorVo;
import io.sc.engine.rule.server.common.util.VariableCodeAndNameReplacer;
import io.sc.platform.jdbc.service.DatasourceService;
import io.sc.platform.jdbc.util.SqlValidator;
import io.sc.platform.orm.entity.support.EntityChangedEventType;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
@ -44,6 +45,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
import java.io.ByteArrayInputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -57,6 +59,7 @@ public class ParameterProcessorServiceImpl
@Autowired private ParameterService parameterService;
@Autowired private DictionaryService dictionaryService;
@Autowired private ParameterAndValueTypeService parameterAndValueTypeService;
@Autowired private DatasourceService datasourceService;
@Autowired private JdbcTemplate jdbcTemplate;
@Override
@ -355,18 +358,31 @@ public class ParameterProcessorServiceImpl
}
}
public SqlQueryResult executeSql(SqlQueryRequest request) {
public SqlQueryResult executeSql(SqlQueryRequest request) throws Exception {
if(request!=null) {
String sql =request.getSql();
if(StringUtils.hasText(sql)) {
Map<String,String> mapping =request.getSqlParameterValueMap();
String replacedSql =ExpressionReplacer.replace(sql, mapping);
if(StringUtils.hasText(request.getDatasourceName())){
DataSource ds =datasourceService.getDatasource(request.getDatasourceName());
if(ds!=null){
JdbcTemplate jd =new JdbcTemplate(ds);
return jd.query(replacedSql, new ResultSetExtractor<SqlQueryResult>() {
@Override
public SqlQueryResult extractData(ResultSet rs) throws SQLException, DataAccessException {
return SqlQueryResult.from(rs);
}
}, new Object[]{});
}
}else {
return jdbcTemplate.query(replacedSql, new ResultSetExtractor<SqlQueryResult>() {
@Override
public SqlQueryResult extractData(ResultSet rs) throws SQLException, DataAccessException {
return SqlQueryResult.from(rs);
}
},new Object[] {});
}, new Object[]{});
}
}
}
return null;

7
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/support/processor/SqlQueryRequest.java

@ -8,6 +8,7 @@ import java.util.Map;
import org.springframework.util.StringUtils;
public class SqlQueryRequest {
private String datasourceName;
private String sql;
private List<SqlParameterValue> sqlParameterValues =new ArrayList<SqlParameterValue>();
@ -23,6 +24,12 @@ public class SqlQueryRequest {
return null;
}
public String getDatasourceName() {
return datasourceName;
}
public void setDatasourceName(String datasourceName) {
this.datasourceName = datasourceName;
}
public String getSql() {
return sql;
}

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.st.frontend",
"version": "8.2.11",
"version": "8.2.13",
"description": "",
"private": false,
"keywords": [],
@ -112,7 +112,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.65",
"platform-core": "8.2.70",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

11
io.sc.engine.st.frontend/webpack.config.mf.cjs

@ -9,13 +9,20 @@ const projectName = packageJson.name; // 项目名称
const deps = packageJson.dependencies; // 项目依赖
// 读取本地路由配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const data = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(data);
const routesJson = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(routesJson);
const mfExposes = {};
for (const route of routes) {
mfExposes[route.component] = route.componentPath;
}
// 读取远程组件配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const remoteComponentsJson = fs.readFileSync('./src/remote-components/remote-components.json', 'utf8');
const remoteComponents = Json5.parse(remoteComponentsJson);
for (const remoteComponent of remoteComponents) {
mfExposes[remoteComponent.component] = remoteComponent.componentPath;
}
// 导出 webapck 配置的模块联邦部分
module.exports = {
plugins: [

4
io.sc.platform.ai.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.ai.frontend",
"version": "8.2.11",
"version": "8.2.13",
"description": "",
"private": false,
"keywords": [],
@ -112,7 +112,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.65",
"platform-core": "8.2.70",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

11
io.sc.platform.ai.frontend/webpack.config.mf.cjs

@ -9,13 +9,20 @@ const projectName = packageJson.name; // 项目名称
const deps = packageJson.dependencies; // 项目依赖
// 读取本地路由配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const data = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(data);
const routesJson = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(routesJson);
const mfExposes = {};
for (const route of routes) {
mfExposes[route.component] = route.componentPath;
}
// 读取远程组件配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const remoteComponentsJson = fs.readFileSync('./src/remote-components/remote-components.json', 'utf8');
const remoteComponents = Json5.parse(remoteComponentsJson);
for (const remoteComponent of remoteComponents) {
mfExposes[remoteComponent.component] = remoteComponent.componentPath;
}
// 导出 webapck 配置的模块联邦部分
module.exports = {
plugins: [

9
io.sc.platform.core.frontend/.bin/sync.js

@ -8,7 +8,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
* 同步 platform-core 定义的前端项目配置
* platform-core 库的 template-project 目录中复制前端项目文件到本地项目
*/
const { rm, cp, mergeJsonFile, parseJson, sortObject } = require('./util.js');
const { mkdir, rm, cp, mergeJsonFile, parseJson, sortObject, isFileExisted } = require('./util.js');
const sync = () => {
if (isFrontendProject()) {
@ -51,6 +51,13 @@ const syncFrontendProject = () => {
const sourceDir = process.cwd() + '/node_modules/platform-core/template-project/';
const targetDir = process.cwd() + '/';
if (!isFileExisted(targetDir + 'src/remote-components')) {
mkdir(targetDir + 'src/remote-components');
}
if (!isFileExisted(targetDir + 'src/remote-components/remote-components.json')) {
cp(sourceDir + 'src/remote-components/remote-components.json', targetDir + 'src/remote-components/remote-components.json');
}
cp(sourceDir + 'src/boostrap.ts', targetDir + 'src/boostrap.ts');
cp(sourceDir + '.browserslistrc', targetDir + '.browserslistrc');
cp(sourceDir + '.editorconfig', targetDir + '.editorconfig');

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

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

4
io.sc.platform.core.frontend/src/components/index.ts

@ -2,7 +2,7 @@
* ,
*/
import component_testcase_globalRoute from '@/views/testcase/global-route/GlobalRoute.vue';
import component_testcase_remoteComponent from '@/views/testcase/remote-component/RemoteComponent.vue';
import component_testcase_openNoMenuRoute from '@/views/testcase/route/OpenNoMenuRoute.vue';
import component_testcase_noMenuRoute from '@/views/testcase/route/NoMenuRoute.vue';
import component_testcase_mathEditor from '@/views/testcase/math/MathEditor.vue';
@ -24,7 +24,7 @@ import component_testcase_gridLayout from '@/views/likm/GridLayout.vue';
import component_testcase_likmTreeGrid from '@/views/likm/TreeGrid.vue';
const localComponents = {
'component.testcase.globalRoute': component_testcase_globalRoute,
'component.testcase.remoteComponent': component_testcase_remoteComponent,
'component.testcase.openNoMenuRoute': component_testcase_openNoMenuRoute,
'component.testcase.noMenuRoute': component_testcase_noMenuRoute,
'component.testcase.mathEditor': component_testcase_mathEditor,

1
io.sc.platform.core.frontend/src/i18n/messages.json

@ -1,5 +1,6 @@
{
"menu.testcase": "Test Case",
"menu.testcase.remoteComponent": "Remote Component",
"menu.testcase.openUrl": "Open At New Tab",
"menu.testcase.openNoMenuRoute": "Open No Menu Route",
"menu.testcase.mathEditor": "Math Formual Editor",

1
io.sc.platform.core.frontend/src/i18n/messages_tw_CN.json

@ -1,5 +1,6 @@
{
"menu.testcase": "測試用例",
"menu.testcase.remoteComponent": "遠程組件",
"menu.testcase.openUrl": "在新標籤頁打開",
"menu.testcase.openNoMenuRoute": "打開無關聯菜單的路由",
"menu.testcase.mathEditor": "數學公式編輯器",

1
io.sc.platform.core.frontend/src/i18n/messages_zh_CN.json

@ -1,5 +1,6 @@
{
"menu.testcase": "测试用例",
"menu.testcase.remoteComponent": "远程组件",
"menu.testcase.openUrl": "在新标签页打开",
"menu.testcase.openNoMenuRoute": "打开无关联菜单的路由示例",
"menu.testcase.mathEditor": "数学公式编辑器",

9
io.sc.platform.core.frontend/src/menus/menus.json

@ -18,6 +18,15 @@
[
{ "type": "GROUP", "order": 20000, "id": "menu.testcase", "titleI18nKey": "menu.testcase", "icon": "bi-gear" },
{
"type": "ROUTE",
"order": 25,
"parentId": "menu.testcase",
"id": "menu.testcase.remoteComponent",
"titleI18nKey": "menu.testcase.remoteComponent",
"icon": "bi-palette",
"routeName": "route.testcase.remoteComponent"
},
{
"type": "URL",
"order": 50,

35
io.sc.platform.core.frontend/src/platform/layout/sub-layout/Topper.vue

@ -62,6 +62,23 @@
<q-tab-panel name="myTasks">
<q-list>
<q-item v-if="unCompletedTasksRef.length <= 0"></q-item>
<template v-if="Tools.trim(gc.setting.notifierTaskNavigateFrontendRoutePath) === ''">
<q-item v-for="item in unCompletedTasksRef" :key="item.id" v-ripple v-close-popup clickable class="px-0 pb-2" @click="handleTask(item)">
<q-item-section avatar style="min-width: 0px; padding-right: 5px">
<q-icon color="blue" name="bi-dot" size="xl" />
</q-item-section>
<q-item-section>
<q-item-label>{{ item.businessDescription }}</q-item-label>
<q-item-label caption lines="2">{{ item.processDefinitionName }} [{{ item.name }}]</q-item-label>
</q-item-section>
<q-item-section side top>
<q-item-label caption>{{ item.createTimeAndNowDiff }}{{ $t(item.createTimeAndNowDiffUnit) }}{{ $t('before') }}</q-item-label>
<q-item-label caption>{{ item.previousAssignee }}</q-item-label>
</q-item-section>
</q-item>
</template>
<template v-if="Tools.trim(gc.setting.notifierTaskNavigateFrontendRoutePath) !== ''">
<q-item
v-for="item in unCompletedTasksRef"
:key="item.id"
@ -69,7 +86,7 @@
v-close-popup
clickable
class="px-0 pb-2"
:to="item.routePath + '?taskId=' + item.id"
:to="Tools.trim(gc.setting.notifierTaskNavigateFrontendRoutePath) + '?taskId=' + item.id"
exact
>
<q-item-section avatar style="min-width: 0px; padding-right: 5px">
@ -82,8 +99,10 @@
<q-item-section side top>
<q-item-label caption>{{ item.createTimeAndNowDiff }}{{ $t(item.createTimeAndNowDiffUnit) }}{{ $t('before') }}</q-item-label>
<q-item-label caption>{{ item.previousAssignee }}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-list>
</q-tab-panel>
<q-tab-panel name="myMessages">
@ -219,7 +238,6 @@
<AboutDialog ref="aboutDialog"></AboutDialog>
<ChangePasswordDialog ref="changePasswordDialog"></ChangePasswordDialog>
<ChangeRoleDialog ref="changeRoleDialog"></ChangeRoleDialog>
<ViewTaskDialog ref="viewTaskDialog"></ViewTaskDialog>
<ViewNotificationDialog ref="viewNotificationDialog"></ViewNotificationDialog>
<ViewAnnouncementDialog ref="viewAnnouncementDialog"></ViewAnnouncementDialog>
</template>
@ -234,7 +252,6 @@ import LoginDialog from '@/platform/views/LoginDialog';
import AboutDialog from './AboutDialog.vue';
import ChangePasswordDialog from './ChangePasswordDialog.vue';
import ChangeRoleDialog from './ChangeRoleDialog.vue';
import ViewTaskDialog from './ViewTaskDialog.vue';
import ViewNotificationDialog from './ViewNotificationDialog.vue';
import ViewAnnouncementDialog from './ViewAnnouncementDialog.vue';
@ -247,7 +264,6 @@ const loginDialog = ref();
const aboutDialog = ref();
const changePasswordDialog = ref();
const changeRoleDialog = ref();
const viewTaskDialog = ref();
const viewNotificationDialog = ref();
const viewAnnouncementDialog = ref();
const { t } = useI18n();
@ -349,9 +365,7 @@ const findUnReadedAnnouncements = () => {
});
};
const viewTask = (item) => {
viewNotificationDialog.value.open(item);
};
const handleTask = (item) => {};
const viewNotification = (item) => {
viewNotificationDialog.value.open(item);
@ -374,9 +388,12 @@ findUnCompletedTasks();
findUnReadedNotifications();
findUnReadedAnnouncements();
registerInterval(() => {
registerInterval(
() => {
findUnCompletedTasks();
findUnReadedNotifications();
findUnReadedAnnouncements();
}, 60 * 1000);
},
3 * 60 * 1000,
);
</script>

12
io.sc.platform.core.frontend/src/platform/layout/sub-layout/ViewTaskDialog.vue

@ -1,12 +0,0 @@
<template>
<w-dialog ref="dialogRef" width="800px" :title="$t('myMessages')" :can-maximize="false" @hide="Environment.executeAction('loadSystemAnnouncements')">
<router-view v-slot="{ Component }" class="full">
<keep-alive>
<suspense>
<component :is="Component" :key="route.fullPath" />
</suspense>
</keep-alive>
</router-view>
</w-dialog>
</template>
<script setup lang="ts"></script>

215
io.sc.platform.core.frontend/src/platform/plugin/environment/default-configure.json

@ -1,129 +1,130 @@
{
"oauth2" : {
"clientId" : "platform-oidc",
"clientSecret" : "secret",
"redirectUri" : "http://localhost:3000"
"oauth2": {
"clientId": "platform-oidc",
"clientSecret": "secret",
"redirectUri": "http://localhost:3000"
},
"setting" : {
"homePage" : "/home",
"i18n" : {
"availableLocales" : [ "en", "zh_CN", "tw_CN" ],
"locale" : "zh_CN",
"fallbackLocale" : "en",
"fallbackWarn" : false,
"missingWarn" : false,
"changeNotify" : true
"setting": {
"homePage": "/home",
"notifierTaskNavigateFrontendRoutePath": null,
"i18n": {
"availableLocales": ["en", "zh_CN", "tw_CN"],
"locale": "zh_CN",
"fallbackLocale": "en",
"fallbackWarn": false,
"missingWarn": false,
"changeNotify": true
}
},
"theme" : {
"dark" : false,
"minWidth" : 600,
"favicon" : "favicon.svg",
"navigateMenuPosition" : "sider",
"brand" : {
"dark" : "#1d1d1d",
"primary" : "#14234a",
"secondary" : "#26a69a",
"accent" : "#9c27b0",
"positive" : "#21ba45",
"negative" : "#c10015",
"info" : "#31ccec",
"warning" : "#f2c037",
"dark-page" : "#121212"
"theme": {
"dark": false,
"minWidth": 600,
"favicon": "favicon.svg",
"navigateMenuPosition": "sider",
"brand": {
"dark": "#1d1d1d",
"primary": "#14234a",
"secondary": "#26a69a",
"accent": "#9c27b0",
"positive": "#21ba45",
"negative": "#c10015",
"info": "#31ccec",
"warning": "#f2c037",
"dark-page": "#121212"
},
"loadingBar" : {
"color" : "positive",
"size" : 3,
"position" : "top",
"reverse" : false
"loadingBar": {
"color": "positive",
"size": 3,
"position": "top",
"reverse": false
},
"topper" : {
"height" : 48,
"color" : "white",
"bgColor" : "#14234a",
"logo" : "logo.svg",
"logoWidth" : 36,
"logoHeight" : 36,
"showTitle" : true,
"titleColor" : "white",
"actions" : {
"full-screen" : {
"enable" : true
"topper": {
"height": 48,
"color": "white",
"bgColor": "#14234a",
"logo": "logo.svg",
"logoWidth": 36,
"logoHeight": 36,
"showTitle": true,
"titleColor": "white",
"actions": {
"full-screen": {
"enable": true
},
"searcher" : {
"enable" : true
"searcher": {
"enable": true
},
"notifier" : {
"enable" : true
"notifier": {
"enable": true
}
}
},
"sider" : {
"position" : "left",
"sider": {
"position": "left",
"isSiderExpaned": false,
"dense" : true,
"border" : true,
"width" : 300,
"miniWidth" : 100,
"iconSize" : 22,
"miniIconSize" : 30,
"iconColor" : "#000000",
"activeIconColor" : "#14234a",
"bgColor" : "#ffffff",
"activeBgColor" : "#ffffff",
"color" : "#000000",
"activeColor" : "#14234a"
"dense": true,
"border": true,
"width": 300,
"miniWidth": 100,
"iconSize": 22,
"miniIconSize": 30,
"iconColor": "#000000",
"activeIconColor": "#14234a",
"bgColor": "#ffffff",
"activeBgColor": "#ffffff",
"color": "#000000",
"activeColor": "#14234a"
},
"tagViewBar" : {
"height" : 50,
"homeTagViewCloseable" : false,
"collapserIconSize" : 20,
"collapserIconColor" : "#000",
"moreIconColor" : "#000",
"bgColor" : "#FFF",
"borderSize" : 1,
"borderColor" : "#E5E7EB"
"tagViewBar": {
"height": 50,
"homeTagViewCloseable": false,
"collapserIconSize": 20,
"collapserIconColor": "#000",
"moreIconColor": "#000",
"bgColor": "#FFF",
"borderSize": 1,
"borderColor": "#E5E7EB"
},
"main" : {
"bgColor" : "#FFFFFF",
"paddingTop" : 5,
"paddingRight" : 5,
"paddingBottom" : 0,
"paddingLeft" : 5,
"containerPaddingTop" : 5,
"containerPaddingRight" : 5,
"containerPaddingBottom" : 5,
"containerPaddingLeft" : 5,
"containerBgColor" : "#EEEEEE"
"main": {
"bgColor": "#FFFFFF",
"paddingTop": 5,
"paddingRight": 5,
"paddingBottom": 0,
"paddingLeft": 5,
"containerPaddingTop": 5,
"containerPaddingRight": 5,
"containerPaddingBottom": 5,
"containerPaddingLeft": 5,
"containerBgColor": "#EEEEEE"
},
"footer" : {
"show" : false,
"height" : 40,
"color" : "#ffffff",
"bgColor" : "#14234a"
"footer": {
"show": false,
"height": 40,
"color": "#ffffff",
"bgColor": "#14234a"
},
"login" : {
"bgImage" : "login-bg.jpg",
"encodePassword" : true,
"logoutConfirm" : true
"login": {
"bgImage": "login-bg.jpg",
"encodePassword": true,
"logoutConfirm": true
},
"scroller" : {
"enable" : true,
"position" : "bottom-right",
"showTitle" : true,
"color" : "#ffffff",
"bgColor" : "#14234a",
"offsetX" : 80,
"offsetY" : 100
"scroller": {
"enable": true,
"position": "bottom-right",
"showTitle": true,
"color": "#ffffff",
"bgColor": "#14234a",
"offsetX": 80,
"offsetY": 100
},
"notifier" : {
"position" : "top",
"timeout" : 2000
"notifier": {
"position": "top",
"timeout": 2000
},
"grid" : {
"headBgColor" : "#f5f7fa",
"stickyBgColor" : "#ffffff",
"borderColor" : "rgba(0, 0, 0, 0.12)"
"grid": {
"headBgColor": "#f5f7fa",
"stickyBgColor": "#ffffff",
"borderColor": "rgba(0, 0, 0, 0.12)"
}
}
}

1
io.sc.platform.core.frontend/src/platform/types/ConfigureType.ts

@ -54,6 +54,7 @@ export type ConfigureType = {
sessionTimeout: number; //会话过期时间,单位:秒
notifyTimeout: number; // 通知提示框显示时间单位:毫秒
homePage: string; // 首页路由 path
notifierTaskNavigateFrontendRoutePath: string; //顶部通知栏任务导航前端路由路径
i18n: {
availableLocales: string[]; // 支持的国际化多语言数组
locale: string; // 默认区域

10
io.sc.platform.core.frontend/src/routes/routes.json

@ -1,11 +1,11 @@
[
{
"name": "route.testcase.globalRoute",
"path": "/testcase/globalRoute",
"parent": null,
"name": "route.testcase.remoteComponent",
"path": "/testcase/remoteComponent",
"parent": "/",
"priority": 0,
"component": "component.testcase.globalRoute",
"componentPath": "@/views/testcase/global-route/GlobalRoute.vue",
"component": "component.testcase.remoteComponent",
"componentPath": "@/views/testcase/remote-component/RemoteComponent.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/loading/**/*"]

4
io.sc.platform.core.frontend/src/views/testcase/global-route/GlobalRoute.vue

@ -1,4 +0,0 @@
<template>
<div style="height: 100%">XXXX</div>
</template>
<script setup lang="ts"></script>

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

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.2.65",
"version": "8.2.70",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"platform-core": "8.2.65",
"platform-core": "8.2.70",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

2
io.sc.platform.core.frontend/template-project/src/components/index.ts

@ -2,6 +2,7 @@
* ,
*/
import component_testcase_remoteComponent from '@/views/testcase/remote-component/RemoteComponent.vue';
import component_testcase_openNoMenuRoute from '@/views/testcase/route/OpenNoMenuRoute.vue';
import component_testcase_noMenuRoute from '@/views/testcase/route/NoMenuRoute.vue';
import component_testcase_mathEditor from '@/views/testcase/math/MathEditor.vue';
@ -23,6 +24,7 @@ import component_testcase_gridLayout from '@/views/likm/GridLayout.vue';
import component_testcase_likmTreeGrid from '@/views/likm/TreeGrid.vue';
const localComponents = {
'component.testcase.remoteComponent': component_testcase_remoteComponent,
'component.testcase.openNoMenuRoute': component_testcase_openNoMenuRoute,
'component.testcase.noMenuRoute': component_testcase_noMenuRoute,
'component.testcase.mathEditor': component_testcase_mathEditor,

1
io.sc.platform.core.frontend/template-project/src/i18n/messages.json

@ -1,5 +1,6 @@
{
"menu.testcase": "Test Case",
"menu.testcase.remoteComponent": "Remote Component",
"menu.testcase.openUrl": "Open At New Tab",
"menu.testcase.openNoMenuRoute": "Open No Menu Route",
"menu.testcase.mathEditor": "Math Formual Editor",

1
io.sc.platform.core.frontend/template-project/src/i18n/messages_tw_CN.json

@ -1,5 +1,6 @@
{
"menu.testcase": "測試用例",
"menu.testcase.remoteComponent": "遠程組件",
"menu.testcase.openUrl": "在新標籤頁打開",
"menu.testcase.openNoMenuRoute": "打開無關聯菜單的路由",
"menu.testcase.mathEditor": "數學公式編輯器",

1
io.sc.platform.core.frontend/template-project/src/i18n/messages_zh_CN.json

@ -1,5 +1,6 @@
{
"menu.testcase": "测试用例",
"menu.testcase.remoteComponent": "远程组件",
"menu.testcase.openUrl": "在新标签页打开",
"menu.testcase.openNoMenuRoute": "打开无关联菜单的路由示例",
"menu.testcase.mathEditor": "数学公式编辑器",

9
io.sc.platform.core.frontend/template-project/src/menus/menus.json

@ -18,6 +18,15 @@
[
{ "type": "GROUP", "order": 20000, "id": "menu.testcase", "titleI18nKey": "menu.testcase", "icon": "bi-gear" },
{
"type": "ROUTE",
"order": 25,
"parentId": "menu.testcase",
"id": "menu.testcase.remoteComponent",
"titleI18nKey": "menu.testcase.remoteComponent",
"icon": "bi-palette",
"routeName": "route.testcase.remoteComponent"
},
{
"type": "URL",
"order": 50,

12
io.sc.platform.core.frontend/template-project/src/routes/routes.json

@ -1,4 +1,16 @@
[
{
"name": "route.testcase.remoteComponent",
"path": "/testcase/remoteComponent",
"parent": "/",
"priority": 0,
"component": "component.testcase.remoteComponent",
"componentPath": "@/views/testcase/remote-component/RemoteComponent.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/loading/**/*"]
}
},
{
"name": "route.testcase.openNoMenuRoute",
"path": "testcase/openNoMenuRoute",

11
io.sc.platform.core.frontend/template-project/webpack.config.mf.cjs

@ -9,13 +9,20 @@ const projectName = packageJson.name; // 项目名称
const deps = packageJson.dependencies; // 项目依赖
// 读取本地路由配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const data = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(data);
const routesJson = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(routesJson);
const mfExposes = {};
for (const route of routes) {
mfExposes[route.component] = route.componentPath;
}
// 读取远程组件配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const remoteComponentsJson = fs.readFileSync('./src/remote-components/remote-components.json', 'utf8');
const remoteComponents = Json5.parse(remoteComponentsJson);
for (const remoteComponent of remoteComponents) {
mfExposes[remoteComponent.component] = remoteComponent.componentPath;
}
// 导出 webapck 配置的模块联邦部分
module.exports = {
plugins: [

11
io.sc.platform.core.frontend/webpack.config.mf.cjs

@ -9,13 +9,20 @@ const projectName = packageJson.name; // 项目名称
const deps = packageJson.dependencies; // 项目依赖
// 读取本地路由配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const data = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(data);
const routesJson = fs.readFileSync('./src/routes/routes.json', 'utf8');
const routes = Json5.parse(routesJson);
const mfExposes = {};
for (const route of routes) {
mfExposes[route.component] = route.componentPath;
}
// 读取远程组件配置, 通过其中 component 和 componentPath 两个属性构建 webpack 模块联邦的 exposes 属性值
const remoteComponentsJson = fs.readFileSync('./src/remote-components/remote-components.json', 'utf8');
const remoteComponents = Json5.parse(remoteComponentsJson);
for (const remoteComponent of remoteComponents) {
mfExposes[remoteComponent.component] = remoteComponent.componentPath;
}
// 导出 webapck 配置的模块联邦部分
module.exports = {
plugins: [

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties

@ -261,3 +261,4 @@ errorOccurred=An Error Occurred
migration=Migration
view=View
before=Before
send=Send

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties

@ -261,3 +261,4 @@ errorOccurred=\u767C\u751F\u932F\u8AA4
migration=\u9077\u79FB
view=\u67E5\u770B
before=\u4EE5\u524D
send=\u767C\u9001

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties

@ -261,3 +261,4 @@ errorOccurred=\u53D1\u751F\u9519\u8BEF
migration=\u8FC1\u79FB
view=\u67E5\u770B
before=\u4EE5\u524D
send=\u53D1\u9001

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save