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. 14
      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. 141
      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. 13
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterWebController.java
  27. 21
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/ParameterProcessorEntity.java
  28. 12
      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. 3
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  58. 3
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  59. 3
      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. 146
      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.executor"),
// project(":io.sc.engine.mv"),
// project(":io.sc.engine.mv.frontend"),
// project(":io.sc.engine.mv.sample"),
//
// project(":io.sc.engine.rule.client"),
// project(":io.sc.engine.rule.client.spring"),
// project(":io.sc.engine.rule.core"),
// project(":io.sc.engine.rule.server"),
// project(":io.sc.engine.rule.sample"),
//
project(":io.sc.engine.mv"),
project(":io.sc.engine.mv.frontend"),
project(":io.sc.engine.mv.sample"),
project(":io.sc.engine.rule.client"),
project(":io.sc.engine.rule.client.spring"),
project(":io.sc.engine.rule.core"),
project(":io.sc.engine.rule.server"),
project(":io.sc.engine.rule.sample"),
project(":io.sc.engine.st"),
project(":io.sc.engine.st.frontend"),
project(":erm"),
project(":erm.frontend"),
// project(":erm"),
// project(":erm.frontend"),
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) {
if(varName!=null) {
if(fieldName!=null) {
return "${" + varName + "." + fieldName + "}";
//return "${" + varName + "." + fieldName + "}";
return varName + "." + fieldName;
}else {
return "${" + varName + "}";
//return "${" + varName + "}";
return varName;
}
}
return null;

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

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.231",
"platform-core": "8.1.237",
"quasar": "2.15.3",
"tailwindcss": "3.4.3",
"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.then": "Then Expression",
"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.conditionRangeVar": "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.then": "Then 表達式",
"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.conditionRangeVar": "條件分段",
"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.then": "Then 表达式",
"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.conditionRangeVar": "条件分段",
"re.resources.designer.processor.grid.entity.conditionRange": "条件分段",

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

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

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

@ -62,6 +62,7 @@
no-caps
inline-label
align="left"
class="px-2"
@update:model-value="
(value) => {
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;

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

@ -210,9 +210,9 @@
'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: 100, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) },
{ width: 100, name: 'enable', label: $t('isEnable'), sortable: false },
{ width: 150, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) },
{
width: '100%',
name: 'content',
@ -220,15 +220,49 @@
sortable: false,
format: (value, row) => {
const type = row.type;
return '';
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 '';
}
},
},
]"
:editor="{
dialog: {
width: '600px',
height: '400px',
},
form: {
colsNum: 1,
@ -243,7 +277,7 @@
name: 'optionCode',
label: $t('re.resources.designer.processor.grid.entity.optionCode'),
type: 'select',
options: [],
options: optionOptionsRef,
showIf: (arg) => {
return 'OPTION_VALUE' === arg.form.getFieldValue('type');
},
@ -252,6 +286,10 @@
name: 'arithmetic',
label: $t('re.resources.designer.processor.grid.entity.arithmetic'),
type: 'code-mirror',
lang: 'java',
rows: 5,
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'ARITHMETIC' === arg.form.getFieldValue('type');
},
@ -260,7 +298,11 @@
name: 'ternaryCondition',
label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'),
type: 'code-mirror',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
@ -269,7 +311,11 @@
name: 'ternaryTrue',
label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'),
type: 'code-mirror',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
@ -278,7 +324,11 @@
name: 'ternaryFalse',
label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'),
type: 'code-mirror',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
@ -287,7 +337,11 @@
name: 'when',
label: $t('re.resources.designer.processor.grid.entity.when'),
type: 'code-mirror',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
@ -296,7 +350,11 @@
name: 'then',
label: $t('re.resources.designer.processor.grid.entity.then'),
type: 'code-mirror',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
@ -304,17 +362,41 @@
{
name: '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',
lang: 'java',
rows: 1,
height: '32px',
autoCompletionOptions: autoCompletionOptionsRef,
extAutoCompletionOptions: GroovyFunctions,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
return 'NUMBER_RANGE' === arg.form.getFieldValue('type');
},
},
{
name: 'numberRange',
label: $t('re.resources.designer.processor.grid.entity.numberRange'),
type: 'code-mirror',
rows: 1,
type: 'w-grid',
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) => {
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>
</template>
<script setup lang="ts">
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({
fetchDataUrl: { type: String, default: '' },
@ -478,7 +595,11 @@ const emit = defineEmits<{
(e: 'rowClick', evt: Event, row: any, index: number): void;
(e: 'beforeRequestData', requestParams: URLSearchParams | any, callback: any): void;
}>();
const gridRef = ref();
const autoCompletionOptionsRef = ref([]);
const optionOptionsRef = ref([]);
const numberRangeGridRef = ref();
const 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 {
@Autowired private DictionaryEntityEventHandler dictionaryEntityEventHandler;
@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>{
private static final Logger log =LoggerFactory.getLogger(DictionaryEntityEventHandler.class);
@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>{
@Autowired private LibService libService;
@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>{
@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>{
@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>{
private static final Logger log =LoggerFactory.getLogger(LibEntityEventHandler.class);
@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>{
@Autowired private ModelService modelService;
@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>{
@Autowired private ModelService modelService;
@Autowired private ParameterProcessorService parameterProcessorService;
@ -122,8 +122,8 @@ public class ParameterEntityEventHandler extends AbstractJpaEntityPersistentEven
}
String sql ="update RE_TEST_CASE_PARAMETER set"
+ " FD_CODE=:newCode"
+ " where FD_CODE=:oldCode and FD_TEST_CASE_ID in (:testCaseIds)";
+ " CODE_=:newCode"
+ " where CODE_=:oldCode and TEST_CASE_ID_ in (:testCaseIds)";
Map<String, Object> params = new HashMap<String, Object>();
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>{
@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>{
@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>{
@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.getCode().equals(newEntity.getCode()) || !oldEntity.getName().equals(newEntity.getName())) { //资源的代码或名称不同时
String sql ="update RE_RESOURCE set"
+ " FD_CODE=?,"
+ " FD_NAME=?,"
+ " FD_LAST_MODIFYDATE=?"
+ " where FD_CODE=?";
+ " CODE_=?,"
+ " NAME_=?,"
+ " LAST_MODIFYDATE_=?"
+ " where CODE_=?";
jdbcTemplate.update(sql, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pstmt) throws SQLException {
@ -75,7 +75,7 @@ public class ResourceEntityEventHandler extends AbstractJpaEntityPersistentEvent
*/
private void deleteTestCase(ResourceEntity oldEntity) {
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() {
@Override
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>{
@Autowired private ResourceService resourceService;
@Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@ -80,8 +80,8 @@ public class ScoreCardVarEntityEventHandler extends AbstractJpaEntityPersistentE
}
String sql ="update RE_TEST_CASE_PARAMETER set"
+ " FD_CODE=:newCode"
+ " where FD_CODE=:oldCode and FD_TEST_CASE_ID in (:testCaseIds)";
+ " CODE_=:newCode"
+ " where CODE_=:oldCode and TEST_CASE_ID_ in (:testCaseIds)";
Map<String, Object> params = new HashMap<String, Object>();
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类字段实体持久化事件处理器
*/
@Service("reUserDefinedJavaClassFieldEntityEventHandler")
@Service("io.sc.engine.rule.server.jpa.listener.handler.UserDefinedJavaClassFieldEntityEventHandler")
public class UserDefinedJavaClassFieldEntityEventHandler extends AbstractJpaEntityPersistentEventHandler<UserDefinedJavaClassFieldEntity>{
@Autowired private DictionaryService dictionaryService;
@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)){
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);
}
//决策树==========================================================================================================

13
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.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.*;
/**
* 模型参数 Controller
@ -95,7 +92,13 @@ public class ParameterWebController extends RestCrudController<ParameterVo,Param
public void addIndicators(@RequestBody ParameterIndicatorsWrapper wrapper) throws Exception{
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)
@ResponseBody
public ParemterHints listParemterHintsByParameterId(@PathVariable(name="parameterId",required=true)String parameterId) throws Exception{

21
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.platform.orm.DeepClone;
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.entity.AuditorEntity;
import org.hibernate.annotations.GenericGenerator;
@ -78,16 +79,16 @@ public class ParameterProcessorEntity extends AuditorEntity<ParameterProcessorVo
protected Integer order;
@Override
public ParameterProcessorVo toVo() {
ParameterProcessorVo vo =new ParameterProcessorVo();
super.toVo(vo);
vo.setId(this.getId());
vo.setType(this.getType());
vo.setParameter(this.getParameter()==null?null:this.getParameter().getId());
vo.setDescription(this.getDescription());
vo.setEnable(this.getEnable());
vo.setOrder(this.getOrder());
return vo;
public void toVo(ParameterProcessorVo vo) {
if(vo!=null){
super.toVo(vo);
vo.setId(this.getId());
vo.setType(this.getType());
vo.setParameter(this.getParameter()==null?null:this.getParameter().getId());
vo.setDescription(this.getDescription());
vo.setEnable(this.getEnable());
vo.setOrder(this.getOrder());
}
}
public String getId() {

12
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.Locale;
import java.util.Map;
import java.util.Set;
import io.sc.engine.rule.server.model.vo.ParameterVo;
import org.springframework.web.multipart.MultipartFile;
import io.sc.engine.rule.server.model.entity.ParameterEntity;
import io.sc.engine.rule.server.model.entity.parameter.OutParameterEntity;
@ -54,7 +56,15 @@ public interface ParameterService extends DaoService<ParameterEntity, String, Pa
* @return 所在模型的参数代码和名称的映射
*/
public CodeAndNameMapping loadCodeAndNameMappingByParameterId(String parameterId);
/**
* 通过参数ID获取当前参数所属的模型的所有参数列表
* @param parameterId 参数ID
* @return 当前参数所属的模型的所有参数列表
* @throws Exception 违例
*/
public List<ParameterVo> listParemtersByParameterId(String parameterId) throws Exception;
/**
* 通过参数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.ParemterHints;
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.platform.core.Environment;
import io.sc.platform.core.util.FileUtil;
import io.sc.platform.orm.entity.support.EntityChangedEventType;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.orm.util.EntityVoUtil;
import org.dmg.pmml.DataType;
import org.dmg.pmml.PMML;
import org.jpmml.evaluator.Evaluator;
@ -335,6 +337,26 @@ public class ParameterServiceImpl extends DaoServiceImpl<ParameterEntity, String
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
public ParemterHints listParemterHintsByParameterId(String parameterId) throws Exception{
ParemterHints hints =new ParemterHints();

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

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.1.231",
"version": "8.1.237",
"description": "前端核心包,用于快速构建前端的脚手架",
"//main": "库的主文件",
"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_mathEditor from '@/views/testcase/math/MathEditor.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_word from '@/views/testcase/word/Word.vue';
import component_testcase_likmDialog from '@/views/likm/Dialog.vue';
@ -23,6 +25,8 @@ const localComponents = {
'component.testcase.noMenuRoute': component_testcase_noMenuRoute,
'component.testcase.mathEditor': component_testcase_mathEditor,
'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.word': component_testcase_word,
'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.mathEditor": "Math Formual Editor",
"menu.testcase.form":"Form Element",
"menu.testcase.codemirror":"Code Mirror",
"menu.testcase.loading":"Loading",
"menu.testcase.excel": "Excel",
"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.mathEditor": "數學公式編輯器",
"menu.testcase.form":"表單元素",
"menu.testcase.codemirror":"代碼編輯器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel",
"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.mathEditor": "数学公式编辑器",
"menu.testcase.form":"表单元素",
"menu.testcase.codemirror":"代码编辑器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel",
"menu.testcase.word": "Word",

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

@ -45,6 +45,24 @@
"icon": "bi-palette",
"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",
"order": 400,

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

@ -4,12 +4,13 @@
<script setup lang="ts">
import { useQuasar, dom, debounce } from 'quasar';
import { Environment, ApplicationInitializer, eventBus } from '@/platform';
import { Environment, ApplicationInitializer, QuasarTools, eventBus } from '@/platform';
const quasar = useQuasar();
const { ready } = dom;
ready(function () {
QuasarTools.setQuasar(quasar);
quasar?.dark?.set(Environment.getConfigure().theme.dark);
ApplicationInitializer.afterInitialized();
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 xml = ref();
const open = (container) => {
const parser = new DOMParser();
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>
</template>
<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 { FormValidators } from '@/platform/components';
import { EditorView } from '@codemirror/view';
@ -53,12 +53,14 @@ import * as search from '@codemirror/search';
import * as autocomplete from '@codemirror/autocomplete';
import { LanguageSupport } from '@codemirror/language';
import { html } from '@codemirror/lang-html';
import { java } from '@codemirror/lang-java';
import { javascript } from '@codemirror/lang-javascript';
import { json } from '@codemirror/lang-json';
import { html, htmlLanguage } from '@codemirror/lang-html';
import { java, javaLanguage } from '@codemirror/lang-java';
import { javascript, javascriptLanguage } from '@codemirror/lang-javascript';
import { json, jsonLanguage } from '@codemirror/lang-json';
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 rules = attrs.rules;
@ -69,6 +71,18 @@ const props = defineProps({
default: () => {},
},
modelValue: { type: String, default: '' },
autoCompletionOptions: {
type: Array,
default: () => {
return [];
},
},
extAutoCompletionOptions: {
type: Array,
default: () => {
return [];
},
},
lang: { type: String, default: 'json' },
width: { type: [Number, String], default: '100%' },
height: { type: [Number, String], default: undefined },
@ -184,7 +198,7 @@ const basicSetup = [
autocomplete.closeBrackets(),
autocomplete.autocompletion(),
search.highlightSelectionMatches(),
//search.highlightSelectionMatches(),
view.keymap.of([
...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();
// q-field stack-label field label
// field , label
@ -243,6 +296,10 @@ onMounted(() => {
height: props.height ? Tools.px(props.height) : props.rows * 22 + 'px',
},
}),
// java
autoCompletion(props.lang),
//
PlaceholderPlugin,
// , , blur
EditorView.updateListener.of(function (e) {
// emits('update:modelValue', e.state.doc.toString());
@ -321,3 +378,4 @@ defineExpose({
configure,
});
</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 { Environment } from '@/platform/plugin/environment';
import { NotifyManager } from './manager';
import { QuasarTools } from '@/platform/utils';
const ignoredUrls: string[] = [PConst.API_I18N_MESSAGES_URL, PConst.API_APP_CONFIGURE_URL];
const gc = Environment.getConfigure();
@ -22,6 +23,14 @@ const requestInterceptor = (config: any) => {
if (gc.axios?.basicAuth?.enable) {
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;
};
@ -33,11 +42,13 @@ const requestErrorInterceptor = (error: any) => {
// 响应拦截器
const responseInterceptor = (response: any) => {
// 请求成功, 进入该方法说明 response 的状态码为 2xx
QuasarTools.getQuasar()?.loading?.hide();
return response.data;
};
// 响应错误拦截器
const responseErrorInterceptor = (error: any) => {
QuasarTools.getQuasar()?.loading?.hide();
// 请求失败, 进入该方法说明 response 的状态码不为 2xx
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.response.use(responseInterceptor, (error: any) => {
QuasarTools.getQuasar()?.loading?.hide();
// 请求失败, 进入该方法说明 response 的状态码不为 2xx
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
*/
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
* @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",
"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",
"version": "8.1.231",
"version": "8.1.237",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -104,7 +104,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.231",
"platform-core": "8.1.237",
"quasar": "2.15.3",
"tailwindcss": "3.4.3",
"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_mathEditor from '@/views/testcase/math/MathEditor.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_word from '@/views/testcase/word/Word.vue';
import component_testcase_likmDialog from '@/views/likm/Dialog.vue';
@ -23,6 +25,8 @@ const localComponents = {
'component.testcase.noMenuRoute': component_testcase_noMenuRoute,
'component.testcase.mathEditor': component_testcase_mathEditor,
'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.word': component_testcase_word,
'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.mathEditor": "Math Formual Editor",
"menu.testcase.form":"Form Element",
"menu.testcase.codemirror":"Code Mirror",
"menu.testcase.loading":"Loading",
"menu.testcase.excel": "Excel",
"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.mathEditor": "數學公式編輯器",
"menu.testcase.form":"表單元素",
"menu.testcase.codemirror":"代碼編輯器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel",
"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.mathEditor": "数学公式编辑器",
"menu.testcase.form":"表单元素",
"menu.testcase.codemirror":"代码编辑器",
"menu.testcase.loading":"正在加載",
"menu.testcase.excel": "Excel",
"menu.testcase.word": "Word",

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

@ -45,6 +45,24 @@
"icon": "bi-palette",
"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",
"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",
"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>

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

@ -227,4 +227,5 @@ paste=Paste
cut =Cut
online=Online
offline=Offline
finish=Finish
finish=Finish
loading=Processing, please wait ......

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

@ -227,4 +227,5 @@ paste=\u7C98\u8CBC
cut =\u526A\u5207
online=\u5728\u7DDA
offline=\u96E2\u7DDA
finish=\u5B8C\u6210
finish=\u5B8C\u6210
loading=\u6B63\u5728\u8655\u7406, \u8ACB\u7B49\u5F85......

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

@ -227,4 +227,5 @@ paste=\u7C98\u8D34
cut =\u526A\u5207
online=\u5728\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",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.231",
"platform-core": "8.1.232",
"quasar": "2.15.3",
"tailwindcss": "3.4.3",
"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
*/
public class JpaEntityPersistentEvent extends ApplicationEvent{
private static final long serialVersionUID = -73175079790751083L;
private Class<?> entityClass; //实体类
private JpaEntityPersistentEventType type; //类型:增删改
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.metamodel.ManagedType;
import java.io.Serializable;
import java.util.List;
@NoRepositoryBean
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 ID getId(E entity);
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);
}

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

@ -1,21 +1,33 @@
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.service.support.ManagedTypeAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import javax.persistence.EntityManager;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.SingularAttribute;
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> {
private JpaEntityInformation<E, ID> jpaEntityInformation;
private EntityManager entityManager;
public DaoRepositoryImpl(Class<E> domainClass, EntityManager entityManager) {
super(domainClass, entityManager);
}
@ -82,4 +94,136 @@ public class DaoRepositoryImpl<E,ID extends Serializable> extends SimpleJpaRepos
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.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.service.DaoService;
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(repository.getId(oldObject).equals(id)) { //主键相同,直接更新
if(oldObject.getClass().equals(entity.getClass())){
//在更新原对象之前发送事件,因为以下操作会将原对象进行修改
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(), JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
copyEntityValues(oldObject,entity);
setCorporation(oldObject);
return repository.save(oldObject);
}else{
//在更新原对象之前发送事件,因为以下操作会将原对象进行修改
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(),JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
repository.delete(oldObject);
repository.flush();//注意,此处必须通过 flush() 方法使得上面的 delete 生效,但不会进行事务提交
setCorporation(entity);
@ -269,10 +275,14 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
}else{ // 通过唯一约束规则未找到记录, 表示修改了唯一约束的值
oldObject =repository.getReferenceById(id);
if(oldObject.getClass().equals(entity.getClass())){
//在更新原对象之前发送事件,因为以下操作会将原对象进行删除
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(),JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
copyEntityValues(oldObject,entity);
setCorporation(oldObject);
return repository.save(oldObject);
}else{
//在更新原对象之前发送事件,因为以下操作会将原对象进行删除
applicationContext.publishEvent(new JpaEntityPersistentEvent(oldObject.getClass(),JpaEntityPersistentEventType.BEFORE_UPDATE,oldObject, entity));
repository.delete(oldObject);
repository.flush();//注意,此处必须通过 flush() 方法使得上面的 delete 生效,但不会进行事务提交
setCorporation(entity);

Loading…
Cancel
Save