Browse Source

update

main
wangshaoping 8 months ago
parent
commit
fb4fa5595a
  1. 24
      app.platform/build.gradle
  2. 6
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/ExpressionReplacer.java
  3. 2
      io.sc.engine.rule.frontend/package.json
  4. 2
      io.sc.engine.rule.frontend/src/i18n/messages.json
  5. 2
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  6. 2
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  7. 10
      io.sc.engine.rule.frontend/src/views/resources/ImportSampleDialog.vue
  8. 1
      io.sc.engine.rule.frontend/src/views/resources/designer/DesignerDialog.vue
  9. 43
      io.sc.engine.rule.frontend/src/views/resources/designer/GroovyFunctions.ts
  10. 139
      io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue
  11. 1029
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/bean/JpaEntityChangedListener.java
  12. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/JpaEntityPersistentEventListener.java
  13. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/DictionaryEntityEventHandler.java
  14. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/IndicatorEntityEventHandler.java
  15. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/IndicatorProcessorEntityEventHandler.java
  16. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/IndicatorValidatorEntityEventHandler.java
  17. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/LibEntityEventHandler.java
  18. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ModelEntityEventHandler.java
  19. 6
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ParameterEntityEventHandler.java
  20. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ParameterProcessorEntityEventHandler.java
  21. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ParameterValidatorEntityEventHandler.java
  22. 12
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ResourceEntityEventHandler.java
  23. 6
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ScoreCardVarEntityEventHandler.java
  24. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/UserDefinedJavaClassFieldEntityEventHandler.java
  25. 5
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterProcessorWebController.java
  26. 11
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterWebController.java
  27. 7
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/ParameterProcessorEntity.java
  28. 10
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ParameterService.java
  29. 22
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterServiceImpl.java
  30. 2
      io.sc.platform.core.frontend/package.json
  31. 4
      io.sc.platform.core.frontend/src/components/index.ts
  32. 2
      io.sc.platform.core.frontend/src/i18n/messages.json
  33. 2
      io.sc.platform.core.frontend/src/i18n/messages_tw_CN.json
  34. 2
      io.sc.platform.core.frontend/src/i18n/messages_zh_CN.json
  35. 18
      io.sc.platform.core.frontend/src/menus/menus.json
  36. 3
      io.sc.platform.core.frontend/src/platform/components/app/WPlatformPage.vue
  37. 1
      io.sc.platform.core.frontend/src/platform/components/expression/dialog/XmlDialog.vue
  38. 72
      io.sc.platform.core.frontend/src/platform/components/form/elements/WCodeMirror.vue
  39. 81
      io.sc.platform.core.frontend/src/platform/components/form/elements/WListGrid.vue
  40. 84
      io.sc.platform.core.frontend/src/platform/components/form/elements/w-code-mirror/PlaceholderPlugin.ts
  41. 12
      io.sc.platform.core.frontend/src/platform/plugin/axios.ts
  42. 18
      io.sc.platform.core.frontend/src/platform/utils/QuasarTools.ts
  43. 26
      io.sc.platform.core.frontend/src/routes/routes.json
  44. 43
      io.sc.platform.core.frontend/src/views/testcase/code-mirror/GroovyFunctions.ts
  45. 525
      io.sc.platform.core.frontend/src/views/testcase/code-mirror/code-mirror.vue
  46. 12
      io.sc.platform.core.frontend/src/views/testcase/loading/loading.vue
  47. 4
      io.sc.platform.core.frontend/template-project/package.json
  48. 4
      io.sc.platform.core.frontend/template-project/src/components/index.ts
  49. 2
      io.sc.platform.core.frontend/template-project/src/i18n/messages.json
  50. 2
      io.sc.platform.core.frontend/template-project/src/i18n/messages_tw_CN.json
  51. 2
      io.sc.platform.core.frontend/template-project/src/i18n/messages_zh_CN.json
  52. 18
      io.sc.platform.core.frontend/template-project/src/menus/menus.json
  53. 26
      io.sc.platform.core.frontend/template-project/src/routes/routes.json
  54. 43
      io.sc.platform.core.frontend/template-project/src/views/testcase/code-mirror/GroovyFunctions.ts
  55. 525
      io.sc.platform.core.frontend/template-project/src/views/testcase/code-mirror/code-mirror.vue
  56. 12
      io.sc.platform.core.frontend/template-project/src/views/testcase/loading/loading.vue
  57. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  58. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  59. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties
  60. 2
      io.sc.platform.developer.frontend/package.json
  61. 2
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/support/JpaEntityPersistentEvent.java
  62. 7
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/repository/DaoRepository.java
  63. 144
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/repository/impl/DaoRepositoryImpl.java
  64. 10
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/impl/DaoServiceImpl.java

24
app.platform/build.gradle

@ -20,21 +20,21 @@ dependencies {
project(":io.sc.platform.scheduler.manager"), project(":io.sc.platform.scheduler.manager"),
project(":io.sc.platform.scheduler.executor"), project(":io.sc.platform.scheduler.executor"),
// project(":io.sc.engine.mv"), project(":io.sc.engine.mv"),
// project(":io.sc.engine.mv.frontend"), project(":io.sc.engine.mv.frontend"),
// project(":io.sc.engine.mv.sample"), project(":io.sc.engine.mv.sample"),
//
// project(":io.sc.engine.rule.client"), project(":io.sc.engine.rule.client"),
// project(":io.sc.engine.rule.client.spring"), project(":io.sc.engine.rule.client.spring"),
// project(":io.sc.engine.rule.core"), project(":io.sc.engine.rule.core"),
// project(":io.sc.engine.rule.server"), project(":io.sc.engine.rule.server"),
// project(":io.sc.engine.rule.sample"), project(":io.sc.engine.rule.sample"),
//
project(":io.sc.engine.st"), project(":io.sc.engine.st"),
project(":io.sc.engine.st.frontend"), project(":io.sc.engine.st.frontend"),
project(":erm"), // project(":erm"),
project(":erm.frontend"), // project(":erm.frontend"),
project(":io.sc.standard"), project(":io.sc.standard"),
) )

6
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/util/ExpressionReplacer.java

@ -36,9 +36,11 @@ public class ExpressionReplacer {
public static String placeholder(String varName,String fieldName) { public static String placeholder(String varName,String fieldName) {
if(varName!=null) { if(varName!=null) {
if(fieldName!=null) { if(fieldName!=null) {
return "${" + varName + "." + fieldName + "}"; //return "${" + varName + "." + fieldName + "}";
return varName + "." + fieldName;
}else { }else {
return "${" + varName + "}"; //return "${" + varName + "}";
return varName;
} }
} }
return null; return null;

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

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.231", "platform-core": "8.1.237",
"quasar": "2.15.3", "quasar": "2.15.3",
"tailwindcss": "3.4.3", "tailwindcss": "3.4.3",
"vue": "3.4.24", "vue": "3.4.24",

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

@ -83,7 +83,7 @@
"re.resources.designer.processor.grid.entity.when": "When Expression", "re.resources.designer.processor.grid.entity.when": "When Expression",
"re.resources.designer.processor.grid.entity.then": "Then Expression", "re.resources.designer.processor.grid.entity.then": "Then Expression",
"re.resources.designer.processor.grid.entity.isWhenThenShorted": "Shorted", "re.resources.designer.processor.grid.entity.isWhenThenShorted": "Shorted",
"re.resources.designer.processor.grid.entity.numberRangeVar": "Number Range", "re.resources.designer.processor.grid.entity.numberRangeVar": "Number Range Expression",
"re.resources.designer.processor.grid.entity.numberRange": "Number Range", "re.resources.designer.processor.grid.entity.numberRange": "Number Range",
"re.resources.designer.processor.grid.entity.conditionRangeVar": "Condition Range", "re.resources.designer.processor.grid.entity.conditionRangeVar": "Condition Range",
"re.resources.designer.processor.grid.entity.conditionRange": "Condition Range", "re.resources.designer.processor.grid.entity.conditionRange": "Condition Range",

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

@ -83,7 +83,7 @@
"re.resources.designer.processor.grid.entity.when": "When 表達式", "re.resources.designer.processor.grid.entity.when": "When 表達式",
"re.resources.designer.processor.grid.entity.then": "Then 表達式", "re.resources.designer.processor.grid.entity.then": "Then 表達式",
"re.resources.designer.processor.grid.entity.isWhenThenShorted": "短路操作", "re.resources.designer.processor.grid.entity.isWhenThenShorted": "短路操作",
"re.resources.designer.processor.grid.entity.numberRangeVar": "數值分段", "re.resources.designer.processor.grid.entity.numberRangeVar": "數值分段表達式",
"re.resources.designer.processor.grid.entity.numberRange": "數值分段", "re.resources.designer.processor.grid.entity.numberRange": "數值分段",
"re.resources.designer.processor.grid.entity.conditionRangeVar": "條件分段", "re.resources.designer.processor.grid.entity.conditionRangeVar": "條件分段",
"re.resources.designer.processor.grid.entity.conditionRange": "條件分段", "re.resources.designer.processor.grid.entity.conditionRange": "條件分段",

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

@ -83,7 +83,7 @@
"re.resources.designer.processor.grid.entity.when": "When 表达式", "re.resources.designer.processor.grid.entity.when": "When 表达式",
"re.resources.designer.processor.grid.entity.then": "Then 表达式", "re.resources.designer.processor.grid.entity.then": "Then 表达式",
"re.resources.designer.processor.grid.entity.isWhenThenShorted": "短路操作", "re.resources.designer.processor.grid.entity.isWhenThenShorted": "短路操作",
"re.resources.designer.processor.grid.entity.numberRangeVar": "数值分段", "re.resources.designer.processor.grid.entity.numberRangeVar": "数值分段表达式",
"re.resources.designer.processor.grid.entity.numberRange": "数值分段", "re.resources.designer.processor.grid.entity.numberRange": "数值分段",
"re.resources.designer.processor.grid.entity.conditionRangeVar": "条件分段", "re.resources.designer.processor.grid.entity.conditionRangeVar": "条件分段",
"re.resources.designer.processor.grid.entity.conditionRange": "条件分段", "re.resources.designer.processor.grid.entity.conditionRange": "条件分段",

10
io.sc.engine.rule.frontend/src/views/resources/ImportSampleDialog.vue

@ -25,13 +25,13 @@
click: (arg) => { click: (arg) => {
if (arg.tickeds && arg.tickeds.length > 0) { if (arg.tickeds && arg.tickeds.length > 0) {
const ids = Tools.extractProperties(arg.tickeds, 'id'); const ids = Tools.extractProperties(arg.tickeds, 'id');
console.log(ids); axios.post(Environment.apiContextPath('/api/re/resource/createExample'), ids, { loading: true }).then(() => {
DialogManager.confirm($t('re.resources.importSample.grid.toolbar.import.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/resource/createExample'), ids).then(() => {
close(); close();
emit('afterImported'); emit('afterImported');
}); });
}); // DialogManager.confirm($t('re.resources.importSample.grid.toolbar.import.tip'), () => {
// });
} }
}, },
}, },
@ -64,12 +64,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, nextTick } from 'vue'; import { ref, nextTick } from 'vue';
import { useQuasar } from 'quasar';
import { axios, Environment, DialogManager, Tools } from 'platform-core'; import { axios, Environment, DialogManager, Tools } from 'platform-core';
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'afterImported', evt: Event): void; (e: 'afterImported', evt: Event): void;
}>(); }>();
const quasar = useQuasar();
const dialogRef = ref(); const dialogRef = ref();
const gridRef = ref(); const gridRef = ref();

1
io.sc.engine.rule.frontend/src/views/resources/designer/DesignerDialog.vue

@ -62,6 +62,7 @@
no-caps no-caps
inline-label inline-label
align="left" align="left"
class="px-2"
@update:model-value=" @update:model-value="
(value) => { (value) => {
if (value === 'testcase') { if (value === 'testcase') {

43
io.sc.engine.rule.frontend/src/views/resources/designer/GroovyFunctions.ts

@ -0,0 +1,43 @@
const GroovyFunctions = [
{ label: 'PI', type: 'constant', apply: 'PI', detail: '常量 π' },
{ label: 'E', type: 'constant', apply: 'E', detail: '常量 e' },
{ label: 'IEEEremainder(v1,v2)', type: 'function', apply: 'IEEEremainder(v1,v2)', detail: '根据 IEEE 754 标准返回 v1 除以 v2 的余数' },
{ label: 'abs(v)', type: 'function', apply: 'abs(v)', detail: '绝对值' },
{ label: 'acos(v)', type: 'function', apply: 'acos(v)', detail: '反余弦' },
{ label: 'asin(v)', type: 'function', apply: 'asin(v)', detail: '反正弦' },
{ label: 'atan(v)', type: 'function', apply: 'atan(v)', detail: '' },
{ label: 'atan2(v)', type: 'function', apply: 'atan2(v)', detail: '' },
{ label: 'cbrt(v)', type: 'function', apply: 'cbrt(v)', detail: '' },
{ label: 'ceil(v)', type: 'function', apply: 'ceil(v)', detail: '' },
{ label: 'cos(v)', type: 'function', apply: 'cos(v)', detail: '' },
{ label: 'cosh(v)', type: 'function', apply: 'cosh(v)', detail: '' },
{ label: 'exp(v)', type: 'function', apply: 'exp(v)', detail: '' },
{ label: 'expm1(v)', type: 'function', apply: 'expm1(v)', detail: '' },
{ label: 'floor(v)', type: 'function', apply: 'floor(v)', detail: '' },
{ label: 'inverseNormalDistributioin(x)', type: 'function', apply: 'inverseNormalDistributioin(x)', detail: '' },
{ label: 'join(split,s1,s2,s3...,sn)', type: 'function', apply: 'join(split,s1,s2,s3...,sn)', detail: '' },
{ label: 'ln(v)', type: 'function', apply: 'ln(v)', detail: '' },
{ label: 'max(v1,v2,...)', type: 'function', apply: 'max(v1,v2,...)', detail: '' },
{ label: 'min(v1,v2,...)', type: 'function', apply: 'min(v1,v2,...)', detail: '' },
{ label: 'normalDistributioin(x)', type: 'function', apply: 'normalDistributioin(x)', detail: '' },
{ label: 'pow(x,y)', type: 'function', apply: 'pow(x,y)', detail: '' },
{ label: 'random()', type: 'function', apply: 'random()', detail: '' },
{ label: 'rint(v)', type: 'function', apply: 'rint(v)', detail: '' },
{ label: 'round(v)', type: 'function', apply: 'round(v)', detail: '' },
{ label: 'sin(v)', type: 'function', apply: 'sin(v)', detail: '' },
{ label: 'sinh(v)', type: 'function', apply: 'sinh(v)', detail: '' },
{ label: 'sqrt(v)', type: 'function', apply: 'sqrt(v)', detail: '' },
{ label: 'sum(v1,v2,...)', type: 'function', apply: 'sum(v1,v2,...)', detail: '' },
{ label: 'tan(v)', type: 'function', apply: 'tan(v)', detail: '' },
{ label: 'tanh(v)', type: 'function', apply: 'tanh(v)', detail: '' },
{ label: 'toDegrees(v)', type: 'function', apply: 'toDegrees(v)', detail: '' },
{ label: 'toRadians(v)', type: 'function', apply: 'toRadians(v)', detail: '' },
{
label: 'transformSequencing(value,sourceMin,sourceMax,targetMin,targetMax)',
type: 'function',
apply: 'transformSequencing(value,sourceMin,sourceMax,targetMin,targetMax)',
detail: '',
},
];
export default GroovyFunctions;

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

@ -210,9 +210,9 @@
'export', 'export',
]" ]"
:columns="[ :columns="[
{ width: 80, name: 'enable', label: $t('isEnable'), align: 'center', sortable: false, format: Formater.enableTag() },
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' }, { width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' },
{ width: 100, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) }, { width: 150, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) },
{ width: 100, name: 'enable', label: $t('isEnable'), sortable: false },
{ {
width: '100%', width: '100%',
name: 'content', name: 'content',
@ -220,15 +220,49 @@
sortable: false, sortable: false,
format: (value, row) => { format: (value, row) => {
const type = row.type; const type = row.type;
if ('OPTION_VALUE' === type) {
return row.optionCode;
} else if ('ARITHMETIC' === type) {
return row.arithmetic;
} else if ('TERNARY' === type) {
return row.ternaryCondition + ' <b><span>?</span></b> ' + row.ternaryTrue + ' <b><span>:</span></b> ' + row.ternaryFalse;
} else if ('WHEN_THEN' === type) {
var str = '';
if (row.isWhenThenShorted) {
str += '<span>' + $t('re.resources.designer.processor.grid.entity.isWhenThenShorted') + ', </span>';
}
if (row.when) {
str += '<span>When</span> ' + row.when + ' ';
}
if (row.then) {
str += '<span>Then</span> ' + row.then;
}
return str;
} else if ('NUMBER_RANGE' === type) {
var objs = Tools.json2Object(row.numberRange);
if (objs) {
var str = '<div>' + row.numberRangeVar + ':</div>';
str += `<div class='border'>`;
str += `<table width='100%'>`;
for (var i = 0; i < objs.length; i++) {
var obj = objs[i];
str += '<tr>';
str += ' <td>' + Tools.generateIntervalRange(obj.minIncluded, obj.min, obj.max, obj.maxIncluded) + '</td>';
str += ' <td><span>' + ('' + obj.value) + '</span></td>';
str += '</tr>';
}
str += '</table>';
str += `</div>`;
return str;
}
return ''; return '';
}
}, },
}, },
]" ]"
:editor="{ :editor="{
dialog: { dialog: {
width: '600px', width: '600px',
height: '400px',
}, },
form: { form: {
colsNum: 1, colsNum: 1,
@ -243,7 +277,7 @@
name: 'optionCode', name: 'optionCode',
label: $t('re.resources.designer.processor.grid.entity.optionCode'), label: $t('re.resources.designer.processor.grid.entity.optionCode'),
type: 'select', type: 'select',
options: [], options: optionOptionsRef,
showIf: (arg) => { showIf: (arg) => {
return 'OPTION_VALUE' === arg.form.getFieldValue('type'); return 'OPTION_VALUE' === arg.form.getFieldValue('type');
}, },
@ -252,6 +286,10 @@
name: 'arithmetic', name: 'arithmetic',
label: $t('re.resources.designer.processor.grid.entity.arithmetic'), label: $t('re.resources.designer.processor.grid.entity.arithmetic'),
type: 'code-mirror', type: 'code-mirror',
lang: 'java',
rows: 5,
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => { showIf: (arg) => {
return 'ARITHMETIC' === arg.form.getFieldValue('type'); return 'ARITHMETIC' === arg.form.getFieldValue('type');
}, },
@ -260,7 +298,11 @@
name: 'ternaryCondition', name: 'ternaryCondition',
label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'), label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'),
type: 'code-mirror', type: 'code-mirror',
lang: 'java',
rows: 1, rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => { showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type'); return 'TERNARY' === arg.form.getFieldValue('type');
}, },
@ -269,7 +311,11 @@
name: 'ternaryTrue', name: 'ternaryTrue',
label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'), label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'),
type: 'code-mirror', type: 'code-mirror',
lang: 'java',
rows: 1, rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => { showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type'); return 'TERNARY' === arg.form.getFieldValue('type');
}, },
@ -278,7 +324,11 @@
name: 'ternaryFalse', name: 'ternaryFalse',
label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'), label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'),
type: 'code-mirror', type: 'code-mirror',
lang: 'java',
rows: 1, rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => { showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type'); return 'TERNARY' === arg.form.getFieldValue('type');
}, },
@ -287,7 +337,11 @@
name: 'when', name: 'when',
label: $t('re.resources.designer.processor.grid.entity.when'), label: $t('re.resources.designer.processor.grid.entity.when'),
type: 'code-mirror', type: 'code-mirror',
lang: 'java',
rows: 1, rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => { showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type'); return 'WHEN_THEN' === arg.form.getFieldValue('type');
}, },
@ -296,7 +350,11 @@
name: 'then', name: 'then',
label: $t('re.resources.designer.processor.grid.entity.then'), label: $t('re.resources.designer.processor.grid.entity.then'),
type: 'code-mirror', type: 'code-mirror',
lang: 'java',
rows: 1, rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => { showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type'); return 'WHEN_THEN' === arg.form.getFieldValue('type');
}, },
@ -304,17 +362,41 @@
{ {
name: 'isWhenThenShorted', name: 'isWhenThenShorted',
label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted'), label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted'),
type: 'checkbox',
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'numberRangeVar',
label: $t('re.resources.designer.processor.grid.entity.numberRangeVar'),
type: 'code-mirror', type: 'code-mirror',
lang: 'java',
rows: 1, rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => { showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type'); return 'NUMBER_RANGE' === arg.form.getFieldValue('type');
}, },
}, },
{ {
name: 'numberRange', name: 'numberRange',
label: $t('re.resources.designer.processor.grid.entity.numberRange'), label: $t('re.resources.designer.processor.grid.entity.numberRange'),
type: 'code-mirror', type: 'w-grid',
rows: 1, height: 300,
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: ['add', 'clone', 'remove'],
columns: [
{ width: 200, name: 'uuid', label: 'uuid', hidden: true },
{ width: 60, name: 'minIncluded', label: $t('include') },
{ width: 100, name: 'min', label: $t('minValue'), align: 'center' },
{ width: 100, name: 'max', label: $t('maxValue'), align: 'center' },
{ width: 60, name: 'maxIncluded', label: $t('include'), type: 'boolean' },
{ width: '100%', name: 'value', label: $t('value') },
],
showIf: (arg) => { showIf: (arg) => {
return 'NUMBER_RANGE' === arg.form.getFieldValue('type'); return 'NUMBER_RANGE' === arg.form.getFieldValue('type');
}, },
@ -462,11 +544,46 @@
], ],
}, },
}" }"
@after-editor-open="
(row) => {
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemterHintsByParameterId/' + parameter.id)).then((response) => {
const names = [];
if (response.data?.parentParameterNames && response.data?.parentParameterNames.length > 0) {
for (const item of response.data?.parentParameterNames) {
names.push({ label: item, type: 'variable', apply: '${' + item + '}' });
}
}
if (response.data?.parameterNames && response.data?.parameterNames.length > 0) {
for (const item of response.data?.parameterNames) {
names.push({ label: item, type: 'variable', apply: '${' + item + '}' });
}
}
autoCompletionOptionsRef = names;
});
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemtersByParameterId/' + parameter.id)).then((response) => {
const parameters = [];
if (response.data) {
for (const parameter of response.data) {
if ('IN_OPTION' === parameter.type) {
parameters.push({ label: parameter.name, value: parameter.code });
}
}
}
optionOptionsRef = parameters;
});
if ('NUMBER_RANGE' === row.type) {
const fields = gridRef.getEditorForm().getFields();
console.log(fields);
numberRangeGridRef.setLocalData(Tools.json2Object(row.numberRange));
}
}
"
></w-grid> ></w-grid>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { Environment, Formater, EnumTools, Options } from 'platform-core'; import { axios, Environment, Formater, Tools, EnumTools, Options } from 'platform-core';
import GroovyFunctions from './GroovyFunctions';
const props = defineProps({ const props = defineProps({
fetchDataUrl: { type: String, default: '' }, fetchDataUrl: { type: String, default: '' },
@ -478,7 +595,11 @@ const emit = defineEmits<{
(e: 'rowClick', evt: Event, row: any, index: number): void; (e: 'rowClick', evt: Event, row: any, index: number): void;
(e: 'beforeRequestData', requestParams: URLSearchParams | any, callback: any): void; (e: 'beforeRequestData', requestParams: URLSearchParams | any, callback: any): void;
}>(); }>();
const gridRef = ref(); const gridRef = ref();
const autoCompletionOptionsRef = ref([]);
const optionOptionsRef = ref([]);
const numberRangeGridRef = ref();
const refresh = () => { const refresh = () => {
gridRef.value.refresh(); gridRef.value.refresh();

1029
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/bean/JpaEntityChangedListener.java

File diff suppressed because it is too large

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/JpaEntityPersistentEventListener.java

@ -36,7 +36,7 @@ import io.sc.platform.orm.entity.support.JpaEntityPersistentEvent;
/** /**
* 实体持久化监听器 * 实体持久化监听器
*/ */
@Service("reJpaEntityPersistentEventListener") @Service("io.sc.engine.rule.server.jpa.listener.JpaEntityPersistentEventListener")
public class JpaEntityPersistentEventListener { public class JpaEntityPersistentEventListener {
@Autowired private DictionaryEntityEventHandler dictionaryEntityEventHandler; @Autowired private DictionaryEntityEventHandler dictionaryEntityEventHandler;
@Autowired private UserDefinedJavaClassFieldEntityEventHandler userDefinedJavaClassFieldEntityEventHandler; @Autowired private UserDefinedJavaClassFieldEntityEventHandler userDefinedJavaClassFieldEntityEventHandler;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/DictionaryEntityEventHandler.java

@ -22,7 +22,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 数据字典实体持久化事件处理器 * 数据字典实体持久化事件处理器
*/ */
@Service("reDictionaryEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.DictionaryEntityEventHandler")
public class DictionaryEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<DictionaryEntity>{ public class DictionaryEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<DictionaryEntity>{
private static final Logger log =LoggerFactory.getLogger(DictionaryEntityEventHandler.class); private static final Logger log =LoggerFactory.getLogger(DictionaryEntityEventHandler.class);
@Autowired private DictionaryService dictionaryService; @Autowired private DictionaryService dictionaryService;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/IndicatorEntityEventHandler.java

@ -23,7 +23,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 指标实体持久化事件处理器 * 指标实体持久化事件处理器
*/ */
@Service("reIndicatorEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.IndicatorEntityEventHandler")
public class IndicatorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<IndicatorEntity>{ public class IndicatorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<IndicatorEntity>{
@Autowired private LibService libService; @Autowired private LibService libService;
@Autowired private IndicatorProcessorService indicatorProcessorService; @Autowired private IndicatorProcessorService indicatorProcessorService;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/IndicatorProcessorEntityEventHandler.java

@ -12,7 +12,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 指标处理器实体持久化事件处理器 * 指标处理器实体持久化事件处理器
*/ */
@Service("reIndicatorProcessorEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.IndicatorProcessorEntityEventHandler")
public class IndicatorProcessorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<IndicatorProcessorEntity>{ public class IndicatorProcessorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<IndicatorProcessorEntity>{
@Autowired private IndicatorService indicatorService; @Autowired private IndicatorService indicatorService;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/IndicatorValidatorEntityEventHandler.java

@ -12,7 +12,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 指标验证器实体持久化事件处理器 * 指标验证器实体持久化事件处理器
*/ */
@Service("reIndicatorValidatorEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.IndicatorValidatorEntityEventHandler")
public class IndicatorValidatorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<IndicatorValidatorEntity>{ public class IndicatorValidatorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<IndicatorValidatorEntity>{
@Autowired private IndicatorService indicatorService; @Autowired private IndicatorService indicatorService;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/LibEntityEventHandler.java

@ -25,7 +25,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 库实体持久化事件处理器 * 库实体持久化事件处理器
*/ */
@Service("reLibEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.LibEntityEventHandler")
public class LibEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<LibEntity>{ public class LibEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<LibEntity>{
private static final Logger log =LoggerFactory.getLogger(LibEntityEventHandler.class); private static final Logger log =LoggerFactory.getLogger(LibEntityEventHandler.class);
@Autowired private LibService libService; @Autowired private LibService libService;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ModelEntityEventHandler.java

@ -13,7 +13,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 模型实体持久化事件处理器 * 模型实体持久化事件处理器
*/ */
@Service("reModelEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.ModelEntityEventHandler")
public class ModelEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ModelEntity>{ public class ModelEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ModelEntity>{
@Autowired private ModelService modelService; @Autowired private ModelService modelService;
@Autowired private ResourceService resourceService; @Autowired private ResourceService resourceService;

6
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ParameterEntityEventHandler.java

@ -22,7 +22,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 参数实体持久化事件处理器 * 参数实体持久化事件处理器
*/ */
@Service("reParameterEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.ParameterEntityEventHandler")
public class ParameterEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ParameterEntity>{ public class ParameterEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ParameterEntity>{
@Autowired private ModelService modelService; @Autowired private ModelService modelService;
@Autowired private ParameterProcessorService parameterProcessorService; @Autowired private ParameterProcessorService parameterProcessorService;
@ -122,8 +122,8 @@ public class ParameterEntityEventHandler extends AbstractJpaEntityPersistentEven
} }
String sql ="update RE_TEST_CASE_PARAMETER set" String sql ="update RE_TEST_CASE_PARAMETER set"
+ " FD_CODE=:newCode" + " CODE_=:newCode"
+ " where FD_CODE=:oldCode and FD_TEST_CASE_ID in (:testCaseIds)"; + " where CODE_=:oldCode and TEST_CASE_ID_ in (:testCaseIds)";
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<String, Object>();
params.put("newCode", newEntity.getCode()); params.put("newCode", newEntity.getCode());

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ParameterProcessorEntityEventHandler.java

@ -12,7 +12,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 参数处理器实体持久化事件处理器 * 参数处理器实体持久化事件处理器
*/ */
@Service("reParameterProcessorEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.ParameterProcessorEntityEventHandler")
public class ParameterProcessorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ParameterProcessorEntity>{ public class ParameterProcessorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ParameterProcessorEntity>{
@Autowired private ParameterService parameterService; @Autowired private ParameterService parameterService;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ParameterValidatorEntityEventHandler.java

@ -12,7 +12,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 参数验证器实体持久化事件处理器 * 参数验证器实体持久化事件处理器
*/ */
@Service("reParameterValidatorEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.ParameterValidatorEntityEventHandler")
public class ParameterValidatorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ParameterValidatorEntity>{ public class ParameterValidatorEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ParameterValidatorEntity>{
@Autowired private ParameterService parameterService; @Autowired private ParameterService parameterService;

12
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ResourceEntityEventHandler.java

@ -15,7 +15,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 资源实体持久化事件处理器 * 资源实体持久化事件处理器
*/ */
@Service("reResourceEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.ResourceEntityEventHandler")
public class ResourceEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ResourceEntity>{ public class ResourceEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ResourceEntity>{
@Autowired private JdbcTemplate jdbcTemplate; @Autowired private JdbcTemplate jdbcTemplate;
@ -52,10 +52,10 @@ public class ResourceEntityEventHandler extends AbstractJpaEntityPersistentEvent
if(oldEntity!=null && newEntity!=null && (!oldEntity.getCode().equals(newEntity.getCode()) || !oldEntity.getName().equals(newEntity.getName()))) { if(oldEntity!=null && newEntity!=null && (!oldEntity.getCode().equals(newEntity.getCode()) || !oldEntity.getName().equals(newEntity.getName()))) {
if(!oldEntity.getCode().equals(newEntity.getCode()) || !oldEntity.getName().equals(newEntity.getName())) { //资源的代码或名称不同时 if(!oldEntity.getCode().equals(newEntity.getCode()) || !oldEntity.getName().equals(newEntity.getName())) { //资源的代码或名称不同时
String sql ="update RE_RESOURCE set" String sql ="update RE_RESOURCE set"
+ " FD_CODE=?," + " CODE_=?,"
+ " FD_NAME=?," + " NAME_=?,"
+ " FD_LAST_MODIFYDATE=?" + " LAST_MODIFYDATE_=?"
+ " where FD_CODE=?"; + " where CODE_=?";
jdbcTemplate.update(sql, new PreparedStatementSetter() { jdbcTemplate.update(sql, new PreparedStatementSetter() {
@Override @Override
public void setValues(PreparedStatement pstmt) throws SQLException { public void setValues(PreparedStatement pstmt) throws SQLException {
@ -75,7 +75,7 @@ public class ResourceEntityEventHandler extends AbstractJpaEntityPersistentEvent
*/ */
private void deleteTestCase(ResourceEntity oldEntity) { private void deleteTestCase(ResourceEntity oldEntity) {
if(oldEntity!=null) { if(oldEntity!=null) {
String sql ="delete from RE_TEST_CASE where FD_OWNER_ID=?"; String sql ="delete from RE_TEST_CASE where OWNER_ID_=?";
jdbcTemplate.update(sql, new PreparedStatementSetter() { jdbcTemplate.update(sql, new PreparedStatementSetter() {
@Override @Override
public void setValues(PreparedStatement pstmt) throws SQLException { public void setValues(PreparedStatement pstmt) throws SQLException {

6
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/ScoreCardVarEntityEventHandler.java

@ -19,7 +19,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 评分卡变量实体持久化事件处理器 * 评分卡变量实体持久化事件处理器
*/ */
@Service("reScoreCardVarEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.ScoreCardVarEntityEventHandler")
public class ScoreCardVarEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ScoreCardVarEntity>{ public class ScoreCardVarEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<ScoreCardVarEntity>{
@Autowired private ResourceService resourceService; @Autowired private ResourceService resourceService;
@Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@ -80,8 +80,8 @@ public class ScoreCardVarEntityEventHandler extends AbstractJpaEntityPersistentE
} }
String sql ="update RE_TEST_CASE_PARAMETER set" String sql ="update RE_TEST_CASE_PARAMETER set"
+ " FD_CODE=:newCode" + " CODE_=:newCode"
+ " where FD_CODE=:oldCode and FD_TEST_CASE_ID in (:testCaseIds)"; + " where CODE_=:oldCode and TEST_CASE_ID_ in (:testCaseIds)";
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<String, Object>();
params.put("newCode", newEntity.getCode()); params.put("newCode", newEntity.getCode());

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/jpa/listener/handler/UserDefinedJavaClassFieldEntityEventHandler.java

@ -35,7 +35,7 @@ import io.sc.platform.orm.entity.support.AbstractJpaEntityPersistentEventHandler
/** /**
* 用户自定义Java类字段实体持久化事件处理器 * 用户自定义Java类字段实体持久化事件处理器
*/ */
@Service("reUserDefinedJavaClassFieldEntityEventHandler") @Service("io.sc.engine.rule.server.jpa.listener.handler.UserDefinedJavaClassFieldEntityEventHandler")
public class UserDefinedJavaClassFieldEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<UserDefinedJavaClassFieldEntity>{ public class UserDefinedJavaClassFieldEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<UserDefinedJavaClassFieldEntity>{
@Autowired private DictionaryService dictionaryService; @Autowired private DictionaryService dictionaryService;
@Autowired private UserDefinedJavaClassFieldService userDefinedJavaClassFieldService; @Autowired private UserDefinedJavaClassFieldService userDefinedJavaClassFieldService;

5
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterProcessorWebController.java

@ -41,7 +41,10 @@ public class ParameterProcessorWebController extends RestCrudController<Paramete
if(!StringUtils.hasText(parameterId)){ if(!StringUtils.hasText(parameterId)){
return Collections.emptyList(); return Collections.emptyList();
} }
return EntityVoUtil.toVo(service.findByParameterId(parameterId)); List<ParameterProcessorEntity> entities =service.findByParameterId(parameterId);
CodeAndNameMapping mapping =parameterService.loadCodeAndNameMappingByParameterId(parameterId);
VariableCodeAndNameReplacer.replace(entities,mapping.getCode2NameMapping());
return EntityVoUtil.toVo(entities);
} }
//决策树========================================================================================================== //决策树==========================================================================================================

11
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterWebController.java

@ -18,10 +18,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/** /**
* 模型参数 Controller * 模型参数 Controller
@ -96,6 +93,12 @@ public class ParameterWebController extends RestCrudController<ParameterVo,Param
service.addIndicators(wrapper); service.addIndicators(wrapper);
} }
@RequestMapping(value="listParemtersByParameterId/{parameterId}",method=RequestMethod.GET)
@ResponseBody
public List<ParameterVo> listParemtersByParameterId(@PathVariable(name="parameterId",required=true)String parameterId) throws Exception{
return service.listParemtersByParameterId(parameterId);
}
@RequestMapping(value="listParemterHintsByParameterId/{parameterId}",method=RequestMethod.GET) @RequestMapping(value="listParemterHintsByParameterId/{parameterId}",method=RequestMethod.GET)
@ResponseBody @ResponseBody
public ParemterHints listParemterHintsByParameterId(@PathVariable(name="parameterId",required=true)String parameterId) throws Exception{ public ParemterHints listParemterHintsByParameterId(@PathVariable(name="parameterId",required=true)String parameterId) throws Exception{

7
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/ParameterProcessorEntity.java

@ -8,6 +8,7 @@ import io.sc.engine.rule.server.model.entity.processor.*;
import io.sc.engine.rule.server.model.vo.ParameterProcessorVo; import io.sc.engine.rule.server.model.vo.ParameterProcessorVo;
import io.sc.platform.orm.DeepClone; import io.sc.platform.orm.DeepClone;
import io.sc.platform.orm.IdClearable; import io.sc.platform.orm.IdClearable;
import io.sc.platform.orm.api.vo.AuditorVo;
import io.sc.platform.orm.converter.NumericBooleanConverter; import io.sc.platform.orm.converter.NumericBooleanConverter;
import io.sc.platform.orm.entity.AuditorEntity; import io.sc.platform.orm.entity.AuditorEntity;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
@ -78,8 +79,8 @@ public class ParameterProcessorEntity extends AuditorEntity<ParameterProcessorVo
protected Integer order; protected Integer order;
@Override @Override
public ParameterProcessorVo toVo() { public void toVo(ParameterProcessorVo vo) {
ParameterProcessorVo vo =new ParameterProcessorVo(); if(vo!=null){
super.toVo(vo); super.toVo(vo);
vo.setId(this.getId()); vo.setId(this.getId());
vo.setType(this.getType()); vo.setType(this.getType());
@ -87,7 +88,7 @@ public class ParameterProcessorEntity extends AuditorEntity<ParameterProcessorVo
vo.setDescription(this.getDescription()); vo.setDescription(this.getDescription());
vo.setEnable(this.getEnable()); vo.setEnable(this.getEnable());
vo.setOrder(this.getOrder()); vo.setOrder(this.getOrder());
return vo; }
} }
public String getId() { public String getId() {

10
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ParameterService.java

@ -2,8 +2,10 @@ package io.sc.engine.rule.server.model.service;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Set; import java.util.Set;
import io.sc.engine.rule.server.model.vo.ParameterVo;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.sc.engine.rule.server.model.entity.ParameterEntity; import io.sc.engine.rule.server.model.entity.ParameterEntity;
import io.sc.engine.rule.server.model.entity.parameter.OutParameterEntity; import io.sc.engine.rule.server.model.entity.parameter.OutParameterEntity;
@ -55,6 +57,14 @@ public interface ParameterService extends DaoService<ParameterEntity, String, Pa
*/ */
public CodeAndNameMapping loadCodeAndNameMappingByParameterId(String parameterId); public CodeAndNameMapping loadCodeAndNameMappingByParameterId(String parameterId);
/**
* 通过参数ID获取当前参数所属的模型的所有参数列表
* @param parameterId 参数ID
* @return 当前参数所属的模型的所有参数列表
* @throws Exception 违例
*/
public List<ParameterVo> listParemtersByParameterId(String parameterId) throws Exception;
/** /**
* 通过参数ID获取当前参数处理器可引用的参数名称列表 * 通过参数ID获取当前参数处理器可引用的参数名称列表
* @param parameterId 参数ID * @param parameterId 参数ID

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

@ -35,11 +35,13 @@ import io.sc.engine.rule.server.model.service.support.ParameterEntityChangedEven
import io.sc.engine.rule.server.model.service.support.ParameterIndicatorsWrapper; import io.sc.engine.rule.server.model.service.support.ParameterIndicatorsWrapper;
import io.sc.engine.rule.server.model.service.support.ParemterHints; import io.sc.engine.rule.server.model.service.support.ParemterHints;
import io.sc.engine.rule.server.model.service.support.PmmlDataTypeConvertor; import io.sc.engine.rule.server.model.service.support.PmmlDataTypeConvertor;
import io.sc.engine.rule.server.model.vo.ParameterVo;
import io.sc.engine.rule.server.util.CodeAndNameMapping; import io.sc.engine.rule.server.util.CodeAndNameMapping;
import io.sc.platform.core.Environment; import io.sc.platform.core.Environment;
import io.sc.platform.core.util.FileUtil; import io.sc.platform.core.util.FileUtil;
import io.sc.platform.orm.entity.support.EntityChangedEventType; import io.sc.platform.orm.entity.support.EntityChangedEventType;
import io.sc.platform.orm.service.impl.DaoServiceImpl; import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.orm.util.EntityVoUtil;
import org.dmg.pmml.DataType; import org.dmg.pmml.DataType;
import org.dmg.pmml.PMML; import org.dmg.pmml.PMML;
import org.jpmml.evaluator.Evaluator; import org.jpmml.evaluator.Evaluator;
@ -335,6 +337,26 @@ public class ParameterServiceImpl extends DaoServiceImpl<ParameterEntity, String
return result; return result;
} }
@Override
public List<ParameterVo> listParemtersByParameterId(String parameterId) throws Exception {
if(!StringUtils.hasText(parameterId)){
return Collections.emptyList();
}
ParameterEntity parameterEntity =findById(parameterId);
if(parameterEntity==null){
return Collections.emptyList();
}
ModelEntity modelEntity = parameterEntity.getModel();
if (modelEntity == null) {
return Collections.emptyList();
}
List<ParameterEntity> parameters =modelEntity.getParameters();
if(parameters==null || parameters.isEmpty()) {
return Collections.emptyList();
}
return EntityVoUtil.toVo(parameters);
}
@Override @Override
public ParemterHints listParemterHintsByParameterId(String parameterId) throws Exception{ public ParemterHints listParemterHintsByParameterId(String parameterId) throws Exception{
ParemterHints hints =new ParemterHints(); ParemterHints hints =new ParemterHints();

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

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

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

@ -6,6 +6,8 @@ import component_testcase_openNoMenuRoute from '@/views/testcase/route/OpenNoMen
import component_testcase_noMenuRoute from '@/views/testcase/route/NoMenuRoute.vue'; import component_testcase_noMenuRoute from '@/views/testcase/route/NoMenuRoute.vue';
import component_testcase_mathEditor from '@/views/testcase/math/MathEditor.vue'; import component_testcase_mathEditor from '@/views/testcase/math/MathEditor.vue';
import component_testcase_form from '@/views/testcase/form/form.vue'; import component_testcase_form from '@/views/testcase/form/form.vue';
import component_testcase_codemirror from '@/views/testcase/code-mirror/code-mirror.vue';
import component_testcase_loading from '@/views/testcase/loading/loading.vue';
import component_testcase_excel from '@/views/testcase/excel/Excel.vue'; import component_testcase_excel from '@/views/testcase/excel/Excel.vue';
import component_testcase_word from '@/views/testcase/word/Word.vue'; import component_testcase_word from '@/views/testcase/word/Word.vue';
import component_testcase_likmDialog from '@/views/likm/Dialog.vue'; import component_testcase_likmDialog from '@/views/likm/Dialog.vue';
@ -23,6 +25,8 @@ const localComponents = {
'component.testcase.noMenuRoute': component_testcase_noMenuRoute, 'component.testcase.noMenuRoute': component_testcase_noMenuRoute,
'component.testcase.mathEditor': component_testcase_mathEditor, 'component.testcase.mathEditor': component_testcase_mathEditor,
'component.testcase.form': component_testcase_form, 'component.testcase.form': component_testcase_form,
'component.testcase.codemirror': component_testcase_codemirror,
'component.testcase.loading': component_testcase_loading,
'component.testcase.excel': component_testcase_excel, 'component.testcase.excel': component_testcase_excel,
'component.testcase.word': component_testcase_word, 'component.testcase.word': component_testcase_word,
'component.testcase.likmDialog': component_testcase_likmDialog, 'component.testcase.likmDialog': component_testcase_likmDialog,

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

@ -3,6 +3,8 @@
"menu.testcase.openNoMenuRoute": "Open No Menu Route", "menu.testcase.openNoMenuRoute": "Open No Menu Route",
"menu.testcase.mathEditor": "Math Formual Editor", "menu.testcase.mathEditor": "Math Formual Editor",
"menu.testcase.form":"Form Element", "menu.testcase.form":"Form Element",
"menu.testcase.codemirror":"Code Mirror",
"menu.testcase.loading":"Loading",
"menu.testcase.excel": "Excel", "menu.testcase.excel": "Excel",
"menu.testcase.word": "Word", "menu.testcase.word": "Word",

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

@ -3,6 +3,8 @@
"menu.testcase.openNoMenuRoute": "打開無關聯菜單的路由", "menu.testcase.openNoMenuRoute": "打開無關聯菜單的路由",
"menu.testcase.mathEditor": "數學公式編輯器", "menu.testcase.mathEditor": "數學公式編輯器",
"menu.testcase.form":"表單元素", "menu.testcase.form":"表單元素",
"menu.testcase.codemirror":"代碼編輯器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel", "menu.testcase.excel": "Excel",
"menu.testcase.word": "Word", "menu.testcase.word": "Word",

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

@ -3,6 +3,8 @@
"menu.testcase.openNoMenuRoute": "打开无关联菜单的路由示例", "menu.testcase.openNoMenuRoute": "打开无关联菜单的路由示例",
"menu.testcase.mathEditor": "数学公式编辑器", "menu.testcase.mathEditor": "数学公式编辑器",
"menu.testcase.form":"表单元素", "menu.testcase.form":"表单元素",
"menu.testcase.codemirror":"代码编辑器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel", "menu.testcase.excel": "Excel",
"menu.testcase.word": "Word", "menu.testcase.word": "Word",

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

@ -45,6 +45,24 @@
"icon": "bi-palette", "icon": "bi-palette",
"routeName": "route.testcase.form" "routeName": "route.testcase.form"
}, },
{
"type": "ROUTE",
"order": 350,
"parentId": "menu.testcase",
"id": "menu.testcase.codemirror",
"titleI18nKey": "menu.testcase.codemirror",
"icon": "bi-palette",
"routeName": "route.testcase.codemirror"
},
{
"type": "ROUTE",
"order": 350,
"parentId": "menu.testcase",
"id": "menu.testcase.loading",
"titleI18nKey": "menu.testcase.loading",
"icon": "bi-palette",
"routeName": "route.testcase.loading"
},
{ {
"type": "ROUTE", "type": "ROUTE",
"order": 400, "order": 400,

3
io.sc.platform.core.frontend/src/platform/components/app/WPlatformPage.vue

@ -4,12 +4,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { useQuasar, dom, debounce } from 'quasar'; import { useQuasar, dom, debounce } from 'quasar';
import { Environment, ApplicationInitializer, eventBus } from '@/platform'; import { Environment, ApplicationInitializer, QuasarTools, eventBus } from '@/platform';
const quasar = useQuasar(); const quasar = useQuasar();
const { ready } = dom; const { ready } = dom;
ready(function () { ready(function () {
QuasarTools.setQuasar(quasar);
quasar?.dark?.set(Environment.getConfigure().theme.dark); quasar?.dark?.set(Environment.getConfigure().theme.dark);
ApplicationInitializer.afterInitialized(); ApplicationInitializer.afterInitialized();
window.addEventListener( window.addEventListener(

1
io.sc.platform.core.frontend/src/platform/components/expression/dialog/XmlDialog.vue

@ -9,6 +9,7 @@ import { ref } from 'vue';
const dialogRef = ref(); const dialogRef = ref();
const xml = ref(); const xml = ref();
const open = (container) => { const open = (container) => {
const parser = new DOMParser(); const parser = new DOMParser();
const mathElementClone = parser.parseFromString(container.getEditor().outerHTML, 'text/xml'); const mathElementClone = parser.parseFromString(container.getEditor().outerHTML, 'text/xml');

72
io.sc.platform.core.frontend/src/platform/components/form/elements/WCodeMirror.vue

@ -41,7 +41,7 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, useAttrs, onMounted, onUnmounted, watch, computed, toRaw } from 'vue'; import { ref, useAttrs, onMounted, onUnmounted, onUpdated, watch, computed, toRaw } from 'vue';
import { Tools } from '@/platform'; import { Tools } from '@/platform';
import { FormValidators } from '@/platform/components'; import { FormValidators } from '@/platform/components';
import { EditorView } from '@codemirror/view'; import { EditorView } from '@codemirror/view';
@ -53,12 +53,14 @@ import * as search from '@codemirror/search';
import * as autocomplete from '@codemirror/autocomplete'; import * as autocomplete from '@codemirror/autocomplete';
import { LanguageSupport } from '@codemirror/language'; import { LanguageSupport } from '@codemirror/language';
import { html } from '@codemirror/lang-html'; import { html, htmlLanguage } from '@codemirror/lang-html';
import { java } from '@codemirror/lang-java'; import { java, javaLanguage } from '@codemirror/lang-java';
import { javascript } from '@codemirror/lang-javascript'; import { javascript, javascriptLanguage } from '@codemirror/lang-javascript';
import { json } from '@codemirror/lang-json'; import { json, jsonLanguage } from '@codemirror/lang-json';
import { sql } from '@codemirror/lang-sql'; import { sql } from '@codemirror/lang-sql';
import { xml } from '@codemirror/lang-xml'; import { xml, xmlLanguage } from '@codemirror/lang-xml';
import PlaceholderPlugin from './w-code-mirror/PlaceholderPlugin';
const attrs = useAttrs(); const attrs = useAttrs();
const rules = attrs.rules; const rules = attrs.rules;
@ -69,6 +71,18 @@ const props = defineProps({
default: () => {}, default: () => {},
}, },
modelValue: { type: String, default: '' }, modelValue: { type: String, default: '' },
autoCompletionOptions: {
type: Array,
default: () => {
return [];
},
},
extAutoCompletionOptions: {
type: Array,
default: () => {
return [];
},
},
lang: { type: String, default: 'json' }, lang: { type: String, default: 'json' },
width: { type: [Number, String], default: '100%' }, width: { type: [Number, String], default: '100%' },
height: { type: [Number, String], default: undefined }, height: { type: [Number, String], default: undefined },
@ -184,7 +198,7 @@ const basicSetup = [
autocomplete.closeBrackets(), autocomplete.closeBrackets(),
autocomplete.autocompletion(), autocomplete.autocompletion(),
search.highlightSelectionMatches(), //search.highlightSelectionMatches(),
view.keymap.of([ view.keymap.of([
...commands.defaultKeymap, ...commands.defaultKeymap,
@ -217,6 +231,45 @@ const getLanguage = (lang: string): LanguageSupport => {
} }
}; };
const autoCompletionFunction = (context: autocomplete.CompletionContext) => {
const word = context.matchBefore(/\w*/);
const options = [];
if (props.autoCompletionOptions && props.autoCompletionOptions.length > 0) {
for (const option of props.autoCompletionOptions) {
options.push(option);
}
}
if (props.extAutoCompletionOptions && props.extAutoCompletionOptions.length > 0) {
for (const option of props.extAutoCompletionOptions) {
options.push(option);
}
}
return {
from: word.from,
options: options,
};
};
const autoCompletion = (lang: string) => {
lang = lang || 'json';
switch (lang.toLowerCase()) {
case 'html':
return htmlLanguage.data.of({ autocomplete: autoCompletionFunction });
case 'java':
return javaLanguage.data.of({ autocomplete: autoCompletionFunction });
case 'javascript':
return javascriptLanguage.data.of({ autocomplete: autoCompletionFunction });
case 'json':
return jsonLanguage.data.of({ autocomplete: autoCompletionFunction });
case 'sql':
return javaLanguage.data.of({ autocomplete: autoCompletionFunction });
case 'xml':
return xmlLanguage.data.of({ autocomplete: autoCompletionFunction });
default:
return jsonLanguage.data.of({ autocomplete: autoCompletionFunction });
}
};
const codemirrorRef = ref(); const codemirrorRef = ref();
// q-field stack-label field label // q-field stack-label field label
// field , label // field , label
@ -243,6 +296,10 @@ onMounted(() => {
height: props.height ? Tools.px(props.height) : props.rows * 22 + 'px', height: props.height ? Tools.px(props.height) : props.rows * 22 + 'px',
}, },
}), }),
// java
autoCompletion(props.lang),
//
PlaceholderPlugin,
// , , blur // , , blur
EditorView.updateListener.of(function (e) { EditorView.updateListener.of(function (e) {
// emits('update:modelValue', e.state.doc.toString()); // emits('update:modelValue', e.state.doc.toString());
@ -321,3 +378,4 @@ defineExpose({
configure, configure,
}); });
</script> </script>
./w-code-mirror/GroovyFunctions

81
io.sc.platform.core.frontend/src/platform/components/form/elements/WListGrid.vue

@ -0,0 +1,81 @@
<template>
<div v-show="showIfComputed">
<w-grid ref="gridRef" v-bind="attrs"></w-grid>
</div>
</template>
<script setup lang="ts">
import { computed, defineProps, useAttrs, ref, watch } from 'vue';
const attrs = useAttrs();
const rules = attrs.rules;
const props = defineProps({
onChange: {
type: Function,
default: () => {},
},
modelValue: { type: String, default: undefined },
showIf: {
type: Function,
default: () => {
return true;
},
},
disableIf: {
type: Function,
default: () => {
return false;
},
},
form: {
type: Object,
default: undefined,
},
});
const emit = defineEmits(['update:modelValue', 'change']);
const gridRef =ref();
const gridValue = ref(props.modelValue);
watch(
() => props.modelValue,
(newVal, oldVal) => {
gridValue.value = newVal;
},
);
const rulesComputed = computed(() => {
let result = rules || <any>[];
if (!showIfComputed.value) {
result = [];
}
return result;
});
const showIfComputed = computed(() => {
return props.showIf({
value: gridValue.value,
form: props.form,
});
});
const disableIfComputed = computed(() => {
if (props.form && props.form.getStatus() === 'view') {
return true;
}
return props.disableIf({
value: gridValue.value,
form: props.form,
});
});
const updateModelValue = (value) => {
emit('update:modelValue', value, props.form);
changeValue(value);
};
const changeValue = (value) => {
emit('change', {
value: value,
form: props.form,
});
};
</script>

84
io.sc.platform.core.frontend/src/platform/components/form/elements/w-code-mirror/PlaceholderPlugin.ts

@ -0,0 +1,84 @@
import { EditorView, ViewPlugin, ViewUpdate, MatchDecorator, Decoration, DecorationSet, WidgetType } from '@codemirror/view';
class PlaceholderWidget extends WidgetType {
constructor(name) {
super();
this.name = name;
}
eq(other) {
return this.name == other.name;
}
toDOM() {
const elt = document.createElement('span');
elt.setAttribute('placeholder', true);
elt.style.cssText = `
border: 1px solid gray;
border-radius: 4px;
padding: 2px 2px;
`;
elt.textContent = this.name;
return elt;
}
ignoreEvent() {
return false;
}
}
const placeholderMatcher = new MatchDecorator({
regexp: /\$\{(.+?)\}/g,
decoration: (match) =>
Decoration.replace({
widget: new PlaceholderWidget(match[1]),
}),
});
const placeholderPlugin = ViewPlugin.fromClass(
class {
placeholders: DecorationSet;
constructor(view: EditorView) {
this.placeholders = placeholderMatcher.createDeco(view);
}
update(update: ViewUpdate) {
this.placeholders = placeholderMatcher.updateDeco(update, this.placeholders);
}
},
{
decorations: (instance) => instance.placeholders,
provide: (plugin) =>
EditorView.atomicRanges.of((view) => {
return view.plugin(plugin)?.placeholders || Decoration.none;
}),
eventHandlers: {
mouseover: (e, view) => {
const target = e.target as HTMLElement;
if (target.tagName.toLowerCase() === 'span' && target.getAttribute('placeholder')) {
target.style.cssText = `
border: 1px solid gray;
border-radius: 4px;
padding: 2px 2px;
background: orange;
`;
}
},
mouseout: (e, view) => {
const target = e.target as HTMLElement;
if (target.tagName.toLowerCase() === 'span' && target.getAttribute('placeholder')) {
target.style.cssText = `
border: 1px solid gray;
border-radius: 4px;
padding: 2px 2px;
`;
}
},
contextmenu: (e, view) => {
e.preventDefault();
console.log(view);
},
},
},
);
export default placeholderPlugin;

12
io.sc.platform.core.frontend/src/platform/plugin/axios.ts

@ -4,6 +4,7 @@ import { i18n } from './i18n';
import { PConst } from '@/platform/PConst'; import { PConst } from '@/platform/PConst';
import { Environment } from '@/platform/plugin/environment'; import { Environment } from '@/platform/plugin/environment';
import { NotifyManager } from './manager'; import { NotifyManager } from './manager';
import { QuasarTools } from '@/platform/utils';
const ignoredUrls: string[] = [PConst.API_I18N_MESSAGES_URL, PConst.API_APP_CONFIGURE_URL]; const ignoredUrls: string[] = [PConst.API_I18N_MESSAGES_URL, PConst.API_APP_CONFIGURE_URL];
const gc = Environment.getConfigure(); const gc = Environment.getConfigure();
@ -22,6 +23,14 @@ const requestInterceptor = (config: any) => {
if (gc.axios?.basicAuth?.enable) { if (gc.axios?.basicAuth?.enable) {
result.headers.Authorization = 'Basic ' + window.btoa(gc.axios.basicAuth.username + ':' + gc.axios.basicAuth.password); result.headers.Authorization = 'Basic ' + window.btoa(gc.axios.basicAuth.username + ':' + gc.axios.basicAuth.password);
} }
// 如果请求时传入 { loading: true } 属性, 则自动显示 "正在处理..., 请等待" 模态对话框
if (config?.loading) {
QuasarTools.getQuasar()?.loading?.show({
message: i18n.global.t('loading'),
boxClass: 'bg-grey-2 text-grey-9',
spinnerColor: 'primary',
});
}
return result; return result;
}; };
@ -33,11 +42,13 @@ const requestErrorInterceptor = (error: any) => {
// 响应拦截器 // 响应拦截器
const responseInterceptor = (response: any) => { const responseInterceptor = (response: any) => {
// 请求成功, 进入该方法说明 response 的状态码为 2xx // 请求成功, 进入该方法说明 response 的状态码为 2xx
QuasarTools.getQuasar()?.loading?.hide();
return response.data; return response.data;
}; };
// 响应错误拦截器 // 响应错误拦截器
const responseErrorInterceptor = (error: any) => { const responseErrorInterceptor = (error: any) => {
QuasarTools.getQuasar()?.loading?.hide();
// 请求失败, 进入该方法说明 response 的状态码不为 2xx // 请求失败, 进入该方法说明 response 的状态码不为 2xx
if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') { if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') {
// 发生网络错误 // 发生网络错误
@ -94,6 +105,7 @@ const noErrorAxios = Axios.create({
}); });
noErrorAxios.interceptors.request.use(requestInterceptor, requestErrorInterceptor); noErrorAxios.interceptors.request.use(requestInterceptor, requestErrorInterceptor);
noErrorAxios.interceptors.response.use(responseInterceptor, (error: any) => { noErrorAxios.interceptors.response.use(responseInterceptor, (error: any) => {
QuasarTools.getQuasar()?.loading?.hide();
// 请求失败, 进入该方法说明 response 的状态码不为 2xx // 请求失败, 进入该方法说明 response 的状态码不为 2xx
if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') { if (error.code === 'ECONNABORTED' || error.message.indexOf('timeout') !== -1 || error.message === 'Network Error') {
// 发生网络错误 // 发生网络错误

18
io.sc.platform.core.frontend/src/platform/utils/QuasarTools.ts

@ -5,6 +5,24 @@ import { Environment } from '@/platform/plugin/environment';
* Quasar * Quasar
*/ */
class QuasarTools { class QuasarTools {
static #quasar: any = null;
/**
* quasar
* @returns quasar
*/
public static getQuasar() {
return QuasarTools.#quasar;
}
/**
* quasar
* @param quasar quasar
*/
public static setQuasar(quasar: any) {
QuasarTools.#quasar = quasar;
}
/** /**
* quasar CSS * quasar CSS
* @param key * @param key

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

@ -52,6 +52,32 @@
} }
}, },
{
"name": "route.testcase.codemirror",
"path": "testcase/codemirror",
"parent": "/",
"priority": 0,
"component": "component.testcase.codemirror",
"componentPath": "@/views/testcase/code-mirror/code-mirror.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/loading/**/*"]
}
},
{
"name": "route.testcase.loading",
"path": "testcase/loading",
"parent": "/",
"priority": 0,
"component": "component.testcase.loading",
"componentPath": "@/views/testcase/loading/loading.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/loading/**/*"]
}
},
{ {
"name": "route.testcase.excel", "name": "route.testcase.excel",
"path": "testcase/excel", "path": "testcase/excel",

43
io.sc.platform.core.frontend/src/views/testcase/code-mirror/GroovyFunctions.ts

@ -0,0 +1,43 @@
const GroovyFunctions = [
{ label: 'PI', type: 'constant', apply: 'PI', detail: '常量 π' },
{ label: 'E', type: 'constant', apply: 'E', detail: '常量 e' },
{ label: 'IEEEremainder(v1,v2)', type: 'function', apply: 'IEEEremainder(v1,v2)', detail: '根据 IEEE 754 标准返回 v1 除以 v2 的余数' },
{ label: 'abs(v)', type: 'function', apply: 'abs(v)', detail: '绝对值' },
{ label: 'acos(v)', type: 'function', apply: 'acos(v)', detail: '反余弦' },
{ label: 'asin(v)', type: 'function', apply: 'asin(v)', detail: '反正弦' },
{ label: 'atan(v)', type: 'function', apply: 'atan(v)', detail: '' },
{ label: 'atan2(v)', type: 'function', apply: 'atan2(v)', detail: '' },
{ label: 'cbrt(v)', type: 'function', apply: 'cbrt(v)', detail: '' },
{ label: 'ceil(v)', type: 'function', apply: 'ceil(v)', detail: '' },
{ label: 'cos(v)', type: 'function', apply: 'cos(v)', detail: '' },
{ label: 'cosh(v)', type: 'function', apply: 'cosh(v)', detail: '' },
{ label: 'exp(v)', type: 'function', apply: 'exp(v)', detail: '' },
{ label: 'expm1(v)', type: 'function', apply: 'expm1(v)', detail: '' },
{ label: 'floor(v)', type: 'function', apply: 'floor(v)', detail: '' },
{ label: 'inverseNormalDistributioin(x)', type: 'function', apply: 'inverseNormalDistributioin(x)', detail: '' },
{ label: 'join(split,s1,s2,s3...,sn)', type: 'function', apply: 'join(split,s1,s2,s3...,sn)', detail: '' },
{ label: 'ln(v)', type: 'function', apply: 'ln(v)', detail: '' },
{ label: 'max(v1,v2,...)', type: 'function', apply: 'max(v1,v2,...)', detail: '' },
{ label: 'min(v1,v2,...)', type: 'function', apply: 'min(v1,v2,...)', detail: '' },
{ label: 'normalDistributioin(x)', type: 'function', apply: 'normalDistributioin(x)', detail: '' },
{ label: 'pow(x,y)', type: 'function', apply: 'pow(x,y)', detail: '' },
{ label: 'random()', type: 'function', apply: 'random()', detail: '' },
{ label: 'rint(v)', type: 'function', apply: 'rint(v)', detail: '' },
{ label: 'round(v)', type: 'function', apply: 'round(v)', detail: '' },
{ label: 'sin(v)', type: 'function', apply: 'sin(v)', detail: '' },
{ label: 'sinh(v)', type: 'function', apply: 'sinh(v)', detail: '' },
{ label: 'sqrt(v)', type: 'function', apply: 'sqrt(v)', detail: '' },
{ label: 'sum(v1,v2,...)', type: 'function', apply: 'sum(v1,v2,...)', detail: '' },
{ label: 'tan(v)', type: 'function', apply: 'tan(v)', detail: '' },
{ label: 'tanh(v)', type: 'function', apply: 'tanh(v)', detail: '' },
{ label: 'toDegrees(v)', type: 'function', apply: 'toDegrees(v)', detail: '' },
{ label: 'toRadians(v)', type: 'function', apply: 'toRadians(v)', detail: '' },
{
label: 'transformSequencing(value,sourceMin,sourceMax,targetMin,targetMax)',
type: 'function',
apply: 'transformSequencing(value,sourceMin,sourceMax,targetMin,targetMax)',
detail: '',
},
];
export default GroovyFunctions;

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

@ -0,0 +1,525 @@
<template>
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.processor.grid.title')"
dense-body
class="px-1"
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/model/parameter/processor/findByParameterId?parameterId=' + parameter.id)"
:data-url="Environment.apiContextPath('/api/re/model/parameter/processor')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
[
{
extend: 'add',
click: undefined,
},
{
extend: 'add',
name: 'optionValue',
label: Formater.enum(Enums.ProcessorType)('OPTION_VALUE'),
icon: 'bi-card-list',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'OPTION_VALUE');
},
},
{
extend: 'add',
name: 'arithmetic',
label: Formater.enum(Enums.ProcessorType)('ARITHMETIC'),
icon: 'bi-calculator',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'ARITHMETIC');
},
},
{
extend: 'add',
name: 'ternary',
label: Formater.enum(Enums.ProcessorType)('TERNARY'),
icon: 'bi-question',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'TERNARY');
},
},
{
extend: 'add',
name: 'whenThen',
label: Formater.enum(Enums.ProcessorType)('WHEN_THEN'),
icon: 'bi-sliders',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'WHEN_THEN');
},
},
{
extend: 'add',
name: 'numberRange',
label: Formater.enum(Enums.ProcessorType)('NUMBER_RANGE'),
icon: 'bi-justify',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'NUMBER_RANGE');
},
},
{
extend: 'add',
name: 'conditionRange',
label: Formater.enum(Enums.ProcessorType)('CONDITION_RANGE'),
icon: 'bi-rainbow',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'CONDITION_RANGE');
},
},
{
extend: 'add',
name: 'decisionTable2c',
label: Formater.enum(Enums.ProcessorType)('DECISION_TABLE_2C'),
icon: 'bi-grid-3x2',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE_2C');
},
},
{
extend: 'add',
name: 'decisionTable',
label: Formater.enum(Enums.ProcessorType)('DECISION_TABLE'),
icon: 'bi-grid-3x3',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE');
},
},
{
extend: 'add',
name: 'decisionTree',
label: Formater.enum(Enums.ProcessorType)('DECISION_TREE'),
icon: 'bi-tree',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'DECISION_TREE');
},
},
{
extend: 'add',
name: 'executionFlow',
label: Formater.enum(Enums.ProcessorType)('EXECUTION_FLOW'),
icon: 'bi-bounding-box-circles',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'EXECUTION_FLOW');
},
},
{
extend: 'add',
name: 'pmml',
label: Formater.enum(Enums.ProcessorType)('PMML'),
icon: 'bi-filetype-xml',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'PMML');
},
},
{
extend: 'add',
name: 'groovyScript',
label: Formater.enum(Enums.ProcessorType)('GROOVY_SCRIPT'),
icon: 'bi-code',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'GROOVY_SCRIPT');
},
},
{
extend: 'add',
name: 'sql',
label: Formater.enum(Enums.ProcessorType)('SQL'),
icon: 'bi-filetype-sql',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'SQL');
},
},
{
extend: 'add',
name: 'rule',
label: Formater.enum(Enums.ProcessorType)('RULE'),
icon: 'bi-shadows',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'RULE');
},
},
{
extend: 'add',
name: 'singleRule',
label: Formater.enum(Enums.ProcessorType)('SINGLE_RULE'),
icon: 'bi-noise-reduction',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'SINGLE_RULE');
},
},
],
'edit',
'remove',
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 80, name: 'enable', label: $t('isEnable'), align: 'center', sortable: false, format: Formater.enableTag() },
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' },
{ width: 150, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) },
{
width: '100%',
name: 'content',
label: $t('re.resources.designer.processor.grid.entity.content'),
sortable: false,
format: (value, row) => {
const type = row.type;
return '';
},
},
]"
:editor="{
dialog: {
width: '600px',
height: '400px',
},
form: {
colsNum: 1,
fields: [
{ name: 'parameter', label: 'parameter', type: 'text', defaultValue: parameter.id, hidden: true },
{ name: 'id', label: $t('id'), type: 'text', hidden: true },
{ name: 'order', label: $t('order'), type: 'number', hidden: true },
{ name: 'type', label: $t('type'), type: 'text', hidden: true },
{ name: 'description', label: $t('description'), type: 'text' },
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
{
name: 'optionCode',
label: $t('re.resources.designer.processor.grid.entity.optionCode'),
type: 'select',
options: [],
showIf: (arg) => {
return 'OPTION_VALUE' === arg.form.getFieldValue('type');
},
},
{
name: 'arithmetic',
label: $t('re.resources.designer.processor.grid.entity.arithmetic'),
type: 'code-mirror',
showIf: (arg) => {
return 'ARITHMETIC' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryCondition',
label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'),
type: 'code-mirror',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: GroovyFunctions,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryTrue',
label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryFalse',
label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'when',
label: $t('re.resources.designer.processor.grid.entity.when'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'then',
label: $t('re.resources.designer.processor.grid.entity.then'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'isWhenThenShorted',
label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'numberRange',
label: $t('re.resources.designer.processor.grid.entity.numberRange'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'NUMBER_RANGE' === arg.form.getFieldValue('type');
},
},
{
name: 'conditionRange',
label: $t('re.resources.designer.processor.grid.entity.conditionRange'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'CONDITION_RANGE' === arg.form.getFieldValue('type');
},
},
{
name: 'decisionTable2C',
label: $t('re.resources.designer.processor.grid.entity.decisionTable2C'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'DECISION_TABLE_2C' === arg.form.getFieldValue('type');
},
},
{
name: 'decisionTable',
label: $t('re.resources.designer.processor.grid.entity.decisionTable'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'DECISION_TABLE' === arg.form.getFieldValue('type');
},
},
{
name: 'decisionTree',
label: $t('re.resources.designer.processor.grid.entity.decisionTree'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'DECISION_TREE' === arg.form.getFieldValue('type');
},
},
{
name: 'executionFlow',
label: $t('re.resources.designer.processor.grid.entity.executionFlow'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'EXECUTION_FLOW' === arg.form.getFieldValue('type');
},
},
{
name: 'pmml',
label: $t('re.resources.designer.processor.grid.entity.pmml'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'PMML' === arg.form.getFieldValue('type');
},
},
{
name: 'groovyScript',
label: $t('re.resources.designer.processor.grid.entity.groovyScript'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'GROOVY_SCRIPT' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlDatasourceName',
label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sql',
label: $t('re.resources.designer.processor.grid.entity.sql'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlParameterValues',
label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlFieldMapping',
label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t(''), primaryKey: true },
{ name: 'parameter', label: $t('') },
{ name: 'description', label: $t('') },
{ name: 'order', label: $t('') },
{ name: 'enable', label: $t('') },
{ name: 'type', label: $t('') },
{ name: 'optionCode', label: $t('re.resources.designer.processor.grid.entity.optionCode') },
{ name: 'arithmetic', label: $t('re.resources.designer.processor.grid.entity.arithmetic') },
{ name: 'ternaryCondition', label: $t('re.resources.designer.processor.grid.entity.ternaryCondition') },
{ name: 'ternaryTrue', label: $t('re.resources.designer.processor.grid.entity.ternaryTrue') },
{ name: 'ternaryFalse', label: $t('re.resources.designer.processor.grid.entity.ternaryFalse') },
{ name: 'when', label: $t('re.resources.designer.processor.grid.entity.when') },
{ name: 'then', label: $t('re.resources.designer.processor.grid.entity.then') },
{ name: 'isWhenThenShorted', label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted') },
{ name: 'rule', label: $t('re.resources.designer.processor.grid.entity.rule') },
{ name: 'singleRule', label: $t('re.resources.designer.processor.grid.entity.singleRule') },
{ name: 'numberRange', label: $t('re.resources.designer.processor.grid.entity.numberRange') },
{ name: 'conditionRange', label: $t('re.resources.designer.processor.grid.entity.conditionRange') },
{ name: 'decisionTable2C', label: $t('re.resources.designer.processor.grid.entity.decisionTable2C') },
{ name: 'decisionTable', label: $t('re.resources.designer.processor.grid.entity.decisionTable') },
{ name: 'groovyScript', label: $t('re.resources.designer.processor.grid.entity.groovyScript') },
{ 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') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { Environment, Formater, EnumTools, Options } from '@/platform';
import GroovyFunctions from './GroovyFunctions';
const props = defineProps({
fetchDataUrl: { type: String, default: '' },
dataUrl: { type: String, default: '' },
});
const parameter = {
jpaVersion: null,
dataComeFrom: 'INPUT',
creator: 'admin',
createDate: '2024-06-25 11:01:38',
lastModifier: 'admin',
lastModifyDate: '2024-06-25 11:01:38',
id: '88691f14-c1ec-4d64-9727-aab6c636fe5f',
code: 'P1628257078232',
name: '是否及格',
description: null,
type: 'OUT',
valueType: 'java.lang.String',
valueTypeVersion: null,
valueScale: null,
valueRoundingMode: null,
valueTypeIsList: false,
defaultValue: null,
order: 2,
model: 'df5b4629-52e1-47aa-a7d7-0dcf7143136c',
_rowKey_: '9d6373aa-ce47-4723-8468-58eb07ed827c',
ticked: true,
selected: true,
_tickedCount: 0,
};
const emit = defineEmits<{
(e: 'rowClick', evt: Event, row: any, index: number): void;
(e: 'beforeRequestData', requestParams: URLSearchParams | any, callback: any): void;
}>();
const gridRef = ref();
const refresh = () => {
gridRef.value.refresh();
};
onMounted(() => {
gridRef.value.refresh();
});
defineExpose({
refresh,
});
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ProcessorType']);
</script>

12
io.sc.platform.core.frontend/src/views/testcase/loading/loading.vue

@ -0,0 +1,12 @@
<template>
<div class="q-pa-md">
<q-btn color="purple" label="Show Loading" @click="showLoading" />
</div>
</template>
<script setup lang="ts">
import { axios, Environment } from '@/platform';
const showLoading = () => {
axios.post(Environment.apiContextPath('/api/re/resource/createExample'), [], { loading: true }).then(() => {});
};
</script>

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

@ -1,6 +1,6 @@
{ {
"name": "platform-core", "name": "platform-core",
"version": "8.1.231", "version": "8.1.237",
"description": "前端核心包,用于快速构建前端的脚手架", "description": "前端核心包,用于快速构建前端的脚手架",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -104,7 +104,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.231", "platform-core": "8.1.237",
"quasar": "2.15.3", "quasar": "2.15.3",
"tailwindcss": "3.4.3", "tailwindcss": "3.4.3",
"vue": "3.4.24", "vue": "3.4.24",

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

@ -6,6 +6,8 @@ import component_testcase_openNoMenuRoute from '@/views/testcase/route/OpenNoMen
import component_testcase_noMenuRoute from '@/views/testcase/route/NoMenuRoute.vue'; import component_testcase_noMenuRoute from '@/views/testcase/route/NoMenuRoute.vue';
import component_testcase_mathEditor from '@/views/testcase/math/MathEditor.vue'; import component_testcase_mathEditor from '@/views/testcase/math/MathEditor.vue';
import component_testcase_form from '@/views/testcase/form/form.vue'; import component_testcase_form from '@/views/testcase/form/form.vue';
import component_testcase_codemirror from '@/views/testcase/code-mirror/code-mirror.vue';
import component_testcase_loading from '@/views/testcase/loading/loading.vue';
import component_testcase_excel from '@/views/testcase/excel/Excel.vue'; import component_testcase_excel from '@/views/testcase/excel/Excel.vue';
import component_testcase_word from '@/views/testcase/word/Word.vue'; import component_testcase_word from '@/views/testcase/word/Word.vue';
import component_testcase_likmDialog from '@/views/likm/Dialog.vue'; import component_testcase_likmDialog from '@/views/likm/Dialog.vue';
@ -23,6 +25,8 @@ const localComponents = {
'component.testcase.noMenuRoute': component_testcase_noMenuRoute, 'component.testcase.noMenuRoute': component_testcase_noMenuRoute,
'component.testcase.mathEditor': component_testcase_mathEditor, 'component.testcase.mathEditor': component_testcase_mathEditor,
'component.testcase.form': component_testcase_form, 'component.testcase.form': component_testcase_form,
'component.testcase.codemirror': component_testcase_codemirror,
'component.testcase.loading': component_testcase_loading,
'component.testcase.excel': component_testcase_excel, 'component.testcase.excel': component_testcase_excel,
'component.testcase.word': component_testcase_word, 'component.testcase.word': component_testcase_word,
'component.testcase.likmDialog': component_testcase_likmDialog, 'component.testcase.likmDialog': component_testcase_likmDialog,

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

@ -3,6 +3,8 @@
"menu.testcase.openNoMenuRoute": "Open No Menu Route", "menu.testcase.openNoMenuRoute": "Open No Menu Route",
"menu.testcase.mathEditor": "Math Formual Editor", "menu.testcase.mathEditor": "Math Formual Editor",
"menu.testcase.form":"Form Element", "menu.testcase.form":"Form Element",
"menu.testcase.codemirror":"Code Mirror",
"menu.testcase.loading":"Loading",
"menu.testcase.excel": "Excel", "menu.testcase.excel": "Excel",
"menu.testcase.word": "Word", "menu.testcase.word": "Word",

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

@ -3,6 +3,8 @@
"menu.testcase.openNoMenuRoute": "打開無關聯菜單的路由", "menu.testcase.openNoMenuRoute": "打開無關聯菜單的路由",
"menu.testcase.mathEditor": "數學公式編輯器", "menu.testcase.mathEditor": "數學公式編輯器",
"menu.testcase.form":"表單元素", "menu.testcase.form":"表單元素",
"menu.testcase.codemirror":"代碼編輯器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel", "menu.testcase.excel": "Excel",
"menu.testcase.word": "Word", "menu.testcase.word": "Word",

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

@ -3,6 +3,8 @@
"menu.testcase.openNoMenuRoute": "打开无关联菜单的路由示例", "menu.testcase.openNoMenuRoute": "打开无关联菜单的路由示例",
"menu.testcase.mathEditor": "数学公式编辑器", "menu.testcase.mathEditor": "数学公式编辑器",
"menu.testcase.form":"表单元素", "menu.testcase.form":"表单元素",
"menu.testcase.codemirror":"代码编辑器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel", "menu.testcase.excel": "Excel",
"menu.testcase.word": "Word", "menu.testcase.word": "Word",

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

@ -45,6 +45,24 @@
"icon": "bi-palette", "icon": "bi-palette",
"routeName": "route.testcase.form" "routeName": "route.testcase.form"
}, },
{
"type": "ROUTE",
"order": 350,
"parentId": "menu.testcase",
"id": "menu.testcase.codemirror",
"titleI18nKey": "menu.testcase.codemirror",
"icon": "bi-palette",
"routeName": "route.testcase.codemirror"
},
{
"type": "ROUTE",
"order": 350,
"parentId": "menu.testcase",
"id": "menu.testcase.loading",
"titleI18nKey": "menu.testcase.loading",
"icon": "bi-palette",
"routeName": "route.testcase.loading"
},
{ {
"type": "ROUTE", "type": "ROUTE",
"order": 400, "order": 400,

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

@ -52,6 +52,32 @@
} }
}, },
{
"name": "route.testcase.codemirror",
"path": "testcase/codemirror",
"parent": "/",
"priority": 0,
"component": "component.testcase.codemirror",
"componentPath": "@/views/testcase/code-mirror/code-mirror.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/loading/**/*"]
}
},
{
"name": "route.testcase.loading",
"path": "testcase/loading",
"parent": "/",
"priority": 0,
"component": "component.testcase.loading",
"componentPath": "@/views/testcase/loading/loading.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/loading/**/*"]
}
},
{ {
"name": "route.testcase.excel", "name": "route.testcase.excel",
"path": "testcase/excel", "path": "testcase/excel",

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

@ -0,0 +1,43 @@
const GroovyFunctions = [
{ label: 'PI', type: 'constant', apply: 'PI', detail: '常量 π' },
{ label: 'E', type: 'constant', apply: 'E', detail: '常量 e' },
{ label: 'IEEEremainder(v1,v2)', type: 'function', apply: 'IEEEremainder(v1,v2)', detail: '根据 IEEE 754 标准返回 v1 除以 v2 的余数' },
{ label: 'abs(v)', type: 'function', apply: 'abs(v)', detail: '绝对值' },
{ label: 'acos(v)', type: 'function', apply: 'acos(v)', detail: '反余弦' },
{ label: 'asin(v)', type: 'function', apply: 'asin(v)', detail: '反正弦' },
{ label: 'atan(v)', type: 'function', apply: 'atan(v)', detail: '' },
{ label: 'atan2(v)', type: 'function', apply: 'atan2(v)', detail: '' },
{ label: 'cbrt(v)', type: 'function', apply: 'cbrt(v)', detail: '' },
{ label: 'ceil(v)', type: 'function', apply: 'ceil(v)', detail: '' },
{ label: 'cos(v)', type: 'function', apply: 'cos(v)', detail: '' },
{ label: 'cosh(v)', type: 'function', apply: 'cosh(v)', detail: '' },
{ label: 'exp(v)', type: 'function', apply: 'exp(v)', detail: '' },
{ label: 'expm1(v)', type: 'function', apply: 'expm1(v)', detail: '' },
{ label: 'floor(v)', type: 'function', apply: 'floor(v)', detail: '' },
{ label: 'inverseNormalDistributioin(x)', type: 'function', apply: 'inverseNormalDistributioin(x)', detail: '' },
{ label: 'join(split,s1,s2,s3...,sn)', type: 'function', apply: 'join(split,s1,s2,s3...,sn)', detail: '' },
{ label: 'ln(v)', type: 'function', apply: 'ln(v)', detail: '' },
{ label: 'max(v1,v2,...)', type: 'function', apply: 'max(v1,v2,...)', detail: '' },
{ label: 'min(v1,v2,...)', type: 'function', apply: 'min(v1,v2,...)', detail: '' },
{ label: 'normalDistributioin(x)', type: 'function', apply: 'normalDistributioin(x)', detail: '' },
{ label: 'pow(x,y)', type: 'function', apply: 'pow(x,y)', detail: '' },
{ label: 'random()', type: 'function', apply: 'random()', detail: '' },
{ label: 'rint(v)', type: 'function', apply: 'rint(v)', detail: '' },
{ label: 'round(v)', type: 'function', apply: 'round(v)', detail: '' },
{ label: 'sin(v)', type: 'function', apply: 'sin(v)', detail: '' },
{ label: 'sinh(v)', type: 'function', apply: 'sinh(v)', detail: '' },
{ label: 'sqrt(v)', type: 'function', apply: 'sqrt(v)', detail: '' },
{ label: 'sum(v1,v2,...)', type: 'function', apply: 'sum(v1,v2,...)', detail: '' },
{ label: 'tan(v)', type: 'function', apply: 'tan(v)', detail: '' },
{ label: 'tanh(v)', type: 'function', apply: 'tanh(v)', detail: '' },
{ label: 'toDegrees(v)', type: 'function', apply: 'toDegrees(v)', detail: '' },
{ label: 'toRadians(v)', type: 'function', apply: 'toRadians(v)', detail: '' },
{
label: 'transformSequencing(value,sourceMin,sourceMax,targetMin,targetMax)',
type: 'function',
apply: 'transformSequencing(value,sourceMin,sourceMax,targetMin,targetMax)',
detail: '',
},
];
export default GroovyFunctions;

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

@ -0,0 +1,525 @@
<template>
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.processor.grid.title')"
dense-body
class="px-1"
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/model/parameter/processor/findByParameterId?parameterId=' + parameter.id)"
:data-url="Environment.apiContextPath('/api/re/model/parameter/processor')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
[
{
extend: 'add',
click: undefined,
},
{
extend: 'add',
name: 'optionValue',
label: Formater.enum(Enums.ProcessorType)('OPTION_VALUE'),
icon: 'bi-card-list',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'OPTION_VALUE');
},
},
{
extend: 'add',
name: 'arithmetic',
label: Formater.enum(Enums.ProcessorType)('ARITHMETIC'),
icon: 'bi-calculator',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'ARITHMETIC');
},
},
{
extend: 'add',
name: 'ternary',
label: Formater.enum(Enums.ProcessorType)('TERNARY'),
icon: 'bi-question',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'TERNARY');
},
},
{
extend: 'add',
name: 'whenThen',
label: Formater.enum(Enums.ProcessorType)('WHEN_THEN'),
icon: 'bi-sliders',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'WHEN_THEN');
},
},
{
extend: 'add',
name: 'numberRange',
label: Formater.enum(Enums.ProcessorType)('NUMBER_RANGE'),
icon: 'bi-justify',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'NUMBER_RANGE');
},
},
{
extend: 'add',
name: 'conditionRange',
label: Formater.enum(Enums.ProcessorType)('CONDITION_RANGE'),
icon: 'bi-rainbow',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'CONDITION_RANGE');
},
},
{
extend: 'add',
name: 'decisionTable2c',
label: Formater.enum(Enums.ProcessorType)('DECISION_TABLE_2C'),
icon: 'bi-grid-3x2',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE_2C');
},
},
{
extend: 'add',
name: 'decisionTable',
label: Formater.enum(Enums.ProcessorType)('DECISION_TABLE'),
icon: 'bi-grid-3x3',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE');
},
},
{
extend: 'add',
name: 'decisionTree',
label: Formater.enum(Enums.ProcessorType)('DECISION_TREE'),
icon: 'bi-tree',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'DECISION_TREE');
},
},
{
extend: 'add',
name: 'executionFlow',
label: Formater.enum(Enums.ProcessorType)('EXECUTION_FLOW'),
icon: 'bi-bounding-box-circles',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'EXECUTION_FLOW');
},
},
{
extend: 'add',
name: 'pmml',
label: Formater.enum(Enums.ProcessorType)('PMML'),
icon: 'bi-filetype-xml',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'PMML');
},
},
{
extend: 'add',
name: 'groovyScript',
label: Formater.enum(Enums.ProcessorType)('GROOVY_SCRIPT'),
icon: 'bi-code',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'GROOVY_SCRIPT');
},
},
{
extend: 'add',
name: 'sql',
label: Formater.enum(Enums.ProcessorType)('SQL'),
icon: 'bi-filetype-sql',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'SQL');
},
},
{
extend: 'add',
name: 'rule',
label: Formater.enum(Enums.ProcessorType)('RULE'),
icon: 'bi-shadows',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'RULE');
},
},
{
extend: 'add',
name: 'singleRule',
label: Formater.enum(Enums.ProcessorType)('SINGLE_RULE'),
icon: 'bi-noise-reduction',
enableIf: (arg) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'SINGLE_RULE');
},
},
],
'edit',
'remove',
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 80, name: 'enable', label: $t('isEnable'), align: 'center', sortable: false, format: Formater.enableTag() },
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' },
{ width: 150, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) },
{
width: '100%',
name: 'content',
label: $t('re.resources.designer.processor.grid.entity.content'),
sortable: false,
format: (value, row) => {
const type = row.type;
return '';
},
},
]"
:editor="{
dialog: {
width: '600px',
height: '400px',
},
form: {
colsNum: 1,
fields: [
{ name: 'parameter', label: 'parameter', type: 'text', defaultValue: parameter.id, hidden: true },
{ name: 'id', label: $t('id'), type: 'text', hidden: true },
{ name: 'order', label: $t('order'), type: 'number', hidden: true },
{ name: 'type', label: $t('type'), type: 'text', hidden: true },
{ name: 'description', label: $t('description'), type: 'text' },
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
{
name: 'optionCode',
label: $t('re.resources.designer.processor.grid.entity.optionCode'),
type: 'select',
options: [],
showIf: (arg) => {
return 'OPTION_VALUE' === arg.form.getFieldValue('type');
},
},
{
name: 'arithmetic',
label: $t('re.resources.designer.processor.grid.entity.arithmetic'),
type: 'code-mirror',
showIf: (arg) => {
return 'ARITHMETIC' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryCondition',
label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'),
type: 'code-mirror',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: GroovyFunctions,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryTrue',
label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryFalse',
label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'when',
label: $t('re.resources.designer.processor.grid.entity.when'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'then',
label: $t('re.resources.designer.processor.grid.entity.then'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'isWhenThenShorted',
label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'numberRange',
label: $t('re.resources.designer.processor.grid.entity.numberRange'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'NUMBER_RANGE' === arg.form.getFieldValue('type');
},
},
{
name: 'conditionRange',
label: $t('re.resources.designer.processor.grid.entity.conditionRange'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'CONDITION_RANGE' === arg.form.getFieldValue('type');
},
},
{
name: 'decisionTable2C',
label: $t('re.resources.designer.processor.grid.entity.decisionTable2C'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'DECISION_TABLE_2C' === arg.form.getFieldValue('type');
},
},
{
name: 'decisionTable',
label: $t('re.resources.designer.processor.grid.entity.decisionTable'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'DECISION_TABLE' === arg.form.getFieldValue('type');
},
},
{
name: 'decisionTree',
label: $t('re.resources.designer.processor.grid.entity.decisionTree'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'DECISION_TREE' === arg.form.getFieldValue('type');
},
},
{
name: 'executionFlow',
label: $t('re.resources.designer.processor.grid.entity.executionFlow'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'EXECUTION_FLOW' === arg.form.getFieldValue('type');
},
},
{
name: 'pmml',
label: $t('re.resources.designer.processor.grid.entity.pmml'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'PMML' === arg.form.getFieldValue('type');
},
},
{
name: 'groovyScript',
label: $t('re.resources.designer.processor.grid.entity.groovyScript'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'GROOVY_SCRIPT' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlDatasourceName',
label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sql',
label: $t('re.resources.designer.processor.grid.entity.sql'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlParameterValues',
label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlFieldMapping',
label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t(''), primaryKey: true },
{ name: 'parameter', label: $t('') },
{ name: 'description', label: $t('') },
{ name: 'order', label: $t('') },
{ name: 'enable', label: $t('') },
{ name: 'type', label: $t('') },
{ name: 'optionCode', label: $t('re.resources.designer.processor.grid.entity.optionCode') },
{ name: 'arithmetic', label: $t('re.resources.designer.processor.grid.entity.arithmetic') },
{ name: 'ternaryCondition', label: $t('re.resources.designer.processor.grid.entity.ternaryCondition') },
{ name: 'ternaryTrue', label: $t('re.resources.designer.processor.grid.entity.ternaryTrue') },
{ name: 'ternaryFalse', label: $t('re.resources.designer.processor.grid.entity.ternaryFalse') },
{ name: 'when', label: $t('re.resources.designer.processor.grid.entity.when') },
{ name: 'then', label: $t('re.resources.designer.processor.grid.entity.then') },
{ name: 'isWhenThenShorted', label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted') },
{ name: 'rule', label: $t('re.resources.designer.processor.grid.entity.rule') },
{ name: 'singleRule', label: $t('re.resources.designer.processor.grid.entity.singleRule') },
{ name: 'numberRange', label: $t('re.resources.designer.processor.grid.entity.numberRange') },
{ name: 'conditionRange', label: $t('re.resources.designer.processor.grid.entity.conditionRange') },
{ name: 'decisionTable2C', label: $t('re.resources.designer.processor.grid.entity.decisionTable2C') },
{ name: 'decisionTable', label: $t('re.resources.designer.processor.grid.entity.decisionTable') },
{ name: 'groovyScript', label: $t('re.resources.designer.processor.grid.entity.groovyScript') },
{ 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') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { Environment, Formater, EnumTools, Options } from '@/platform';
import GroovyFunctions from './GroovyFunctions';
const props = defineProps({
fetchDataUrl: { type: String, default: '' },
dataUrl: { type: String, default: '' },
});
const parameter = {
jpaVersion: null,
dataComeFrom: 'INPUT',
creator: 'admin',
createDate: '2024-06-25 11:01:38',
lastModifier: 'admin',
lastModifyDate: '2024-06-25 11:01:38',
id: '88691f14-c1ec-4d64-9727-aab6c636fe5f',
code: 'P1628257078232',
name: '是否及格',
description: null,
type: 'OUT',
valueType: 'java.lang.String',
valueTypeVersion: null,
valueScale: null,
valueRoundingMode: null,
valueTypeIsList: false,
defaultValue: null,
order: 2,
model: 'df5b4629-52e1-47aa-a7d7-0dcf7143136c',
_rowKey_: '9d6373aa-ce47-4723-8468-58eb07ed827c',
ticked: true,
selected: true,
_tickedCount: 0,
};
const emit = defineEmits<{
(e: 'rowClick', evt: Event, row: any, index: number): void;
(e: 'beforeRequestData', requestParams: URLSearchParams | any, callback: any): void;
}>();
const gridRef = ref();
const refresh = () => {
gridRef.value.refresh();
};
onMounted(() => {
gridRef.value.refresh();
});
defineExpose({
refresh,
});
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ProcessorType']);
</script>

12
io.sc.platform.core.frontend/template-project/src/views/testcase/loading/loading.vue

@ -0,0 +1,12 @@
<template>
<div class="q-pa-md">
<q-btn color="purple" label="Show Loading" @click="showLoading" />
</div>
</template>
<script setup lang="ts">
import { axios, Environment } from '@/platform';
const showLoading = () => {
axios.post(Environment.apiContextPath('/api/re/resource/createExample'), [], { loading: true }).then(() => {});
};
</script>

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

@ -228,3 +228,4 @@ cut =Cut
online=Online online=Online
offline=Offline offline=Offline
finish=Finish finish=Finish
loading=Processing, please wait ......

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

@ -228,3 +228,4 @@ cut =\u526A\u5207
online=\u5728\u7DDA online=\u5728\u7DDA
offline=\u96E2\u7DDA offline=\u96E2\u7DDA
finish=\u5B8C\u6210 finish=\u5B8C\u6210
loading=\u6B63\u5728\u8655\u7406, \u8ACB\u7B49\u5F85......

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

@ -228,3 +228,4 @@ cut =\u526A\u5207
online=\u5728\u7EBF online=\u5728\u7EBF
offline=\u79BB\u7EBF offline=\u79BB\u7EBF
finish=\u5B8C\u6210 finish=\u5B8C\u6210
loading=\u6B63\u5728\u5904\u7406, \u8BF7\u7B49\u5F85......

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

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.231", "platform-core": "8.1.232",
"quasar": "2.15.3", "quasar": "2.15.3",
"tailwindcss": "3.4.3", "tailwindcss": "3.4.3",
"vue": "3.4.24", "vue": "3.4.24",

2
io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/support/JpaEntityPersistentEvent.java

@ -6,8 +6,6 @@ import org.springframework.context.ApplicationEvent;
* Jpa * Jpa
*/ */
public class JpaEntityPersistentEvent extends ApplicationEvent{ public class JpaEntityPersistentEvent extends ApplicationEvent{
private static final long serialVersionUID = -73175079790751083L;
private Class<?> entityClass; //实体类 private Class<?> entityClass; //实体类
private JpaEntityPersistentEventType type; //类型:增删改 private JpaEntityPersistentEventType type; //类型:增删改
private Object oldEntity; //原实体对象 private Object oldEntity; //原实体对象

7
io.sc.platform.orm/src/main/java/io/sc/platform/orm/repository/DaoRepository.java

@ -9,6 +9,7 @@ import org.springframework.data.repository.NoRepositoryBean;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.ManagedType;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
@NoRepositoryBean @NoRepositoryBean
public interface DaoRepository<E,ID extends Serializable> extends JpaRepository<E,ID>,JpaSpecificationExecutor<E>{ public interface DaoRepository<E,ID extends Serializable> extends JpaRepository<E,ID>,JpaSpecificationExecutor<E>{
@ -24,4 +25,10 @@ public interface DaoRepository<E,ID extends Serializable> extends JpaRepository<
public String getIdName(); public String getIdName();
public ID getId(E entity); public ID getId(E entity);
public void setId(E entity,ID id); public void setId(E entity,ID id);
public <S extends E> S save(S entity,boolean isSendEvent);
public <S extends E> List<S> saveAll(Iterable<S> entities, boolean isSendEvent);
public void delete(E entity,boolean isSendEvent);
public void deleteInBatch(Iterable<E> entities,boolean isSendEvent);
public void deleteAllInBatch(boolean isSendEvent);
} }

144
io.sc.platform.orm/src/main/java/io/sc/platform/orm/repository/impl/DaoRepositoryImpl.java

@ -1,16 +1,28 @@
package io.sc.platform.orm.repository.impl; package io.sc.platform.orm.repository.impl;
import io.sc.platform.core.Environment;
import io.sc.platform.orm.entity.support.JpaEntityPersistentEvent;
import io.sc.platform.orm.entity.support.JpaEntityPersistentEventType;
import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.orm.service.support.ManagedTypeAttributes; import io.sc.platform.orm.service.support.ManagedTypeAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository; import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.metamodel.ManagedType; import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.SingularAttribute;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.data.jpa.repository.query.QueryUtils.DELETE_ALL_QUERY_STRING;
import static org.springframework.data.jpa.repository.query.QueryUtils.applyAndBind;
import static org.springframework.data.jpa.repository.query.QueryUtils.getQueryString;
public class DaoRepositoryImpl<E,ID extends Serializable> extends SimpleJpaRepository<E,ID> implements DaoRepository<E,ID> { public class DaoRepositoryImpl<E,ID extends Serializable> extends SimpleJpaRepository<E,ID> implements DaoRepository<E,ID> {
private JpaEntityInformation<E, ID> jpaEntityInformation; private JpaEntityInformation<E, ID> jpaEntityInformation;
@ -82,4 +94,136 @@ public class DaoRepositoryImpl<E,ID extends Serializable> extends SimpleJpaRepos
wrapper.setPropertyValue(idName, id); wrapper.setPropertyValue(idName, id);
} }
} }
@Override
@Transactional
public <S extends E> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (jpaEntityInformation.isNew(entity)) {
entityManager.persist(entity);
applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.AFTER_ADD,null, entity));
return entity;
} else if("".equals(getId(entity))){//当单一主键为空字符串时,也认为需要新增
setId(entity,null);
entityManager.persist(entity);
applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.AFTER_ADD,null, entity));
return entity;
}else {
E oldEntity = this.getReferenceById(getId(entity));
applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(), JpaEntityPersistentEventType.BEFORE_UPDATE, oldEntity, entity));
S result = entityManager.merge(entity);
return result;
}
}
@Override
@Transactional
public <S extends E> S save(S entity, boolean isSendEvent) {
if (jpaEntityInformation.isNew(entity)) {
entityManager.persist(entity);
if(isSendEvent) {applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.AFTER_ADD,null, entity));}
return entity;
} else if("".equals(getId(entity))){//当单一主键为空字符串时,也认为需要新增
setId(entity,null);
entityManager.persist(entity);
if(isSendEvent) {applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.AFTER_ADD,null, entity));}
return entity;
}else {
E oldEntity =this.getReferenceById(getId(entity));
if(isSendEvent) {applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.BEFORE_UPDATE,oldEntity, entity));}
S result =entityManager.merge(entity);
return result;
}
}
@Override
@Transactional
public <S extends E> List<S> saveAll(Iterable<S> entities, boolean isSendEvent) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
List<S> result = new ArrayList<S>();
if(isSendEvent) {
for (S entity : entities) {
result.add(save(entity));
}
}else {
for (S entity : entities) {
result.add(save(entity,false));
}
}
return result;
}
@Override
@Transactional
public void delete(E entity) {
Assert.notNull(entity, "The entity must not be null!");
applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.BEFORE_DELETE,entity, null));
entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity));
}
@Override
@Transactional
public void delete(E entity,boolean isSendEvent) {
Assert.notNull(entity, "The entity must not be null!");
if(isSendEvent) {
applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.BEFORE_DELETE,entity, null));
}
entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity));
}
@Override
@Transactional
public void deleteInBatch(Iterable<E> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
if (!entities.iterator().hasNext()) {
return;
}
E entity =entities.iterator().next();
applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.BEFORE_DELETE,entities, null));
applyAndBind(getQueryString(DELETE_ALL_QUERY_STRING, jpaEntityInformation.getEntityName()), entities, entityManager)
.executeUpdate();
}
@Override
@Transactional
public void deleteInBatch(Iterable<E> entities,boolean isSendEvent) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
if (!entities.iterator().hasNext()) {
return;
}
E entity =entities.iterator().next();
if(isSendEvent) {
applicationContext().publishEvent(new JpaEntityPersistentEvent(entity.getClass(),JpaEntityPersistentEventType.BEFORE_DELETE,entities, null));
}
applyAndBind(getQueryString(DELETE_ALL_QUERY_STRING, jpaEntityInformation.getEntityName()), entities, entityManager)
.executeUpdate();
}
@Override
@Transactional
public void deleteAllInBatch() {
String entityName =jpaEntityInformation.getEntityName();
Assert.hasText(entityName, "Entity name must not be null or empty!");
applicationContext().publishEvent(new JpaEntityPersistentEvent(jpaEntityInformation.getJavaType(),JpaEntityPersistentEventType.BEFORE_DELETE_ALL,null, null));
String sql =String.format("delete from %s x", entityName);
entityManager.createQuery(sql).executeUpdate();
}
@Override
@Transactional
public void deleteAllInBatch(boolean isSendEvent) {
String entityName =jpaEntityInformation.getEntityName();
Assert.hasText(entityName, "Entity name must not be null or empty!");
if(isSendEvent) {
applicationContext().publishEvent(new JpaEntityPersistentEvent(jpaEntityInformation.getJavaType(),JpaEntityPersistentEventType.BEFORE_DELETE_ALL,null, null));
}
String sql =String.format("delete from %s x", entityName);
entityManager.createQuery(sql).executeUpdate();
}
private ApplicationContext applicationContext(){
return Environment.getInstance().getApplicationContext();
}
} }

10
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/impl/DaoServiceImpl.java

@ -2,6 +2,8 @@ package io.sc.platform.orm.service.impl;
import io.sc.platform.core.Environment; import io.sc.platform.core.Environment;
import io.sc.platform.orm.entity.CorporationAuditorEntity; import io.sc.platform.orm.entity.CorporationAuditorEntity;
import io.sc.platform.orm.entity.support.JpaEntityPersistentEvent;
import io.sc.platform.orm.entity.support.JpaEntityPersistentEventType;
import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.orm.service.DaoService; import io.sc.platform.orm.service.DaoService;
import io.sc.platform.orm.service.support.*; import io.sc.platform.orm.service.support.*;
@ -254,10 +256,14 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
if(oldObject!=null){ // 找到,表示已经存在 if(oldObject!=null){ // 找到,表示已经存在
if(repository.getId(oldObject).equals(id)) { //主键相同,直接更新 if(repository.getId(oldObject).equals(id)) { //主键相同,直接更新
if(oldObject.getClass().equals(entity.getClass())){ if(oldObject.getClass().equals(entity.getClass())){
//在更新原对象之前发送事件,因为以下操作会将原对象进行修改
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(), JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
copyEntityValues(oldObject,entity); copyEntityValues(oldObject,entity);
setCorporation(oldObject); setCorporation(oldObject);
return repository.save(oldObject); return repository.save(oldObject);
}else{ }else{
//在更新原对象之前发送事件,因为以下操作会将原对象进行修改
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(),JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
repository.delete(oldObject); repository.delete(oldObject);
repository.flush();//注意,此处必须通过 flush() 方法使得上面的 delete 生效,但不会进行事务提交 repository.flush();//注意,此处必须通过 flush() 方法使得上面的 delete 生效,但不会进行事务提交
setCorporation(entity); setCorporation(entity);
@ -269,10 +275,14 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
}else{ // 通过唯一约束规则未找到记录, 表示修改了唯一约束的值 }else{ // 通过唯一约束规则未找到记录, 表示修改了唯一约束的值
oldObject =repository.getReferenceById(id); oldObject =repository.getReferenceById(id);
if(oldObject.getClass().equals(entity.getClass())){ if(oldObject.getClass().equals(entity.getClass())){
//在更新原对象之前发送事件,因为以下操作会将原对象进行删除
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(),JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
copyEntityValues(oldObject,entity); copyEntityValues(oldObject,entity);
setCorporation(oldObject); setCorporation(oldObject);
return repository.save(oldObject); return repository.save(oldObject);
}else{ }else{
//在更新原对象之前发送事件,因为以下操作会将原对象进行删除
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(),JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
repository.delete(oldObject); repository.delete(oldObject);
repository.flush();//注意,此处必须通过 flush() 方法使得上面的 delete 生效,但不会进行事务提交 repository.flush();//注意,此处必须通过 flush() 方法使得上面的 delete 生效,但不会进行事务提交
setCorporation(entity); setCorporation(entity);

Loading…
Cancel
Save