Browse Source

1. 前端核心工程: EnumTools 支持缓存

2. 规则引擎工程: 将参数和指标的处理器共享
main
wangshaoping 5 months ago
parent
commit
74948fcbdc
  1. 91
      erm.frontend/.eslintrc.cjs
  2. 4
      erm.frontend/package.json
  3. 2
      gradle.properties
  4. 91
      io.sc.engine.mv.frontend/.eslintrc.cjs
  5. 4
      io.sc.engine.mv.frontend/package.json
  6. 91
      io.sc.engine.rule.frontend/.eslintrc.cjs
  7. 4
      io.sc.engine.rule.frontend/package.json
  8. 2
      io.sc.engine.rule.frontend/src/utils/PlaceHolder.ts
  9. 2
      io.sc.engine.rule.frontend/src/views/dictionary/dictionary.vue
  10. 2
      io.sc.engine.rule.frontend/src/views/lib/IndicatorGrid.vue
  11. 2
      io.sc.engine.rule.frontend/src/views/lib/LibGrid.vue
  12. 1304
      io.sc.engine.rule.frontend/src/views/lib/ProcessorGrid.vue
  13. 6
      io.sc.engine.rule.frontend/src/views/resources/Resources.vue
  14. 37
      io.sc.engine.rule.frontend/src/views/resources/designer/DecisionTreeDialog.vue
  15. 45
      io.sc.engine.rule.frontend/src/views/resources/designer/ExecutionFlowDialog.vue
  16. 2
      io.sc.engine.rule.frontend/src/views/resources/designer/Model.vue
  17. 85
      io.sc.engine.rule.frontend/src/views/resources/designer/ObjectPropertiesMatcherDialog.vue
  18. 2
      io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue
  19. 1883
      io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue
  20. 2
      io.sc.engine.rule.frontend/src/views/resources/designer/Validator.vue
  21. 53
      io.sc.engine.rule.frontend/src/views/shared/AutoCompletionManager.ts
  22. 6
      io.sc.engine.rule.frontend/src/views/shared/IndicatorManager.ts
  23. 53
      io.sc.engine.rule.frontend/src/views/shared/ObjectPropertiesMatcherDialog.vue
  24. 32
      io.sc.engine.rule.frontend/src/views/shared/UserDefinedFunctionsManager.ts
  25. 75
      io.sc.engine.rule.frontend/src/views/shared/processors/Arithmetic.ts
  26. 197
      io.sc.engine.rule.frontend/src/views/shared/processors/ConditionRange.ts
  27. 211
      io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTable.ts
  28. 286
      io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTable2c.ts
  29. 53
      io.sc.engine.rule.frontend/src/views/shared/processors/DecisionTree.ts
  30. 53
      io.sc.engine.rule.frontend/src/views/shared/processors/ExecutionFlow.ts
  31. 69
      io.sc.engine.rule.frontend/src/views/shared/processors/GroovyScript.ts
  32. 67
      io.sc.engine.rule.frontend/src/views/shared/processors/MathFormula.ts
  33. 215
      io.sc.engine.rule.frontend/src/views/shared/processors/NumberRange.ts
  34. 266
      io.sc.engine.rule.frontend/src/views/shared/processors/ObjectProperties.ts
  35. 62
      io.sc.engine.rule.frontend/src/views/shared/processors/OptionValue.ts
  36. 54
      io.sc.engine.rule.frontend/src/views/shared/processors/Pmml.ts
  37. 36
      io.sc.engine.rule.frontend/src/views/shared/processors/Rule.ts
  38. 37
      io.sc.engine.rule.frontend/src/views/shared/processors/SingleRule.ts
  39. 418
      io.sc.engine.rule.frontend/src/views/shared/processors/Sql.ts
  40. 108
      io.sc.engine.rule.frontend/src/views/shared/processors/Ternary.ts
  41. 105
      io.sc.engine.rule.frontend/src/views/shared/processors/WhenThen.ts
  42. 17
      io.sc.engine.rule.frontend/src/views/shared/processors/index.ts
  43. 14
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/IndicatorProcessorServiceImpl.java
  44. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterProcessorServiceImpl.java
  45. 10
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/support/AutoMatchObjectProperties.java
  46. 91
      io.sc.engine.st.frontend/.eslintrc.cjs
  47. 4
      io.sc.engine.st.frontend/package.json
  48. 1
      io.sc.platform.core.frontend/.bin/sync.js
  49. 1
      io.sc.platform.core.frontend/.eslintrc.cjs
  50. 2
      io.sc.platform.core.frontend/package.json
  51. 2
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/Toolbar.vue
  52. 1
      io.sc.platform.core.frontend/src/platform/index.ts
  53. 2
      io.sc.platform.core.frontend/src/platform/plugin/i18n.ts
  54. 54
      io.sc.platform.core.frontend/src/platform/utils/EnumTools.ts
  55. 32
      io.sc.platform.core.frontend/src/platform/utils/Tools.ts
  56. 49
      io.sc.platform.core.frontend/src/views/testcase/code-mirror/code-mirror.vue
  57. 1
      io.sc.platform.core.frontend/template-project/.eslintrc.cjs
  58. 6
      io.sc.platform.core.frontend/template-project/package.json
  59. 49
      io.sc.platform.core.frontend/template-project/src/views/testcase/code-mirror/code-mirror.vue
  60. 2
      io.sc.platform.core/src/main/java/io/sc/platform/core/controller/EnumWebController.java
  61. 10
      io.sc.platform.developer.doc/package.json
  62. 6
      io.sc.platform.developer.doc/src/main/resources/META-INF/platform/plugins/security.json
  63. 91
      io.sc.platform.developer.frontend/.eslintrc.cjs
  64. 4
      io.sc.platform.developer.frontend/package.json
  65. 2
      io.sc.platform.gradle/templates/pgp/setup/gradle.properties
  66. 91
      io.sc.platform.lcdp.frontend/.eslintrc.cjs
  67. 4
      io.sc.platform.lcdp.frontend/package.json
  68. 91
      io.sc.platform.license.keygen.frontend/.eslintrc.cjs
  69. 4
      io.sc.platform.license.keygen.frontend/package.json
  70. 91
      io.sc.platform.mvc.frontend/.eslintrc.cjs
  71. 4
      io.sc.platform.mvc.frontend/package.json
  72. 91
      io.sc.platform.scheduler.manager.frontend/.eslintrc.cjs
  73. 4
      io.sc.platform.scheduler.manager.frontend/package.json
  74. 91
      io.sc.platform.system.frontend/.eslintrc.cjs
  75. 4
      io.sc.platform.system.frontend/package.json
  76. 91
      io.sc.standard.frontend/.eslintrc.cjs
  77. 4
      io.sc.standard.frontend/package.json
  78. 4
      io.sc.website/package.json

91
erm.frontend/.eslintrc.cjs

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

4
erm.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "erm.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

2
gradle.properties

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

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.mv.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.rule.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.416",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -3,7 +3,7 @@ import { Tools } from 'platform-core';
class PlaceHolder {
static #prefix: string = '<span class="p-0.5"><span class="p-0.5 border border-gray-800 rounded-md">';
static #suffix: string = '</span></span>';
public static replace(str, prefix, suffix) {
public static replace(str: string, prefix?: string, suffix?: string) {
if (str) {
if (Tools.isUndefinedOrNull(prefix)) {
prefix = PlaceHolder.#prefix;

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

@ -5,7 +5,7 @@
<w-grid
ref="treeGridRef"
:title="$t('re.dictionary.grid.title')"
:draggable="true"
draggable="server"
hide-bottom
dense-body
db-click-operation="edit"

2
io.sc.engine.rule.frontend/src/views/lib/IndicatorGrid.vue

@ -3,7 +3,7 @@
<w-grid
ref="gridRef"
:title="$t('re.lib.tab.indicator.title')"
:draggable="true"
draggable="server"
dense
hide-bottom
db-click-operation="edit"

2
io.sc.engine.rule.frontend/src/views/lib/LibGrid.vue

@ -3,7 +3,7 @@
<w-grid
ref="treeGridRef"
:title="$t('re.lib.grid.title')"
:draggable="true"
draggable="server"
dense-body
hide-bottom
db-click-operation="edit"

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

File diff suppressed because it is too large

6
io.sc.engine.rule.frontend/src/views/resources/Resources.vue

@ -176,7 +176,7 @@
DialogManager.confirm($t('re.resources.grid.toolbar.deploy.online.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/resource/online/' + arg.selected.id)).then(() => {
axios.get(Environment.apiContextPath('/api/re/resource/' + currentSelectedResourceIdRef)).then((response) => {
treeGridRef.replaceRow(response.data);
treeGridRef.updateLocalData(response.data);
});
});
});
@ -200,7 +200,7 @@
DialogManager.confirm($t('re.resources.grid.toolbar.deploy.offline.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/resource/offline/' + arg.selected.id)).then(() => {
axios.get(Environment.apiContextPath('/api/re/resource/' + currentSelectedResourceIdRef)).then((response) => {
treeGridRef.replaceRow(response.data);
treeGridRef.updateLocalData(response.data);
});
});
});
@ -367,7 +367,7 @@
@after-started="
() => {
axios.get(Environment.apiContextPath('/api/re/resource/' + currentSelectedResourceIdRef)).then((response) => {
treeGridRef.replaceRow(response.data);
treeGridRef.updateLocalData(response.data);
});
}
"

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

@ -13,6 +13,7 @@
import { ref } from 'vue';
import { axios, Environment, NotifyManager, Formater, EnumTools, $t } from 'platform-core';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
import { PlaceHolder } from '@/utils/PlaceHolder';
import ResourceDeployStatusTag from '@/views/shared/ResourceDeployStatusTag.vue';
@ -21,13 +22,9 @@ const processorIdRef = ref();
const modelValueRef = ref();
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsRef = ref();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
const resourceAbstractsRef = ref();
const autoCompletion = (context) => {
return autoCompletionManager.autoCompletion(context);
};
const edgeDefines = [
{
type: 'EdgeConditionBranch',
@ -77,8 +74,8 @@ const edgeDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -161,8 +158,8 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -212,8 +209,8 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -354,26 +351,14 @@ const findResourceAbstractByCodeAndVersion = (code, version) => {
};
const open = async (parameterId, processorId) => {
autoCompletionManager.load(parameterId);
userDefinedFunctionsManager.load();
processorIdRef.value = processorId;
//
const resourceAbstractResponse = await axios.get(Environment.apiContextPath('/api/re/resource/getAllReleasableResourceAbstract'));
resourceAbstractsRef.value = resourceAbstractResponse?.data;
//
const functionResponse = await axios.get(Environment.apiContextPath('/api/re/function?pageable=false'));
const functionOptions = [];
for (const item of functionResponse?.data?.content || []) {
if (item.enable) {
functionOptions.push(item);
}
}
userDefinedFunctionsRef.value = functionOptions;
//
const tipResponse = await axios.get(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + parameterId));
autoCompletionManager.setParameters(tipResponse?.data?.parameters);
autoCompletionManager.setValueTypes(tipResponse?.data?.valueTypes);
// graph xml
const graphResponse = await axios.get(Environment.apiContextPath('api/re/model/parameter/processor/getDecisionTreeById/' + processorIdRef.value));
modelValueRef.value = graphResponse?.data;

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

@ -13,6 +13,7 @@
import { ref } from 'vue';
import { axios, Environment, NotifyManager, Formater, EnumTools, $t } from 'platform-core';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
import { PlaceHolder } from '@/utils/PlaceHolder';
import ResourceDeployStatusTag from '@/views/shared/ResourceDeployStatusTag.vue';
@ -21,14 +22,10 @@ const processorIdRef = ref();
const modelValueRef = ref('');
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsRef = ref();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
const resourceAbstractsRef = ref();
const modeAbstractsRef = ref();
const autoCompletion = (context) => {
return autoCompletionManager.autoCompletion(context);
};
const edgeDefines = [
{
type: 'EdgeConditionBranch',
@ -78,8 +75,8 @@ const edgeDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -162,8 +159,8 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -208,8 +205,8 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -452,8 +449,8 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
{
name: 'outputCommands',
@ -464,8 +461,8 @@ const vertexDefines = [
placeholder: true,
lineWrap: true,
lineBreak: true,
autoCompletion: autoCompletion,
userDefinedFunctions: userDefinedFunctionsRef,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
];
},
@ -536,6 +533,9 @@ const findResourceAbstractByCodeAndVersion = (code, version) => {
};
const open = async (parameterId, processorId) => {
autoCompletionManager.load(parameterId);
userDefinedFunctionsManager.load();
processorIdRef.value = processorId;
//
const resourceAbstractResponse = await axios.get(Environment.apiContextPath('/api/re/resource/getAllReleasableResourceAbstract'));
@ -549,21 +549,6 @@ const open = async (parameterId, processorId) => {
}
modeAbstractsRef.value = modelOptions;
//
const functionResponse = await axios.get(Environment.apiContextPath('/api/re/function?pageable=false'));
const functionOptions = [];
for (const item of functionResponse?.data?.content || []) {
if (item.enable) {
functionOptions.push(item);
}
}
userDefinedFunctionsRef.value = functionOptions;
//
const tipResponse = await axios.get(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + parameterId));
autoCompletionManager.setParameters(tipResponse?.data?.parameters);
autoCompletionManager.setValueTypes(tipResponse?.data?.valueTypes);
// graph xml
const graphResponse = await axios.get(Environment.apiContextPath('api/re/model/parameter/processor/getExecutionFlowById/' + processorIdRef.value));
modelValueRef.value = graphResponse?.data;

2
io.sc.engine.rule.frontend/src/views/resources/designer/Model.vue

@ -3,7 +3,7 @@
<w-grid
ref="treeGridRef"
:title="$t('re.resources.designer.model.grid.title')"
:draggable="true"
draggable="server"
dense-body
class="px-1"
hide-bottom

85
io.sc.engine.rule.frontend/src/views/resources/designer/ObjectPropertiesMatcherDialog.vue

@ -1,85 +0,0 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('re.resources.designer.parameter.grid.title')"
:can-maximize="false"
:maximized="false"
:buttons="[
{
label: $t('confirm'),
noCaps: true,
click: () => {
axios
.post(Environment.apiContextPath('/api/re/model/parameter/processor/autoMatch'), {
parameterId: parameterRef,
objectProperties: currentObjectProperties,
})
.then((response) => {
emit('afterMatched', response.data);
close();
});
},
},
]"
>
<div class="pt-2">
<q-select v-model="parameterRef" :label="$t('parameter')" outlined dense emit-value map-options :options="parameterOptionsRef"></q-select>
</div>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, Tools } from 'platform-core';
const props = defineProps({
parameter: { type: Object, default: undefined },
processor: { type: Object, default: undefined },
});
const emit = defineEmits<{
(e: 'afterMatched', objectProperties: any): void;
}>();
const dialogRef = ref();
const parameterRef = ref();
const parameterOptionsRef = ref();
let currentObjectProperties = {};
const open = (objectProperties) => {
currentObjectProperties = objectProperties;
parameterRef.value = undefined;
dialogRef.value.show();
axios.get(Environment.apiContextPath('/api/re/model/parameter/findParametersByParameterId?parameterId=' + props.parameter.id)).then((response) => {
const options = [];
response.data.forEach((item) => {
const valueType = item.valueType;
if (
valueType !== 'java.lang.Boolean' &&
valueType !== 'java.lang.Long' &&
valueType !== 'java.lang.Float' &&
valueType !== 'Float' &&
valueType !== 'java.math.BigDecimal' &&
valueType !== 'java.lang.String' &&
valueType !== 'java.util.Date' &&
valueType !== 'io.sc.engine.rule.core.classes.ResourceAbstract' &&
valueType !== 'io.sc.engine.rule.core.classes.RuleResult' &&
valueType !== 'io.sc.engine.rule.core.classes.SingleRuleResult' &&
!valueType.startsWith('List') &&
!valueType.startsWith('Map')
) {
options.push({ value: item.id, label: item.name });
}
});
parameterOptionsRef.value = options;
});
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

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

@ -3,7 +3,7 @@
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.parameter.grid.title')"
:draggable="true"
draggable="server"
dense-body
class="px-1"
hide-bottom

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

File diff suppressed because it is too large

2
io.sc.engine.rule.frontend/src/views/resources/designer/Validator.vue

@ -2,7 +2,7 @@
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.validator.grid.title')"
:draggable="true"
draggable="server"
dense-body
class="px-1"
hide-bottom

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

@ -1,13 +1,18 @@
import { Tools } from 'platform-core';
import { axios, Tools } from 'platform-core';
class AutoCompletionManager {
parameters: object[];
valueTypes: object[];
parameters: any[];
valueTypes: any[];
public setParameters(parameters) {
constructor() {
this.parameters = [];
this.valueTypes = [];
}
public setParameters(parameters: any) {
this.parameters = parameters;
}
public setValueTypes(valueTypes) {
public setValueTypes(valueTypes: any) {
this.valueTypes = valueTypes;
}
@ -38,7 +43,7 @@ class AutoCompletionManager {
valueType = this.findValueTypeByProperty(valueType.code, valueType.version, names[index++]);
}
const options = [];
const options: any[] = [];
for (const property of valueType.properties) {
const propertyValueType = this.findValueType(property.valueType, property.valueTypeVersion);
if (!propertyValueType) {
@ -50,7 +55,7 @@ class AutoCompletionManager {
return options;
}
public findParmeter(parameterName) {
public findParmeter(parameterName: string) {
for (const parameter of this.parameters) {
if (parameter.name === parameterName) {
return parameter;
@ -59,7 +64,7 @@ class AutoCompletionManager {
return null;
}
public findValueType(valueTypeString, valueTypeVersion) {
public findValueType(valueTypeString: string, valueTypeVersion: number): any {
for (const valueType of this.valueTypes) {
if (valueType.code === valueTypeString && valueType.version === valueTypeVersion) {
return valueType;
@ -68,7 +73,7 @@ class AutoCompletionManager {
return null;
}
public findValueTypeByProperty(valueTypeString, valueTypeVersion, propertyName) {
public findValueTypeByProperty(valueTypeString: string, valueTypeVersion: number, propertyName: string) {
const valueType = this.findValueType(valueTypeString, valueTypeVersion);
if (!valueType) {
return null;
@ -81,7 +86,7 @@ class AutoCompletionManager {
}
public getParameterOptions(): any {
const options = [];
const options: any[] = [];
for (const parameter of this.parameters) {
const valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion);
const info = valueType.version ? valueType.name + '(V' + valueType.version + ')' : valueType.name;
@ -91,7 +96,7 @@ class AutoCompletionManager {
}
public getPropertyOptions(parameterName: string): any {
let parameterType = undefined;
let parameterType: any = undefined;
for (const parameter of this.parameters) {
if (parameter.name === parameterName) {
parameterType = parameter.valueType;
@ -110,15 +115,15 @@ class AutoCompletionManager {
}
if (parameterType.properties && parameterType.properties.length > 0) {
const options = [];
const options: any = [];
parameterType.properties.forEach((property) => {
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', detail: this.findValueTypeInfo(property.valueType) });
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', detail: property.valueType });
});
return options;
}
}
public autoCompletionParameters(to, matchedText): any {
public autoCompletionParameters(to: any, matchedText?: any): any {
return {
from: to,
options: this.getParameterOptions(),
@ -126,10 +131,10 @@ class AutoCompletionManager {
};
}
public autoCompletionProperties(to, matchedText): any {
public autoCompletionProperties(to: any, matchedText?: any): any {
const matchedTextReverse = Tools.reverseString(matchedText);
const regReverse = /(\.\}(.+?)\{\$)+/g; //匹配 '.}xxx{$' 模式
const matcheds = matchedTextReverse.match(regReverse);
const matcheds: any = matchedTextReverse.match(regReverse);
if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) {
return null;
}
@ -149,7 +154,7 @@ class AutoCompletionManager {
};
}
public autoCompletion(context): any {
public doAutoCompletion(context: any): any {
const beforeMatched = context.matchBefore(/(.+?)/g);
if (Tools.isUndefinedOrNull(beforeMatched)) {
return null;
@ -165,6 +170,20 @@ class AutoCompletionManager {
return null;
}
}
public load(url: string) {
axios.get(url).then((response) => {
this.setParameters(response.data.parameters);
this.setValueTypes(response.data.valueTypes);
});
}
public autoCompletion(): any {
const This = this;
return function (context: any) {
return This.doAutoCompletion(context);
};
}
}
export { AutoCompletionManager };

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

@ -7,7 +7,7 @@ class IndicatorManager {
public static getLibMap() {
if (IndicatorManager.#wrapper) {
const result = [];
const result: any[] = [];
for (const libCode in IndicatorManager.#wrapper) {
const lib = IndicatorManager.#wrapper[libCode];
if (lib) {
@ -26,7 +26,7 @@ class IndicatorManager {
if (lib) {
const versions = lib.versions;
if (versions) {
const result = [];
const result: any[] = [];
for (const version in versions) {
result.push({ label: version, value: version });
}
@ -47,7 +47,7 @@ class IndicatorManager {
if (versions) {
const indicators = versions['' + libVersion];
if (indicators) {
const result = [];
const result: any[] = [];
for (const code in indicators) {
result.push({ label: indicators[code], value: code });
}

53
io.sc.engine.rule.frontend/src/views/lib/ObjectPropertiesMatcherDialog.vue → io.sc.engine.rule.frontend/src/views/shared/ObjectPropertiesMatcherDialog.vue

@ -8,22 +8,12 @@
{
label: $t('confirm'),
noCaps: true,
click: () => {
axios
.post(Environment.apiContextPath('/api/re/indicator/processor/autoMatch'), {
parameterId: indicatorRef,
objectProperties: currentObjectProperties,
})
.then((response) => {
emit('afterMatched', response.data);
close();
});
},
click: click,
},
]"
>
<div class="pt-2">
<q-select v-model="indicatorRef" :label="$t('parameter')" outlined dense emit-value map-options :options="indicatorOptionsRef"></q-select>
<q-select v-model="modelValueRef" :label="$t('parameter')" outlined dense emit-value map-options :options="modelValueOptionsRef"></q-select>
</div>
</w-dialog>
</template>
@ -32,7 +22,8 @@ import { ref } from 'vue';
import { axios, Environment, Tools } from 'platform-core';
const props = defineProps({
indicator: { type: Object, default: undefined },
targetType: { type: String, default: undefined },
target: { type: Object, default: undefined },
processor: { type: Object, default: undefined },
});
@ -41,15 +32,41 @@ const emit = defineEmits<{
}>();
const dialogRef = ref();
const indicatorRef = ref();
const indicatorOptionsRef = ref();
const modelValueRef = ref('');
const modelValueOptionsRef = ref([]);
let currentObjectProperties = {};
const click = () => {
let url = '';
if (props.targetType === 'parameter') {
url = Environment.apiContextPath('/api/re/model/parameter/processor/autoMatch');
} else if (props.targetType === 'indicator') {
url = Environment.apiContextPath('/api/re/indicator/processor/autoMatch');
}
axios
.post(url, {
id: modelValueRef.value,
objectProperties: currentObjectProperties,
})
.then((response) => {
emit('afterMatched', response.data);
close();
});
};
const open = (objectProperties) => {
currentObjectProperties = objectProperties;
indicatorRef.value = undefined;
modelValueRef.value = undefined;
dialogRef.value.show();
axios.get(Environment.apiContextPath('/api/re/indicator/findIndicatorsByIndicatorId?indicatorId=' + props.indicator.id)).then((response) => {
let url = '';
if (props.targetType === 'parameter') {
url = Environment.apiContextPath('/api/re/model/parameter/findParametersByParameterId?parameterId=' + props.target.id);
} else if (props.targetType === 'indicator') {
url = Environment.apiContextPath('/api/re/indicator/findIndicatorsByIndicatorId?indicatorId=' + props.target.id);
}
axios.get(url).then((response) => {
const options = [];
response.data.forEach((item) => {
const valueType = item.valueType;
@ -70,7 +87,7 @@ const open = (objectProperties) => {
options.push({ value: item.id, label: item.name });
}
});
indicatorOptionsRef.value = options;
modelValueOptionsRef.value = options;
});
};

32
io.sc.engine.rule.frontend/src/views/shared/UserDefinedFunctionsManager.ts

@ -0,0 +1,32 @@
import { ref } from 'vue';
import { axios, Environment, Tools } from 'platform-core';
class UserDefinedFunctionsManager {
#functions: any;
constructor() {
this.#functions = ref([]);
}
public userDefinedFunctions(): any {
return this.#functions;
}
public load() {
// 获取自定义函数库中的函数
axios.get(Environment.apiContextPath('/api/re/function?pageable=false')).then((response) => {
const options: any[] = [];
const items: any[] = response.data?.content;
if (items && items.length > 0) {
items.forEach((item) => {
if (item.enable) {
options.push(item);
}
});
}
this.#functions.value = options;
});
}
}
export { UserDefinedFunctionsManager };

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

@ -0,0 +1,75 @@
import { $t, Environment } from 'platform-core';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class Arithmetic {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'arithmetic',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.ARITHMETIC'),
icon: 'bi-calculator',
enableIf: (args) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'ARITHMETIC');
},
};
}
public static format(row: any) {
return {
componentType: 'w-code-mirror',
attrs: {
lang: 'java',
rows: 4,
modelValue: row.arithmetic,
editable: false,
placeholder: true,
lineWrap: true,
},
};
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'arithmetic',
label: $t('re.resources.designer.processor.grid.entity.arithmetic'),
type: 'w-code-mirror',
lang: 'java',
rows: 5,
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'ARITHMETIC' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [{ name: 'arithmetic', label: $t('re.resources.designer.processor.grid.entity.arithmetic') }];
}
public static beforeEditorDataSubmit(args) {}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
}
}
export { Arithmetic };

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

@ -0,0 +1,197 @@
import { $t, Environment, Tools } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class ConditionRange {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'conditionRange',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.CONDITION_RANGE'),
icon: 'bi-rainbow',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'CONDITION_RANGE');
},
};
}
public static format(row: any) {
const objs = Tools.json2Object(row.conditionRange);
if (objs) {
let str = `<div class='border border-b-0 overflow-auto' style='max-height:100px'>`;
str += `<table width='100%' height='100%'>`;
objs.forEach((obj: any) => {
str += '<tr>';
str += ' <td>' + PlaceHolder.replace(obj.condition) + '</td>';
str += ' <td><span>' + ('' + PlaceHolder.replace(obj.value)) + '</span></td>';
str += '</tr>';
});
str += '</table>';
str += `</div>`;
return str;
}
return '';
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'conditionRange',
label: $t('re.resources.designer.processor.grid.entity.conditionRange'),
showIf: (args: any) => {
return 'CONDITION_RANGE' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 300,
dbClickOperation: 'edit',
autoFetchData: false,
denseBody: true,
draggable: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
'add',
'clone',
'edit',
{
extend: 'remove',
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('conditionRange');
grid.removeLocalData(args.selecteds);
},
},
'separator',
{
name: 'example',
label: $t('example'),
icon: 'bi-balloon',
click: (args) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('conditionRange');
const sampleData = [
{ uuid: Tools.uuid(), condition: '${变量名}<=0', value: '0' },
{ uuid: Tools.uuid(), condition: '${变量名}>0 && ${变量名}<=50', value: '50' },
{ uuid: Tools.uuid(), condition: '${变量名}>50 && ${变量名}<=80', value: '80' },
{ uuid: Tools.uuid(), condition: '${变量名}>80 && ${变量名}<=100', value: '100' },
{ uuid: Tools.uuid(), condition: '${变量名}>100', value: '60' },
];
grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: [
{ name: 'uuid', label: 'uuid', hidden: true },
{
name: 'condition',
label: $t('condition'),
align: 'left',
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
{
name: 'value',
label: $t('value'),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
],
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false },
{
name: 'condition',
label: $t('condition'),
type: 'w-code-mirror',
lang: 'java',
rows: 4,
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
{
name: 'value',
label: $t('value'),
type: 'w-code-mirror',
lang: 'java',
rows: 4,
lineWrap: true,
lineBreak: false,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('conditionRange');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
},
];
}
public static getViewerFields(properties: any) {
return [{ name: 'conditionRange', label: $t('re.resources.designer.processor.grid.entity.conditionRange') }];
}
public static beforeEditorDataSubmit(args) {
const form = args.grid.getEditorForm();
const grid = form.getFieldComponent('conditionRange');
const localData: any[] = grid.getRows();
const ranges: any[] = [];
localData.forEach((item) => {
ranges.push({
uuid: item.uuid,
condition: item.condition,
value: item.value,
});
});
args.data.conditionRange = Tools.object2Json(ranges);
}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
const form = args.grid.getEditorForm();
const row = args.data;
const grid = form.getFieldComponent('conditionRange');
const rows = Tools.json2Object(row.conditionRange);
grid.setLocalData(rows);
}
}
export { ConditionRange };

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

@ -0,0 +1,211 @@
import { ref } from 'vue';
import { $t, Tools } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
const tableHeaderColumnsRef = ref([]);
class DecisionTable {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'decisionTable',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.DECISION_TABLE'),
icon: 'bi-grid-3x3',
enableIf: (args) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args) => {
args.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE');
},
};
}
public static format(row) {
const objs = Tools.json2Object(row.decisionTable);
if (objs) {
let str = `<div class='border border-b-0 overflow-auto' style='max-height:100px'>`;
str += `<table width='100%' height='100%'>`;
objs.forEach((obj) => {
str += '<tr>';
Object.keys(obj).forEach((key) => {
if (key !== 'uuid' && typeof obj[key] === 'string') {
str += ' <td>' + PlaceHolder.replace(obj[key]) + '</td>';
}
});
str += '</tr>';
});
str += '</table>';
str += `</div>`;
return str;
}
return '';
}
public static getEditorFields(properties) {
return [
{
colSpan: 5,
name: 'decisionTable',
label: $t('re.resources.designer.processor.grid.entity.decisionTable'),
showIf: (arg) => {
return 'DECISION_TABLE' === arg.form.getFieldValue('type');
},
type: 'w-grid',
height: 300,
dbClickOperation: 'edit',
autoFetchData: false,
denseBody: true,
draggable: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
[
{
extend: 'add',
click: undefined,
},
{
name: 'addCol2Left',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addCol2Left'),
enableIf: (args) => {
return true;
},
click: () => {},
},
{
name: 'addCol2Right',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addCol2Right'),
enableIf: (args) => {
return true;
},
click: () => {},
},
'separator',
{
name: 'addRow',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addRow'),
click: () => {},
},
],
[
{
extend: 'remove',
click: undefined,
},
{
name: 'removeCol',
label: $t('re.resources.designer.processor.decisionTable.toolbar.removeCol'),
click: () => {},
},
{
name: 'removeRow',
label: $t('re.resources.designer.processor.decisionTable.toolbar.removeRow'),
click: (args) => {},
},
],
'separator',
{
name: 'example',
label: $t('example'),
icon: 'bi-balloon',
click: (args) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('decisionTable2C');
const sampleData = [
{ uuid: Tools.uuid(), C0: '', C1: "${客户类型}=='普通客户'", C2: "${客户类型}=='VIP客户'", C3: "${客户类型}=='临时客户'" },
{ uuid: Tools.uuid(), C0: '${评分结果}<60', C1: '1', C2: '3', C3: '5' },
{ uuid: Tools.uuid(), C0: '${评分结果}>=60', C1: '2', C2: '4', C3: '6' },
];
grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: [
{ name: 'uuid', label: 'uuid', hidden: true },
{
name: 'C0',
label: $t('C0'),
align: 'left',
sortable: false,
format: (value) => {
return PlaceHolder.replace(value);
},
},
{
name: 'C1',
label: $t('C1'),
sortable: false,
format: (value) => {
return PlaceHolder.replace(value);
},
},
{
name: 'C2',
label: $t('C2'),
sortable: false,
format: (value) => {
return PlaceHolder.replace(value);
},
},
{
name: 'C3',
label: $t('C3'),
sortable: false,
format: (value) => {
return PlaceHolder.replace(value);
},
},
],
},
];
}
public static getViewerFields(properties) {
return [{ name: 'decisionTable', label: $t('re.resources.designer.processor.grid.entity.decisionTable') }];
}
public static beforeEditorDataSubmit(args) {
const form = args.grid.getEditorForm();
const grid = form.getFieldComponent('decisionTable');
const localData = grid.getRows();
args.data.decisionTable2C = Tools.object2Json(localData);
}
public static afterEditorOpen(args) {}
}
const addDecisionTable2CCol = (grid, currentSelectedColName, colNamePattern, mode) => {
//更新表数据
const rows = grid.getRows();
const propertyNames = Tools.extractAllPropertyNames(rows, colNamePattern);
propertyNames.sort();
const selectedColIndex = propertyNames.indexOf(currentSelectedColName) + (mode === 'left' ? 0 : 1);
rows.forEach((row) => {
let i;
for (i = propertyNames.length; i > selectedColIndex; i--) {
row['C' + i] = row['C' + (i - 1)];
}
row['C' + selectedColIndex] = '';
});
// 更新表头
const fields = [];
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
let i = 0;
for (i = 0; i <= propertyNames.length; i++) {
fields.push({
name: 'C' + i,
label: $t('C' + i),
sortable: false,
format: (value) => {
return PlaceHolder.replace(value);
},
});
}
tableHeaderColumnsRef.value = fields;
grid.setLocalData(rows);
};
export { DecisionTable };

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

@ -0,0 +1,286 @@
import { ref } from 'vue';
import { $t, Tools } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
const tableHeaderColumnsRef = ref(<any>[]);
class DecisionTable2c {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'decisionTable2c',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.DECISION_TABLE_2C'),
icon: 'bi-grid-3x2',
enableIf: (args) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'DECISION_TABLE_2C');
},
};
}
public static format(row: any) {
const objs: any[] = Tools.json2Object(row.decisionTable2C);
if (objs) {
let str = `<div class='border border-b-0 overflow-auto' style='max-height:100px'>`;
str += `<table width='100%' height='100%'>`;
objs.forEach((obj) => {
str += '<tr>';
Object.keys(obj).forEach((key) => {
if (key !== 'uuid' && typeof obj[key] === 'string') {
str += ' <td>' + PlaceHolder.replace(obj[key]) + '</td>';
}
});
str += '</tr>';
});
str += '</table>';
str += `</div>`;
return str;
}
return '';
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'decisionTable2C',
label: $t('re.resources.designer.processor.grid.entity.decisionTable2C'),
showIf: (args: any) => {
return 'DECISION_TABLE_2C' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 300,
dbClickOperation: 'edit',
selectedMode: 'cell',
autoFetchData: false,
denseBody: true,
draggable: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
[
{
extend: 'add',
click: undefined,
},
{
name: 'addCol2Left',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addCol2Left'),
enableIf: (args: any) => {
if (args.selectedColName) {
return true;
}
return false;
},
click: (args: any) => {
addDecisionTable2CCol(args.grid, args.selectedColName, /C[\d]/, 'left');
},
},
{
name: 'addCol2Right',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addCol2Right'),
enableIf: (args: any) => {
if (args.selectedColName) {
return true;
}
return false;
},
click: (args: any) => {
addDecisionTable2CCol(args.grid, args.selectedColName, /C[\d]/, 'right');
},
},
'separator',
{
name: 'addRow',
label: $t('re.resources.designer.processor.decisionTable.toolbar.addRow'),
click: (args: any) => {
const rows = args.grid.getRows();
const propertyNames = Tools.extractAllPropertyNames(rows, /C[\d]/);
propertyNames.sort();
const row: any = {
uuid: Tools.uuid(),
};
propertyNames.forEach((name) => {
row[name] = '';
});
args.grid.addLocalData(row);
},
},
],
[
{
extend: 'remove',
click: undefined,
},
{
name: 'removeCol',
label: $t('re.resources.designer.processor.decisionTable.toolbar.removeCol'),
enableIf: (args: any) => {
if (args.selectedColName) {
return true;
}
return false;
},
click: (args: any) => {
deleteDecisionTable2CCol(args.grid, args.selectedColName, /C[\d]/);
},
},
{
name: 'removeRow',
label: $t('re.resources.designer.processor.decisionTable.toolbar.removeRow'),
enableIf: (args: any) => {
if (args.selected) {
return true;
}
return false;
},
click: (args: any) => {
args.grid.removeLocalData(args.selected);
},
},
],
'separator',
'rowEdit',
'separator',
{
name: 'example',
label: $t('example'),
icon: 'bi-balloon',
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('decisionTable2C');
const sampleData = [
{ uuid: Tools.uuid(), C0: '', C1: "${客户类型}=='普通客户'", C2: "${客户类型}=='VIP客户'", C3: "${客户类型}=='临时客户'" },
{ uuid: Tools.uuid(), C0: '${评分结果}<60', C1: '1', C2: '3', C3: '5' },
{ uuid: Tools.uuid(), C0: '${评分结果}>=60', C1: '2', C2: '4', C3: '6' },
];
grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: tableHeaderColumnsRef,
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: tableHeaderColumnsRef,
},
},
},
];
}
public static getViewerFields(properties: any) {
return [{ name: 'decisionTable2C', label: $t('re.resources.designer.processor.grid.entity.decisionTable2C') }];
}
public static beforeEditorDataSubmit(args: any) {
const form = args.grid.getEditorForm();
const grid = form.getFieldComponent('decisionTable2C');
const localData = grid.getRows();
args.data.decisionTable2C = Tools.object2Json(localData);
}
public static afterEditorOpen(args: any) {
const form = args.grid.getEditorForm();
const row = args.data;
// 构建表格的头
const rows = Tools.json2Object(row.decisionTable2C);
const fieldNames = Tools.extractAllPropertyNames(rows, /C[\d]/);
fieldNames.sort();
const fields: any = [];
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
fieldNames.forEach((name) => {
fields.push({
name: name,
label: $t(name),
sortable: false,
type: 'w-code-mirror',
attrs: {
toolbar: false,
rows: 1,
},
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
});
tableHeaderColumnsRef.value = fields;
// 设置表格数据
const grid = form.getFieldComponent('decisionTable2C');
grid.setLocalData(rows);
}
}
const addDecisionTable2CCol = (grid: any, currentSelectedColName: string, colNamePattern: any, mode: string) => {
//更新表数据
const rows: any[] = grid.getRows();
const propertyNames: string[] = Tools.extractAllPropertyNames(rows, colNamePattern);
propertyNames.sort();
const selectedColIndex = propertyNames.indexOf(currentSelectedColName) + (mode === 'left' ? 0 : 1);
rows.forEach((row) => {
let i = 0;
for (i = propertyNames.length; i > selectedColIndex; i--) {
row['C' + i] = row['C' + (i - 1)];
}
row['C' + selectedColIndex] = '';
});
// 更新表头
const fields: any[] = [];
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
let i = 0;
for (i = 0; i <= propertyNames.length; i++) {
fields.push({
name: 'C' + i,
label: $t('C' + i),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
}
tableHeaderColumnsRef.value = fields;
grid.setLocalData(rows);
};
const deleteDecisionTable2CCol = (grid: any, currentSelectedColName: string, colNamePattern: any) => {
//更新表数据
const rows: any[] = grid.getRows();
const propertyNames: string[] = Tools.extractAllPropertyNames(rows, colNamePattern);
propertyNames.sort();
const selectedColIndex = propertyNames.indexOf(currentSelectedColName);
rows.forEach((row) => {
let i = 0;
for (i = selectedColIndex; i < propertyNames.length; i++) {
row['C' + i] = row['C' + (i + 1)];
}
delete row['C' + (propertyNames.length - 1)];
});
// 更新表头
const fields: any[] = [];
fields.push({ name: 'uuid', label: 'uuid', hidden: true });
let i = 0;
for (i = 0; i < propertyNames.length - 1; i++) {
fields.push({
name: 'C' + i,
label: $t('C' + i),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
});
}
tableHeaderColumnsRef.value = fields;
grid.setLocalData(rows);
};
export { DecisionTable2c };

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

@ -0,0 +1,53 @@
import { $t } from 'platform-core';
class DecisionTree {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'decisionTree',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.DECISION_TREE'),
icon: 'bi-tree',
enableIf: (args) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'DECISION_TREE');
},
};
}
public static format(row: any) {
const div = document.createElement('div');
div.textContent = row.decisionTree;
const result = div.outerHTML;
div.parentNode?.removeChild(div);
return result;
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'decisionTree',
label: $t('re.resources.designer.processor.grid.entity.decisionTree'),
type: 'w-code-mirror',
rows: 20,
lineNumber: true,
toolbar: false,
showIf: (args: any) => {
return 'DECISION_TREE' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {}
}
export { DecisionTree };

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

@ -0,0 +1,53 @@
import { $t } from 'platform-core';
class ExecutionFlow {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'executionFlow',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.EXECUTION_FLOW'),
icon: 'bi-bounding-box-circles',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'EXECUTION_FLOW');
},
};
}
public static format(row: any) {
const div = document.createElement('div');
div.textContent = row.executionFlow;
const result = div.outerHTML;
div.parentNode?.removeChild(div);
return result;
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'executionFlow',
label: $t('re.resources.designer.processor.grid.entity.executionFlow'),
type: 'w-code-mirror',
rows: 20,
lineNumber: true,
toolbar: false,
showIf: (args: any) => {
return 'EXECUTION_FLOW' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {}
}
export { ExecutionFlow };

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

@ -0,0 +1,69 @@
import { $t, Environment } from 'platform-core';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class GroovyScript {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'groovyScript',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.GROOVY_SCRIPT'),
icon: 'bi-code',
enableIf: (args) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args) => {
args.grid.getEditorForm().setFieldValue('type', 'GROOVY_SCRIPT');
},
};
}
public static format(row: any) {
const div = document.createElement('div');
div.textContent = row.groovyScript;
const result = div.outerHTML;
div.parentNode?.removeChild(div);
return result;
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'groovyScript',
label: $t('re.resources.designer.processor.grid.entity.groovyScript'),
type: 'w-code-mirror',
rows: 20,
lineNumber: true,
lang: 'java',
lineWrap: false,
lineBreak: true,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args) => {
return 'GROOVY_SCRIPT' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [{ name: 'groovyScript', label: $t('re.resources.designer.processor.grid.entity.groovyScript') }];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
}
}
export { GroovyScript };

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

@ -0,0 +1,67 @@
import { $t, Environment } from 'platform-core';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class MathFormula {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'mathFormula',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.MATH_FORMULA'),
icon: 'bi-calculator',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'MATH_FORMULA');
},
};
}
public static format(row: any) {
return {
componentType: 'w-math',
attrs: {
modelValue: row.mathFormula,
readOnly: true,
zoom: 2,
},
};
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'mathFormula',
label: $t('re.resources.designer.processor.grid.entity.mathFormula'),
type: 'w-math',
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'MATH_FORMULA' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
}
}
export { MathFormula };

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

@ -0,0 +1,215 @@
import { $t, Environment, Tools } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class NumberRange {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'numberRange',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.NUMBER_RANGE'),
icon: 'bi-justify',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'NUMBER_RANGE');
},
};
}
public static format(row: any) {
const objs: any[] = Tools.json2Object(row.numberRange);
if (objs) {
let str = `<div class='border border-b-0 overflow-auto' style='max-height:100px'>`;
str += `<table width='100%' height='100%'>`;
objs.forEach((obj, index) => {
str += '<tr>';
if (index == 0) {
str += ' <td rowspan=' + objs.length + '>' + PlaceHolder.replace(row.numberRangeVar) + '</td>';
}
str += ' <td>' + Tools.generateIntervalRange(obj.minIncluded, obj.min, obj.max, obj.maxIncluded) + '</td>';
str += ' <td>' + ('' + PlaceHolder.replace('' + obj.value)) + '</td>';
str += '</tr>';
});
str += '</table>';
str += '</div>';
return str;
}
return '';
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'numberRangeVar',
label: $t('re.resources.designer.processor.grid.entity.numberRangeVar'),
showIf: (args: any) => {
return 'NUMBER_RANGE' === args.form.getFieldValue('type');
},
type: 'w-code-mirror',
lang: 'java',
rows: 3,
lineWrap: true,
lineBreak: false,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
{
colSpan: 5,
name: 'numberRange',
label: $t('re.resources.designer.processor.grid.entity.numberRange'),
showIf: (args: any) => {
return 'NUMBER_RANGE' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 300,
dbClickOperation: 'edit',
autoFetchData: false,
denseBody: true,
draggable: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
'add',
'clone',
'edit',
{
extend: 'remove',
click: (arg: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('numberRange');
grid.removeLocalData(arg.selecteds);
},
},
'separator',
{
name: 'example',
label: $t('example'),
icon: 'bi-balloon',
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('numberRange');
const sampleData = [
{ uuid: Tools.uuid(), minIncluded: false, min: null, max: 0, maxIncluded: false, value: 1 },
{ uuid: Tools.uuid(), minIncluded: true, min: 0, max: 1, maxIncluded: false, value: 2 },
{ uuid: Tools.uuid(), minIncluded: true, min: 1, max: 2, maxIncluded: false, value: 3 },
{ uuid: Tools.uuid(), minIncluded: true, min: 2, max: 3, maxIncluded: false, value: 4 },
{ uuid: Tools.uuid(), minIncluded: true, min: 3, max: null, maxIncluded: false, value: 5 },
{ uuid: Tools.uuid(), minIncluded: false, min: null, max: null, maxIncluded: false, value: 0 },
];
grid.setLocalData(sampleData);
},
},
],
primaryKey: 'uuid',
columns: [
{ width: 200, name: 'uuid', label: 'uuid', hidden: true },
{
width: 60,
name: 'minIncluded',
label: $t('include'),
align: 'center',
sortable: false,
format: (value: any) => {
if (value) {
return '[';
} else {
return '(';
}
},
},
{ width: 150, name: 'min', label: $t('minValue'), align: 'right', sortable: false },
{ width: 150, name: 'max', label: $t('maxValue'), align: 'right', sortable: false },
{
width: 60,
name: 'maxIncluded',
label: $t('include'),
align: 'center',
sortable: false,
format: (value: any) => {
if (value) {
return ']';
} else {
return ')';
}
},
},
{ width: '100%', name: 'value', label: $t('value'), sortable: false },
],
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 4,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false, colSpan: 4 },
{ name: 'min', label: $t('minValue'), type: 'w-text', colSpan: 3 },
{ name: 'minIncluded', label: $t('include'), type: 'w-checkbox' },
{ name: 'max', label: $t('maxValue'), type: 'w-text', colSpan: 3 },
{ name: 'maxIncluded', label: $t('include'), type: 'w-checkbox' },
{ name: 'value', label: $t('value'), type: 'w-number', colSpan: 3 },
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('numberRange');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
},
];
}
public static getViewerFields(properties: any) {
return [{ name: 'numberRange', label: $t('re.resources.designer.processor.grid.entity.numberRange') }];
}
public static beforeEditorDataSubmit(args: any) {
const form = args.grid.getEditorForm();
const grid = form.getFieldComponent('numberRange');
const localData: any[] = grid.getRows();
const ranges: any[] = [];
localData.forEach((item) => {
ranges.push({
uuid: item.uuid,
minIncluded: item.minIncluded,
min: item.min,
max: item.max,
maxIncluded: item.maxIncluded,
value: item.value,
});
});
args.data.numberRange = Tools.object2Json(ranges);
}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
const form = args.grid.getEditorForm();
const row = args.data;
const grid = form.getFieldComponent('numberRange');
const rows = Tools.json2Object(row.numberRange);
grid.setLocalData(rows);
}
}
export { NumberRange };

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

@ -0,0 +1,266 @@
import { $t, axios, Environment, Tools } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class ObjectProperties {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'objectProperties',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.OBJECT_PROPERTIES'),
icon: 'bi-card-list',
enableIf: (args: any) => {
const valueType = parameter.valueType;
return (
valueType !== 'java.lang.Boolean' &&
valueType !== 'java.lang.Long' &&
valueType !== 'java.lang.Float' &&
valueType !== 'Float' &&
valueType !== 'java.math.BigDecimal' &&
valueType !== 'java.lang.String' &&
valueType !== 'java.util.Date' &&
valueType !== 'io.sc.engine.rule.core.classes.ResourceAbstract' &&
valueType !== 'io.sc.engine.rule.core.classes.RuleResult' &&
valueType !== 'io.sc.engine.rule.core.classes.SingleRuleResult' &&
!valueType.startsWith('List') &&
!valueType.startsWith('Map')
);
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'OBJECT_PROPERTIES');
},
};
}
public static format(row: any) {
let str = '';
if (row.objectCondition) {
str += `<div class='py-2'>When ` + PlaceHolder.replace(row.objectCondition) + ' Then</div>';
}
const objs = Tools.json2Object(row.objectProperties);
if (objs) {
str += `<div class='border border-b-0 overflow-auto' style='max-height:100px'>`;
str += `<table width='100%' height='100%'>`;
objs.forEach((obj: any) => {
str += '<tr>';
str += ` <td width='30%'>` + obj.name + `</td>`;
str += ` <td width='70%'><span>` + ('' + PlaceHolder.replace(obj.expression)) + '</span></td>';
str += '</tr>';
});
str += '</table>';
str += `</div>`;
}
return str;
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'objectCondition',
label: $t('re.resources.designer.processor.grid.entity.objectCondition'),
type: 'w-code-mirror',
lang: 'java',
rows: 3,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'OBJECT_PROPERTIES' === args.form.getFieldValue('type');
},
},
{
colSpan: 5,
name: 'objectProperties',
label: $t('re.resources.designer.processor.grid.entity.objectProperties'),
showIf: (args: any) => {
return 'OBJECT_PROPERTIES' === args.form.getFieldValue('type');
},
type: 'w-grid',
title: $t('re.resources.designer.processor.grid.entity.objectProperties'),
height: 400,
autoFetchData: false,
dbClickOperation: 'edit',
dense: true,
draggable: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
'separator',
{
name: 'autoMatch',
label: $t('autoMatch'),
icon: 'bi-link-45deg',
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('objectProperties');
const localData = grid.getRows();
const objectProperties: any[] = [];
localData.forEach((item: any) => {
objectProperties.push({
code: item.code,
name: item.name,
expression: item.expression,
});
});
properties.objectPropertiesMatcherDialogRef.open(objectProperties);
},
},
'edit',
{
extend: 'remove',
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('objectProperties');
const selecteds: any[] = args.selecteds;
selecteds.forEach((selected) => {
selected.expression = '';
grid.updateLocalData(selected);
});
},
},
'separator',
{
extend: 'remove',
name: 'removeAll',
label: $t('removeAll'),
icon: 'bi-trash3',
enableIf: () => {
return true;
},
click: (args) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('objectProperties');
const rows: any[] = grid.getRows();
rows.forEach((row) => {
row.expression = '';
});
grid.setLocalData(rows);
},
},
],
primaryKey: 'code',
columns: [
{ name: 'code', label: 'code', hidden: true },
{
width: 300,
name: 'name',
label: $t('propertyName'),
align: 'left',
sortable: false,
format: (value: any, row: any) => {
if (row.expression) {
const expression = row.expression.replace(/\$\{(.+?)\.(.+?)\}/g, '$2');
if (expression.trim() !== value.trim()) {
return `<span class='text-red-500'>` + value + '</span>';
}
}
return value;
},
},
{
width: '100%',
name: 'expression',
label: $t('expression'),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
],
editor: {
dialog: {
width: '800px',
},
form: {
colsNum: 1,
fields: [
{ name: 'code', label: 'code', showIf: false },
{
name: 'expression',
label: $t('expression'),
type: 'w-code-mirror',
lang: 'java',
rows: 3,
lineWrap: true,
lineBreak: false,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('objectProperties');
const form = grid.getEditorForm();
if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
},
];
}
public static getViewerFields(properties) {
return [];
}
public static beforeEditorDataSubmit(args: any) {
const form = args.grid.getEditorForm();
const grid = form.getFieldComponent('objectProperties');
const localData: any[] = grid.getRows();
const objectProperties: any[] = [];
localData.forEach((item) => {
objectProperties.push({
code: item.code,
name: item.name,
expression: item.expression,
});
});
args.data.objectProperties = Tools.object2Json(objectProperties);
}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
const form = args.grid.getEditorForm();
const row = args.data;
if ('add' == form.getStatus()) {
let listObejctPropertiesUrl = '';
if (args.type === 'parameter') {
listObejctPropertiesUrl = '/api/re/model/parameter/listObejctPropertiesByParameterId/' + args.parameter.id;
} else if (args.type === 'indicator') {
listObejctPropertiesUrl = '/api/re/indicator/listObejctPropertiesByIndicatorId/' + args.indicator.id;
}
axios.get(Environment.apiContextPath(listObejctPropertiesUrl)).then((response) => {
const properties = response.data;
const grid = form.getFieldComponent('objectProperties');
grid?.setLocalData(properties);
});
} else if ('edit' == form.getStatus()) {
let listObejctPropertiesUrl = '';
if (args.type === 'parameter') {
listObejctPropertiesUrl = '/api/re/model/parameter/processor/listObejctPropertiesByProcessorId/' + row.id;
} else if (args.type === 'indicator') {
listObejctPropertiesUrl = '/api/re/indicator/processor/listObejctPropertiesByProcessorId/' + row.id;
}
axios.get(Environment.apiContextPath(listObejctPropertiesUrl)).then((response) => {
const properties = response.data;
const grid = form.getFieldComponent('objectProperties');
grid?.setLocalData(properties);
});
}
}
}
export { ObjectProperties };

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

@ -0,0 +1,62 @@
import { ref } from 'vue';
import { $t, axios, Environment } from 'platform-core';
const optionOptionsRef = ref(<any>[]);
class OptionValue {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'optionValue',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.OPTION_VALUE'),
icon: 'bi-card-list',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'OPTION_VALUE');
},
};
}
public static format(row: any) {
return row.optionCode;
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'optionCode',
label: $t('re.resources.designer.processor.grid.entity.optionCode'),
type: 'w-select',
options: optionOptionsRef,
showIf: (args: any) => {
return 'OPTION_VALUE' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [{ name: 'optionCode', label: $t('re.resources.designer.processor.grid.entity.optionCode') }];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {
// 获取选项输入参数列表
axios.get(Environment.apiContextPath('/api/re/model/parameter/listParemtersByParameterId/' + args.parameter.id)).then((response) => {
const parameters: any[] = response.data;
const options: any[] = [];
parameters.forEach((item) => {
if (item.type === 'IN_OPTION') {
options.push({ label: item.name, value: item.code });
}
});
optionOptionsRef.value = options;
});
}
}
export { OptionValue };

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

@ -0,0 +1,54 @@
import { $t } from 'platform-core';
class Pmml {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'pmml',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.PMML'),
icon: 'bi-filetype-xml',
enableIf: (args) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'PMML');
},
};
}
public static format(row: any) {
const div = document.createElement('div');
div.textContent = row.pmml;
const result = div.outerHTML;
div.parentNode?.removeChild(div);
return result;
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'pmml',
label: $t('re.resources.designer.processor.grid.entity.pmml'),
type: 'w-code-mirror',
rows: 20,
lineNumber: true,
toolbar: false,
lang: 'xml',
showIf: (args: any) => {
return 'PMML' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {}
}
export { Pmml };

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

@ -0,0 +1,36 @@
import { $t } from 'platform-core';
class Rule {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'rule',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.RULE'),
icon: 'bi-shadows',
enableIf: (args: any) => {
return parameter.type === 'RULE_RESULT' || parameter.type === 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'RULE');
},
};
}
public static format(row: any) {
return row.rule;
}
public static getEditorFields(properties: any) {
return [];
}
public static getViewerFields(properties: any) {
return [{ name: 'rule', label: $t('re.resources.designer.processor.grid.entity.rule') }];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {}
}
export { Rule };

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

@ -0,0 +1,37 @@
import { $t } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
class SingleRule {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'singleRule',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.SINGLE_RULE'),
icon: 'bi-noise-reduction',
enableIf: (args: any) => {
return parameter.type === 'RULE_RESULT' || parameter.type === 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'SINGLE_RULE');
},
};
}
public static format(row: any) {
return row.singleRule;
}
public static getEditorFields(properties: any) {
return [];
}
public static getViewerFields(properties: any) {
return [{ name: 'singleRule', label: $t('re.resources.designer.processor.grid.entity.singleRule') }];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {}
}
export { SingleRule };

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

@ -0,0 +1,418 @@
import { ref, computed } from 'vue';
import { axios, Environment, $t, Tools } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
const autoCompletionManager = new AutoCompletionManager();
const dsOptionsRef = ref(<any>[]);
const parameterOptionsRef = ref(<any>[]);
const sqlQueryResultFieldsRef = ref(<any>[]);
class Sql {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'sql',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.SQL'),
icon: 'bi-filetype-sql',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'SQL');
},
};
}
public static format(row: any) {
return {
componentType: 'w-code-mirror',
attrs: {
lang: 'sql',
rows: 4,
editable: false,
modelValue: row.sql,
placeholder: true,
},
};
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'sqlDatasourceName',
label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName'),
type: 'w-select',
clearable: true,
options: dsOptionsRef,
rows: 1,
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
},
{
colSpan: 3,
name: 'sql',
label: $t('re.resources.designer.processor.grid.entity.sql'),
type: 'w-code-mirror',
height: 180,
lang: 'sql',
toolbar: false,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
},
{
colSpan: 2,
name: 'sqlParameterValues',
label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 150,
title: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
autoFetchData: false,
dense: true,
dbClickOperation: 'edit',
draggable: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
{
name: 'analyze',
label: $t('analyze'),
icon: 'bi-tag',
click: (args: any) => {
const sql = properties.gridRef.getEditorForm().getFieldValue('sql');
const regex = /\$\{[\u0000-\uFFFF]+?\}/g;
const array: any[] = sql.match(regex);
const rows: any[] = [];
array.forEach((item) => {
rows.push({ uuid: Tools.uuid(), name: item, value: '' });
});
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlParameterValues');
grid.setLocalData(rows);
},
},
'separator',
'add',
'edit',
[
{
extend: 'remove',
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlParameterValues');
grid.removeRows(args.selecteds);
},
},
{
extend: 'remove',
name: 'removeAll',
label: $t('deleteAll'),
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlParameterValues');
grid.setLocalData([]);
},
},
],
],
primaryKey: 'uuid',
columns: [
{ name: 'uuid', label: 'uuid', hidden: true },
{
width: '50%',
name: 'name',
label: $t('name'),
align: 'left',
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
{
width: '100%',
name: 'value',
label: $t('value'),
sortable: false,
},
],
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false },
{
name: 'name',
label: $t('name'),
type: 'w-code-mirror',
toolbar: false,
lang: 'java',
rows: 1,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
},
{
name: 'value',
label: $t('value'),
type: 'w-text',
},
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlParameterValues');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
},
{
colSpan: 3,
name: 'sqlQueryResult',
label: $t('re.resources.designer.processor.grid.entity.sqlQueryResult'),
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 250,
autoFetchData: false,
title: $t('re.resources.designer.processor.grid.entity.sqlQueryResult'),
dense: true,
draggable: 'local',
pageable: false,
checkboxSelection: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
{
name: 'execute',
label: $t('execute'),
icon: 'bi-caret-right',
click: (args: any) => {
const sql = properties.gridRef.getEditorForm().getFieldValue('sql');
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlParameterValues');
const sqlParameterValues = grid?.getRows();
axios
.post(Environment.apiContextPath('/api/re/model/parameter/processor/executeSql'), {
sql: sql,
sqlParameterValues: sqlParameterValues,
})
.then((response) => {
const fieldMetaDatas: any[] = response.data.fieldMetaDatas;
fieldMetaDatas.forEach((field) => {
field.value = field.name;
field.label = field.name;
});
const data = response.data.data;
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlQueryResult');
sqlQueryResultFieldsRef.value = fieldMetaDatas;
grid.setLocalData(data);
});
},
},
],
columns: computed(() => {
return sqlQueryResultFieldsRef.value;
}),
},
{
colSpan: 2,
name: 'sqlFieldMapping',
label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
showIf: (args: any) => {
return 'SQL' === args.form.getFieldValue('type');
},
type: 'w-grid',
height: 250,
width: '100%',
autoFetchData: false,
title: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
dense: true,
dbClickOperation: 'edit',
draggable: 'local',
pageable: false,
configButton: false,
toolbarConfigure: { noIcon: false },
toolbarActions: [
'add',
'edit',
[
{
extend: 'remove',
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlFieldMapping');
grid.removeLocalData(args.selecteds);
},
},
{
extend: 'remove',
name: 'removeAll',
label: $t('deleteAll'),
click: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlFieldMapping');
grid.setLocalData([]);
},
},
],
],
primaryKey: 'uuid',
columns: [
{ name: 'uuid', label: 'uuid', hidden: true },
{
width: '50%',
name: 'parameter',
label: $t('parameterName'),
sortable: false,
format: (value: any) => {
return PlaceHolder.replace(value);
},
},
{
width: '50%',
name: 'field',
label: $t('fieldName'),
align: 'left',
sortable: false,
},
],
editor: {
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{ name: 'uuid', label: 'uuid', showIf: false },
{
name: 'parameter',
label: $t('parameterName'),
type: 'w-select',
options: properties.parameterOptionsRef,
},
{
name: 'field',
label: $t('fieldName'),
type: 'w-select',
options: sqlQueryResultFieldsRef.value,
},
],
},
},
onBeforeEditorDataSubmit: (args: any) => {
const grid = properties.gridRef.getEditorForm().getFieldComponent('sqlFieldMapping');
const form = grid.getEditorForm();
if ('add' == form.getStatus() || 'clone' == form.getStatus()) {
args.data.uuid = Tools.uuid();
grid.addLocalData(args.data);
args.callback(false);
} else if ('edit' == form.getStatus()) {
grid.updateLocalData(args.data);
args.callback(false);
}
},
},
];
}
public static getViewerFields(properties: any) {
return [
{ name: 'sqlDatasourceName', label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName') },
{ name: 'sql', label: $t('re.resources.designer.processor.grid.entity.sql') },
{ name: 'sqlParameterValues', label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues') },
{ name: 'sqlFieldMapping', label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping') },
];
}
public static beforeEditorDataSubmit(args: any) {
axios.get(Environment.apiContextPath('/api/system/datasource')).then((response) => {
const items: any[] = response.data?.content;
if (items) {
const options: any[] = [];
items.forEach((item) => {
options.push({ label: item.name, value: item.name });
});
dsOptionsRef.value = options;
}
});
const form = args.grid.getEditorForm();
const sqlParameterValuesGrid = form.getFieldComponent('sqlParameterValues');
const sqlParameterValuesLocalData: any[] = sqlParameterValuesGrid.getRows();
const sqlParameterValues: any[] = [];
sqlParameterValuesLocalData.forEach((item) => {
sqlParameterValues.push({
uuid: item.uuid,
name: item.name,
value: item.value,
});
});
args.data.sqlParameterValues = Tools.object2Json(sqlParameterValues);
const sqlFieldMappingGrid = form.getFieldComponent('sqlFieldMapping');
const sqlFieldMappingLocalData: any[] = sqlFieldMappingGrid.getRows();
const sqlFieldMapping: any[] = [];
sqlFieldMappingLocalData.forEach((item) => {
sqlFieldMapping.push({
uuid: item.uuid,
field: item.field,
parameter: item.parameter,
});
});
args.data.sqlFieldMapping = Tools.object2Json(sqlFieldMapping);
}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
const form = args.grid.getEditorForm();
const row = args.data;
axios.get(Environment.apiContextPath('/api/system/datasource')).then((response) => {
const items: any[] = response.data?.content;
if (items) {
const options: any[] = [];
items.forEach((item) => {
options.push({ label: item.name, value: item.name });
});
dsOptionsRef.value = options;
}
});
axios.get(Environment.apiContextPath('api/re/model/parameter/findParametersByParameterId?parameterId=' + args.parameter.id)).then((response) => {
const options: any[] = [];
response.data.forEach((parameter) => {
options.push({ label: parameter.name, value: '${' + parameter.name + '}' });
});
parameterOptionsRef.value = options;
});
const sqlParameterValuesGrid = form.getFieldComponent('sqlParameterValues');
const sqlParameterValuesRows = Tools.json2Object(row.sqlParameterValues);
sqlParameterValuesGrid.setLocalData(sqlParameterValuesRows);
const sqlFieldMappingGrid = form.getFieldComponent('sqlFieldMapping');
const sqlFieldMappingRows = Tools.json2Object(row.sqlFieldMapping);
sqlFieldMappingGrid.setLocalData(sqlFieldMappingRows);
}
}
export { Sql };

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

@ -0,0 +1,108 @@
import { $t, Environment } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class Ternary {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'ternary',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.TERNARY'),
icon: 'bi-question',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'TERNARY');
},
};
}
public static format(row: any) {
return (
PlaceHolder.replace(row.ternaryCondition) +
' <b><span>?</span></b> ' +
PlaceHolder.replace(row.ternaryTrue) +
' <b><span>:</span></b> ' +
PlaceHolder.replace(row.ternaryFalse)
);
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'ternaryCondition',
label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'),
type: 'w-code-mirror',
lang: 'java',
rows: 4,
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'TERNARY' === args.form.getFieldValue('type');
},
},
{
colSpan: 5,
name: 'ternaryTrue',
label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'),
type: 'w-code-mirror',
lang: 'java',
rows: 4,
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'TERNARY' === args.form.getFieldValue('type');
},
},
{
colSpan: 5,
name: 'ternaryFalse',
label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'),
type: 'w-code-mirror',
lang: 'java',
rows: 4,
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'TERNARY' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [
{ 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') },
];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
}
}
export { Ternary };

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

@ -0,0 +1,105 @@
import { $t, Environment } from 'platform-core';
import { PlaceHolder } from '@/utils/PlaceHolder';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
const autoCompletionManager = new AutoCompletionManager();
const userDefinedFunctionsManager = new UserDefinedFunctionsManager();
class WhenThen {
public static getToolbarAction(parameter: any) {
return {
extend: 'add',
name: 'whenThen',
label: $t('io.sc.engine.rule.core.enums.ProcessorType.WHEN_THEN'),
icon: 'bi-sliders',
enableIf: (args: any) => {
return parameter.type !== 'RULE_RESULT' && parameter.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (args: any) => {
args.grid.getEditorForm().setFieldValue('type', 'WHEN_THEN');
},
};
}
public static format(row: any) {
let str = '';
if (row.isWhenThenShorted) {
str += '<span>' + $t('re.resources.designer.processor.grid.entity.isWhenThenShorted') + ', </span>';
}
if (row.when) {
str += '<span>When</span> ' + PlaceHolder.replace(row.when) + ' ';
}
if (row.then) {
str += '<span>Then</span> ' + PlaceHolder.replace(row.then);
}
return str;
}
public static getEditorFields(properties: any) {
return [
{
colSpan: 5,
name: 'when',
label: $t('re.resources.designer.processor.grid.entity.when'),
type: 'w-code-mirror',
lang: 'java',
rows: 4,
lineWrap: true,
lineBreak: false,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'WHEN_THEN' === args.form.getFieldValue('type');
},
},
{
colSpan: 5,
name: 'then',
label: $t('re.resources.designer.processor.grid.entity.then'),
type: 'w-code-mirror',
lang: 'java',
rows: 4,
lineWrap: true,
lineBreak: false,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
showIf: (args: any) => {
return 'WHEN_THEN' === args.form.getFieldValue('type');
},
},
{
colSpan: 5,
name: 'isWhenThenShorted',
label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted'),
type: 'w-checkbox',
showIf: (args: any) => {
return 'WHEN_THEN' === args.form.getFieldValue('type');
},
},
];
}
public static getViewerFields(properties: any) {
return [
{ 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') },
];
}
public static beforeEditorDataSubmit(args: any) {}
public static afterEditorOpen(args: any) {
if (args.type === 'parameter') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/' + args.parameter.id));
} else if (args.type === 'indicator') {
autoCompletionManager.load(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/' + args.indicator.id));
}
userDefinedFunctionsManager.load();
}
}
export { WhenThen };

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

@ -0,0 +1,17 @@
export { Arithmetic } from './Arithmetic';
export { ConditionRange } from './ConditionRange';
export { DecisionTable } from './DecisionTable';
export { DecisionTable2c } from './DecisionTable2c';
export { DecisionTree } from './DecisionTree';
export { ExecutionFlow } from './ExecutionFlow';
export { GroovyScript } from './GroovyScript';
export { MathFormula } from './MathFormula';
export { NumberRange } from './NumberRange';
export { ObjectProperties } from './ObjectProperties';
export { OptionValue } from './OptionValue';
export { Pmml } from './Pmml';
export { Rule } from './Rule';
export { SingleRule } from './SingleRule';
export { Sql } from './Sql';
export { Ternary } from './Ternary';
export { WhenThen } from './WhenThen';

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

@ -177,18 +177,18 @@ public class IndicatorProcessorServiceImpl extends DaoServiceImpl<IndicatorProce
if(autoMatchObjectProperties==null){
return Collections.emptyList();
}
String parameterId =autoMatchObjectProperties.getParameterId();
String indicatorId =autoMatchObjectProperties.getId();
List<ObjectProperty> objectProperties =autoMatchObjectProperties.getObjectProperties();
if(!StringUtils.hasText(parameterId) || objectProperties==null || objectProperties.isEmpty()){
if(!StringUtils.hasText(indicatorId) || objectProperties==null || objectProperties.isEmpty()){
return objectProperties;
}
IndicatorEntity parameter =indicatorService.findById(parameterId);
if(parameter==null){
IndicatorEntity indicator =indicatorService.findById(indicatorId);
if(indicator==null){
return objectProperties;
}
String valueType =parameter.getValueType();
Integer valueTypeVersion =parameter.getValueTypeVersion();
String valueType =indicator.getValueType();
Integer valueTypeVersion =indicator.getValueTypeVersion();
if(
"java.lang.Boolean".equals(valueType) ||
"java.lang.Long".equals(valueType) ||
@ -228,7 +228,7 @@ public class IndicatorProcessorServiceImpl extends DaoServiceImpl<IndicatorProce
if(!StringUtils.hasText(objectProperty.getExpression())){
String catchedName =matchName(objectProperty.getName(),cache);
if(StringUtils.hasText(catchedName)) {
objectProperty.setExpression("${" + parameter.getName() + "." + catchedName + "}");
objectProperty.setExpression("${" + indicator.getName() + "." + catchedName + "}");
}
}
}

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

@ -107,7 +107,7 @@ public class ParameterProcessorServiceImpl
if(autoMatchObjectProperties==null){
return Collections.emptyList();
}
String parameterId =autoMatchObjectProperties.getParameterId();
String parameterId =autoMatchObjectProperties.getId();
List<ObjectProperty> objectProperties =autoMatchObjectProperties.getObjectProperties();
if(!StringUtils.hasText(parameterId) || objectProperties==null || objectProperties.isEmpty()){
return objectProperties;

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

@ -4,15 +4,15 @@ import java.util.ArrayList;
import java.util.List;
public class AutoMatchObjectProperties {
private String parameterId;
private String id;
private List<ObjectProperty> objectProperties =new ArrayList<ObjectProperty>();
public String getParameterId() {
return parameterId;
public String getId() {
return id;
}
public void setParameterId(String parameterId) {
this.parameterId = parameterId;
public void setId(String id) {
this.id = id;
}
public List<ObjectProperty> getObjectProperties() {

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.st.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -54,6 +54,7 @@ const syncFrontendProject = () => {
cp(sourceDir + 'src/boostrap.ts', targetDir + 'src/boostrap.ts');
cp(sourceDir + '.browserslistrc', targetDir + '.browserslistrc');
cp(sourceDir + '.editorconfig', targetDir + '.editorconfig');
cp(sourceDir + '.eslintrc.cjs', targetDir + '.eslintrc.cjs');
cp(sourceDir + '.gitignore', targetDir + '.gitignore');
cp(sourceDir + '.npmignore', targetDir + '.npmignore');
cp(sourceDir + '.npmrc', targetDir + '.npmrc');

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

@ -64,5 +64,6 @@ module.exports = {
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

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

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

@ -1,6 +1,6 @@
<template>
<q-toolbar style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px">
<input style="width: 0px" /><!--采用宽度为0的输入框,避免第一按钮默认获得焦点-->
<input style="width: 0px; height: 0px; border: 0px" /><!--采用宽度为0的输入框,避免第一按钮默认获得焦点-->
<template v-if="!sourceCodeEditor">
<!-- 操作 -->
<Xml v-model="modelValueRef"></Xml>

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

@ -13,6 +13,7 @@ import '@quasar/extras/bootstrap-icons/bootstrap-icons.css';
import '@quasar/extras/material-icons/material-icons.css';
// 引入 tailwindcss
import 'tailwindcss/base.css';
import 'tailwindcss/utilities.css';
// 引入 maxgraph css

2
io.sc.platform.core.frontend/src/platform/plugin/i18n.ts

@ -29,7 +29,7 @@ const i18n = createI18n({
* @param defaultMessage key时返回的缺省文本
* @returns
*/
const t = (key, args, defaultMessage) => {
const t = (key: string, args?: any, defaultMessage?: any) => {
if (key === null || typeof key === 'undefined') {
return null;
}

54
io.sc.platform.core.frontend/src/platform/utils/EnumTools.ts

@ -2,6 +2,8 @@ import type { EnumType } from '@/platform/types';
import { axios, Environment, Tools } from '@/platform';
class EnumTools {
static #cache: Map<string, EnumType> = new Map();
public static async fetch(codes: string | string[]) {
if (!Tools.isUndefinedOrNull(codes)) {
if (Tools.isArray(codes)) {
@ -13,39 +15,41 @@ class EnumTools {
}
public static async fetchSingle(type: string): Promise<EnumType> {
const response = await axios.get(Environment.apiContextPath('/api/enum/list/') + type);
if (response) {
return {
name: type,
items: response.data,
};
} else {
return {
name: type,
items: [],
};
if (EnumTools.#cache.has(type)) {
return EnumTools.#cache.get(type) as EnumType;
}
const response = await axios.get(Environment.apiContextPath('/api/enum/list/') + type);
const enumType = {
name: type,
items: response?.data || [],
};
EnumTools.#cache.set(type, enumType);
return enumType;
}
public static async fetchMultiple(types: string[]): Promise<Map<string, EnumType>> {
if (types && types.length > 0) {
// 从缓存中查找, 标记还未加载的枚举
const parameters: any[] = [];
for (const type of types) {
parameters.push({ key: 'types', value: type });
}
const response = await axios.get(Environment.apiContextPath('/api/enum/list?' + Tools.buildHttpQueryString(parameters)));
if (response) {
const map = response.data;
const result = {};
for (const code in map) {
const items = map[code];
result[code] = {
name: code,
items: items,
};
types.forEach((type) => {
if (!EnumTools.#cache.has(type)) {
parameters.push({ key: 'types', value: type });
}
});
if (parameters.length > 0) {
// 加载还未加载的枚举
const response = await axios.get(Environment.apiContextPath('/api/enum/list?' + Tools.buildHttpQueryString(parameters)));
const map = response?.data || {};
for (const type in map) {
EnumTools.#cache.set(type, { name: type, items: map[type] || [] });
}
return result as Map<string, EnumType>;
}
const result = {};
types.forEach((type) => {
const simpleType = type.indexOf('.') > -1 ? type.substring(type.lastIndexOf('.') + 1) : type;
result[simpleType] = EnumTools.#cache.get(type);
});
return result as Map<string, EnumType>;
}
return {} as Map<string, EnumType>;
}

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

@ -975,6 +975,38 @@ class Tools {
parent.insertBefore(newElement, targetElement.nextSibling);
}
}
public static extractAllPropertyNames(objects: any[], propertyNamePattern) {
if (objects && Tools.isArray(objects)) {
//必须是数组
const allPropertyNames = [];
let index = 0;
for (let i = 0; i < objects.length; i++) {
const object = objects[i];
if (Tools.isObject(object)) {
//数组元素必须是对象
const propertyNames = Object.keys(object); //获取所有对象的属性
for (let j = 0; j < propertyNames.length; j++) {
if (propertyNamePattern) {
if (propertyNamePattern.test(propertyNames[j])) {
//匹配属性名正则表达式
if (allPropertyNames.indexOf(propertyNames[j]) == -1) {
//是否已经存在
allPropertyNames[index++] = propertyNames[j];
}
}
} else {
if (allPropertyNames.indexOf(propertyNames[j]) == -1) {
allPropertyNames[index++] = propertyNames[j];
}
}
}
}
}
return allPropertyNames;
}
return [];
}
}
export { Tools };

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

@ -1,45 +1,14 @@
<template>
<w-code-mirror
lang="sql"
:rows="20"
:placeholder="true"
:auto-completion="autoCompletion"
:editable="true"
:user-defined-functions="userDefinedFunctionsRef"
user-defined-functions-ref
></w-code-mirror>
<w-code-mirror lang="sql" :rows="20" :placeholder="true" :editable="true"></w-code-mirror>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, Tools } from '@/platform';
import { AutoCompletionManager } from './AutoCompletionManager';
import { AutoCompletionManager2 } from './AutoCompletionManager2';
const autoCompletionManager = new AutoCompletionManager();
// axios.get(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/bc8add2e-df95-44f3-96f5-e9d106a48729')).then((response) => {
// autoCompletionManager.setParameters(response.data.parameters);
// autoCompletionManager.setValueTypes(response.data.valueTypes);
// });
const autoCompletion = (context) => {
return autoCompletionManager.autoCompletion(context);
};
const activateOnCompletion = (completion) => {
console.log(completion);
};
const userDefinedFunctionsRef = ref();
axios.get(Environment.apiContextPath('/api/re/function?pageable=false')).then((response) => {
userDefinedFunctionsRef.value = response.data.content;
});
const reg = /\$\{(.+?)\}\.$/g;
//const regReverse = /(\.\}(.+?)\{\$)+/g;
let str = ' ${对象}.${属性}+${对象2}.';
//console.log(str);
//str = Tools.reverseString(str);
//console.log(str);
const matched = str.match(reg);
console.log(matched);
//console.log(Tools.reverseString(matched[0]));
import { axios, Environment, EnumTools, Tools, Formater } from '@/platform';
//const v = await EnumTools.fetch(['io.sc.platform.system.enums.MenuType', 'io.sc.platform.system.enums.UrlOpenType']);
let v = await EnumTools.fetch('io.sc.platform.system.enums.MenuType');
console.log(Formater.enum(v)('GROUP'));
v = await EnumTools.fetch(['io.sc.platform.system.enums.MenuType', 'io.sc.platform.system.enums.UrlOpenType']);
console.log(Formater.enum(v.MenuType)('GROUP'));
//const UrlOpenTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.UrlOpenType');
</script>

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

@ -64,5 +64,6 @@ module.exports = {
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,17 +1,17 @@
{
"name": "platform-core",
"version": "8.1.410",
"version": "8.1.416",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
"author": "",
"license": "ISC",
"scripts": {
"clean": "platform clean dist ./node_modules ./pnpm-lock.yaml ./package-lock.json",
"dev": "nodemon",
"serve": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack serve --config webpack.env.serve.cjs",
"build": "node ./util-components-generator.cjs && cross-env NODE_ENV=development webpack --config webpack.env.build.cjs",
"prod": "node ./util-components-generator.cjs && cross-env NODE_ENV=production webpack --config webpack.env.prod.cjs",
"clean": "platform clean dist ./node_modules ./pnpm-lock.yaml ./package-lock.json",
"sync": "platform sync"
},
"engines": {
@ -110,7 +110,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"platform-core": "8.1.410",
"platform-core": "8.1.416",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"vue": "3.5.10",

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

@ -1,45 +1,14 @@
<template>
<w-code-mirror
lang="sql"
:rows="20"
:placeholder="true"
:auto-completion="autoCompletion"
:editable="true"
:user-defined-functions="userDefinedFunctionsRef"
user-defined-functions-ref
></w-code-mirror>
<w-code-mirror lang="sql" :rows="20" :placeholder="true" :editable="true"></w-code-mirror>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, Tools } from '@/platform';
import { AutoCompletionManager } from './AutoCompletionManager';
import { AutoCompletionManager2 } from './AutoCompletionManager2';
const autoCompletionManager = new AutoCompletionManager();
// axios.get(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByIndicatorId/bc8add2e-df95-44f3-96f5-e9d106a48729')).then((response) => {
// autoCompletionManager.setParameters(response.data.parameters);
// autoCompletionManager.setValueTypes(response.data.valueTypes);
// });
const autoCompletion = (context) => {
return autoCompletionManager.autoCompletion(context);
};
const activateOnCompletion = (completion) => {
console.log(completion);
};
const userDefinedFunctionsRef = ref();
axios.get(Environment.apiContextPath('/api/re/function?pageable=false')).then((response) => {
userDefinedFunctionsRef.value = response.data.content;
});
const reg = /\$\{(.+?)\}\.$/g;
//const regReverse = /(\.\}(.+?)\{\$)+/g;
let str = ' ${对象}.${属性}+${对象2}.';
//console.log(str);
//str = Tools.reverseString(str);
//console.log(str);
const matched = str.match(reg);
console.log(matched);
//console.log(Tools.reverseString(matched[0]));
import { axios, Environment, EnumTools, Tools, Formater } from '@/platform';
//const v = await EnumTools.fetch(['io.sc.platform.system.enums.MenuType', 'io.sc.platform.system.enums.UrlOpenType']);
let v = await EnumTools.fetch('io.sc.platform.system.enums.MenuType');
console.log(Formater.enum(v)('GROUP'));
v = await EnumTools.fetch(['io.sc.platform.system.enums.MenuType', 'io.sc.platform.system.enums.UrlOpenType']);
console.log(Formater.enum(v.MenuType)('GROUP'));
//const UrlOpenTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.UrlOpenType');
</script>

2
io.sc.platform.core/src/main/java/io/sc/platform/core/controller/EnumWebController.java

@ -38,7 +38,7 @@ public class EnumWebController {
if(clazz.isEnum()){
Method method =clazz.getDeclaredMethod("values");
Enum<?>[] enums =(Enum<?>[])method.invoke(null);
result.put(clazz.getSimpleName(),convert(enums));
result.put(clazz.getName(),convert(enums));
}
}
}

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

@ -1,12 +1,14 @@
{
"name": "io.sc.platform.developer.doc",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"main": "index.js",
"scripts": {
"serve": "vuepress dev vuepress-src",
"build": "vuepress build vuepress-src && rm -rf dist/public/io.sc.platform.developer.doc && mv dist/public/site/ dist/public/io.sc.platform.developer.doc/",
"prod": "vuepress build vuepress-src && rm -rf dist/public/io.sc.platform.developer.doc && mv dist/public/site/ dist/public/io.sc.platform.developer.doc/",
"//build": "vuepress build vuepress-src && rm -rf dist/public/io.sc.platform.developer.doc && mv dist/public/site/ dist/public/io.sc.platform.developer.doc/",
"//prod": "vuepress build vuepress-src && rm -rf dist/public/io.sc.platform.developer.doc && mv dist/public/site/ dist/public/io.sc.platform.developer.doc/",
"build": "cd .",
"prod": "cd .",
"clean": "platform clean dist ./node_modules ./pnpm-lock.yaml ./package-lock.json",
"sync": "platform sync"
},
@ -26,7 +28,7 @@
"vuepress": "2.0.0-rc.15"
},
"dependencies": {
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"vue": "3.5.10",
"vue-i18n": "10.0.3"

6
io.sc.platform.developer.doc/src/main/resources/META-INF/platform/plugins/security.json

@ -1,6 +0,0 @@
{
"permitPatterns": [
"/help/io.sc.platform.developer.doc/**/*",
"/io.sc.platform.developer.doc/**/*"
]
}

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.developer.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -37,7 +37,7 @@ application_version=1.0.0
###########################################################
platform_group=io.sc
platform_version=8.1.50
platform_plugin_version=8.1.49
platform_plugin_version=8.1.50
platform_core_frontend_version=8.1.410
###########################################################

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.lcdp.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.license.keygen.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.mvc.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.scheduler.manager.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.system.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -110,7 +110,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"vue": "3.5.10",

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

@ -1,36 +1,69 @@
module.exports = {
root: true,
// https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
// This option interrupts the configuration hierarchy at this file
// Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
root: true,
env: {
browser: true,
es2022: true,
"vue/setup-compiler-macros": true,
},
env: {
browser: true,
es2022: true,
node: true,
'vue/setup-compiler-macros': true,
},
parserOptions:{
ecmaVersion: 2022,
sourceType:"module",
},
// Rules order is important, please avoid shuffling them
extends: [
// Base ESLint recommended rules
'eslint:recommended',
extends:[
"eslint:recommended",
"plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
],
parser: "vue-eslint-parser",
parserOptions: {
ecmaVersion: 2022,
parser: "@typescript-eslint/parser",
sourceType: "module",
},
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage
// ESLint typescript rules
'plugin:@typescript-eslint/recommended',
// Vue ESLint recommended rules
// 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
// 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
// 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
'plugin:vue/vue3-recommended',
// https://github.com/prettier/eslint-config-prettier#installation
// usage with Prettier, provided by 'eslint-config-prettier'.
'plugin:prettier/recommended', // Recommended
],
rules:{
'semi':[1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": 'off',
'vue/multi-word-component-names': 'off', /* 禁用 vue 组件名称检查规则 */
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2022,
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: false,
},
},
plugins: [
// required to apply rules which need type information
'@typescript-eslint',
// https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
// required to lint *.vue files
'vue',
// https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
// Prettier has not been included as plugin to avoid performance impact
// add it as an extension for your IDE
],
rules: {
semi: [1],
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-this-alias': 'off',
'vue/multi-word-component-names': 'off' /* 禁用 vue 组件名称检查规则 */,
'no-prototype-builtins': 'off',
'prefer-rest-params': 'off',
'no-control-regex': 'off',
},
};

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

@ -1,6 +1,6 @@
{
"name": "io.sc.standard.frontend",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"node-sql-parser": "5.3.2",
"pinia": "2.2.2",
"pinia-undo": "0.2.4",
"platform-core": "8.1.410",
"platform-core": "8.1.414",
"quasar": "2.17.0",
"svg-path-commander": "2.0.10",
"tailwindcss": "3.4.10",

4
io.sc.website/package.json

@ -1,6 +1,6 @@
{
"name": "io.sc.website",
"version": "8.1.49",
"version": "8.1.50",
"description": "",
"main": "index.js",
"scripts": {
@ -28,6 +28,6 @@
},
"dependencies": {
"vue": "3.5.10",
"platform-core": "8.1.410"
"platform-core": "8.1.414"
}
}
Loading…
Cancel
Save