Browse Source

update

main
wangshaoping 4 months ago
parent
commit
a282da7342
  1. 1
      erm.frontend/.eslintrc.cjs
  2. 2
      erm.frontend/package.json
  3. 2
      gradle.properties
  4. 1
      io.sc.engine.mv.frontend/.eslintrc.cjs
  5. 2
      io.sc.engine.mv.frontend/package.json
  6. 7
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/processor/ConditionRange.java
  7. 9
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/processor/ScoreCardItem.java
  8. 2
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpMethodType.java
  9. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums.properties
  10. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_tw_CN.properties
  11. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_zh_CN.properties
  12. 1
      io.sc.engine.rule.frontend/.eslintrc.cjs
  13. 2
      io.sc.engine.rule.frontend/package.json
  14. 6
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  15. 115
      io.sc.engine.rule.frontend/src/views/lib/ProcessorGrid.vue
  16. 26
      io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue
  17. 4
      io.sc.engine.rule.frontend/src/views/shared/AutoCompletionManager.ts
  18. 24
      io.sc.engine.rule.frontend/src/views/shared/Processor.ts
  19. 66
      io.sc.engine.rule.frontend/src/views/shared/ProcessorManager.ts
  20. 18
      io.sc.engine.rule.frontend/src/views/shared/processors/Arithmetic.ts
  21. 73
      io.sc.engine.rule.frontend/src/views/shared/processors/ConditionRange.ts
  22. 200
      io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTable.ts
  23. 162
      io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTable2c.ts
  24. 11
      io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTree.ts
  25. 11
      io.sc.engine.rule.frontend/src/views/shared/processors/ExecutionFlow.ts
  26. 20
      io.sc.engine.rule.frontend/src/views/shared/processors/GroovyScript.ts
  27. 390
      io.sc.engine.rule.frontend/src/views/shared/processors/HttpRequest.ts
  28. 18
      io.sc.engine.rule.frontend/src/views/shared/processors/MathFormula.ts
  29. 78
      io.sc.engine.rule.frontend/src/views/shared/processors/NumberRange.ts
  30. 27
      io.sc.engine.rule.frontend/src/views/shared/processors/ObjectProperties.ts
  31. 17
      io.sc.engine.rule.frontend/src/views/shared/processors/OptionValue.ts
  32. 19
      io.sc.engine.rule.frontend/src/views/shared/processors/Pmml.ts
  33. 15
      io.sc.engine.rule.frontend/src/views/shared/processors/Rule.ts
  34. 185
      io.sc.engine.rule.frontend/src/views/shared/processors/ScoreCard.ts
  35. 15
      io.sc.engine.rule.frontend/src/views/shared/processors/SingleRule.ts
  36. 104
      io.sc.engine.rule.frontend/src/views/shared/processors/Sql.ts
  37. 22
      io.sc.engine.rule.frontend/src/views/shared/processors/Ternary.ts
  38. 22
      io.sc.engine.rule.frontend/src/views/shared/processors/WhenThen.ts
  39. 1
      io.sc.engine.rule.frontend/src/views/shared/processors/index.ts
  40. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/ScoreCardParameterProcessorEntity.java
  41. 1
      io.sc.engine.st.frontend/.eslintrc.cjs
  42. 2
      io.sc.engine.st.frontend/package.json
  43. 1
      io.sc.platform.core.frontend/.eslintrc.cjs
  44. 2
      io.sc.platform.core.frontend/package.json
  45. 2
      io.sc.platform.core.frontend/src/platform/components/code-mirror/WCodeMirror.vue
  46. 21
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/Toolbar.vue
  47. 39
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/Log.vue
  48. 7
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/log/Lg.vue
  49. 9
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/log/Ln.vue
  50. 7
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/log/Log.vue
  51. 6
      io.sc.platform.core.frontend/src/platform/css/q-markup-table.css
  52. 8
      io.sc.platform.core.frontend/src/platform/i18n/messages.json
  53. 10
      io.sc.platform.core.frontend/src/platform/i18n/messages_tw_CN.json
  54. 10
      io.sc.platform.core.frontend/src/platform/i18n/messages_zh_CN.json
  55. 1
      io.sc.platform.core.frontend/src/platform/index.ts
  56. 31
      io.sc.platform.core.frontend/src/platform/utils-components/MarkupTableUtil.ts
  57. 135
      io.sc.platform.core.frontend/src/platform/utils/Tools.ts
  58. 33
      io.sc.platform.core.frontend/src/platform/utils/UnitOfMeasure.ts
  59. 1
      io.sc.platform.core.frontend/src/platform/utils/index.ts
  60. 64
      io.sc.platform.core.frontend/src/views/testcase/math/MathEditor.vue
  61. 1
      io.sc.platform.core.frontend/template-project/.eslintrc.cjs
  62. 4
      io.sc.platform.core.frontend/template-project/package.json
  63. 64
      io.sc.platform.core.frontend/template-project/src/views/testcase/math/MathEditor.vue
  64. 10
      io.sc.platform.core/src/main/java/io/sc/platform/core/License.java
  65. 2
      io.sc.platform.core/src/main/java/io/sc/platform/core/service/LicenseManagerService.java
  66. 7
      io.sc.platform.core/src/main/java/io/sc/platform/core/service/impl/LicenseManagerServiceImpl.java
  67. 4
      io.sc.platform.core/src/main/java/io/sc/platform/core/util/NetworkUtil.java
  68. 2
      io.sc.platform.developer.doc/package.json
  69. 1
      io.sc.platform.developer.frontend/.eslintrc.cjs
  70. 2
      io.sc.platform.developer.frontend/package.json
  71. 1
      io.sc.platform.lcdp.frontend/.eslintrc.cjs
  72. 2
      io.sc.platform.lcdp.frontend/package.json
  73. 1
      io.sc.platform.license.keygen.frontend/.eslintrc.cjs
  74. 2
      io.sc.platform.license.keygen.frontend/package.json
  75. 3
      io.sc.platform.license.keygen.frontend/src/i18n/messages.json
  76. 3
      io.sc.platform.license.keygen.frontend/src/i18n/messages_tw_CN.json
  77. 3
      io.sc.platform.license.keygen.frontend/src/i18n/messages_zh_CN.json
  78. 22
      io.sc.platform.license.keygen.frontend/src/views/license/KeyGenerator.vue
  79. 105
      io.sc.platform.license.keygen/src/main/java/io/sc/platform/license/keygen/controller/LicenseKeyGeneratorWebController.java
  80. 3
      io.sc.platform.license.keygen/src/main/java/io/sc/platform/license/keygen/service/impl/LicenseKeyGeneratorServiceImpl.java
  81. 1
      io.sc.platform.mvc.frontend/.eslintrc.cjs
  82. 2
      io.sc.platform.mvc.frontend/package.json
  83. 1
      io.sc.platform.scheduler.manager.frontend/.eslintrc.cjs
  84. 2
      io.sc.platform.scheduler.manager.frontend/package.json
  85. 1
      io.sc.platform.system.frontend/.eslintrc.cjs
  86. 2
      io.sc.platform.system.frontend/package.json
  87. 2
      io.sc.platform.system.frontend/src/i18n/messages.json
  88. 1
      io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json
  89. 1
      io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json
  90. 1
      io.sc.platform.system.frontend/src/views/license/License.vue
  91. 4
      io.sc.platform.system.frontend/src/views/menu/Menu.vue
  92. 1
      io.sc.standard.frontend/.eslintrc.cjs
  93. 2
      io.sc.standard.frontend/package.json
  94. 2
      io.sc.website/package.json

1
erm.frontend/.eslintrc.cjs

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

2
erm.frontend/package.json

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

2
gradle.properties

@ -38,7 +38,7 @@ application_version=1.0.0
platform_group=io.sc
platform_version=8.1.50
platform_plugin_version=8.1.50
platform_core_frontend_version=8.1.416
platform_core_frontend_version=8.1.430
###########################################################
# dependencies version

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

7
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/processor/ConditionRange.java

@ -16,7 +16,6 @@ import com.fasterxml.jackson.core.type.TypeReference;
@JsonIgnoreProperties(ignoreUnknown=true)
public class ConditionRange {
private String uuid;
private String condition;
private String value;
@ -112,12 +111,6 @@ public class ConditionRange {
return null;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getCondition() {
return condition;
}

9
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/processor/ScoreCardItem.java

@ -8,7 +8,6 @@ import java.util.List;
@JsonIgnoreProperties(ignoreUnknown=true)
public class ScoreCardItem {
private String code;
private String name;
private Double weight;
private ProcessorType type;
private List<ConditionRange> conditionRange;
@ -22,14 +21,6 @@ public class ScoreCardItem {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getWeight() {
return weight;
}

2
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/HttpMethodType.java

@ -6,5 +6,5 @@ package io.sc.engine.rule.core.enums;
*
*/
public enum HttpMethodType {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE;
}

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

@ -73,9 +73,9 @@ io.sc.engine.rule.core.enums.ProcessorType.WHEN_THEN=When-Then
io.sc.engine.rule.core.enums.HttpMethodType.GET=GET
io.sc.engine.rule.core.enums.HttpMethodType.POST=POST
io.sc.engine.rule.core.enums.HttpMethodType.PUT=PUT
io.sc.engine.rule.core.enums.HttpMethodType.PATCH=PATCH
io.sc.engine.rule.core.enums.HttpMethodType.DELETE=DELETE
io.sc.engine.rule.core.enums.HttpMethodType.HEAD=HEAD
io.sc.engine.rule.core.enums.HttpMethodType.PATCH=PATCH
io.sc.engine.rule.core.enums.HttpMethodType.OPTIONS=OPTIONS
io.sc.engine.rule.core.enums.HttpMethodType.TRACE=TRACE

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

@ -73,9 +73,9 @@ io.sc.engine.rule.core.enums.ProcessorType.WHEN_THEN=When Then \u904B\u7B97
io.sc.engine.rule.core.enums.HttpMethodType.GET=GET
io.sc.engine.rule.core.enums.HttpMethodType.POST=POST
io.sc.engine.rule.core.enums.HttpMethodType.PUT=PUT
io.sc.engine.rule.core.enums.HttpMethodType.PATCH=PATCH
io.sc.engine.rule.core.enums.HttpMethodType.DELETE=DELETE
io.sc.engine.rule.core.enums.HttpMethodType.HEAD=HEAD
io.sc.engine.rule.core.enums.HttpMethodType.PATCH=PATCH
io.sc.engine.rule.core.enums.HttpMethodType.OPTIONS=OPTIONS
io.sc.engine.rule.core.enums.HttpMethodType.TRACE=TRACE

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

@ -73,9 +73,9 @@ io.sc.engine.rule.core.enums.ProcessorType.WHEN_THEN=When Then \u8FD0\u7B97
io.sc.engine.rule.core.enums.HttpMethodType.GET=GET
io.sc.engine.rule.core.enums.HttpMethodType.POST=POST
io.sc.engine.rule.core.enums.HttpMethodType.PUT=PUT
io.sc.engine.rule.core.enums.HttpMethodType.PATCH=PATCH
io.sc.engine.rule.core.enums.HttpMethodType.DELETE=DELETE
io.sc.engine.rule.core.enums.HttpMethodType.HEAD=HEAD
io.sc.engine.rule.core.enums.HttpMethodType.PATCH=PATCH
io.sc.engine.rule.core.enums.HttpMethodType.OPTIONS=OPTIONS
io.sc.engine.rule.core.enums.HttpMethodType.TRACE=TRACE

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.421",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -102,6 +102,12 @@
"re.resources.designer.processor.grid.entity.sqlParameterValues": "参数值",
"re.resources.designer.processor.grid.entity.sqlQueryResult": "执行结果",
"re.resources.designer.processor.grid.entity.sqlFieldMapping": "结果映射",
"re.resources.designer.processor.grid.entity.httpMethod": "请求方法",
"re.resources.designer.processor.grid.entity.httpUrl": "URL",
"re.resources.designer.processor.grid.entity.httpAuthType": "认证类型",
"re.resources.designer.processor.grid.entity.httpMethod": "请求方法",
"re.resources.designer.processor.grid.entity.httpMethod": "请求方法",
"re.resources.designer.processor.grid.entity.rule": "规则",
"re.resources.designer.processor.grid.entity.singleRule": "单规则",

115
io.sc.engine.rule.frontend/src/views/lib/ProcessorGrid.vue

@ -26,15 +26,7 @@
return !readOnly;
},
},
objectProperties.getToolbarAction(indicator),
mathFormula.getToolbarAction(indicator),
arithmetic.getToolbarAction(indicator),
ternary.getToolbarAction(indicator),
whenThen.getToolbarAction(indicator),
numberRange.getToolbarAction(indicator),
conditionRange.getToolbarAction(indicator),
groovyScript.getToolbarAction(indicator),
sql.getToolbarAction(indicator),
...processorManager.getToolbarAction(),
],
{
extend: 'clone',
@ -76,27 +68,7 @@
label: $t('re.resources.designer.processor.grid.entity.content'),
sortable: false,
format: (value, row) => {
switch (row.type) {
case 'ARITHMETIC':
return arithmetic.format(row);
case 'CONDITION_RANGE':
return conditionRange.format(row);
case 'GROOVY_SCRIPT':
return groovyScript.format(row);
case 'MATH_FORMULA':
return mathFormula.format(row);
case 'NUMBER_RANGE':
return numberRange.format(row);
case 'OBJECT_PROPERTIES':
return objectProperties.format(row);
case 'SQL':
return sql.format(row);
case 'TERNARY':
return ternary.format(row);
case 'WHEN_THEN':
return whenThen.format(row);
}
return '';
return processorManager.format(value, row);
},
},
]"
@ -111,16 +83,7 @@
{ colSpan: 5, name: 'id', label: $t('id'), type: 'w-text', showIf: false },
{ colSpan: 5, name: 'order', label: $t('order'), type: 'w-number', showIf: false },
{ colSpan: 5, name: 'type', label: $t('type'), type: 'w-text', showIf: false },
...arithmetic.getEditorFields(),
...conditionRange.getEditorFields(),
...groovyScript.getEditorFields(),
...mathFormula.getEditorFields(),
...numberRange.getEditorFields(),
...objectProperties.getEditorFields({ objectPropertiesMatcherDialogRef }),
...sql.getEditorFields(),
...ternary.getEditorFields(),
...whenThen.getEditorFields(),
...processorManager.getEditorFields(),
],
},
}"
@ -134,17 +97,7 @@
{ name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable') },
{ name: 'type', label: $t('type') },
...arithmetic.getViewerFields(),
...conditionRange.getViewerFields(),
...groovyScript.getViewerFields(),
...mathFormula.getViewerFields(),
...numberRange.getViewerFields(),
...objectProperties.getViewerFields(),
...sql.getViewerFields(),
...ternary.getViewerFields(),
...whenThen.getViewerFields(),
...processorManager.getViewerFields(),
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
@ -155,51 +108,12 @@
}"
@before-editor-data-submit="
(args) => {
switch (args.data.type) {
case 'ARITHMETIC':
return arithmetic.beforeEditorDataSubmit(args);
case 'CONDITION_RANGE':
return conditionRange.beforeEditorDataSubmit(args);
case 'GROOVY_SCRIPT':
return groovyScript.beforeEditorDataSubmit(args);
case 'MATH_FORMULA':
return mathFormula.beforeEditorDataSubmit(args);
case 'NUMBER_RANGE':
return numberRange.beforeEditorDataSubmit(args);
case 'OBJECT_PROPERTIES':
return objectProperties.beforeEditorDataSubmit(args);
case 'SQL':
return sql.beforeEditorDataSubmit(args);
case 'TERNARY':
return ternary.beforeEditorDataSubmit(args);
case 'WHEN_THEN':
return whenThen.beforeEditorDataSubmit(args);
}
processorManager.beforeEditorDataSubmit(args);
}
"
@after-editor-open="
(args) => {
args.target = indicator;
switch (args.grid.getEditorForm().getFieldValue('type')) {
case 'ARITHMETIC':
return arithmetic.afterEditorOpen(args);
case 'CONDITION_RANGE':
return conditionRange.afterEditorOpen(args);
case 'GROOVY_SCRIPT':
return groovyScript.afterEditorOpen(args);
case 'MATH_FORMULA':
return mathFormula.afterEditorOpen(args);
case 'NUMBER_RANGE':
return numberRange.afterEditorOpen(args);
case 'OBJECT_PROPERTIES':
return objectProperties.afterEditorOpen(args);
case 'SQL':
return sql.afterEditorOpen(args);
case 'TERNARY':
return ternary.afterEditorOpen(args);
case 'WHEN_THEN':
return whenThen.afterEditorOpen(args);
}
processorManager.afterEditorOpen(args);
}
"
></w-grid>
@ -220,20 +134,10 @@
import 'tailwindcss/utilities.css';
import { ref, onMounted } from 'vue';
import { axios, Environment, Formater } from 'platform-core';
import { ProcessorManager } from '@/views/shared/ProcessorManager';
import { Processor } from '@/views/shared/Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
import ObjectPropertiesMatcherDialog from '@/views/shared/ObjectPropertiesMatcherDialog.vue';
import { Arithmetic, ConditionRange, GroovyScript, MathFormula, NumberRange, ObjectProperties, Sql, Ternary, WhenThen } from '@/views/shared/processors';
const arithmetic = new Arithmetic(Processor.INDICATOR);
const conditionRange = new ConditionRange(Processor.INDICATOR);
const groovyScript = new GroovyScript(Processor.INDICATOR);
const mathFormula = new MathFormula(Processor.INDICATOR);
const numberRange = new NumberRange(Processor.INDICATOR);
const objectProperties = new ObjectProperties(Processor.INDICATOR);
const sql = new Sql(Processor.INDICATOR);
const ternary = new Ternary(Processor.INDICATOR);
const whenThen = new WhenThen(Processor.INDICATOR);
const props = defineProps({
indicator: { type: Object, default: undefined },
@ -242,6 +146,11 @@ const props = defineProps({
const gridRef = ref();
const objectPropertiesMatcherDialogRef = ref();
const processorManagerContext = {
target: props.indicator,
objectPropertiesMatcherDialogRef: objectPropertiesMatcherDialogRef,
};
const processorManager = new ProcessorManager(Processor.INDICATOR, processorManagerContext);
const refresh = () => {
gridRef?.value?.refresh();

26
io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue

@ -27,8 +27,9 @@
},
click: undefined,
},
...processorManager.getToolbarAction(parameter),
...processorManager.getToolbarAction(),
],
'clone',
{
extend: 'edit',
name: 'customEdit',
@ -111,15 +112,15 @@
width: '50%',
},
form: {
colsNum: 5,
colsNum: 7,
fields: [
{ colSpan: 5, name: 'parameter', label: 'parameter', type: 'w-text', defaultValue: parameter.id, showIf: false },
{ colSpan: 5, name: 'id', label: $t('id'), type: 'w-text', showIf: false },
{ colSpan: 5, name: 'order', label: $t('order'), type: 'w-number', showIf: false },
{ colSpan: 5, name: 'type', label: $t('type'), type: 'w-text', showIf: false },
{ colSpan: 5, name: 'description', label: $t('description'), type: 'w-text', showIf: false },
{ colSpan: 5, name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true, showIf: false },
...processorManager.getEditorFields({ objectPropertiesMatcherDialogRef }),
{ colSpan: 7, name: 'parameter', label: 'parameter', type: 'w-text', defaultValue: parameter.id, showIf: false },
{ colSpan: 7, name: 'id', label: $t('id'), type: 'w-text', showIf: false },
{ colSpan: 7, name: 'order', label: $t('order'), type: 'w-number', showIf: false },
{ colSpan: 7, name: 'type', label: $t('type'), type: 'w-text', showIf: false },
{ colSpan: 7, name: 'description', label: $t('description'), type: 'w-text', showIf: false },
{ colSpan: 7, name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true, showIf: false },
...processorManager.getEditorFields(),
],
},
}"
@ -149,7 +150,6 @@
"
@after-editor-open="
(args) => {
args.target = parameter;
processorManager.afterEditorOpen(args);
}
"
@ -191,7 +191,11 @@ const gridRef = ref();
const decisionTreeDialogRef = ref();
const executionFlowDialogRef = ref();
const objectPropertiesMatcherDialogRef = ref();
const processorManager = new ProcessorManager(Processor.PARAMETER);
const processorManagerContext = {
target: props.parameter,
objectPropertiesMatcherDialogRef: objectPropertiesMatcherDialogRef,
};
const processorManager = new ProcessorManager(Processor.PARAMETER, processorManagerContext);
const refresh = () => {
gridRef.value.refresh();

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

@ -181,9 +181,9 @@ class AutoCompletionManager {
}
public autoCompletion(): any {
const This = this;
const THIS = this;
return function (context: any) {
return This.doAutoCompletion(context);
return THIS.doAutoCompletion(context);
};
}
}

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

@ -9,22 +9,24 @@ abstract class Processor {
public static PARAMETER: string = 'parameter';
public static INDICATOR: string = 'indicator';
public static SCORE_CARD: string = 'scoreCard';
public static FORMAT_TABLE_STYLE: any = { dense: false, bordered: false };
targetType: string;
context: any;
autoCompletionManager: any;
userDefinedFunctionsManager: any;
constructor(targetType: string) {
constructor(targetType: string, context?: any) {
this.targetType = targetType;
this.context = context;
this.autoCompletionManager = new AutoCompletionManager();
this.userDefinedFunctionsManager = new UserDefinedFunctionsManager();
}
/**
*
* @param target
*/
abstract getToolbarAction(target: any): any;
abstract getToolbarAction(): any;
/**
*
@ -34,15 +36,13 @@ abstract class Processor {
/**
*
* @param context
*/
abstract getEditorFields(context?: any): any;
abstract getEditorFields(): any;
/**
*
* @param context
*/
abstract getViewerFields(context?: any): any;
abstract getViewerFields(): any;
/**
*
@ -60,11 +60,11 @@ abstract class Processor {
* code-mirror
* @param args
*/
initAutoCompletionManager(args: any) {
if (this.targetType === Processor.PARAMETER) {
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.target.id));
initAutoCompletionManager() {
if (this.targetType === Processor.PARAMETER || this.targetType === Processor.SCORE_CARD) {
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + this.context.target.id));
} else if (this.targetType === Processor.INDICATOR) {
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.target.id));
this.autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + this.context.target.id));
}
}
@ -72,7 +72,7 @@ abstract class Processor {
*
* @param args
*/
initUserDefinedFunctionsManager(args: any) {
initUserDefinedFunctionsManager() {
this.userDefinedFunctionsManager.load();
}
}

66
io.sc.engine.rule.frontend/src/views/shared/ProcessorManager.ts

@ -1,3 +1,4 @@
import { toRaw } from 'vue';
import { Processor } from './Processor';
import {
Arithmetic,
@ -7,6 +8,7 @@ import {
DecisionTree,
ExecutionFlow,
GroovyScript,
HttpRequest,
MathFormula,
NumberRange,
ObjectProperties,
@ -38,6 +40,7 @@ class ProcessorManager {
'PMML',
'GROOVY_SCRIPT',
'SQL',
'HTTP_REQUEST',
'RULE',
'SINGLE_RULE',
];
@ -51,44 +54,46 @@ class ProcessorManager {
'CONDITION_RANGE',
'GROOVY_SCRIPT',
'SQL',
'HTTP_REQUEST',
];
targetType: string;
processors: any;
constructor(targetType: string) {
constructor(targetType: string, context?: any) {
this.targetType = targetType;
this.processors = {};
this.processors.ARITHMETIC = new Arithmetic(this.targetType);
this.processors.CONDITION_RANGE = new ConditionRange(this.targetType);
this.processors.DECISION_TABLE = new DecisionTable(this.targetType);
this.processors.DECISION_TABLE_2C = new DecisionTable2C(this.targetType);
this.processors.DECISION_TREE = new DecisionTree(this.targetType);
this.processors.EXECUTION_FLOW = new ExecutionFlow(this.targetType);
this.processors.GROOVY_SCRIPT = new GroovyScript(this.targetType);
this.processors.MATH_FORMULA = new MathFormula(this.targetType);
this.processors.NUMBER_RANGE = new NumberRange(this.targetType);
this.processors.OBJECT_PROPERTIES = new ObjectProperties(this.targetType);
this.processors.OPTION_VALUE = new OptionValue(this.targetType);
this.processors.PMML = new Pmml(this.targetType);
this.processors.RULE = new Rule(this.targetType);
this.processors.SCORE_CARD = new ScoreCard(this.targetType);
this.processors.SINGLE_RULE = new SingleRule(this.targetType);
this.processors.SQL = new Sql(this.targetType);
this.processors.TERNARY = new Ternary(this.targetType);
this.processors.WHEN_THEN = new WhenThen(this.targetType);
this.processors.ARITHMETIC = new Arithmetic(this.targetType, context);
this.processors.CONDITION_RANGE = new ConditionRange(this.targetType, context);
this.processors.DECISION_TABLE = new DecisionTable(this.targetType, context);
this.processors.DECISION_TABLE_2C = new DecisionTable2C(this.targetType, context);
this.processors.DECISION_TREE = new DecisionTree(this.targetType, context);
this.processors.EXECUTION_FLOW = new ExecutionFlow(this.targetType, context);
this.processors.GROOVY_SCRIPT = new GroovyScript(this.targetType, context);
this.processors.MATH_FORMULA = new MathFormula(this.targetType, context);
this.processors.NUMBER_RANGE = new NumberRange(this.targetType, context);
this.processors.OBJECT_PROPERTIES = new ObjectProperties(this.targetType, context);
this.processors.OPTION_VALUE = new OptionValue(this.targetType, context);
this.processors.PMML = new Pmml(this.targetType, context);
this.processors.RULE = new Rule(this.targetType, context);
this.processors.SCORE_CARD = new ScoreCard(this.targetType, context);
this.processors.SINGLE_RULE = new SingleRule(this.targetType, context);
this.processors.SQL = new Sql(this.targetType, context);
this.processors.HTTP_REQUEST = new HttpRequest(this.targetType, context);
this.processors.TERNARY = new Ternary(this.targetType, context);
this.processors.WHEN_THEN = new WhenThen(this.targetType, context);
}
public getToolbarAction(target: any): any {
public getToolbarAction(): any {
const result: any = [];
switch (this.targetType) {
case Processor.PARAMETER:
ProcessorManager.PROCESSOR_TYPES_PARAMETER.forEach((name) => {
result.push(this.processors[name].getToolbarAction(target));
result.push(this.processors[name].getToolbarAction());
});
break;
case Processor.INDICATOR:
ProcessorManager.PROCESSOR_TYPES_INDICATOR.forEach((name) => {
result.push(this.processors[name].getToolbarAction(target));
result.push(this.processors[name].getToolbarAction());
});
break;
}
@ -102,34 +107,34 @@ class ProcessorManager {
return value;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
const result: any = [];
switch (this.targetType) {
case Processor.PARAMETER:
ProcessorManager.PROCESSOR_TYPES_PARAMETER.forEach((name) => {
result.push(...this.processors[name].getEditorFields(context));
result.push(...this.processors[name].getEditorFields());
});
break;
case Processor.INDICATOR:
ProcessorManager.PROCESSOR_TYPES_INDICATOR.forEach((name) => {
result.push(...this.processors[name].getEditorFields(context));
result.push(...this.processors[name].getEditorFields());
});
break;
}
return result;
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
const result: any = [];
switch (this.targetType) {
case Processor.PARAMETER:
ProcessorManager.PROCESSOR_TYPES_PARAMETER.forEach((name) => {
result.push(...this.processors[name].getViewerFields(context));
result.push(...this.processors[name].getViewerFields());
});
break;
case Processor.INDICATOR:
ProcessorManager.PROCESSOR_TYPES_INDICATOR.forEach((name) => {
result.push(...this.processors[name].getViewerFields(context));
result.push(...this.processors[name].getViewerFields());
});
break;
}
@ -143,11 +148,14 @@ class ProcessorManager {
}
public afterEditorOpen(args: any): void {
const type = args.grid.getEditorForm().getFieldValue('type');
const form = args.grid.getEditorForm();
if (form) {
const type = form.getFieldValue('type');
if (this.processors[type]) {
this.processors[type].afterEditorOpen(args);
}
}
}
}
export { ProcessorManager };

18
io.sc.engine.rule.frontend/src/views/shared/processors/Arithmetic.ts

@ -2,14 +2,17 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class Arithmetic extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'arithmetic',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.ARITHMETIC'),
icon: 'bi-calculator',
enableIf: (args) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'ARITHMETIC');
@ -31,10 +34,10 @@ class Arithmetic extends Processor {
};
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'arithmetic',
label: $t('re.resources.designer.processor.grid.entity.arithmetic'),
type: 'w-code-mirror',
@ -52,15 +55,16 @@ class Arithmetic extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'arithmetic', label: $t('re.resources.designer.processor.grid.entity.arithmetic') }];
}
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
}
}

73
io.sc.engine.rule.frontend/src/views/shared/processors/ConditionRange.ts

@ -3,14 +3,17 @@ import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
class ConditionRange extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'conditionRange',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.CONDITION_RANGE'),
icon: 'bi-card-checklist',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'CONDITION_RANGE');
@ -25,18 +28,18 @@ class ConditionRange extends Processor {
objs.forEach((obj) => {
str += '<tr>';
str += ' <td>' + PlaceHolder.replace(obj.condition) + '</td>';
str += ' <td><span>' + ('' + PlaceHolder.replace(obj.value)) + '</span></td>';
str += ' <td width="100px"><span>' + ('' + PlaceHolder.replace(obj.value)) + '</span></td>';
str += '</tr>';
});
return MarkupTableUtil.markupTable('', str, { dense: false });
return MarkupTableUtil.markupTable('', str, Tools.mergeObject({}, Processor.FORMAT_TABLE_STYLE));
}
return '';
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'conditionRange',
label: $t('re.resources.designer.processor.grid.entity.conditionRange'),
showIf: (args: any) => {
@ -44,6 +47,7 @@ class ConditionRange extends Processor {
},
type: 'w-grid',
height: 300,
localMode: true,
dbClickOperation: 'edit',
autoFetchData: false,
denseBody: true,
@ -55,13 +59,7 @@ class ConditionRange extends Processor {
'add',
'clone',
'edit',
{
extend: 'remove',
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('conditionRange');
grid.removeLocalData(args.selecteds);
},
},
'remove',
'separator',
{
name: 'example',
@ -69,19 +67,17 @@ class ConditionRange extends Processor {
icon: 'bi-balloon',
click: (args: any) => {
const sampleData = [
{ uuid: Tools.uuid(), condition: '${变量名}<=0', value: '0' },
{ uuid: Tools.uuid(), condition: '${变量名}>0 && ${变量名}<=50', value: '50' },
{ uuid: Tools.uuid(), condition: '${变量名}>50 && ${变量名}<=80', value: '80' },
{ uuid: Tools.uuid(), condition: '${变量名}>80 && ${变量名}<=100', value: '100' },
{ uuid: Tools.uuid(), condition: '${变量名}>100', value: '60' },
{ condition: '${变量名}<=0', value: '0' },
{ condition: '${变量名}>0 && ${变量名}<=50', value: '50' },
{ condition: '${变量名}>50 && ${变量名}<=80', value: '80' },
{ condition: '${变量名}>80 && ${变量名}<=100', value: '100' },
{ condition: '${变量名}>100', value: '60' },
];
args.grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: [
{ name: 'uuid', label: 'uuid', hidden: true },
{
name: 'condition',
label: $t('condition'),
@ -107,7 +103,6 @@ class ConditionRange extends Processor {
form: {
colsNum: 1,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false },
{
name: 'condition',
label: $t('condition'),
@ -135,33 +130,22 @@ class ConditionRange extends Processor {
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('conditionRange');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
onBeforeEditorDataSubmit: (args: any) => {},
},
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'conditionRange', label: $t('re.resources.designer.processor.grid.entity.conditionRange') }];
}
public beforeEditorDataSubmit(args: any): void {
// 将编辑对话框中的具体分段表格组件转换成 json 字符串
const grid = args.grid.getEditorForm().getFieldComponent('conditionRange');
const localData: any[] = grid.getRows();
const ranges: any[] = [];
localData.forEach((item) => {
ranges.push({
uuid: item.uuid,
condition: item.condition,
value: item.value,
});
@ -170,12 +154,27 @@ class ConditionRange extends Processor {
}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
// 初始化代码编辑器的自动完成提示管理器
this.initAutoCompletionManager();
// 初始化代码编辑器的用户自定义函数管理器
this.initUserDefinedFunctionsManager();
//获取条件分段编辑对话框中的编辑表单
const form = args.grid.getEditorForm();
//获取编辑表单中的具体分段表格组件
const grid = args.grid.getEditorForm().getFieldComponent('conditionRange');
switch (form.getStatus()) {
case 'add': // 新增时清空表格内容
grid.setLocalData([]);
break;
case 'edit': // 编辑/复制时填充表格内容
case 'clone':
const data = Tools.json2Object(args.data.conditionRange);
grid.setLocalData(data);
break;
}
}
}

200
io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTable.ts

@ -3,17 +3,19 @@ import { $t, Tools, MarkupTableUtil } from 'platform-core';
import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
const columnsRef = ref(<any>[]);
class DecisionTable extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 1024;
protected columnsRef = ref(<any>[]);
public getToolbarAction(): any {
return {
extend: 'add',
name: 'decisionTable',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.DECISION_TABLE'),
icon: 'bi-grid-3x3',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE');
@ -32,7 +34,7 @@ class DecisionTable extends Processor {
if (obj[key] === 'condition') {
str += ' <td>' + $t(obj[key]) + '</td>';
} else {
str += ' <td class="text-blue-500">' + $t(obj[key]) + '</td>';
str += ' <td class="font-bold">' + $t(obj[key]) + '</td>';
}
} else if (key.startsWith('C')) {
str += ' <td>' + PlaceHolder.replace(obj[key]) + '</td>';
@ -40,15 +42,15 @@ class DecisionTable extends Processor {
});
str += '</tr>';
});
return MarkupTableUtil.markupTable('', str);
return MarkupTableUtil.markupTable('', str, Tools.mergeObject({}, Processor.FORMAT_TABLE_STYLE));
}
return '';
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'decisionTable',
label: $t('re.resources.designer.processor.grid.entity.decisionTable'),
showIf: (args: any) => {
@ -56,8 +58,9 @@ class DecisionTable extends Processor {
},
type: 'w-grid',
height: 300,
dbClickOperation: 'edit',
selectedMode: 'cell',
localMode: true,
selectMode: 'cell',
dbClickOperation: 'cellEdit',
autoFetchData: false,
denseBody: true,
dndMode: 'local',
@ -80,7 +83,7 @@ class DecisionTable extends Processor {
return false;
},
click: (args: any) => {
addCol(args.grid, args.selectedColName, /C[\d]/, 'left');
this.addCol(args.grid, args.selectedColName, /C[\d]/, 'left');
},
},
{
@ -93,7 +96,7 @@ class DecisionTable extends Processor {
return false;
},
click: (args: any) => {
addCol(args.grid, args.selectedColName, /C[\d]/, 'right');
this.addCol(args.grid, args.selectedColName, /C[\d]/, 'right');
},
},
'separator',
@ -101,34 +104,24 @@ class DecisionTable extends Processor {
name: 'addConditionRow',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addConditionRow'),
click: (args: any) => {
let rowNum = 0;
const rows = args.grid.getRows();
const propertyNames = Tools.extractAllPropertyNames(rows, /C[\d]/);
propertyNames.sort();
const row: any = {
uuid: Tools.uuid(),
type: 'condition',
};
propertyNames.forEach((name) => {
row[name] = '';
});
args.grid.addLocalData(row);
if (rows && rows.length > 0) {
for (let i = 0; i < rows.length; i++) {
if (rows[i].type === 'result') {
rowNum = i;
break;
}
}
}
args.grid.addLocalData({ type: 'condition' }, rowNum);
},
},
{
name: 'addResultRow',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addResultRow'),
click: (args: any) => {
const rows = args.grid.getRows();
const propertyNames = Tools.extractAllPropertyNames(rows, /C[\d]/);
propertyNames.sort();
const row: any = {
uuid: Tools.uuid(),
type: 'result',
};
propertyNames.forEach((name) => {
row[name] = '';
});
args.grid.addLocalData(row);
args.grid.addLocalData({ type: 'result' });
},
},
],
@ -147,7 +140,7 @@ class DecisionTable extends Processor {
return false;
},
click: (args: any) => {
removeCol(args.grid, args.selectedColName, /C[\d]/);
this.removeCol(args.grid, args.selectedColName, /C[\d]/);
},
},
{
@ -160,12 +153,12 @@ class DecisionTable extends Processor {
return false;
},
click: (args: any) => {
args.grid.removeLocalData(args.selected);
args.grid.removeLocalData(args.selecteds);
},
},
],
'separator',
'edit',
'cellEdit',
'separator',
{
name: 'example',
@ -173,31 +166,33 @@ class DecisionTable extends Processor {
icon: 'bi-balloon',
click: (args: any) => {
const sampleData = [
{ uuid: Tools.uuid(), type: 'condition', C0: '${客户类型}="普通客户"', C1: 'Y', C2: 'Y', C3: null, C4: null },
{ uuid: Tools.uuid(), type: 'condition', C0: '${评分结果}>=60', C1: 'Y', C2: null, C3: 'Y', C4: null },
{ uuid: Tools.uuid(), type: 'result', C0: '${风险等级}', C1: 'A', C2: 'B', C3: 'B', C4: 'C' },
{ uuid: Tools.uuid(), type: 'result', C0: '${决策结果}', C1: '直接通过', C2: '人工审查', C3: '人工审查', C4: '直接拒绝' },
{ type: 'condition', C0: '${客户类型}="普通客户"', C1: 'Y', C2: 'Y', C3: null, C4: null },
{ type: 'condition', C0: '${评分结果}>=60', C1: 'Y', C2: null, C3: 'Y', C4: null },
{ type: 'result', C0: '${风险等级}', C1: 'A', C2: 'B', C3: 'B', C4: 'C' },
{ type: 'result', C0: '${决策结果}', C1: '直接通过', C2: '人工审查', C3: '人工审查', C4: '直接拒绝' },
];
const propertyNames: any[] = Tools.extractAllPropertyNames(sampleData, /C[\d]/);
propertyNames.sort();
this.buildColumsRef(propertyNames);
args.grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: columnsRef,
columns: this.columnsRef,
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: columnsRef,
fields: this.columnsRef,
},
},
},
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'decisionTable', label: $t('re.resources.designer.processor.grid.entity.decisionTable') }];
}
@ -206,7 +201,6 @@ class DecisionTable extends Processor {
const grid = form.getFieldComponent('decisionTable');
const localData: any[] = grid.getRows();
const fieldNames: any[] = [];
fieldNames.push('uuid');
fieldNames.push('type');
const propertyNames: any[] = Tools.extractAllPropertyNames(localData, /C[\d]/);
propertyNames.sort();
@ -225,43 +219,36 @@ class DecisionTable extends Processor {
}
public afterEditorOpen(args: any): void {
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
const form = args.grid.getEditorForm();
const row = args.data;
// 构建表格的头
const row = args.data || [];
const rows = Tools.json2Object(row.decisionTable);
const fieldNames = Tools.extractAllPropertyNames(rows, /C[\d]/);
fieldNames.sort();
const fields: any = [];
addFixedFields(fields);
fieldNames.forEach((name) => {
fields.push({
name: name,
label: $t(name),
sortable: false,
type: 'w-code-mirror',
attrs: {
toolbar: false,
rows: 1,
},
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
});
columnsRef.value = fields;
// 设置表格数据
this.buildColumsRef(fieldNames);
const grid = form.getFieldComponent('decisionTable');
switch (form.getStatus()) {
case 'add':
grid.setLocalData([]);
break;
case 'edit':
case 'clone':
grid.setLocalData(rows);
break;
}
}
const addCol = (grid: any, currentSelectedColName: string, colNamePattern: any, mode: string) => {
protected addCol(grid: any, currentSelectedColName: string, colNamePattern: any, mode: string) {
//更新表数据
const rows: any[] = grid.getRows();
const propertyNames: string[] = Tools.extractAllPropertyNames(rows, colNamePattern);
propertyNames.sort();
const selectedColIndex = propertyNames.indexOf(currentSelectedColName) + (mode === 'left' ? 0 : 1);
rows.forEach((row) => {
let i = 0;
for (i = propertyNames.length; i > selectedColIndex; i--) {
@ -269,32 +256,15 @@ const addCol = (grid: any, currentSelectedColName: string, colNamePattern: any,
}
row['C' + selectedColIndex] = '';
});
// 更新表头
const fields: any[] = [];
addFixedFields(fields);
let i = 0;
for (i = 0; i <= propertyNames.length; i++) {
fields.push({
name: 'C' + i,
label: $t('C' + i),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
}
columnsRef.value = fields;
this.buildColumsRef(Tools.extractAllPropertyNames(rows, colNamePattern));
grid.setLocalData(rows);
};
}
const removeCol = (grid: any, currentSelectedColName: string, colNamePattern: any) => {
//更新表数据
protected removeCol(grid: any, currentSelectedColName: string, colNamePattern: any) {
const rows: any[] = grid.getRows();
const propertyNames: string[] = Tools.extractAllPropertyNames(rows, colNamePattern);
propertyNames.sort();
const selectedColIndex = propertyNames.indexOf(currentSelectedColName);
rows.forEach((row) => {
let i = 0;
for (i = selectedColIndex; i < propertyNames.length; i++) {
@ -302,37 +272,49 @@ const removeCol = (grid: any, currentSelectedColName: string, colNamePattern: an
}
delete row['C' + (propertyNames.length - 1)];
});
this.buildColumsRef(Tools.extractAllPropertyNames(rows, colNamePattern));
grid.setLocalData(rows);
}
// 更新表头
const fields: any[] = [];
addFixedFields(fields);
protected buildColumsRef(propertyNames: string[]) {
const columns: any[] = [];
// 添加"类型"列
columns.push({
name: 'type',
label: $t('type'),
format: (value: any) => {
if (value === 'result') {
return '<span class="font-bold">' + $t(value) + '</span>';
}
return $t(value);
},
});
// 添加其他列
let i = 0;
for (i = 0; i < propertyNames.length - 1; i++) {
fields.push({
for (i = 0; i < propertyNames.length; i++) {
columns.push({
name: 'C' + i,
label: $t('C' + i),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
type: 'w-code-mirror',
attrs: {
toolbar: false,
lang: 'java',
rows: 4,
lineWrap: true,
lineBreak: false,
placeholder: true,
autoCompletion: this.autoCompletionManager.autoCompletion(),
userDefinedFunctions: this.userDefinedFunctionsManager.userDefinedFunctions(),
},
});
}
columnsRef.value = fields;
grid.setLocalData(rows);
};
const addFixedFields = (fields: any[]) => {
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
fields.push({
name: 'type',
label: $t('type'),
format: (value: any) => {
if (value === 'result') {
return '<span class="text-blue-500">' + $t(value) + '</span>';
this.columnsRef.value = columns;
}
}
return $t(value);
},
});
};
export { DecisionTable };

162
io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTable2c.ts

@ -1,19 +1,21 @@
import { ref } from 'vue';
import { $t, Tools, MarkupTableUtil } from 'platform-core';
import { Processor } from '../Processor';
import { DecisionTable } from './DecisionTable';
import { PlaceHolder } from '@/utils/PlaceHolder';
const columnsRef = ref(<any>[]);
class DecisionTable2C extends DecisionTable {
#editorDialogWidth: number = 1024;
class DecisionTable2C extends Processor {
public getToolbarAction(target: any): any {
public getToolbarAction(): any {
return {
extend: 'add',
name: 'decisionTable2C',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.DECISION_TABLE_2C'),
icon: 'bi-grid-3x2',
enableIf: (args) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE_2C');
@ -28,31 +30,31 @@ class DecisionTable2C extends Processor {
objs.forEach((obj) => {
str += '<tr>';
Object.keys(obj).forEach((key) => {
if (key !== 'uuid' && typeof obj[key] === 'string') {
if (typeof obj[key] === 'string') {
str += ' <td>' + PlaceHolder.replace(obj[key]) + '</td>';
}
});
str += '</tr>';
});
return MarkupTableUtil.markupTable('', str);
return MarkupTableUtil.markupTable('', str, Tools.mergeObject({}, Processor.FORMAT_TABLE_STYLE));
}
return '';
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'decisionTable2C',
label: $t('re.resources.designer.processor.grid.entity.decisionTable2C'),
showIf: (args: any) => {
return 'DECISION_TABLE_2C' === args.form.getFieldValue('type');
},
type: 'w-grid',
localMode: true,
height: 300,
dbClickOperation: 'edit',
selectedMode: 'cell',
localMode: true,
selectMode: 'cell',
dbClickOperation: 'cellEdit',
autoFetchData: false,
denseBody: true,
dndMode: 'local',
@ -75,7 +77,7 @@ class DecisionTable2C extends Processor {
return false;
},
click: (args: any) => {
addCol(args.grid, args.selectedColName, /C[\d]/, 'left');
this.addCol(args.grid, args.selectedColName, /C[\d]/, 'left');
},
},
{
@ -88,7 +90,7 @@ class DecisionTable2C extends Processor {
return false;
},
click: (args: any) => {
addCol(args.grid, args.selectedColName, /C[\d]/, 'right');
this.addCol(args.grid, args.selectedColName, /C[\d]/, 'right');
},
},
'separator',
@ -96,16 +98,7 @@ class DecisionTable2C extends Processor {
name: 'addRow',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addRow'),
click: (args: any) => {
const rows = args.grid.getRows();
const propertyNames = Tools.extractAllPropertyNames(rows, /C[\d]/);
propertyNames.sort();
const row: any = {
uuid: Tools.uuid(),
};
propertyNames.forEach((name) => {
row[name] = '';
});
args.grid.addLocalData(row);
args.grid.addLocalData({});
},
},
],
@ -124,7 +117,7 @@ class DecisionTable2C extends Processor {
return false;
},
click: (args: any) => {
removeCol(args.grid, args.selectedColName, /C[\d]/);
this.removeCol(args.grid, args.selectedColName, /C[\d]/);
},
},
{
@ -137,12 +130,12 @@ class DecisionTable2C extends Processor {
return false;
},
click: (args: any) => {
args.grid.removeLocalData(args.selected);
args.grid.removeLocalData(args.selecteds);
},
},
],
'separator',
'edit',
'cellEdit',
'separator',
{
name: 'example',
@ -150,30 +143,32 @@ class DecisionTable2C extends Processor {
icon: 'bi-balloon',
click: (args: any) => {
const sampleData = [
{ uuid: Tools.uuid(), C0: '', C1: "${客户类型}=='普通客户'", C2: "${客户类型}=='VIP客户'", C3: "${客户类型}=='临时客户'" },
{ uuid: Tools.uuid(), C0: '${评分结果}<60', C1: '1', C2: '3', C3: '5' },
{ uuid: Tools.uuid(), C0: '${评分结果}>=60', C1: '2', C2: '4', C3: '6' },
{ C0: '', C1: "${客户类型}=='普通客户'", C2: "${客户类型}=='VIP客户'", C3: "${客户类型}=='临时客户'" },
{ C0: '${评分结果}<60', C1: '1', C2: '3', C3: '5' },
{ C0: '${评分结果}>=60', C1: '2', C2: '4', C3: '6' },
];
const propertyNames: any[] = Tools.extractAllPropertyNames(sampleData, /C[\d]/);
propertyNames.sort();
this.buildColumsRef(propertyNames);
args.grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: columnsRef,
columns: this.columnsRef,
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: columnsRef,
fields: this.columnsRef,
},
},
},
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'decisionTable2C', label: $t('re.resources.designer.processor.grid.entity.decisionTable2C') }];
}
@ -182,7 +177,6 @@ class DecisionTable2C extends Processor {
const grid = form.getFieldComponent('decisionTable2C');
const localData: any[] = grid.getRows();
const fieldNames: any[] = Tools.extractAllPropertyNames(localData, /C[\d]/);
fieldNames.push('uuid');
fieldNames.sort();
const data: any = [];
localData.forEach((row) => {
@ -196,100 +190,34 @@ class DecisionTable2C extends Processor {
}
public afterEditorOpen(args: any): void {
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
const form = args.grid.getEditorForm();
const row = args.data;
// 构建表格的头
const rows = Tools.json2Object(row.decisionTable2C);
const fieldNames = Tools.extractAllPropertyNames(rows, /C[\d]/);
fieldNames.sort();
const fields: any = [];
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
fieldNames.forEach((name) => {
fields.push({
name: name,
label: $t(name),
sortable: false,
type: 'w-code-mirror',
attrs: {
toolbar: false,
rows: 1,
},
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
});
columnsRef.value = fields;
// 设置表格数据
this.buildColumsRef(fieldNames);
const grid = form.getFieldComponent('decisionTable2C');
switch (form.getStatus()) {
case 'add':
grid.setLocalData([]);
break;
case 'edit':
case 'clone':
grid.setLocalData(rows);
break;
}
}
const addCol = (grid: any, currentSelectedColName: string, colNamePattern: any, mode: string) => {
//更新表数据
const rows: any[] = grid.getRows();
const propertyNames: string[] = Tools.extractAllPropertyNames(rows, colNamePattern);
propertyNames.sort();
const selectedColIndex = propertyNames.indexOf(currentSelectedColName) + (mode === 'left' ? 0 : 1);
rows.forEach((row) => {
let i = 0;
for (i = propertyNames.length; i > selectedColIndex; i--) {
row['C' + i] = row['C' + (i - 1)];
protected buildColumsRef(propertyNames: string[]) {
super.buildColumsRef(propertyNames);
this.columnsRef.value.splice(0, 1);
}
row['C' + selectedColIndex] = '';
});
// 更新表头
const fields: any[] = [];
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
let i = 0;
for (i = 0; i <= propertyNames.length; i++) {
fields.push({
name: 'C' + i,
label: $t('C' + i),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
}
columnsRef.value = fields;
grid.setLocalData(rows);
};
const removeCol = (grid: any, currentSelectedColName: string, colNamePattern: any) => {
//更新表数据
const rows: any[] = grid.getRows();
const propertyNames: string[] = Tools.extractAllPropertyNames(rows, colNamePattern);
propertyNames.sort();
const selectedColIndex = propertyNames.indexOf(currentSelectedColName);
rows.forEach((row) => {
let i = 0;
for (i = selectedColIndex; i < propertyNames.length; i++) {
row['C' + i] = row['C' + (i + 1)];
}
delete row['C' + (propertyNames.length - 1)];
});
// 更新表头
const fields: any[] = [];
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
let i = 0;
for (i = 0; i < propertyNames.length - 1; i++) {
fields.push({
name: 'C' + i,
label: $t('C' + i),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
}
columnsRef.value = fields;
grid.setLocalData(rows);
};
export { DecisionTable2C };

11
io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTree.ts

@ -2,14 +2,15 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class DecisionTree extends Processor {
public getToolbarAction(target: any): any {
public getToolbarAction(): any {
return {
extend: 'add',
name: 'decisionTree',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.DECISION_TREE'),
icon: 'bi-tree',
enableIf: (args) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'DECISION_TREE');
@ -25,10 +26,10 @@ class DecisionTree extends Processor {
return result;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'decisionTree',
label: $t('re.resources.designer.processor.grid.entity.decisionTree'),
type: 'w-code-mirror',
@ -42,7 +43,7 @@ class DecisionTree extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [];
}

11
io.sc.engine.rule.frontend/src/views/shared/processors/ExecutionFlow.ts

@ -2,14 +2,15 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class ExecutionFlow extends Processor {
public getToolbarAction(target: any): any {
public getToolbarAction(): any {
return {
extend: 'add',
name: 'executionFlow',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.EXECUTION_FLOW'),
icon: 'bi-bounding-box-circles',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'EXECUTION_FLOW');
@ -25,10 +26,10 @@ class ExecutionFlow extends Processor {
return result;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'executionFlow',
label: $t('re.resources.designer.processor.grid.entity.executionFlow'),
type: 'w-code-mirror',
@ -42,7 +43,7 @@ class ExecutionFlow extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [];
}

20
io.sc.engine.rule.frontend/src/views/shared/processors/GroovyScript.ts

@ -2,14 +2,17 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class GroovyScript extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'groovyScript',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.GROOVY_SCRIPT'),
icon: 'bi-code',
enableIf: (args) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'GROOVY_SCRIPT');
@ -24,10 +27,10 @@ class GroovyScript extends Processor {
return result;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'groovyScript',
label: $t('re.resources.designer.processor.grid.entity.groovyScript'),
type: 'w-code-mirror',
@ -39,22 +42,23 @@ class GroovyScript extends Processor {
placeholder: true,
autoCompletion: this.autoCompletionManager.autoCompletion(),
userDefinedFunctions: this.userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args) => {
showIf: (args: any) => {
return 'GROOVY_SCRIPT' === args.form.getFieldValue('type');
},
},
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'groovyScript', label: $t('re.resources.designer.processor.grid.entity.groovyScript') }];
}
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
}
}

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

@ -0,0 +1,390 @@
import { ref, computed } from 'vue';
import { axios, Environment, $t, Tools, EnumTools, Options } from 'platform-core';
import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
class HttpRequest extends Processor {
#editorDialogWidth: number = 1280;
#HttpMethodTypeEnum: any;
#httpMethodTypeOptionsRef = ref(<any>[]);
#parameterOptionsRef = ref(<any>[]);
#sqlQueryResultFieldsRef = ref(<any>[]);
#editorForm: any;
constructor(targetType: string, context?: any) {
super(targetType, context);
EnumTools.fetch(['io.sc.engine.rule.core.enums.HttpMethodType']).then((value) => {
this.#HttpMethodTypeEnum = value.HttpMethodType;
this.#httpMethodTypeOptionsRef = Options.enum(this.#HttpMethodTypeEnum);
});
if (this.targetType === Processor.PARAMETER) {
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemtersByParameterId/' + this.context.target.id)).then((response) => {
this.#parameterOptionsRef.value = Tools.objects2Options(response.data, 'name', 'code');
});
}
}
public getToolbarAction(): any {
return {
extend: 'add',
name: 'http',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.HTTP_REQUEST'),
icon: 'sync_alt',
enableIf: (args: any) => {
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'HTTP_REQUEST');
},
};
}
public format(row: any): any {
return {
componentType: 'w-code-mirror',
attrs: {
lang: 'sql',
rows: 4,
editable: false,
modelValue: row.sql,
placeholder: true,
},
};
}
public getEditorFields(): any {
return [
{
colSpan: 2,
name: 'httpMethod',
label: $t('re.resources.designer.processor.grid.entity.httpMethod'),
type: 'w-select',
clearable: true,
options: this.#httpMethodTypeOptionsRef,
rows: 1,
showIf: (args: any) => {
return 'HTTP_REQUEST' === args.form.getFieldValue('type');
},
},
{
colSpan: 5,
name: 'sql',
label: $t('re.resources.designer.processor.grid.entity.httpUrl'),
type: 'w-text',
showIf: (args: any) => {
return 'HTTP_REQUEST' === args.form.getFieldValue('type');
},
},
{
colSpan: 3,
name: 'sqlParameterValues',
label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 150,
title: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
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 = args.grid.getEditorForm().getFieldValue('sql');
const regex = /\$\{[\u0000-\uFFFF]+?\}/g;
const array: any[] = sql.match(regex);
const rows: any[] = [];
array.forEach((item) => {
rows.push({ name: item, value: '' });
});
const grid = args.grid.getEditorForm().getFieldComponent('sqlParameterValues');
grid.setLocalData(rows);
},
},
'separator',
'add',
'edit',
[
{
extend: 'remove',
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('sqlParameterValues');
grid.removeRows(args.selecteds);
},
},
{
extend: 'remove',
name: 'removeAll',
label: $t('deleteAll'),
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('sqlParameterValues');
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',
},
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('sqlParameterValues');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
},
{
colSpan: 4,
name: 'sqlQueryResult',
label: $t('re.resources.designer.processor.grid.entity.sqlQueryResult'),
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 250,
autoFetchData: false,
title: $t('re.resources.designer.processor.grid.entity.sqlQueryResult'),
dense: true,
dndMode: 'local',
pageable: false,
checkboxSelection: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
{
name: 'execute',
label: $t('execute'),
icon: 'bi-caret-right',
click: (args: any) => {
const sql = this.#editorForm.getFieldValue('sql');
const grid = this.#editorForm.getFieldComponent('sqlParameterValues');
const sqlParameterValues = grid?.getRows();
axios
.post(Environment.apiContextPath('/api/re/model/parameter/processor/executeSql'), {
sql: sql,
sqlParameterValues: sqlParameterValues,
})
.then((response) => {
const fieldMetaDatas: any[] = response.data.fieldMetaDatas;
fieldMetaDatas.forEach((field) => {
field.value = field.name;
field.label = field.name;
});
const data = response.data.data;
const grid = this.#editorForm.getFieldComponent('sqlQueryResult');
this.#sqlQueryResultFieldsRef.value = fieldMetaDatas;
grid.setLocalData(data);
});
},
},
],
columns: computed(() => {
return this.#sqlQueryResultFieldsRef.value;
}),
},
{
colSpan: 3,
name: 'sqlFieldMapping',
label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 250,
width: '100%',
autoFetchData: false,
title: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
dense: true,
dbClickOperation: 'edit',
dndMode: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
'add',
'edit',
[
{
extend: 'remove',
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('sqlFieldMapping');
grid.removeLocalData(args.selecteds);
},
},
{
extend: 'remove',
name: 'removeAll',
label: $t('deleteAll'),
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('sqlFieldMapping');
grid.setLocalData([]);
},
},
],
],
columns: [
{
width: '50%',
name: 'parameter',
label: $t('parameterName'),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
{
width: '50%',
name: 'field',
label: $t('fieldName'),
align: 'left',
sortable: false,
},
],
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{
name: 'parameter',
label: $t('parameterName'),
type: 'w-select',
options: this.#parameterOptionsRef.value,
},
{
name: 'field',
label: $t('fieldName'),
type: 'w-select',
options: this.#sqlQueryResultFieldsRef.value,
},
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('sqlFieldMapping');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
},
];
}
public getViewerFields(): any {
return [
{ name: 'sqlDatasourceName', label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName') },
{ name: 'sql', label: $t('re.resources.designer.processor.grid.entity.sql') },
{ name: 'sqlParameterValues', label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues') },
{ name: 'sqlFieldMapping', label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping') },
];
}
public beforeEditorDataSubmit(args: any): void {
const form = args.grid.getEditorForm();
const sqlParameterValuesGrid = form.getFieldComponent('sqlParameterValues');
const sqlParameterValuesLocalData: any[] = sqlParameterValuesGrid.getRows();
const sqlParameterValues: any[] = [];
sqlParameterValuesLocalData.forEach((item) => {
sqlParameterValues.push({
name: item.name,
value: item.value,
});
});
args.data.sqlParameterValues = Tools.object2Json(sqlParameterValues);
const sqlFieldMappingGrid = form.getFieldComponent('sqlFieldMapping');
const sqlFieldMappingLocalData: any[] = sqlFieldMappingGrid.getRows();
const sqlFieldMapping: any[] = Tools.objects2Objects(sqlFieldMappingLocalData, { field: 'field', parameter: 'parameter' });
args.data.sqlFieldMapping = Tools.object2Json(sqlFieldMapping);
}
public afterEditorOpen(args: any): void {
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
this.#editorForm = args.grid.getEditorForm();
const form = args.grid.getEditorForm();
const row = args.data;
axios.get(Environment.apiContextPath('api/re/model/parameter/findParametersByParameterId?parameterId=' + this.context.target.id)).then((response) => {
this.#parameterOptionsRef.value = Tools.objects2Objects(response.data, {
label: 'name',
value: (parameter: any) => {
return '${' + parameter.name + '}';
},
});
});
const sqlParameterValuesGrid = form.getFieldComponent('sqlParameterValues');
const sqlParameterValuesRows = Tools.json2Object(row.sqlParameterValues);
sqlParameterValuesGrid.setLocalData(sqlParameterValuesRows);
const sqlFieldMappingGrid = form.getFieldComponent('sqlFieldMapping');
const sqlFieldMappingRows = Tools.json2Object(row.sqlFieldMapping);
sqlFieldMappingGrid.setLocalData(sqlFieldMappingRows);
}
}
export { HttpRequest };

18
io.sc.engine.rule.frontend/src/views/shared/processors/MathFormula.ts

@ -2,14 +2,17 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class MathFormula extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'mathFormula',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.MATH_FORMULA'),
icon: 'bi-superscript',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'MATH_FORMULA');
@ -28,10 +31,10 @@ class MathFormula extends Processor {
};
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'mathFormula',
label: $t('re.resources.designer.processor.grid.entity.mathFormula'),
type: 'w-math',
@ -44,15 +47,16 @@ class MathFormula extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [];
}
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
}
}

78
io.sc.engine.rule.frontend/src/views/shared/processors/NumberRange.ts

@ -3,14 +3,17 @@ import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
class NumberRange extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'numberRange',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.NUMBER_RANGE'),
icon: 'bi-justify',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'NUMBER_RANGE');
@ -25,22 +28,22 @@ class NumberRange extends Processor {
objs.forEach((obj, index) => {
str += '<tr>';
if (index == 0 && this.targetType !== Processor.SCORE_CARD) {
str += ' <td rowspan=' + objs.length + '>' + PlaceHolder.replace(row.numberRangeVar) + '</td>';
str += ' <td rowspan=' + objs.length + ' width="200px">' + PlaceHolder.replace(row.numberRangeVar) + '</td>';
}
str += ' <td>' + Tools.generateIntervalRange(obj.minIncluded, obj.min, obj.max, obj.maxIncluded) + '</td>';
str += ' <td>' + ('' + PlaceHolder.replace('' + obj.value)) + '</td>';
str += ' <td width="100px">' + ('' + PlaceHolder.replace('' + obj.value)) + '</td>';
str += '</tr>';
});
return MarkupTableUtil.markupTable('', str);
return MarkupTableUtil.markupTable('', str, Tools.mergeObject({}, Processor.FORMAT_TABLE_STYLE));
}
return '';
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
const result: any[] = [];
if (this.targetType !== Processor.SCORE_CARD) {
result.push({
colSpan: 5,
colSpan: 7,
name: 'numberRangeVar',
label: $t('re.resources.designer.processor.grid.entity.numberRangeVar'),
showIf: (args: any) => {
@ -57,7 +60,7 @@ class NumberRange extends Processor {
});
}
result.push({
colSpan: 5,
colSpan: 7,
name: 'numberRange',
label: $t('re.resources.designer.processor.grid.entity.numberRange'),
showIf: (args: any) => {
@ -65,6 +68,7 @@ class NumberRange extends Processor {
},
type: 'w-grid',
height: 300,
localMode: true,
dbClickOperation: 'edit',
autoFetchData: false,
denseBody: true,
@ -76,13 +80,7 @@ class NumberRange extends Processor {
'add',
'clone',
'edit',
{
extend: 'remove',
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('numberRange');
grid.removeLocalData(args.selecteds);
},
},
'remove',
'separator',
{
name: 'example',
@ -90,20 +88,18 @@ class NumberRange extends Processor {
icon: 'bi-balloon',
click: (args: any) => {
const sampleData = [
{ uuid: Tools.uuid(), minIncluded: false, min: null, max: 0, maxIncluded: false, value: 1 },
{ uuid: Tools.uuid(), minIncluded: true, min: 0, max: 1, maxIncluded: false, value: 2 },
{ uuid: Tools.uuid(), minIncluded: true, min: 1, max: 2, maxIncluded: false, value: 3 },
{ uuid: Tools.uuid(), minIncluded: true, min: 2, max: 3, maxIncluded: false, value: 4 },
{ uuid: Tools.uuid(), minIncluded: true, min: 3, max: null, maxIncluded: false, value: 5 },
{ uuid: Tools.uuid(), minIncluded: false, min: null, max: null, maxIncluded: false, value: 0 },
{ minIncluded: false, min: null, max: 0, maxIncluded: false, value: 1 },
{ minIncluded: true, min: 0, max: 1, maxIncluded: false, value: 2 },
{ minIncluded: true, min: 1, max: 2, maxIncluded: false, value: 3 },
{ minIncluded: true, min: 2, max: 3, maxIncluded: false, value: 4 },
{ minIncluded: true, min: 3, max: null, maxIncluded: false, value: 5 },
{ minIncluded: false, min: null, max: null, maxIncluded: false, value: 0 },
];
args.grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: [
{ width: 200, name: 'uuid', label: 'uuid', hidden: true },
{
width: 60,
name: 'minIncluded',
@ -143,7 +139,6 @@ class NumberRange extends Processor {
form: {
colsNum: 4,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false, colSpan: 4 },
{ name: 'min', label: $t('minValue'), type: 'w-text', colSpan: 3 },
{ name: 'minIncluded', label: $t('include'), type: 'w-checkbox' },
{ name: 'max', label: $t('maxValue'), type: 'w-text', colSpan: 3 },
@ -152,34 +147,21 @@ class NumberRange extends Processor {
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('numberRange');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
onBeforeEditorDataSubmit: (args: any) => {},
});
return result;
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'numberRange', label: $t('re.resources.designer.processor.grid.entity.numberRange') }];
}
public beforeEditorDataSubmit(args: any): void {
const form = args.grid.getEditorForm();
const grid = form.getFieldComponent('numberRange');
const grid = args.grid.getEditorForm().getFieldComponent('numberRange');
const localData: any[] = grid.getRows();
const ranges: any[] = [];
localData.forEach((item) => {
ranges.push({
uuid: item.uuid,
minIncluded: item.minIncluded,
min: item.min,
max: item.max,
@ -191,14 +173,18 @@ class NumberRange extends Processor {
}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
const form = args.grid.getEditorForm();
const row = args.data;
const grid = form.getFieldComponent('numberRange');
const rows = Tools.json2Object(row.numberRange);
grid.setLocalData(rows);
const grid = args.grid.getEditorForm().getFieldComponent('numberRange');
if ('add' == form.getStatus()) {
grid.setLocalData([]);
} else if ('edit' == form.getStatus() || 'clone' == form.getStatus()) {
const data = Tools.json2Object(args.data.numberRange);
grid.setLocalData(data);
}
}
}

27
io.sc.engine.rule.frontend/src/views/shared/processors/ObjectProperties.ts

@ -4,14 +4,16 @@ import { PlaceHolder } from '@/utils/PlaceHolder';
import { ValueTypeUtil } from '@/utils/ValueTypeUtil';
class ObjectProperties extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'objectProperties',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.OBJECT_PROPERTIES'),
icon: 'bi-list-task',
enableIf: (args: any) => {
return !ValueTypeUtil.isBase(target.valueType);
return !ValueTypeUtil.isBase(this.context.target.valueType);
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'OBJECT_PROPERTIES');
@ -33,15 +35,15 @@ class ObjectProperties extends Processor {
body += ` <td width='70%'><span>` + ('' + PlaceHolder.replace(obj.expression)) + '</span></td>';
body += '</tr>';
});
str += MarkupTableUtil.markupTable('', body, { 'max-height': '200px' });
str += MarkupTableUtil.markupTable('', body, Tools.mergeObject({ 'max-height': '150px' }, Processor.FORMAT_TABLE_STYLE));
}
return str;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'objectCondition',
label: $t('re.resources.designer.processor.grid.entity.objectCondition'),
type: 'w-code-mirror',
@ -56,7 +58,7 @@ class ObjectProperties extends Processor {
},
},
{
colSpan: 5,
colSpan: 7,
name: 'objectProperties',
label: $t('re.resources.designer.processor.grid.entity.objectProperties'),
showIf: (args: any) => {
@ -88,7 +90,7 @@ class ObjectProperties extends Processor {
expression: item.expression,
});
});
context.objectPropertiesMatcherDialogRef.open(objectProperties);
this.context.objectPropertiesMatcherDialogRef.value.open(objectProperties);
},
},
'edit',
@ -183,7 +185,7 @@ class ObjectProperties extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [];
}
@ -203,17 +205,18 @@ class ObjectProperties extends Processor {
}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
const form = args.grid.getEditorForm();
const row = args.data;
if ('add' == form.getStatus()) {
let listObejctPropertiesUrl = '';
if (this.targetType === Processor.PARAMETER) {
listObejctPropertiesUrl = '/api/re/model/parameter/listObejctPropertiesByParameterId/' + args.target.id;
listObejctPropertiesUrl = '/api/re/model/parameter/listObejctPropertiesByParameterId/' + this.context.target.id;
} else if (this.targetType === Processor.INDICATOR) {
listObejctPropertiesUrl = '/api/re/indicator/listObejctPropertiesByIndicatorId/' + args.target.id;
listObejctPropertiesUrl = '/api/re/indicator/listObejctPropertiesByIndicatorId/' + this.context.target.id;
}
axios.get(Environment.apiContextPath(listObejctPropertiesUrl)).then((response) => {
const properties = response.data;

17
io.sc.engine.rule.frontend/src/views/shared/processors/OptionValue.ts

@ -5,14 +5,17 @@ import { Processor } from '../Processor';
const optionOptionsRef = ref(<any>[]);
class OptionValue extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 400;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'optionValue',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.OPTION_VALUE'),
icon: 'bi-card-list',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'OPTION_VALUE');
@ -24,10 +27,10 @@ class OptionValue extends Processor {
return row.optionCode;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'optionCode',
label: $t('re.resources.designer.processor.grid.entity.optionCode'),
type: 'w-select',
@ -39,16 +42,16 @@ class OptionValue extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'optionCode', label: $t('re.resources.designer.processor.grid.entity.optionCode') }];
}
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {
args.grid.getEditorDialog().setWidth('40%');
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
// 获取选项输入参数列表
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemtersByParameterId/' + args.target.id)).then((response) => {
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemtersByParameterId/' + this.context.target.id)).then((response) => {
const parameters: any[] = response.data;
const options: any[] = [];
parameters.forEach((item) => {

19
io.sc.engine.rule.frontend/src/views/shared/processors/Pmml.ts

@ -2,14 +2,17 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class Pmml extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 1024;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'pmml',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.PMML'),
icon: 'bi-filetype-xml',
enableIf: (args) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'PMML');
@ -25,14 +28,15 @@ class Pmml extends Processor {
return result;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'pmml',
label: $t('re.resources.designer.processor.grid.entity.pmml'),
type: 'w-code-mirror',
rows: 20,
tabSize: 2,
lineNumber: true,
toolbar: false,
lang: 'xml',
@ -45,15 +49,16 @@ class Pmml extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [];
}
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
}
}

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

@ -2,14 +2,17 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class Rule extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'rule',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.RULE'),
icon: 'bi-shadows',
enableIf: (args: any) => {
return target.type === 'RULE_RESULT' || target.type === 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'RULE');
@ -21,17 +24,19 @@ class Rule extends Processor {
return row.rule;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'rule', label: $t('re.resources.designer.processor.grid.entity.rule') }];
}
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {}
public afterEditorOpen(args: any): void {
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
}
}
export { Rule };

185
io.sc.engine.rule.frontend/src/views/shared/processors/ScoreCard.ts

@ -1,23 +1,38 @@
import { ref, toRaw } from 'vue';
import { $t, axios, Environment, Tools } from 'platform-core';
import { ref } from 'vue';
import { $t, axios, Environment, MarkupTableUtil, Tools } from 'platform-core';
import { Processor } from '../Processor';
import { ConditionRange } from './ConditionRange';
import { NumberRange } from './NumberRange';
const parameterOptionsRef = ref(<any>[]);
const varProcessorTypeOptionsRef = ref(<any>[]);
const conditionRange = new ConditionRange(Processor.SCORE_CARD);
const numberRange = new NumberRange(Processor.SCORE_CARD);
class ScoreCard extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 1024;
#conditionRange: any;
#numberRange: any;
#parameterOptionsRef = ref(<any>[]);
#scoreCard: any; //评分卡因素列表
constructor(targetType: string, context?: any) {
super(targetType, context);
this.#conditionRange = new ConditionRange(Processor.SCORE_CARD, context);
this.#numberRange = new NumberRange(Processor.SCORE_CARD, context);
if (this.targetType === Processor.PARAMETER) {
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemtersByParameterId/' + this.context.target.id)).then((response) => {
this.#parameterOptionsRef.value = Tools.objects2Options(response.data, 'name', 'code');
});
}
}
public getToolbarAction(): any {
return {
extend: 'add',
name: 'scoreCard',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.SCORE_CARD'),
icon: 'bi-credit-card-2-front',
enableIf: (args) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'SCORE_CARD');
@ -28,36 +43,34 @@ class ScoreCard extends Processor {
public format(row: any): any {
const objs = Tools.json2Object(row.scoreCard);
if (objs) {
let str = `<div class='border border-b-0'>`;
str += `<table width='100%' height='100%'>`;
let str = '';
objs.forEach((obj: any) => {
str += '<tr>';
str += ' <td>' + $t('io.sc.engine.rule.core.enums.ProcessorType.' + obj.type) + '</td>';
str += ' <td>' + obj.name + '</td>';
str += ' <td>' + this.getParameterNameByCode(obj.code) + '</td>';
if (obj.type === 'CONDITION_RANGE') {
str += ' <td style="pading:0px">' + conditionRange.format({ conditionRange: Tools.object2Json(obj.conditionRange) }) + '</td>';
str += ' <td>' + this.#conditionRange.format({ conditionRange: Tools.object2Json(obj.conditionRange) }) + '</td>';
} else if (obj.type === 'NUMBER_RANGE') {
str += ' <td>' + numberRange.format({ numberRange: Tools.object2Json(obj.numberRange) }) + '</td>';
str += ' <td>' + this.#numberRange.format({ numberRange: Tools.object2Json(obj.numberRange) }) + '</td>';
}
str += '</tr>';
});
str += '</table>';
str += `</div>`;
return str;
return MarkupTableUtil.markupTable('', str, Tools.mergeObject({ maxHeight: 100 }, Processor.FORMAT_TABLE_STYLE));
}
return '';
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'scoreCard',
label: $t('re.resources.designer.processor.grid.entity.scoreCard'),
type: 'w-grid',
showIf: (args: any) => {
return 'SCORE_CARD' === args.form.getFieldValue('type');
},
localMode: true,
height: 600,
dbClickOperation: 'edit',
autoFetchData: false,
@ -72,33 +85,29 @@ class ScoreCard extends Processor {
extend: 'add',
click: undefined,
},
conditionRange.getToolbarAction({}),
numberRange.getToolbarAction({}),
this.#conditionRange.getToolbarAction({}),
this.#numberRange.getToolbarAction({}),
],
'clone',
'edit',
{
extend: 'remove',
click: (args: any) => {
const grid = args.grid.getEditorForm().getFieldComponent('scoreCard');
grid.removeLocalData(args.selecteds);
},
},
'remove',
],
primaryKey: 'uuid',
columns: [
{ width: 200, name: 'uuid', label: 'uuid', hidden: true },
{
width: 120,
name: 'code',
label: $t('code'),
sortable: false,
hidden: true,
},
{
width: 120,
name: 'name',
label: $t('name'),
sortable: false,
format: (value: any, row: any) => {
return this.getParameterNameByCode(row.code);
},
},
{
width: 80,
@ -120,15 +129,16 @@ class ScoreCard extends Processor {
name: 'content',
label: $t('content'),
sortable: false,
title: () => {},
format: (value, row: any) => {
const data = JSON.parse(JSON.stringify(row));
const data = Tools.deepClone(row);
data.conditionRange = Tools.object2Json(data.conditionRange);
data.numberRange = Tools.object2Json(data.numberRange);
switch (data.type) {
case 'CONDITION_RANGE':
return conditionRange.format(data);
return this.#conditionRange.format(data);
case 'NUMBER_RANGE':
return numberRange.format(data);
return this.#numberRange.format(data);
}
return '';
},
@ -139,91 +149,100 @@ class ScoreCard extends Processor {
width: '800px',
},
form: {
colsNum: 5,
colsNum: 7,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false, colSpan: 4 },
{ colSpan: 3, name: 'name', label: $t('name'), type: 'w-select', options: parameterOptionsRef.value },
{ colSpan: 2, name: 'weight', label: $t('weight'), type: 'w-number', precision: 6 },
{ colSpan: 4, name: 'code', label: $t('name'), type: 'w-select', options: this.#parameterOptionsRef.value },
{ colSpan: 3, name: 'weight', label: $t('weight'), type: 'w-number', precision: 6 },
{ name: 'type', label: $t('type'), type: 'w-text', showIf: false },
...conditionRange.getEditorFields(),
...numberRange.getEditorFields(),
...this.#conditionRange.getEditorFields(),
...this.#numberRange.getEditorFields(),
],
},
},
// 评分卡变量对话框
onBeforeEditorDataSubmit: (args: any) => {
const newArgs: any = {};
newArgs.grid = args.grid;
newArgs.callback = args.callback;
newArgs.data = Tools.deepClone(args.data);
switch (args.data.type) {
case 'CONDITION_RANGE':
// args.data.conditionRange = Tools.object2Json(args.data.conditionRange);
return conditionRange.beforeEditorDataSubmit(data);
newArgs.data.conditionRange = Tools.object2Json(newArgs.data.conditionRange);
this.#conditionRange.beforeEditorDataSubmit(newArgs);
args.data.conditionRange = Tools.json2Object(newArgs.data.conditionRange);
break;
case 'NUMBER_RANGE':
//args.data.numberRange = Tools.object2Json(args.data.numberRange);
return numberRange.beforeEditorDataSubmit(data);
newArgs.data.numberRange = Tools.object2Json(newArgs.data.numberRange);
this.#numberRange.beforeEditorDataSubmit(newArgs);
args.data.numberRange = Tools.json2Object(newArgs.data.numberRange);
break;
}
this.#scoreCard = args.grid.getRows();
//args.grid.setLocalData(this.#scoreCard);
},
onAfterEditorOpen: (args: any) => {
// const args: any = {};
// args.grid = _args.grid;
// args.data = Tools.deepClone(toValue(_args.data));
// args.data.conditionRange = Tools.object2Json(args.data.conditionRange);
// args.data.numberRange = Tools.object2Json(args.data.numberRange);
// const data = Tools.deepClone(toValue(args.data));
// data.conditionRange = Tools.object2Json(data.conditionRange);
// data.numberRange = Tools.object2Json(data.numberRange);
// args.data = data;
const newArgs: any = {};
newArgs.grid = args.grid;
newArgs.callback = args.callback;
switch (args.grid.getEditorForm().getStatus()) {
case 'add':
newArgs.data = {
conditionRange: Tools.object2Json(JSON.parse(JSON.stringify(args.data.conditionRange))),
numberRange: Tools.object2Json(JSON.parse(JSON.stringify(args.data.numberRange))),
conditionRange: '[]',
numberRange: '[]',
};
break;
case 'edit':
case 'clone':
newArgs.data = {
conditionRange: Tools.object2Json(Tools.deepClone(args.data.conditionRange)),
numberRange: Tools.object2Json(Tools.deepClone(args.data.numberRange)),
};
break;
}
switch (args.grid.getEditorForm().getFieldValue('type')) {
case 'CONDITION_RANGE':
//args.data.conditionRange = Tools.object2Json(JSON.parse(JSON.stringify(args.data.conditionRange)));
return conditionRange.afterEditorOpen(newArgs);
return this.#conditionRange.afterEditorOpen(newArgs);
case 'NUMBER_RANGE':
//args.data.numberRange = Tools.object2Json(JSON.parse(JSON.stringify(args.data.numberRange)));
return numberRange.afterEditorOpen(newArgs);
return this.#numberRange.afterEditorOpen(newArgs);
}
},
},
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'scoreCard', label: $t('re.resources.designer.processor.grid.entity.scoreCard') }];
}
public beforeEditorDataSubmit(args: any): void {
console.log(args);
args.data.scoreCard = Tools.object2Json(this.#scoreCard);
}
public afterEditorOpen(args: any): void {
varProcessorTypeOptionsRef.value = [
{ label: $t('io.sc.engine.rule.core.enums.ProcessorType.CONDITION_RANGE'), value: 'CONDITION_RANGE' },
{ label: $t('io.sc.engine.rule.core.enums.ProcessorType.NUMBER_RANGE'), value: 'NUMBER_RANGE' },
];
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemtersByParameterId/' + args.target.id)).then((response) => {
const data: any[] = response.data;
const options: any[] = [];
if (data && data.length > 0) {
data.forEach((item) => {
options.push({
label: item.name,
value: item.code,
});
});
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.#scoreCard = Tools.json2Object(args.data.scoreCard);
const form = args.grid.getEditorForm();
const scoreCardGrid = form.getFieldComponent('scoreCard');
switch (args.grid.getEditorForm().getStatus()) {
case 'add':
scoreCardGrid.setLocalData([]);
break;
case 'edit':
case 'clone':
scoreCardGrid.setLocalData(Tools.json2Object(args.data.scoreCard));
break;
}
}
parameterOptionsRef.value = options;
});
const grid = args.grid.getEditorForm().getFieldComponent('scoreCard');
const row = args.data;
const rows = Tools.json2Object(row.scoreCard);
grid.setLocalData(rows);
private getParameterNameByCode(code: string): string {
for (const option of this.#parameterOptionsRef.value) {
if (option.value === code) {
return option.label;
}
}
return code;
}
}

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

@ -2,14 +2,17 @@ import { $t } from 'platform-core';
import { Processor } from '../Processor';
class SingleRule extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'singleRule',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.SINGLE_RULE'),
icon: 'bi-noise-reduction',
enableIf: (args: any) => {
return target.type === 'RULE_RESULT' || target.type === 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'SINGLE_RULE');
@ -21,17 +24,19 @@ class SingleRule extends Processor {
return row.singleRule;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [{ name: 'singleRule', label: $t('re.resources.designer.processor.grid.entity.singleRule') }];
}
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {}
public afterEditorOpen(args: any): void {
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
}
}
export { SingleRule };

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

@ -3,19 +3,22 @@ import { axios, Environment, $t, Tools } from 'platform-core';
import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
const dsOptionsRef = ref(<any>[]);
const parameterOptionsRef = ref(<any>[]);
const sqlQueryResultFieldsRef = ref(<any>[]);
class Sql extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 1280;
#dsOptionsRef = ref(<any>[]);
#parameterOptionsRef = ref(<any>[]);
#sqlQueryResultFieldsRef = ref(<any>[]);
#editorForm: any;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'sql',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.SQL'),
icon: 'bi-filetype-sql',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'SQL');
@ -36,22 +39,22 @@ class Sql extends Processor {
};
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'sqlDatasourceName',
label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName'),
type: 'w-select',
clearable: true,
options: dsOptionsRef,
options: this.#dsOptionsRef,
rows: 1,
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
},
{
colSpan: 3,
colSpan: 4,
name: 'sql',
label: $t('re.resources.designer.processor.grid.entity.sql'),
type: 'w-code-mirror',
@ -65,7 +68,7 @@ class Sql extends Processor {
},
},
{
colSpan: 2,
colSpan: 3,
name: 'sqlParameterValues',
label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
showIf: (args: any) => {
@ -92,7 +95,7 @@ class Sql extends Processor {
const array: any[] = sql.match(regex);
const rows: any[] = [];
array.forEach((item) => {
rows.push({ uuid: Tools.uuid(), name: item, value: '' });
rows.push({ name: item, value: '' });
});
const grid = args.grid.getEditorForm().getFieldComponent('sqlParameterValues');
grid.setLocalData(rows);
@ -120,9 +123,7 @@ class Sql extends Processor {
},
],
],
primaryKey: 'uuid',
columns: [
{ name: 'uuid', label: 'uuid', hidden: true },
{
width: '50%',
name: 'name',
@ -147,7 +148,6 @@ class Sql extends Processor {
form: {
colsNum: 1,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false },
{
name: 'name',
label: $t('name'),
@ -170,7 +170,6 @@ class Sql extends Processor {
const grid = args.grid.getEditorForm().getFieldComponent('sqlParameterValues');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
@ -180,7 +179,7 @@ class Sql extends Processor {
},
},
{
colSpan: 3,
colSpan: 4,
name: 'sqlQueryResult',
label: $t('re.resources.designer.processor.grid.entity.sqlQueryResult'),
showIf: (args: any) => {
@ -202,8 +201,8 @@ class Sql extends Processor {
label: $t('execute'),
icon: 'bi-caret-right',
click: (args: any) => {
const sql = args.grid.getEditorForm().getFieldValue('sql');
const grid = args.grid.getEditorForm().getFieldComponent('sqlParameterValues');
const sql = this.#editorForm.getFieldValue('sql');
const grid = this.#editorForm.getFieldComponent('sqlParameterValues');
const sqlParameterValues = grid?.getRows();
axios
.post(Environment.apiContextPath('/api/re/model/parameter/processor/executeSql'), {
@ -217,19 +216,19 @@ class Sql extends Processor {
field.label = field.name;
});
const data = response.data.data;
const grid = args.grid.getEditorForm().getFieldComponent('sqlQueryResult');
sqlQueryResultFieldsRef.value = fieldMetaDatas;
const grid = this.#editorForm.getFieldComponent('sqlQueryResult');
this.#sqlQueryResultFieldsRef.value = fieldMetaDatas;
grid.setLocalData(data);
});
},
},
],
columns: computed(() => {
return sqlQueryResultFieldsRef.value;
return this.#sqlQueryResultFieldsRef.value;
}),
},
{
colSpan: 2,
colSpan: 3,
name: 'sqlFieldMapping',
label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
showIf: (args: any) => {
@ -268,9 +267,7 @@ class Sql extends Processor {
},
],
],
primaryKey: 'uuid',
columns: [
{ name: 'uuid', label: 'uuid', hidden: true },
{
width: '50%',
name: 'parameter',
@ -295,18 +292,17 @@ class Sql extends Processor {
form: {
colsNum: 1,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false },
{
name: 'parameter',
label: $t('parameterName'),
type: 'w-select',
options: parameterOptionsRef.value,
options: this.#parameterOptionsRef.value,
},
{
name: 'field',
label: $t('fieldName'),
type: 'w-select',
options: sqlQueryResultFieldsRef.value,
options: this.#sqlQueryResultFieldsRef.value,
},
],
},
@ -315,7 +311,6 @@ class Sql extends Processor {
const grid = args.grid.getEditorForm().getFieldComponent('sqlFieldMapping');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
@ -327,7 +322,7 @@ class Sql extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [
{ name: 'sqlDatasourceName', label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName') },
{ name: 'sql', label: $t('re.resources.designer.processor.grid.entity.sql') },
@ -337,24 +332,12 @@ class Sql extends Processor {
}
public beforeEditorDataSubmit(args: any): void {
axios.get(Environment.apiContextPath('/api/system/datasource')).then((response) => {
const items: any[] = response.data?.content;
if (items) {
const options: any[] = [];
items.forEach((item) => {
options.push({ label: item.name, value: item.name });
});
dsOptionsRef.value = options;
}
});
const form = args.grid.getEditorForm();
const sqlParameterValuesGrid = form.getFieldComponent('sqlParameterValues');
const sqlParameterValuesLocalData: any[] = sqlParameterValuesGrid.getRows();
const sqlParameterValues: any[] = [];
sqlParameterValuesLocalData.forEach((item) => {
sqlParameterValues.push({
uuid: item.uuid,
name: item.name,
value: item.value,
});
@ -363,43 +346,30 @@ class Sql extends Processor {
const sqlFieldMappingGrid = form.getFieldComponent('sqlFieldMapping');
const sqlFieldMappingLocalData: any[] = sqlFieldMappingGrid.getRows();
const sqlFieldMapping: any[] = [];
sqlFieldMappingLocalData.forEach((item) => {
sqlFieldMapping.push({
uuid: item.uuid,
field: item.field,
parameter: item.parameter,
});
});
const sqlFieldMapping: any[] = Tools.objects2Objects(sqlFieldMappingLocalData, { field: 'field', parameter: 'parameter' });
args.data.sqlFieldMapping = Tools.object2Json(sqlFieldMapping);
}
public afterEditorOpen(args: any): void {
args.editorDialogWidthRef.value = '80%';
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
this.#editorForm = args.grid.getEditorForm();
const form = args.grid.getEditorForm();
const row = args.data;
axios.get(Environment.apiContextPath('/api/system/datasource')).then((response) => {
const items: any[] = response.data?.content;
if (items) {
const options: any[] = [];
items.forEach((item) => {
options.push({ label: item.name, value: item.name });
});
dsOptionsRef.value = options;
}
this.#dsOptionsRef.value = Tools.objects2Options(response.data?.content, 'name', 'name');
});
axios.get(Environment.apiContextPath('api/re/model/parameter/findParametersByParameterId?parameterId=' + args.parameter.id)).then((response) => {
const options: any[] = [];
const data: any[] = response.data;
data.forEach((parameter) => {
options.push({ label: parameter.name, value: '${' + parameter.name + '}' });
axios.get(Environment.apiContextPath('api/re/model/parameter/findParametersByParameterId?parameterId=' + this.context.target.id)).then((response) => {
this.#parameterOptionsRef.value = Tools.objects2Objects(response.data, {
label: 'name',
value: (parameter: any) => {
return '${' + parameter.name + '}';
},
});
parameterOptionsRef.value = options;
});
const sqlParameterValuesGrid = form.getFieldComponent('sqlParameterValues');

22
io.sc.engine.rule.frontend/src/views/shared/processors/Ternary.ts

@ -3,14 +3,17 @@ import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
class Ternary extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'ternary',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.TERNARY'),
icon: 'bi-question',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'TERNARY');
@ -28,10 +31,10 @@ class Ternary extends Processor {
);
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'ternaryCondition',
label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'),
type: 'w-code-mirror',
@ -47,7 +50,7 @@ class Ternary extends Processor {
},
},
{
colSpan: 5,
colSpan: 7,
name: 'ternaryTrue',
label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'),
type: 'w-code-mirror',
@ -63,7 +66,7 @@ class Ternary extends Processor {
},
},
{
colSpan: 5,
colSpan: 7,
name: 'ternaryFalse',
label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'),
type: 'w-code-mirror',
@ -81,7 +84,7 @@ class Ternary extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [
{ name: 'ternaryCondition', label: $t('re.resources.designer.processor.grid.entity.ternaryCondition') },
{ name: 'ternaryTrue', label: $t('re.resources.designer.processor.grid.entity.ternaryTrue') },
@ -92,8 +95,9 @@ class Ternary extends Processor {
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
}
}

22
io.sc.engine.rule.frontend/src/views/shared/processors/WhenThen.ts

@ -3,14 +3,17 @@ import { Processor } from '../Processor';
import { PlaceHolder } from '@/utils/PlaceHolder';
class WhenThen extends Processor {
public getToolbarAction(target: any): any {
#editorDialogWidth: number = 800;
public getToolbarAction(): any {
return {
extend: 'add',
name: 'whenThen',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.WHEN_THEN'),
icon: 'bi-sliders',
enableIf: (args: any) => {
return target.type !== 'RULE_RESULT' && target.type !== 'SINGLE_RULE_RESULT';
const type = this.context.target.type;
return type !== 'RULE_RESULT' && type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'WHEN_THEN');
@ -32,10 +35,10 @@ class WhenThen extends Processor {
return str;
}
public getEditorFields(context?: any): any {
public getEditorFields(): any {
return [
{
colSpan: 5,
colSpan: 7,
name: 'when',
label: $t('re.resources.designer.processor.grid.entity.when'),
type: 'w-code-mirror',
@ -51,7 +54,7 @@ class WhenThen extends Processor {
},
},
{
colSpan: 5,
colSpan: 7,
name: 'then',
label: $t('re.resources.designer.processor.grid.entity.then'),
type: 'w-code-mirror',
@ -67,7 +70,7 @@ class WhenThen extends Processor {
},
},
{
colSpan: 5,
colSpan: 7,
name: 'isWhenThenShorted',
label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted'),
type: 'w-checkbox',
@ -78,7 +81,7 @@ class WhenThen extends Processor {
];
}
public getViewerFields(context?: any): any {
public getViewerFields(): any {
return [
{ name: 'when', label: $t('re.resources.designer.processor.grid.entity.when') },
{ name: 'then', label: $t('re.resources.designer.processor.grid.entity.then') },
@ -89,8 +92,9 @@ class WhenThen extends Processor {
public beforeEditorDataSubmit(args: any): void {}
public afterEditorOpen(args: any): void {
this.initAutoCompletionManager(args);
this.initUserDefinedFunctionsManager(args);
args.grid.getEditorDialog().setWidth(this.#editorDialogWidth);
this.initAutoCompletionManager();
this.initUserDefinedFunctionsManager();
}
}

1
io.sc.engine.rule.frontend/src/views/shared/processors/index.ts

@ -5,6 +5,7 @@ export { DecisionTable2C } from './DecisionTable2C';
export { DecisionTree } from './DecisionTree';
export { ExecutionFlow } from './ExecutionFlow';
export { GroovyScript } from './GroovyScript';
export { HttpRequest } from './HttpRequest';
export { MathFormula } from './MathFormula';
export { NumberRange } from './NumberRange';
export { ObjectProperties } from './ObjectProperties';

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/processor/ScoreCardParameterProcessorEntity.java

@ -64,7 +64,7 @@ public class ScoreCardParameterProcessorEntity extends ParameterProcessorEntity
}
if(scoreCardItems!=null && !scoreCardItems.isEmpty()){
for(ScoreCardItem scoreCardItem : scoreCardItems){
scoreCardItem.setName(ExpressionReplacer.replace(scoreCardItem.getCode(), mapping));
//scoreCardItem.setName(ExpressionReplacer.replace(scoreCardItem.getCode(), mapping));
List<ConditionRange> conditionRanges =scoreCardItem.getConditionRange();
if(conditionRanges!=null && !conditionRanges.isEmpty()){
for(ConditionRange conditionRange : conditionRanges){

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

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

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

@ -111,7 +111,7 @@ const props = withDefaults(defineProps<FieldProps>(), {
toolbar: true,
editable: true,
lineWrap: false,
tabSize: 4,
tabSize: 2,
lineNumber: false,
lineBreak: true,
placeholder: false,

21
io.sc.platform.core.frontend/src/platform/components/math/toolbar/Toolbar.vue

@ -53,16 +53,6 @@
<q-item v-close-popup clickable>
<q-item-section><Root v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Root></q-item-section>
</q-item>
<q-separator inset spaced />
<q-item v-close-popup clickable>
<q-item-section><Lg v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Lg></q-item-section>
</q-item>
<q-item v-close-popup clickable>
<q-item-section><Ln v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Ln></q-item-section>
</q-item>
<q-item v-close-popup clickable>
<q-item-section><Log v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Log></q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
@ -70,7 +60,7 @@
<!-- 函数 -->
<q-btn :label="$t('math.toolbar.functions')" stretch flat dense no-caps padding="0px 10px" icon-right="arrow_drop_down">
<q-menu>
<q-list>
<q-list dense>
<!-- 特殊值值处理函数 -->
<SpecialValue v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></SpecialValue>
<q-separator inset spaced />
@ -83,6 +73,9 @@
<!-- 日期处理函数 -->
<Date v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Date>
<q-separator inset spaced />
<!-- 对数处理函数 -->
<Log v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Log>
<q-separator inset spaced />
<!-- 三角函数 -->
<Trigonometric v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Trigonometric>
<q-separator inset spaced />
@ -107,7 +100,7 @@
icon-right="arrow_drop_down"
>
<q-menu>
<q-list>
<q-list dense>
<q-item
v-for="userDefinedFunction in userDefinedFunctions"
:key="userDefinedFunction.name"
@ -163,9 +156,6 @@ import Comma from './base/Comma.vue';
import E from './math/E.vue';
import Root from './math/Root.vue';
import Lg from './math/Lg.vue';
import Ln from './math/Ln.vue';
import Log from './math/Log.vue';
import Pi from './math/Pi.vue';
import Power from './math/Power.vue';
import Power2 from './math/Power2.vue';
@ -176,6 +166,7 @@ import SpecialValue from './functions/SpecialValue.vue';
import Digit from './functions/Digit.vue';
import StringVue from './functions/String.vue';
import Date from './functions/Date.vue';
import Log from './functions/Log.vue';
import Trigonometric from './functions/Trigonometric.vue';
import Probability from './functions/Probability.vue';
import Formater from './functions/Formater.vue';

39
io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/Log.vue

@ -0,0 +1,39 @@
<template>
<q-item clickable>
<q-item-section>
<q-item-label>{{ $t('math.toolbar.functions.log') }}</q-item-label>
</q-item-section>
<q-item-section side>
<q-icon name="keyboard_arrow_right" />
</q-item-section>
<q-menu anchor="top end" self="top start">
<q-list>
<q-item v-close-popup clickable :title="$t('math.toolbar.functions.log.lg')" draggable="true" @dragstart="nowRef?.dragstart" @click="lgRef?.append">
<q-item-section><Lg ref="lgRef" v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Lg></q-item-section>
</q-item>
<q-item v-close-popup clickable :title="$t('math.toolbar.functions.log.ln')" draggable="true" @dragstart="nowRef?.dragstart" @click="lnRef?.append">
<q-item-section><Ln ref="lnRef" v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Ln></q-item-section>
</q-item>
<q-item v-close-popup clickable :title="$t('math.toolbar.functions.log.log')" draggable="true" @dragstart="nowRef?.dragstart" @click="logRef?.append">
<q-item-section><Log ref="logRef" v-model="modelValueRef" :source-code-editor="sourceCodeEditor"></Log></q-item-section>
</q-item>
</q-list>
</q-menu>
</q-item>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Lg from './log/Lg.vue';
import Ln from './log/Ln.vue';
import Log from './log/Log.vue';
const modelValueRef = defineModel({ type: String, default: '' });
const props = defineProps({
sourceCodeEditor: { type: Object, default: undefined },
});
const nowRef = ref();
const lgRef = ref();
const lnRef = ref();
const logRef = ref();
</script>

7
io.sc.platform.core.frontend/src/platform/components/math/toolbar/math/Lg.vue → io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/log/Lg.vue

@ -1,5 +1,4 @@
<template>
<div v-close-popup :title="$t('math.toolbar.math.lg')" class="text-xl" draggable="true" @dragstart="dragstart" @click="append">
<math display="inline">
<mrow>
<mo>lg</mo>
@ -10,7 +9,6 @@
<mi>)</mi>
</mrow>
</math>
</div>
</template>
<script setup lang="ts">
const xmlData = `
@ -40,4 +38,9 @@ const append = () => {
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('lg(x)'));
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', '');
};
defineExpose({
dragstart,
append,
});
</script>

9
io.sc.platform.core.frontend/src/platform/components/math/toolbar/math/Ln.vue → io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/log/Ln.vue

@ -1,12 +1,10 @@
<template>
<div v-close-popup :title="$t('math.toolbar.math.ln')" class="text-xl" draggable="true" @dragstart="dragstart" @click="append">
<math display="inline">
<mo>ln</mo>
<mi>(</mi>
<mi>x</mi>
<mi>)</mi>
</math>
</div>
</template>
<script setup lang="ts">
const xmlData = `
@ -31,7 +29,12 @@ const dragstart = (event) => {
};
const append = () => {
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('ln(x)'));
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('ln(x,y)'));
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', '');
};
defineExpose({
dragstart,
append,
});
</script>

7
io.sc.platform.core.frontend/src/platform/components/math/toolbar/math/Log.vue → io.sc.platform.core.frontend/src/platform/components/math/toolbar/functions/log/Log.vue

@ -1,5 +1,4 @@
<template>
<div v-close-popup :title="$t('math.toolbar.math.log')" class="text-xl" draggable="true" @dragstart="dragstart" @click="append">
<math display="inline">
<mo>
<msub>
@ -9,7 +8,6 @@
</mo>
<mi>x</mi>
</math>
</div>
</template>
<script setup lang="ts">
const xmlData = `
@ -43,4 +41,9 @@ const append = () => {
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('log(x,y)'));
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', '');
};
defineExpose({
dragstart,
append,
});
</script>

6
io.sc.platform.core.frontend/src/platform/css/q-markup-table.css

@ -0,0 +1,6 @@
.q-markup-table.q-table--horizontal-separator thead tr:last-child > th,
.q-markup-table.q-table--horizontal-separator tbody tr:last-child > td,
.q-markup-table.q-table--cell-separator thead tr:last-child > th,
.q-markup-table.q-table--cell-separator tbody tr:last-child > td {
border-bottom-width: 0px !important;
}

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

@ -142,7 +142,6 @@
"action.export": "Export",
"action.export.failed": "Export Failed",
"action.submit": "Submit",
"action.confirm": "Confirm",
"action.expandAll": "Expand All",
"action.collapseAll": "Collapse All",
@ -187,9 +186,6 @@
"math.toolbar.math.exp": "e raised to the power of x",
"math.toolbar.math.sqrt": "square root of x",
"math.toolbar.math.root": "y root of x",
"math.toolbar.math.lg": "base 10 logarithm of x",
"math.toolbar.math.ln": "base e logarithm of x",
"math.toolbar.math.log": "base y logarithm of x",
"math.toolbar.math.pi": "PI",
"math.toolbar.math.e": "E",
@ -226,6 +222,10 @@
"math.toolbar.functions.string.endsWith": "x end with y",
"math.toolbar.functions.date": "Date",
"math.toolbar.functions.date.now": "Now",
"math.toolbar.functions.date.log": "Logarithm",
"math.toolbar.functions.date.log.lg": "base 10 logarithm of x",
"math.toolbar.functions.date.log.ln": "base e logarithm of x",
"math.toolbar.functions.date.log.log": "base y logarithm of x",
"math.toolbar.functions.trigonometric": "Trigonometric",
"math.toolbar.functions.trigonometric.degrees": "degrees of x",
"math.toolbar.functions.trigonometric.radians": "radians of x",

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

@ -142,7 +142,6 @@
"action.export": "導出",
"action.export.failed": "導出失敗",
"action.submit": "提交",
"action.confirm": "确定",
"action.expandAll": "全部展开",
"action.collapseAll": "全部收起",
@ -181,15 +180,12 @@
"math.toolbar.base.comma": ",",
"math.toolbar.math": "數學符號",
"math.toolbar.math": "符號",
"math.toolbar.math.power": "x 的 y 次方",
"math.toolbar.math.power2": "x 的平方",
"math.toolbar.math.exp": "自然對數 e 的 x 次方",
"math.toolbar.math.sqrt": "x 的開平方",
"math.toolbar.math.root": "x 開 y 次方",
"math.toolbar.math.lg": "以 10 為底的對數",
"math.toolbar.math.ln": "以自然對數 e 為底的對數",
"math.toolbar.math.log": "以 y 為底的對數",
"math.toolbar.math.pi": "圓周率",
"math.toolbar.math.e": "自然對數",
@ -226,6 +222,10 @@
"math.toolbar.functions.string.endsWith": "x 是否以 y 結尾",
"math.toolbar.functions.date": "日期函數",
"math.toolbar.functions.date.now": "當前日期",
"math.toolbar.functions.log": "對數",
"math.toolbar.functions.log.lg": "以 10 為底的對數",
"math.toolbar.functions.log.ln": "以自然對數 e 為底的對數",
"math.toolbar.functions.log.log": "以 y 為底的對數",
"math.toolbar.functions.trigonometric": "三角函數",
"math.toolbar.functions.trigonometric.degrees": "x 的角度值",
"math.toolbar.functions.trigonometric.radians": "x 的弧度值",

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

@ -142,7 +142,6 @@
"action.export": "导出",
"action.export.failed": "导出失败",
"action.submit": "提交",
"action.confirm": "确定",
"action.expandAll": "全部展开",
"action.collapseAll": "全部收起",
@ -181,15 +180,12 @@
"math.toolbar.base.comma": ",",
"math.toolbar.math": "数学符号",
"math.toolbar.math": "符号",
"math.toolbar.math.power": "x 的 y 次方",
"math.toolbar.math.power2": "x 的平方",
"math.toolbar.math.exp": "自然对数 e 的 x 次方",
"math.toolbar.math.sqrt": "x 的开平方",
"math.toolbar.math.root": "x 开 y 次方",
"math.toolbar.math.lg": "以 10 为底的对数",
"math.toolbar.math.ln": "以自然对数 e 为底的对数",
"math.toolbar.math.log": "以 y 为底的对数",
"math.toolbar.math.pi": "圆周率",
"math.toolbar.math.e": "自然常数",
@ -226,6 +222,10 @@
"math.toolbar.functions.string.endsWith": "x 是否以 y 结尾",
"math.toolbar.functions.date": "日期函数",
"math.toolbar.functions.date.now": "当前日期",
"math.toolbar.functions.log": "对数函数",
"math.toolbar.functions.log.lg": "以 10 为底的对数",
"math.toolbar.functions.log.ln": "以自然对数 e 为底的对数",
"math.toolbar.functions.log.log": "以 y 为底的对数",
"math.toolbar.functions.trigonometric": "三角函数",
"math.toolbar.functions.trigonometric.degrees": "x 的角度值",
"math.toolbar.functions.trigonometric.radians": "x 的弧度值",

1
io.sc.platform.core.frontend/src/platform/index.ts

@ -116,6 +116,7 @@ export { KeyCode } from './utils';
export { Tools } from './utils';
export { TreeBuilder } from './utils';
export { UndoManager } from './utils';
export { UnitOfMeasure } from './utils';
export { VueTools } from './utils';
/**

31
io.sc.platform.core.frontend/src/platform/utils-components/MarkupTableUtil.ts

@ -1,4 +1,5 @@
import { Tools } from '@/platform';
import { Tools, UnitOfMeasure } from '@/platform';
import '@/platform/css/q-markup-table.css';
class MarkupTableUtil {
public static sample(props: any): string {
@ -23,32 +24,32 @@ class MarkupTableUtil {
public static markupTable(tableHeader: string, tableBody: string, props: any): string {
props = props || {};
props['separator'] = !Tools.isUndefinedOrNull(props['separator']) ? props['separator'] : 'cell';
props['wrap-cells'] = !Tools.isUndefinedOrNull(props['wrap-cells']) ? props['wrap-cells'] : true;
props['dense'] = !Tools.isUndefinedOrNull(props['dense']) ? props['dense'] : false;
props['dark'] = !Tools.isUndefinedOrNull(props['dark']) ? props['dark'] : false;
props['flat'] = !Tools.isUndefinedOrNull(props['flat']) ? props['flat'] : true;
props['bordered'] = !Tools.isUndefinedOrNull(props['bordered']) ? props['bordered'] : true;
props['square'] = !Tools.isUndefinedOrNull(props['square']) ? props['square'] : false;
props['separator'] = Tools.initialize(props['separator'], 'cell');
props['wrap-cells'] = Tools.initialize(props['wrap-cells'], true);
props['dense'] = Tools.initialize(props['dense'], false);
props['dark'] = Tools.initialize(props['dark'], false);
props['flat'] = Tools.initialize(props['flat'], true);
props['bordered'] = Tools.initialize(props['bordered'], true);
props['square'] = Tools.initialize(props['square'], false);
let tableContainerStyle = '';
if (!Tools.isUndefinedOrNull(props['width'])) {
tableContainerStyle += 'width:' + props['width'] + ';';
if (!Tools.isNill(props['width'])) {
tableContainerStyle += 'width:' + UnitOfMeasure.width(props['width']) + ';';
}
if (!Tools.isUndefinedOrNull(props['height'])) {
tableContainerStyle += 'height:' + props['height'] + ';';
tableContainerStyle += 'height:' + UnitOfMeasure.height(props['height']) + ';';
}
if (!Tools.isUndefinedOrNull(props['maxWidth'])) {
tableContainerStyle += 'max-width:' + props['maxWidth'] + ';';
tableContainerStyle += 'max-width:' + UnitOfMeasure.width(props['maxWidth']) + ';';
}
if (!Tools.isUndefinedOrNull(props['maxHeight'])) {
tableContainerStyle += 'max-height:' + props['maxHeight'] + ';';
tableContainerStyle += 'max-height:' + UnitOfMeasure.height(props['maxHeight']) + ';';
}
if (!Tools.isUndefinedOrNull(props['max-width'])) {
tableContainerStyle += 'max-width:' + props['max-width'] + ';';
tableContainerStyle += 'max-width:' + UnitOfMeasure.width(props['max-width']) + ';';
}
if (!Tools.isUndefinedOrNull(props['max-height'])) {
tableContainerStyle += 'max-height:' + props['max-height'] + ';';
tableContainerStyle += 'max-height:' + UnitOfMeasure.height(props['max-height']) + ';';
}
let html = '';

135
io.sc.platform.core.frontend/src/platform/utils/Tools.ts

@ -1,6 +1,16 @@
import xmlFormat from 'xml-formatter';
class Tools {
/**
*
* @param value
* @param defaultValue
* @returns
*/
public static initialize(value: any, defaultValue: any): any {
return value === null || typeof value === 'undefined' ? defaultValue : value;
}
/**
*
* undefined === undeinfed === null === ''
@ -30,6 +40,16 @@ class Tools {
return obj === null || typeof obj === 'undefined';
}
/**
* null undefined
* isUndefinedOrNull
* @param obj
* @returns null undefined
*/
public static isNill(obj: any): boolean {
return obj === null || typeof obj === 'undefined';
}
/**
* null undefined
* @param obj
@ -75,6 +95,15 @@ class Tools {
return !Tools.isEmpty(obj) && Array.isArray(obj);
}
/**
*
* @param obj
* @returns
*/
public static isFunction(obj: any): boolean {
return typeof obj === 'function';
}
/**
*
* @param date
@ -425,66 +454,10 @@ class Tools {
* @returns
*/
public static deepClone(target: any): any {
const map = new WeakMap();
function isObject(target: any) {
return (typeof target === 'object' && target) || typeof target === 'function';
}
function clone(data: any) {
if (!isObject(data)) {
return data;
}
if ([Date, RegExp].includes(data.constructor)) {
return new data.constructor(data);
}
if (typeof data === 'function') {
return new Function('return ' + data.toString())();
}
const exist = map.get(data);
if (exist) {
return exist;
}
if (data instanceof Map) {
const result = new Map();
map.set(data, result);
data.forEach((val, key) => {
if (isObject(val)) {
result.set(key, clone(val));
} else {
result.set(key, val);
}
});
return result;
}
if (data instanceof Set) {
const result = new Set();
map.set(data, result);
data.forEach((val) => {
if (isObject(val)) {
result.add(clone(val));
} else {
result.add(val);
}
});
return result;
}
const keys = Reflect.ownKeys(data);
const allDesc = Object.getOwnPropertyDescriptors(data);
const result = Object.create(Object.getPrototypeOf(data), allDesc);
map.set(data, result);
keys.forEach((key) => {
const val = data[key];
if (isObject(val)) {
result[key] = clone(val);
} else {
result[key] = val;
}
});
return result;
if (Tools.isNill(target)) {
return null;
}
return clone(target);
return JSON.parse(JSON.stringify(target));
}
/**
@ -976,7 +949,7 @@ class Tools {
}
}
public static extractAllPropertyNames(objects: any[], propertyNamePattern) {
public static extractAllPropertyNames(objects: any[], propertyNamePattern: any) {
if (objects && Tools.isArray(objects)) {
//必须是数组
const allPropertyNames = [];
@ -985,7 +958,7 @@ class Tools {
const object = objects[i];
if (Tools.isObject(object)) {
//数组元素必须是对象
const propertyNames = Object.keys(object); //获取所有对象的属性
const propertyNames: string[] = Object.keys(object); //获取所有对象的属性
for (let j = 0; j < propertyNames.length; j++) {
if (propertyNamePattern) {
if (propertyNamePattern.test(propertyNames[j])) {
@ -1007,6 +980,46 @@ class Tools {
}
return [];
}
/**
*
* @param objects
* @param label , ,,
* @param value , ,,
* @returns
*/
public static objects2Options(objects: object[], labelPropertyName: string, valuePropertyName: string): any[] {
return Tools.objects2Objects(objects, { label: labelPropertyName, value: valuePropertyName });
}
/**
*
* @param objects
* @param mapping
* {
* label:'label', // 返回的对象的 label 属性的值为转换前对象的 label 属性
* value: (obj) => {return obj.value; } //返回的对象的 value 属性的值为一个函数
* }
* @returns
*/
public static objects2Objects(objects: object[], mapping: object): any[] {
const result: any[] = [];
if (objects && Tools.isArray(objects) && objects.length > 0 && !Tools.isNill(mapping)) {
objects.forEach((obj) => {
const item = {};
for (const propertyName in mapping) {
const property = mapping[propertyName];
if (Tools.isString(property)) {
item[propertyName] = obj[property];
} else if (Tools.isFunction(property)) {
item[propertyName] = property(obj);
}
}
result.push(item);
});
}
return result;
}
}
export { Tools };

33
io.sc.platform.core.frontend/src/platform/utils/UnitOfMeasure.ts

@ -0,0 +1,33 @@
import { Tools } from './Tools';
/**
*
*/
class UnitOfMeasure {
/**
*
* @param width (,示例: 100, '50%', '100px')
* @returns
*/
public static width(width: number | string): string {
return UnitOfMeasure.distance(width);
}
/**
*
* @param width (,示例: 100, '50%', '100px')
* @returns
*/
public static height(height: number | string): string {
return UnitOfMeasure.distance(height);
}
private static distance(width: number | string): string {
if (Tools.isNumber(width)) {
return width + 'px';
}
return width as string;
}
}
export { UnitOfMeasure };

1
io.sc.platform.core.frontend/src/platform/utils/index.ts

@ -9,4 +9,5 @@ export { QuasarTools } from './QuasarTools';
export { Tools } from './Tools';
export { TreeBuilder } from './TreeBuilder';
export { UndoManager } from './UndoManager';
export { UnitOfMeasure } from './UnitOfMeasure';
export { VueTools } from './VueTools';

64
io.sc.platform.core.frontend/src/views/testcase/math/MathEditor.vue

@ -2,14 +2,69 @@
<div class="p-2">
<w-math v-model="formulaRef" v-model:zoom="zoomRef" :auto-completion="autoCompletion" :user-defined-functions="userDefinedFunctionsRef"></w-math>
<br />
<div class="w-grid" v-html="MarkupTableUtil.sample({ 'max-height': '50px' })"></div>
<div v-dompurify-html="MarkupTableUtil.sample({ bordered: false })" class="w-grid"></div>
<table border="1">
<thead>
<tr>
<th>H1</th>
<th>H2</th>
</tr>
</thead>
<tbody class="overflow-auto h-[50px]">
<tr>
<td>D1</td>
<td>D2</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
</tr>
</tbody>
</table>
<p>我是一个段落</p>
<p class="fancy">我非常非常喜欢</p>
<div>我不是一个段落</div>
<h2>
<div class="foo">
<span class="wsp">11111</span>
</div>
<div class="bar">
<div class="foo">
<span class="wsp">2222</span>
</div>
<span class="wsp"><div class="b">4444</div></span>
</div>
</h2>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, MarkupTableUtil } from '@/platform';
import { axios, Environment, MarkupTableUtil, Tools } from '@/platform';
import { AutoCompletionManager } from './AutoCompletionManager';
const objs = [
{ name: 'wsp', age: 30 },
{ name: 'sc', age: 33 },
];
console.log(Tools.objects2Options(objs, 'name', 'age'));
console.log(
Tools.objects2Objects(objs, {
name2: 'name',
age2: (obj) => {
return obj.age + 10;
},
}),
);
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsRef = ref();
@ -236,3 +291,8 @@ const formulaRef3 = ref(`<mrow>
</mrow>
`);
</script>
<style>
h2 :not(.foo) > .wsp {
color: red;
}
</style>

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.1.421",
"version": "8.1.430",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -110,7 +110,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"platform-core": "8.1.421",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"vue": "3.5.10",

64
io.sc.platform.core.frontend/template-project/src/views/testcase/math/MathEditor.vue

@ -2,14 +2,69 @@
<div class="p-2">
<w-math v-model="formulaRef" v-model:zoom="zoomRef" :auto-completion="autoCompletion" :user-defined-functions="userDefinedFunctionsRef"></w-math>
<br />
<div class="w-grid" v-html="MarkupTableUtil.sample({ 'max-height': '50px' })"></div>
<div v-dompurify-html="MarkupTableUtil.sample({ bordered: false })" class="w-grid"></div>
<table border="1">
<thead>
<tr>
<th>H1</th>
<th>H2</th>
</tr>
</thead>
<tbody class="overflow-auto h-[50px]">
<tr>
<td>D1</td>
<td>D2</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
</tr>
</tbody>
</table>
<p>我是一个段落</p>
<p class="fancy">我非常非常喜欢</p>
<div>我不是一个段落</div>
<h2>
<div class="foo">
<span class="wsp">11111</span>
</div>
<div class="bar">
<div class="foo">
<span class="wsp">2222</span>
</div>
<span class="wsp"><div class="b">4444</div></span>
</div>
</h2>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, MarkupTableUtil } from '@/platform';
import { axios, Environment, MarkupTableUtil, Tools } from '@/platform';
import { AutoCompletionManager } from './AutoCompletionManager';
const objs = [
{ name: 'wsp', age: 30 },
{ name: 'sc', age: 33 },
];
console.log(Tools.objects2Options(objs, 'name', 'age'));
console.log(
Tools.objects2Objects(objs, {
name2: 'name',
age2: (obj) => {
return obj.age + 10;
},
}),
);
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsRef = ref();
@ -236,3 +291,8 @@ const formulaRef3 = ref(`<mrow>
</mrow>
`);
</script>
<style>
h2 :not(.foo) > .wsp {
color: red;
}
</style>

10
io.sc.platform.core/src/main/java/io/sc/platform/core/License.java

@ -18,6 +18,7 @@ public class License {
private Date expiredDate; //结束日期
private Integer term; //期限(天数)
private String macAddresses; //mac 地址
private String serverMacAddresses; //服务器 mac 地址
/**
* 获取免费试用许可证
@ -116,6 +117,14 @@ public class License {
this.macAddresses = macAddresses;
}
public String getServerMacAddresses() {
return serverMacAddresses;
}
public void setServerMacAddresses(String serverMacAddresses) {
this.serverMacAddresses = serverMacAddresses;
}
@Override
public String toString() {
try {
@ -131,6 +140,7 @@ public class License {
+ " startDate=" + startDate + ",\n"
+ " expiredDate=" + expiredDate + ",\n"
+ " macAddresses=" + macAddresses + "\n"
+ " serverMacAddresses=" + serverMacAddresses + "\n"
+ "]";
}
}

2
io.sc.platform.core/src/main/java/io/sc/platform/core/service/LicenseManagerService.java

@ -3,8 +3,6 @@ package io.sc.platform.core.service;
import io.sc.platform.core.License;
import io.sc.platform.core.exception.LicenseInvalidatedException;
import java.io.IOException;
public interface LicenseManagerService {
public License getLicense();
public void load();

7
io.sc.platform.core/src/main/java/io/sc/platform/core/service/impl/LicenseManagerServiceImpl.java

@ -5,10 +5,7 @@ import io.sc.platform.core.License;
import io.sc.platform.core.enums.LicenseStatus;
import io.sc.platform.core.exception.LicenseInvalidatedException;
import io.sc.platform.core.service.LicenseManagerService;
import io.sc.platform.core.util.FileUtil;
import io.sc.platform.core.util.NetworkUtil;
import io.sc.platform.core.util.ObjectMapper4Json;
import io.sc.platform.core.util.RSAUtil;
import io.sc.platform.core.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@ -46,11 +43,13 @@ public class LicenseManagerServiceImpl implements LicenseManagerService {
byte[] encrypted = RSAUtil.decryptByPublicKey(Base64.getMimeDecoder().decode(licenseString), publicKey);
String json = new String(encrypted, StandardCharsets.UTF_8);
this.license =ObjectMapper4Json.getMapper().readValue(json, License.class);
this.license.setServerMacAddresses(StringUtil.combine(",",NetworkUtil.getMacAddress()));
this.license.setStatus(LicenseStatus.OK);
verify(this.license);
} catch (Exception e) {
log.error("", e);
this.license =new License();
this.license.setServerMacAddresses(StringUtil.combine(",",NetworkUtil.getMacAddress()));
this.license.setStatus(LicenseStatus.INVALIDATED);
}
}

4
io.sc.platform.core/src/main/java/io/sc/platform/core/util/NetworkUtil.java

@ -27,10 +27,6 @@ public class NetworkUtil {
result.add(sb.toString());
}
}
for (String s : result) {
System.out.println(s);
}
}catch (SocketException e){
log.error("",e);
}

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

@ -28,7 +28,7 @@
"vuepress": "2.0.0-rc.15"
},
"dependencies": {
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"vue": "3.5.10",
"vue-i18n": "10.0.3"

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

3
io.sc.platform.license.keygen.frontend/src/i18n/messages.json

@ -11,5 +11,6 @@
"license.keygen.grid.entity.issuedDate": "Issued Date",
"license.keygen.grid.entity.startDate": "Start Date",
"license.keygen.grid.entity.expiredDate": "Expired Date",
"license.keygen.grid.entity.macAddresses": "Mac Addresses(split by commons)"
"license.keygen.grid.entity.macAddresses": "Mac Addresses(split by commons)",
"license.keygen.grid.entity.macAddressesOnly": "MAC Addresses"
}

3
io.sc.platform.license.keygen.frontend/src/i18n/messages_tw_CN.json

@ -11,5 +11,6 @@
"license.keygen.grid.entity.issuedDate": "許可證發行日期",
"license.keygen.grid.entity.startDate": "有效期開始日期",
"license.keygen.grid.entity.expiredDate": "有效期結束日期",
"license.keygen.grid.entity.macAddresses": "Mac 地址(多個採用逗號分隔)"
"license.keygen.grid.entity.macAddresses": "Mac 地址(多個採用逗號分隔)",
"license.keygen.grid.entity.macAddressesOnly": "MAC 地址"
}

3
io.sc.platform.license.keygen.frontend/src/i18n/messages_zh_CN.json

@ -11,5 +11,6 @@
"license.keygen.grid.entity.issuedDate": "许可证发行日期",
"license.keygen.grid.entity.startDate": "有效期开始日期",
"license.keygen.grid.entity.expiredDate": "有效期结束日期",
"license.keygen.grid.entity.macAddresses": "Mac 地址(多个采用逗号分隔)"
"license.keygen.grid.entity.macAddresses": "MAC 地址(多个采用逗号分隔)",
"license.keygen.grid.entity.macAddressesOnly": "MAC 地址"
}

22
io.sc.platform.license.keygen.frontend/src/views/license/KeyGenerator.vue

@ -38,13 +38,33 @@
:columns="[
{ width: 150, name: 'productName', label: $t('license.keygen.grid.entity.productName') },
{ width: '*', name: 'consumerName', label: $t('license.keygen.grid.entity.consumerName') },
{
width: 140,
name: 'macAddresses',
label: $t('license.keygen.grid.entity.macAddressesOnly'),
format: (value, row) => {
if (value) {
let str = '';
const splits: string[] = value.split(',');
splits.forEach((split, index) => {
if (index === splits.length) {
str += split;
} else {
str += split + '<br>';
}
});
return str;
}
return value;
},
},
{
width: 100,
name: 'type',
label: $t('license.keygen.grid.entity.type'),
format: Formater.enum(LicenseTypeEnum),
},
{ width: 100, name: 'term', label: $t('license.keygen.grid.entity.term') },
{ width: 80, name: 'term', label: $t('license.keygen.grid.entity.term'), align: 'right' },
{ width: 140, name: 'issuedDate', label: $t('license.keygen.grid.entity.issuedDate') },
{ width: 140, name: 'startDate', label: $t('license.keygen.grid.entity.startDate') },
{ width: 140, name: 'expiredDate', label: $t('license.keygen.grid.entity.expiredDate') },

105
io.sc.platform.license.keygen/src/main/java/io/sc/platform/license/keygen/controller/LicenseKeyGeneratorWebController.java

@ -1,39 +1,118 @@
package io.sc.platform.license.keygen.controller;
import io.sc.platform.core.License;
import io.sc.platform.core.annotation.AuditLog;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.core.annotation.LicenseVerify;
import io.sc.platform.core.enums.AuditLogAction;
import io.sc.platform.core.response.ValidateException;
import io.sc.platform.core.util.ValidatorUtil;
import io.sc.platform.license.keygen.jpa.entity.LicenseEntity;
import io.sc.platform.license.keygen.jpa.repository.LicenseRepository;
import io.sc.platform.license.keygen.jpa.vo.LicenseVo;
import io.sc.platform.license.keygen.service.LicenseKeyGeneratorService;
import io.sc.platform.license.keygen.service.LicenseService;
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.orm.service.support.criteria.Criteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("api/license/keygen")
public class LicenseKeyGeneratorWebController extends RestCrudController<LicenseVo, LicenseEntity,String, LicenseRepository, LicenseService> {
public class LicenseKeyGeneratorWebController {
@Autowired private LicenseKeyGeneratorService licenseKeyGeneratorService;
@Autowired private LicenseService licenseService;
@Override
protected LicenseVo add(HttpServletRequest request, HttpServletResponse response, LicenseEntity entity) throws Exception {
format(entity);
return super.add(request,response,entity);
@AuditLog(action= AuditLogAction.ADD)
@PostMapping("")
@ResponseBody
public LicenseVo add(HttpServletRequest request, HttpServletResponse response, @RequestBody @Valid LicenseEntity entity, BindingResult bindingResult) throws Exception{
ValidateException result = ValidatorUtil.validate(bindingResult);
if(result!=null){
throw result;
}
LicenseEntity addedEntity =licenseService.add(entity);
if(addedEntity instanceof BaseEntity){
return ((BaseEntity<LicenseVo>)addedEntity).toVo();
}
return null;
}
@Override
protected LicenseVo update(HttpServletRequest request, HttpServletResponse response, String id, LicenseEntity entity) throws Exception {
format(entity);
return super.update(request, response, id, entity);
@AuditLog(action=AuditLogAction.UPDATE)
@PutMapping("{id}")
@ResponseBody
public LicenseVo update(HttpServletRequest request,HttpServletResponse response,@PathVariable(name="id")String id,@RequestBody @Valid LicenseEntity entity,BindingResult bindingResult) throws Exception{
ValidateException result =ValidatorUtil.validate(bindingResult);
if(result!=null){
throw result;
}
LicenseEntity updatedEntity =licenseService.update(id,entity);
if(updatedEntity instanceof BaseEntity){
return ((BaseEntity<LicenseVo>)updatedEntity).toVo();
}
return null;
}
@AuditLog(action=AuditLogAction.REMOVE)
@DeleteMapping("{id}")
@ResponseBody
public String remove(HttpServletRequest request,HttpServletResponse response,@PathVariable(name="id")String id) throws Exception{
return licenseService.remove(id);
}
@AuditLog(action=AuditLogAction.REMOVE)
@DeleteMapping("")
@ResponseBody
@LicenseVerify
public List<String> removes(HttpServletRequest request, HttpServletResponse response, @RequestBody List<String> ids) throws Exception{
return licenseService.remove(ids);
}
@AuditLog(action=AuditLogAction.FIND_ONE)
@GetMapping("{id}")
@ResponseBody
public LicenseVo findById(HttpServletRequest request,HttpServletResponse response,@PathVariable(name="id")String id) throws Exception{
LicenseEntity foundEntity =licenseService.findById(id);
if(foundEntity instanceof BaseEntity){
return ((BaseEntity<LicenseVo>)foundEntity).toVo();
}
return null;
}
@AuditLog(action=AuditLogAction.QUERY)
@GetMapping("")
@ResponseBody
public Page<LicenseVo> _query(HttpServletRequest request, HttpServletResponse response, LicenseEntity entity, QueryParameter queryParameter) throws Exception{
List<Criteria> criterias =licenseService.buildCriteriaFromEntity(request.getParameterNames(),entity);
if(criterias!=null && !criterias.isEmpty()){
queryParameter.addCriterias(criterias);
}
Page<LicenseEntity> page =licenseService.query(queryParameter);
if(page==null){
return QueryResult.emptyPage();
}
List<LicenseEntity> entities =page.getContent();
List<LicenseVo> vos =new ArrayList<>(entities.size());
for(LicenseEntity e : entities){
if(e instanceof BaseEntity){
vos.add(((BaseEntity<LicenseVo>)e).toVo());
}
}
return new PageImpl<>(vos,page.getPageable(),page.getTotalElements());
}
@GetMapping(value="generateLicenseFile/{id}")

3
io.sc.platform.license.keygen/src/main/java/io/sc/platform/license/keygen/service/impl/LicenseKeyGeneratorServiceImpl.java

@ -16,7 +16,6 @@ import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.Base64;
@Service("io.sc.platform.license.keygen.service.impl.LicenseKeyGeneratorServiceImpl")
@ -37,7 +36,7 @@ public class LicenseKeyGeneratorServiceImpl implements LicenseKeyGeneratorServic
license.setStartDate(entity.getStartDate());
license.setExpiredDate(entity.getExpiredDate());
license.setTerm(entity.getTerm());
license.setMacAddresses(entity.getMacAddresses());
license.setMacAddresses(entity.getMacAddresses().replace("-",":"));
String json =ObjectMapper4Json.getMapper().writeValueAsString(license);
String privateKey =RSAUtil.loadPrivateKeyBase64String("classpath:/license.privateKey.txt");

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -110,7 +110,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"vue": "3.5.10",

2
io.sc.platform.system.frontend/src/i18n/messages.json

@ -45,7 +45,6 @@
"system.shared.selectOrg.grid.title": "Organization Tree",
"system.shared.selectOrg.grid.toolbar.save.tip": "Are you sure to update organizations?",
"system.shared.selectApplication.grid.title": "Included Application List",
"system.shared.selectApplication.grid.toolbar.selectIn": "Select In",
"system.shared.selectApplication.grid.toolbar.selectOut": "Select Out",
@ -74,6 +73,7 @@
"system.license.entity.expiredDate": "Expired Date",
"system.license.entity.term": "Term(day)",
"system.license.entity.macAddresses": "MAC Addresses",
"system.license.entity.serverMacAddresses": "Active MAC Addresses of Server",
"system.license.updateDialog.title": "Update License",
"system.application.grid.title": "Application List",

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

@ -73,6 +73,7 @@
"system.license.entity.expiredDate": "有效期結束日期",
"system.license.entity.term": "期限(天)",
"system.license.entity.macAddresses": "MAC 地址",
"system.license.entity.serverMacAddresses": "當前服務器活動網卡 MAC 地址",
"system.license.updateDialog.title": "更新許可證",
"system.application.grid.title": "應用列表",

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

@ -73,6 +73,7 @@
"system.license.entity.expiredDate": "有效期结束日期",
"system.license.entity.term": "期限(天)",
"system.license.entity.macAddresses": "MAC 地址",
"system.license.entity.serverMacAddresses": "当前服务器活动网卡 MAC 地址",
"system.license.updateDialog.title": "更新许可证",
"system.application.grid.title": "应用列表",

1
io.sc.platform.system.frontend/src/views/license/License.vue

@ -24,6 +24,7 @@
<div class="pl-8 py-1 text-xs text-gray-600">{{ $t('system.license.entity.expiredDate') }} : {{ licenseRef?.expiredDate }}</div>
<div class="pl-8 py-1 text-xs text-gray-600">{{ $t('system.license.entity.term') }} : {{ licenseRef?.term }}</div>
<div class="pl-8 py-1 text-xs text-gray-600">{{ $t('system.license.entity.macAddresses') }} : {{ licenseRef?.macAddresses }}</div>
<div class="pl-8 py-1 text-xs text-gray-600">{{ $t('system.license.entity.serverMacAddresses') }} : {{ licenseRef?.serverMacAddresses }}</div>
</q-card-section>
</q-card>
</div>

4
io.sc.platform.system.frontend/src/views/menu/Menu.vue

@ -9,7 +9,7 @@
selection="multiple"
:checkbox-selection="true"
:tree="true"
dndMode="server"
dnd-mode="server"
:tree-icon="
(row) => {
if (row.type === 'SEPARATOR') {
@ -80,7 +80,7 @@
form: {
colsNum: 1,
fields: [
{ name: 'parent', label: $t('parent'), type: 'w-text', hidden: true },
{ name: 'parent', label: $t('parent'), type: 'w-text', showIf: false },
{
name: 'type',
label: $t('type'),

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

@ -65,5 +65,6 @@ module.exports = {
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
'no-case-declarations': 'off',
},
};

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

@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.416",
"platform-core": "8.1.430",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

2
io.sc.website/package.json

@ -28,6 +28,6 @@
},
"dependencies": {
"vue": "3.5.10",
"platform-core": "8.1.416"
"platform-core": "8.1.430"
}
}
Loading…
Cancel
Save