Browse Source

update

main
wangshaoping 11 months ago
parent
commit
bf364d9028
  1. 2
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/IndicatorType.java
  2. 2
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/LibType.java
  3. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums.properties
  4. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_tw_CN.properties
  5. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_zh_CN.properties
  6. 2
      io.sc.engine.rule.frontend/package.json
  7. 77
      io.sc.engine.rule.frontend/src/i18n/messages.json
  8. 78
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  9. 52
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  10. 71
      io.sc.engine.rule.frontend/src/views/dictionary/ImportDialog.vue
  11. 91
      io.sc.engine.rule.frontend/src/views/dictionary/ImportSampleDialog.vue
  12. 25
      io.sc.engine.rule.frontend/src/views/dictionary/UserDefinedJavaClassDictionaryJsonDialog.vue
  13. 212
      io.sc.engine.rule.frontend/src/views/dictionary/dictionary.vue
  14. 71
      io.sc.engine.rule.frontend/src/views/lib/ImportDialog.vue
  15. 91
      io.sc.engine.rule.frontend/src/views/lib/ImportSampleDialog.vue
  16. 166
      io.sc.engine.rule.frontend/src/views/lib/IndicatorGrid.vue
  17. 99
      io.sc.engine.rule.frontend/src/views/lib/Lib.vue
  18. 275
      io.sc.engine.rule.frontend/src/views/lib/LibGrid.vue
  19. 337
      io.sc.engine.rule.frontend/src/views/lib/ProcessorGrid.vue
  20. 217
      io.sc.engine.rule.frontend/src/views/lib/ValidatorGrid.vue
  21. 147
      io.sc.engine.rule.frontend/src/views/migration/Migration.vue
  22. 6
      io.sc.engine.rule.frontend/src/views/resources/ImportDialog.vue
  23. 3
      io.sc.engine.rule.frontend/src/views/resources/Resources.vue
  24. 19
      io.sc.engine.rule.frontend/src/views/resources/designer/Model.vue
  25. 16
      io.sc.engine.rule.sample/src/main/resources/META-INF/platform/plugins/messages.json
  26. 70
      io.sc.engine.rule.sample/src/main/resources/META-INF/platform/plugins/rule-engine-sample-resource.json
  27. 150995
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/irs/hankou/汉口银行-内部评级模型(非零售).json
  28. 14015
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/other/个人消费贷模型(英语).json
  29. 536
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/other/昆山农商行-反洗钱模型(机器学习模型).json
  30. 1695
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/other/昆山农商行-非法集资(规则).json
  31. 2342
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/rirs/hankou/汉口银行-内部评级模型(零售).json
  32. 8901
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/rirs/tianfu/天府银行-风险定价模型.json
  33. 4908
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-租后预警规则.json
  34. 74651
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警(指标库).json
  35. 10572
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警(数据字典).json
  36. 60321
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警.json
  37. 34
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/i18n/messages.properties
  38. 35
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/i18n/messages_tw_CN.properties
  39. 35
      io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/i18n/messages_zh_CN.properties
  40. 16
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/controller/DictionaryWebController.java
  41. 3
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/DictionaryService.java
  42. 6
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/impl/DictionaryServiceImpl.java
  43. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/controller/IndicatorValidatorWebController.java
  44. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/controller/IndicatorWebController.java
  45. 47
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/IndicatorEntity.java
  46. 67
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/IndicatorProcessorEntity.java
  47. 70
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/IndicatorValidatorEntity.java
  48. 4
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/LibEntity.java
  49. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/RangeIndicatorValidatorEntity.java
  50. 1
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/ReleasableLibEntity.java
  51. 5
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/IndicatorProcessorServiceImpl.java
  52. 5
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/IndicatorServiceImpl.java
  53. 4
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/IndicatorValidatorServiceImpl.java
  54. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/LibServiceImpl.java
  55. 8
      io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule Engine Database Schema DDL.xml
  56. 2
      io.sc.platform.core.frontend/package.json
  57. 9
      io.sc.platform.core.frontend/src/platform/components-ext/formater/BooleanFormater.ts
  58. 6
      io.sc.platform.core.frontend/src/platform/components-ext/formater/index.ts
  59. 3
      io.sc.platform.core.frontend/src/platform/components/index.ts
  60. 8
      io.sc.platform.core.frontend/src/platform/components/tag/WCheckTag.vue
  61. 58
      io.sc.platform.core.frontend/src/platform/components/workflow/WWorkflowAction.vue
  62. 1
      io.sc.platform.core.frontend/src/platform/index.ts
  63. 115
      io.sc.platform.core.frontend/src/views/FormElements.vue
  64. 4
      io.sc.platform.core.frontend/template-project/package.json
  65. 115
      io.sc.platform.core.frontend/template-project/src/views/FormElements.vue
  66. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  67. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  68. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties
  69. 7
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/support/ProcessProperties.java
  70. 2
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/AuditorEntity.java

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

@ -2,8 +2,6 @@ package io.sc.engine.rule.core.enums;
/**
* 指标类型枚举
* @author wangshaoping
*
*/
public enum IndicatorType {
INTERFACE, //接口

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

@ -2,8 +2,6 @@ package io.sc.engine.rule.core.enums;
/**
* 库类型枚举
* @author wangshaoping
*
*/
public enum LibType {
FOLDER, //文件夹

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

@ -111,7 +111,7 @@ io.sc.engine.rule.core.enums.DictionaryType.ENUM=Enumerate
#================================================
# \u5E93\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.LibType.INDICATOR=Indicator Lib
io.sc.engine.rule.core.enums.LibType.INDICATOR=Feature Lib
#================================================
# \u6307\u6807\u9A8C\u8BC1\u5668\u7C7B\u578B\u679A\u4E3E

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

@ -111,7 +111,7 @@ io.sc.engine.rule.core.enums.DictionaryType.ENUM=\u679A\u8209
#================================================
# \u5E93\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.LibType.INDICATOR=\u6307\u6A19\u5EAB
io.sc.engine.rule.core.enums.LibType.INDICATOR=\u7279\u5F81\u5EAB
#================================================
# \u6307\u6807\u9A8C\u8BC1\u5668\u7C7B\u578B\u679A\u4E3E

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

@ -111,7 +111,7 @@ io.sc.engine.rule.core.enums.DictionaryType.ENUM=\u679A\u4E3E
#================================================
# \u5E93\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.LibType.INDICATOR=\u6307\u6807\u5E93
io.sc.engine.rule.core.enums.LibType.INDICATOR=\u7279\u5F81\u5E93
#================================================
# \u6307\u6807\u9A8C\u8BC1\u5668\u7C7B\u578B\u679A\u4E3E

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

@ -91,7 +91,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.160",
"platform-core": "8.1.163",
"quasar": "2.14.5",
"tailwindcss": "3.4.0",
"vue": "3.4.3",

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

@ -108,10 +108,85 @@
"re.resources.designer.testCaseParameter.grid.entity.skipCheck": "Skip Check",
"re.resources.designer.testCaseParameter.grid.entity.testResult": "Result",
"re.resources.import.dialog.title": "Import Resource",
"re.resources.importSample.dialog.title": "Import Sample Resource",
"re.resources.importSample.grid.title": "Sample List",
"re.resources.importSample.grid.toolbar.import": "Import Sample",
"re.resources.importSample.grid.toolbar.import.tip": "Are you sure to import the samples?",
"re.dictionary.grid.title": "Dictionary Tree",
"re.dictionary.grid.title": "Meta Data Tree",
"re.dictionary.grid.toolbar.addGroup": "Add New",
"re.dictionary.grid.toolbar.addTop": "Top Folder",
"re.dictionary.grid.toolbar.addChild": "Child Folder",
"re.dictionary.grid.toolbar.addJavaType": "Java Type",
"re.dictionary.grid.toolbar.addUserDefinedJavaClassType": "User Defined Type",
"re.dictionary.grid.toolbar.addEnumType": "Enum Type",
"re.dictionary.grid.toolbar.cloneGroup": "Clone",
"re.dictionary.grid.toolbar.deepClone": "Deep Clone",
"re.dictionary.grid.toolbar.deepClone.tip": "Are you sure to deep clone the meta data?",
"re.dictionary.grid.toolbar.deepCloneNew": "Deep Clone (New Meta Data)",
"re.dictionary.grid.toolbar.deepCloneNew.tip": "Are you sure to deep clone the meta data as a new meta data?",
"re.dictionary.grid.toolbar.generateJson": "Generate JSON",
"re.dictionary.grid.toolbar.deploy": "Deploy",
"re.dictionary.grid.toolbar.deploy.tip": "Are you sure to deploy the meta data?",
"re.dictionary.grid.toolbar.importGroup": "Import",
"re.dictionary.grid.toolbar.import": "Import",
"re.dictionary.grid.toolbar.importSample": "Import Example",
"re.dictionary.grid.entity.javaClassName": "Java Class Name",
"re.dictionary.field.grid.title": "Field List",
"re.dictionary.field.grid.entity.valueType": "Value Type",
"re.dictionary.field.grid.entity.valueTypeIsList": "Is List",
"re.dictionary.field.grid.entity.valueCalculation": "Calculation Expression",
"re.dictionary.enum.grid.title": "Enum List",
"re.dictionary.sampleJson.dialog.title": "Example JSON",
"re.dictionary.import.dialog.title": "Import Meta Data",
"re.dictionary.importSample.dialog.title": "Import Example Meta Data",
"re.dictionary.importSample.grid.title": "Example Meta Data List",
"re.dictionary.importSample.grid.toolbar.import": "Import Example",
"re.dictionary.importSample.grid.toolbar.import.tip": "Are you sure to import the meta data?",
"re.lib.grid.title": "Feature Library Tree",
"re.lib.grid.toolbar.addGroup": "Add New",
"re.lib.grid.toolbar.addTop": "Top Folder",
"re.lib.grid.toolbar.addChild": "Child Folder",
"re.lib.grid.toolbar.addLib": "Feature Library",
"re.lib.grid.toolbar.cloneGroup": "Clone",
"re.lib.grid.toolbar.deepClone": "Deep Clone",
"re.lib.grid.toolbar.deepClone.tip": "Are you sure to clone the Feature Library?",
"re.lib.grid.toolbar.deepCloneNew": "Deep Clone (New Feature Library)",
"re.lib.grid.toolbar.deepCloneNew.tip": "Are you sure to clone the feature library as a new feature library?",
"re.lib.grid.toolbar.generateGroovy": "Generate Groovy Code",
"re.lib.grid.toolbar.deploy": "Deploy",
"re.lib.grid.toolbar.deploy.tip": "Are you sure to deploy the Feature Library?",
"re.lib.grid.toolbar.importGroup": "Import",
"re.lib.grid.toolbar.import": "Import",
"re.lib.grid.toolbar.importSample": "Import Example",
"re.lib.tab.indicator.title": "Feature",
"re.lib.tab.testcase.title": "Test Case",
"re.migration.import.title":"Import ( From The File Uploaded )",
"re.migration.import.subTitle":"",
"re.migration.import.action":"Import",
"re.migration.importFromServer.title":"Import ( From Server File)",
"re.migration.importFromServer.subTitle":"",
"re.migration.importFromServer.action":"Import",
"re.migration.export.title":"Export",
"re.migration.export.subTitle":"",
"re.migration.export.action":"Export",
"re.migration.remove.title":"Remove",
"re.migration.remove.subTitle":"Warning: It will remove all data in the engine, and can NOT undo!",
"re.migration.remove.action":"Remove",
"re.migration.remove.action.tip":"Are you sure to remove the all data?",
}

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

@ -108,10 +108,86 @@
"re.resources.designer.testCaseParameter.grid.entity.skipCheck": "跳過檢查",
"re.resources.designer.testCaseParameter.grid.entity.testResult": "測試結果",
"re.resources.import.dialog.title": "導入資源",
"re.resources.importSample.dialog.title": "導入示例資源",
"re.resources.importSample.grid.title": "示例資源列表",
"re.resources.importSample.grid.toolbar.import": "導入示例",
"re.resources.importSample.grid.toolbar.import.tip": "您確定要導入示例資源嗎?",
"re.dictionary.grid.title": "數據字典樹",
"re.dictionary.grid.title": "元數據樹",
"re.dictionary.grid.toolbar.addGroup": "新增",
"re.dictionary.grid.toolbar.addTop": "頂級文件夾",
"re.dictionary.grid.toolbar.addChild": "子文件夾",
"re.dictionary.grid.toolbar.addJavaType": "Java 類型",
"re.dictionary.grid.toolbar.addUserDefinedJavaClassType": "用戶自定義類型",
"re.dictionary.grid.toolbar.addEnumType": "枚舉類型",
"re.dictionary.grid.toolbar.cloneGroup": "複製",
"re.dictionary.grid.toolbar.deepClone": "深度複製",
"re.dictionary.grid.toolbar.deepClone.tip": "您確定要深度複製元數據嗎?",
"re.dictionary.grid.toolbar.deepCloneNew": "深度復製(新元數據)",
"re.dictionary.grid.toolbar.deepCloneNew.tip": "您確定要深度複製元數據成一個新的元數據嗎?",
"re.dictionary.grid.toolbar.generateJson": "生成示例 JSON",
"re.dictionary.grid.toolbar.deploy": "發佈",
"re.dictionary.grid.toolbar.deploy.tip": "您確定要發佈元數據嗎?",
"re.dictionary.grid.toolbar.importGroup": "導入",
"re.dictionary.grid.toolbar.import": "導入",
"re.dictionary.grid.toolbar.importSample": "導入示例",
"re.dictionary.grid.entity.javaClassName": "Java 類全路徑名稱",
"re.dictionary.field.grid.title": "字段列表",
"re.dictionary.field.grid.entity.valueType": "值類型",
"re.dictionary.field.grid.entity.valueTypeIsList": "是否列表",
"re.dictionary.field.grid.entity.valueCalculation": "值計算公式",
"re.dictionary.enum.grid.title": "枚舉列表",
"re.dictionary.sampleJson.dialog.title": "示例 JSON",
"re.dictionary.import.dialog.title": "導入元數據",
"re.dictionary.importSample.dialog.title": "導入示例元數據",
"re.dictionary.importSample.grid.title": "示例元數據列表",
"re.dictionary.importSample.grid.toolbar.import": "導入示例",
"re.dictionary.importSample.grid.toolbar.import.tip": "您確定要導入示例元數據嗎?",
"re.lib.grid.title": "特征庫樹",
"re.lib.grid.toolbar.addGroup": "新增",
"re.lib.grid.toolbar.addTop": "頂級文件夾",
"re.lib.grid.toolbar.addChild": "子文件夾",
"re.lib.grid.toolbar.addLib": "特征庫",
"re.lib.grid.toolbar.cloneGroup": "複製",
"re.lib.grid.toolbar.deepClone": "深度複製",
"re.lib.grid.toolbar.deepClone.tip": "您確定要深度複製特征庫嗎?",
"re.lib.grid.toolbar.deepCloneNew": "深度複製(新特征庫)",
"re.lib.grid.toolbar.deepCloneNew.tip": "您確定要深度複製特征庫成一個新的特征庫嗎?",
"re.lib.grid.toolbar.generateGroovy": "生成 Groovy 源代碼",
"re.lib.grid.toolbar.deploy": "發佈",
"re.lib.grid.toolbar.deploy.tip": "您確定要發佈特征庫嗎?",
"re.lib.grid.toolbar.importGroup": "導入",
"re.lib.grid.toolbar.import": "導入",
"re.lib.grid.toolbar.importSample": "導入示例",
"re.lib.tab.indicator.title": "特征",
"re.lib.tab.testcase.title": "測試用例",
"re.migration.import.title":"導入數據 (通過上傳文件導入)",
"re.migration.import.subTitle":"",
"re.migration.import.action":"導入數據",
"re.migration.importFromServer.title":"導入數據 (從服務器文件導入)",
"re.migration.importFromServer.subTitle":"",
"re.migration.importFromServer.action":"導入數據",
"re.migration.export.title":"導出所有數據",
"re.migration.export.subTitle":"",
"re.migration.export.action":"導出數據",
"re.migration.remove.title":"刪除所有現有數據",
"re.migration.remove.subTitle":"清注意: 此操作將刪除引擎中配置的所有數據, 且不可逆!",
"re.migration.remove.action":"刪除數據",
"re.migration.remove.action.tip":"您確定要刪除所有數據嗎?",
}

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

@ -108,6 +108,8 @@
"re.resources.designer.testCaseParameter.grid.entity.skipCheck": "跳过检查",
"re.resources.designer.testCaseParameter.grid.entity.testResult": "测试结果",
"re.resources.import.dialog.title": "导入资源",
"re.resources.importSample.dialog.title": "导入示例资源",
"re.resources.importSample.grid.title": "示例资源列表",
"re.resources.importSample.grid.toolbar.import": "导入示例",
@ -123,7 +125,7 @@
"re.dictionary.grid.toolbar.cloneGroup": "复制",
"re.dictionary.grid.toolbar.deepClone": "深度复制",
"re.dictionary.grid.toolbar.deepClone.tip": "您确定要深度复制元数据吗?",
"re.dictionary.grid.toolbar.deepCloneNew": "深度复制(新数据字典)",
"re.dictionary.grid.toolbar.deepCloneNew": "深度复制(新元數據)",
"re.dictionary.grid.toolbar.deepCloneNew.tip": "您确定要深度复制元数据成一个新的元数据吗?",
"re.dictionary.grid.toolbar.generateJson": "生成示例 JSON",
"re.dictionary.grid.toolbar.deploy": "发布",
@ -139,10 +141,54 @@
"re.dictionary.field.grid.entity.valueTypeIsList": "是否列表",
"re.dictionary.field.grid.entity.valueCalculation": "值计算公式",
"re.dictionary.enum.grid.title": "枚举列表",
"re.dictionary.sampleJson.dialog.title": "示例 JSON",
"re.dictionary.import.dialog.title": "导入元数据",
"re.dictionary.importSample.dialog.title": "导入示例元数据",
"re.dictionary.importSample.grid.title": "示例元数据列表",
"re.dictionary.importSample.grid.toolbar.import": "导入示例",
"re.dictionary.importSample.grid.toolbar.import.tip": "您确定要导入示例元数据吗?",
"re.lib.grid.title": "特征库树",
"re.lib.grid.toolbar.addGroup": "新增",
"re.lib.grid.toolbar.addTop": "顶级文件夹",
"re.lib.grid.toolbar.addChild": "子文件夹",
"re.lib.grid.toolbar.addLib": "特征库",
"re.lib.grid.toolbar.cloneGroup": "复制",
"re.lib.grid.toolbar.deepClone": "深度复制",
"re.lib.grid.toolbar.deepClone.tip": "您确定要深度复制特征库吗?",
"re.lib.grid.toolbar.deepCloneNew": "深度复制(新特征库)",
"re.lib.grid.toolbar.deepCloneNew.tip": "您确定要深度复制特征库成一个新的特征库吗?",
"re.lib.grid.toolbar.generateGroovy": "生成 Groovy 源代码",
"re.lib.grid.toolbar.deploy": "发布",
"re.lib.grid.toolbar.deploy.tip": "您确定要发布特征库吗?",
"re.lib.grid.toolbar.importGroup": "导入",
"re.lib.grid.toolbar.import": "导入",
"re.lib.grid.toolbar.importSample": "导入示例",
"re.lib.tab.indicator.title": "特征",
"re.lib.tab.testcase.title": "测试用例",
"re.migration.import.title":"导入数据 (通过上传文件导入)",
"re.migration.import.subTitle":"",
"re.migration.import.action":"导入数据",
"re.migration.importFromServer.title":"导入数据 (从服务器文件导入)",
"re.migration.importFromServer.subTitle":"",
"re.migration.importFromServer.action":"导入数据",
"re.migration.export.title":"导出所有数据",
"re.migration.export.subTitle":"",
"re.migration.export.action":"导出数据",
"re.migration.remove.title":"删除所有现有数据",
"re.migration.remove.subTitle":"请注意: 此操作将删除引擎中配置的所有数据, 且不可逆!",
"re.migration.remove.action":"删除数据",
"re.migration.remove.action.tip":"您确定要删除所有数据吗?",

71
io.sc.engine.rule.frontend/src/views/dictionary/ImportDialog.vue

@ -0,0 +1,71 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.dictionary.import.dialog.title')" width="600px" :can-maximize="false">
<q-form action="post">
<div class="row py-1">
<div class="col-3"></div>
<div class="col-6">
<q-file ref="fileRef" v-model="modelValue.file" :label="$t('file.single.tip')" dense outlined clearable counter accept=".json">
<template #prepend>
<q-icon name="cloud_upload" />
</template>
</q-file>
</div>
<div class="col-3"></div>
</div>
<div class="row py-1">
<div class="col-3"></div>
<div class="col-6 row justify-center q-gutter-md py-2">
<q-btn icon="bi-database-up" :label="$t('import')" color="primary" @click="importData"></q-btn>
</div>
<div class="col-3"></div>
</div>
</q-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { axios, Environment } from 'platform-core';
const emit = defineEmits<{
(e: 'afterImported', evt: Event): void;
}>();
const dialogRef = ref();
const modelValue = reactive({
file: undefined,
});
const fileRef = ref();
const importData = () => {
axios
.post(
Environment.apiContextPath('/api/re/dictionary/import'),
{
file: fileRef.value.nativeEl.files[0],
},
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
)
.then(() => {
close();
emit('afterImported');
});
};
const open = () => {
modelValue.file = undefined;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

91
io.sc.engine.rule.frontend/src/views/dictionary/ImportSampleDialog.vue

@ -0,0 +1,91 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.dictionary.importSample.dialog.title')" width="900px" :can-maximize="false">
<div class="px-2">
<w-grid
ref="gridRef"
:height="300"
:title="$t('re.dictionary.importSample.grid.title')"
selection="multiple"
:full-screen-button="false"
:tree="true"
dense-body
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
'expand',
'separator',
{
name: 'import',
label: $t('re.dictionary.importSample.grid.toolbar.import'),
icon: 'bi-database-up',
enableIf: (arg) => {
return arg.ticked;
},
click: (arg) => {
if (arg.tickeds && arg.tickeds.length > 0) {
const ids = Tools.extractProperties(arg.tickeds, 'id');
console.log(ids);
DialogManager.confirm($t('re.dictionary.importSample.grid.toolbar.import.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/dictionary/createExample'), ids).then(() => {
close();
emit('afterImported');
});
});
}
},
},
]"
:query-form-fields="[]"
:auto-fetch-data="false"
:fetch-data-url="Environment.apiContextPath('/api/re/dictionary/listDictionaryExampleContributionItems')"
foreign-key="parentId"
:columns="[
{
width: 200,
name: 'name',
label: $t('name'),
format: (value, row) => {
return $t(row.id);
},
},
{
width: '100%',
name: 'description',
label: $t('description'),
format: (value, row) => {
return $t(row.id + '.description');
},
},
]"
></w-grid>
</div>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { axios, Environment, DialogManager, Tools } from 'platform-core';
const emit = defineEmits<{
(e: 'afterImported', evt: Event): void;
}>();
const dialogRef = ref();
const gridRef = ref();
const open = () => {
dialogRef.value.show();
nextTick(() => {
gridRef.value.refresh();
});
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

25
io.sc.engine.rule.frontend/src/views/dictionary/UserDefinedJavaClassDictionaryJsonDialog.vue

@ -0,0 +1,25 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.dictionary.sampleJson.dialog.title')" width="600px" :can-maximize="false">
<w-code-mirror v-model="sourceCodeRef" lang="json" :rows="15"></w-code-mirror>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const dialogRef = ref();
const sourceCodeRef = ref();
const open = (sourceCode: string) => {
sourceCodeRef.value = sourceCode;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

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

@ -111,6 +111,13 @@
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
click: (arg) => {
DialogManager.confirm($t('re.dictionary.grid.toolbar.deepClone.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/dictionary/deepClone/' + arg.selected.id)).then(() => {
treeGridRef.refresh();
});
});
},
},
{
extend: 'clone',
@ -120,6 +127,13 @@
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
click: (arg) => {
DialogManager.confirm($t('re.dictionary.grid.toolbar.deepCloneNew.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/dictionary/deepCloneNew/' + arg.selected.id)).then(() => {
treeGridRef.refresh();
});
});
},
},
],
@ -132,7 +146,14 @@
label: $t('re.dictionary.grid.toolbar.generateJson'),
icon: 'bi-code',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
return arg.selected && arg.selected.type === 'UD_JAVA_CLASS';
},
click: (arg) => {
axios
.post(Environment.apiContextPath('/api/re/dictionary/generateUserDefinedJavaClassDictionarySampleJsonCode/' + arg.selected.id))
.then((response) => {
userDefinedJavaClassDictionaryJsonDialogRef.open(response.data.source);
});
},
},
'separator',
@ -141,7 +162,14 @@
label: $t('re.dictionary.grid.toolbar.deploy'),
icon: 'bi-balloon',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
return arg.selected && arg.selected.type !== 'FOLDER' && arg.selected.status === 'SKETCH';
},
click: (arg) => {
DialogManager.confirm($t('re.dictionary.grid.toolbar.deploy.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/dictionary/deploy/' + arg.selected.id)).then(() => {
treeGridRef.refresh();
});
});
},
},
'separator',
@ -156,11 +184,17 @@
name: 'import',
label: $t('re.dictionary.grid.toolbar.import'),
icon: 'file_upload',
click: () => {
importDialogRef.open();
},
},
{
name: 'importSample',
label: $t('re.dictionary.grid.toolbar.importSample'),
icon: 'bi-database-up',
click: () => {
importSampleDialogRef.open();
},
},
],
'separator',
@ -168,14 +202,27 @@
'separator',
{
extend: 'export',
name: 'export',
enableIf: (arg) => {
return arg.selected;
},
click: (arg) => {
let url = Environment.apiContextPath('/api/re/dictionary/export/' + arg.selected.id);
downloadIframe.src = url;
},
},
]"
:columns="[
{ width: '100%', name: 'name', label: $t('name') },
{
width: '100%',
name: 'name',
label: $t('name'),
format: (value, row) => {
if (row.type === 'JAVA_CLASS') {
return value + ' ( ' + row.javaClassName + ' )';
}
return value;
},
},
{
width: 80,
name: 'type',
@ -225,14 +272,13 @@
panel: {
columnNum: 1,
fields: [
{ name: 'order', label: $t('order') },
{ name: 'type', label: $t('type') },
{ name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable') },
{ name: 'category', label: $t('category'), format: Formater.none() },
{ name: 'executeMode', label: $t('re.resources.designer.model.grid.entity.executeMode'), format: Formater.none() },
{ name: 'order', label: $t('order') },
{ name: 'javaClassName', label: $t('re.dictionary.grid.entity.javaClassName') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
@ -246,24 +292,41 @@
@row-click="
(evt, row, index) => {
currentSelectedDictionaryIdRef = row.id;
gridRef?.refresh();
if (row.type === 'UD_JAVA_CLASS') {
divStatus.isShowFieldGrid = true;
divStatus.isShowEnumGrid = false;
fieldGridRef?.refresh();
} else if (row.type === 'ENUM') {
divStatus.isShowFieldGrid = false;
divStatus.isShowEnumGrid = true;
enumGridRef?.refresh();
} else {
divStatus.isShowFieldGrid = false;
divStatus.isShowEnumGrid = false;
}
}
"
@before-request-data="
() => {
currentSelectedDictionaryIdRef = '';
gridRef?.refresh();
divStatus.isShowFieldGrid = false;
divStatus.isShowEnumGrid = false;
}
"
></w-grid>
<UserDefinedJavaClassDictionaryJsonDialog ref="userDefinedJavaClassDictionaryJsonDialogRef"></UserDefinedJavaClassDictionaryJsonDialog>
<ImportDialog ref="importDialogRef"></ImportDialog>
<ImportSampleDialog ref="importSampleDialogRef"></ImportSampleDialog>
<iframe ref="downloadIframe" src="javascript:;" style="width: 0px; height: 0px"></iframe>
</div>
</template>
<template #after>
<!--字段-->
<div class="pl-1" style="height: 100%">
<div v-if="divStatus.isShowFieldGrid" class="pl-1" style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('system.role.grid.title')"
ref="fieldGridRef"
:title="$t('re.dictionary.field.grid.title')"
dense-body
hide-bottom
:config-button="true"
selection="multiple"
@ -273,11 +336,11 @@
:pageable="false"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
{ name: 'code', label: $t('code'), type: 'text', clearable: true },
{ name: 'name', label: $t('name'), type: 'text', clearable: true },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'separator', 'refresh', 'separator', 'view', 'separator', 'export']"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view']"
:columns="[
{ width: 50, name: 'order', label: $t('order'), align: 'right', sortable: false },
{ width: 100, name: 'code', label: $t('code') },
@ -300,6 +363,29 @@
},
{ width: 150, name: 'defaultValue', label: $t('defaultValue'), sortable: false },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{ name: 'dictionary', label: $t('dictionary'), type: 'text', hidden: true, defaultValue: currentSelectedDictionaryIdRef },
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'text' },
{ name: 'valueType', label: $t('re.dictionary.field.grid.entity.valueType'), required: true, type: 'select', options: ValueTypeList },
{
name: 'valueTypeIsList',
label: $t('re.dictionary.field.grid.entity.valueTypeIsList'),
type: 'checkbox',
},
{ name: 'defaultValue', label: $t('defaultValue'), type: 'text' },
{ name: 'valueCalculation', label: $t('re.dictionary.field.grid.entity.valueCalculation'), type: 'code-mirror', lang: 'groovy' },
{ name: 'order', label: $t('order'), type: 'number' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
@ -308,7 +394,11 @@
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.none() },
{ name: 'valueType', label: $t('re.dictionary.field.grid.entity.valueType') },
{ name: 'valueTypeIsList', label: $t('re.dictionary.field.grid.entity.valueTypeIsList') },
{ name: 'defaultValue', label: $t('defaultValue') },
{ name: 'valueCalculation', label: $t('re.dictionary.field.grid.entity.valueCalculation') },
{ name: 'order', label: $t('order') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
@ -323,55 +413,59 @@
</div>
<!--选项-->
<div class="pl-1" style="height: 100%">
<div v-if="divStatus.isShowEnumGrid" class="pl-1" style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('system.role.grid.title')"
ref="enumGridRef"
:title="$t('re.dictionary.enum.grid.title')"
dense-body
hide-bottom
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:fetch-data-url="Environment.apiContextPath('/api/re/dictionary/userDefinedJavaClassField?dictionary=' + currentSelectedDictionaryIdRef)"
:data-url="Environment.apiContextPath('/api/re/dictionary/userDefinedJavaClassField')"
:fetch-data-url="Environment.apiContextPath('/api/re/dictionary/enumItem?dictionary=' + currentSelectedDictionaryIdRef)"
:data-url="Environment.apiContextPath('/api/re/dictionary/enumItem')"
:pageable="false"
:pagination="{
sortBy: 'value',
descending: false,
}"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
]"
:query-form-fields="[]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'separator', 'refresh', 'separator', 'view', 'separator', 'export']"
:toolbar-actions="['refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view']"
:columns="[
{ width: 50, name: 'order', label: $t('order'), align: 'right', sortable: false },
{ width: 100, name: 'code', label: $t('code') },
{ width: '100%', name: 'name', label: $t('name') },
{
width: 150,
name: 'valueType',
label: $t('re.resources.designer.parameter.grid.entity.valueType'),
sortable: false,
format: (value) => {
return ValueTypeMap[value];
},
{ width: 100, name: 'value', label: $t('value') },
{ width: 250, name: 'title', label: $t('title') },
{ width: '100%', name: 'description', label: $t('description') },
]"
:editor="{
dialog: {
width: '600px',
},
{
width: 80,
name: 'valueTypeIsList',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'),
sortable: false,
format: Formater.yesNo(),
form: {
colsNum: 1,
fields: [
{ name: 'dictionary', label: $t('dictionary'), type: 'text', hidden: false, defaultValue: currentSelectedDictionaryIdRef },
{ name: 'value', label: $t('value'), type: 'text', hidden: false },
{
name: 'title',
label: $t('title'),
type: 'text',
},
{ name: 'description', label: $t('description'), type: 'text' },
{ name: 'order', label: $t('order'), type: 'number' },
],
},
{ width: 150, name: 'defaultValue', label: $t('defaultValue'), sortable: false },
]"
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'value', label: $t('value') },
{ name: 'title', label: $t('title') },
{ name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.none() },
{ name: 'order', label: $t('order') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
@ -388,14 +482,26 @@
</q-splitter>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, Formater, EnumTools, Options } from 'platform-core';
import { ref, reactive } from 'vue';
import { axios, Environment, Formater, EnumTools, DialogManager } from 'platform-core';
import UserDefinedJavaClassDictionaryJsonDialog from './UserDefinedJavaClassDictionaryJsonDialog.vue';
import ImportDialog from './ImportDialog.vue';
import ImportSampleDialog from './ImportSampleDialog.vue';
const treeGridRef = ref();
const gridRef = ref();
const fieldGridRef = ref();
const enumGridRef = ref();
const userDefinedJavaClassDictionaryJsonDialogRef = ref();
const importDialogRef = ref();
const importSampleDialogRef = ref();
const downloadIframe = ref();
const currentSelectedDictionaryIdRef = ref('');
const divStatus = reactive({
isShowFieldGrid: false,
isShowEnumGrid: false,
});
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ResourceType', 'io.sc.engine.rule.core.enums.DeployStatus']);
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.DictionaryType', 'io.sc.engine.rule.core.enums.DeployStatus']);
let ValueTypeMap = {};
const ValueTypeList = [];
const response = await axios.get(Environment.apiContextPath('/api/re/dictionary/getAllDictionaryMap'));

71
io.sc.engine.rule.frontend/src/views/lib/ImportDialog.vue

@ -0,0 +1,71 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.dictionary.import.dialog.title')" width="600px" :can-maximize="false">
<q-form action="post">
<div class="row py-1">
<div class="col-3"></div>
<div class="col-6">
<q-file ref="fileRef" v-model="modelValue.file" :label="$t('file.single.tip')" dense outlined clearable counter accept=".json">
<template #prepend>
<q-icon name="cloud_upload" />
</template>
</q-file>
</div>
<div class="col-3"></div>
</div>
<div class="row py-1">
<div class="col-3"></div>
<div class="col-6 row justify-center q-gutter-md py-2">
<q-btn icon="bi-database-up" :label="$t('import')" color="primary" @click="importData"></q-btn>
</div>
<div class="col-3"></div>
</div>
</q-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { axios, Environment } from 'platform-core';
const emit = defineEmits<{
(e: 'afterImported', evt: Event): void;
}>();
const dialogRef = ref();
const modelValue = reactive({
file: undefined,
});
const fileRef = ref();
const importData = () => {
axios
.post(
Environment.apiContextPath('/api/re/dictionary/import'),
{
file: fileRef.value.nativeEl.files[0],
},
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
)
.then(() => {
close();
emit('afterImported');
});
};
const open = () => {
modelValue.file = undefined;
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

91
io.sc.engine.rule.frontend/src/views/lib/ImportSampleDialog.vue

@ -0,0 +1,91 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.dictionary.importSample.dialog.title')" width="900px" :can-maximize="false">
<div class="px-2">
<w-grid
ref="gridRef"
:height="300"
:title="$t('re.dictionary.importSample.grid.title')"
selection="multiple"
:full-screen-button="false"
:tree="true"
dense-body
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
'expand',
'separator',
{
name: 'import',
label: $t('re.dictionary.importSample.grid.toolbar.import'),
icon: 'bi-database-up',
enableIf: (arg) => {
return arg.ticked;
},
click: (arg) => {
if (arg.tickeds && arg.tickeds.length > 0) {
const ids = Tools.extractProperties(arg.tickeds, 'id');
console.log(ids);
DialogManager.confirm($t('re.dictionary.importSample.grid.toolbar.import.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/dictionary/createExample'), ids).then(() => {
close();
emit('afterImported');
});
});
}
},
},
]"
:query-form-fields="[]"
:auto-fetch-data="false"
:fetch-data-url="Environment.apiContextPath('/api/re/dictionary/listDictionaryExampleContributionItems')"
foreign-key="parentId"
:columns="[
{
width: 200,
name: 'name',
label: $t('name'),
format: (value, row) => {
return $t(row.id);
},
},
{
width: '100%',
name: 'description',
label: $t('description'),
format: (value, row) => {
return $t(row.id + '.description');
},
},
]"
></w-grid>
</div>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { axios, Environment, DialogManager, Tools } from 'platform-core';
const emit = defineEmits<{
(e: 'afterImported', evt: Event): void;
}>();
const dialogRef = ref();
const gridRef = ref();
const open = () => {
dialogRef.value.show();
nextTick(() => {
gridRef.value.refresh();
});
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

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

@ -0,0 +1,166 @@
<template>
<div style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('re.lib.grid.title')"
dense-body
hide-bottom
:config-button="true"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('api/re/indicator?lib=' + lib.id)"
:data-url="Environment.apiContextPath('api/re/indicator')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'query',
'refresh',
'separator',
[
{
name: 'addGroup',
label: $t('re.lib.grid.toolbar.addGroup'),
icon: 'add',
click: undefined,
},
{
extend: 'add',
name: 'addInterface',
label: $t('re.lib.grid.toolbar.addTop'),
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'FOLDER');
},
},
{
extend: 'add',
name: 'addIndicator',
label: $t('re.lib.grid.toolbar.addChild'),
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'FOLDER';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'FOLDER');
},
},
],
[
{
name: 'cloneGroup',
label: $t('re.lib.grid.toolbar.cloneGroup'),
icon: 'content_copy',
click: undefined,
enableIf: (arg) => {
return arg.selected;
},
},
'clone',
{
extend: 'deepClone',
name: 'deepClone',
label: $t('re.lib.grid.toolbar.deepClone'),
icon: 'bi-copy',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
click: (arg) => {
DialogManager.confirm($t('re.lib.grid.toolbar.deepClone.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/lib/deepClone/' + arg.selected.id)).then(() => {
libTreeGridRef.refresh();
});
});
},
},
],
'separator',
'edit',
'remove',
'separator',
'view',
'separator',
'export',
]"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text', clearable: true },
{ name: 'name', label: $t('name'), type: 'text', clearable: true },
]"
:columns="[
{ width: 60, name: 'order', label: $t('order'), align: 'right' },
{ width: 250, name: 'name', label: $t('name') },
{ width: 100, name: 'type', label: $t('type'), format: Formater.enum(Enums.IndicatorType) },
{
width: 100,
name: 'valueType',
label: $t('valueType'),
format: (value, row) => {
return ValueTypeMap[value];
},
},
{ width: 80, name: 'valueTypeIsList', label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'), format: Formater.checkTag() },
{ width: '100%', name: 'defaultValue', label: $t('defaultValue') },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
v-bind="attrs"
></w-grid>
<ImportDialog ref="importDialogRef"></ImportDialog>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs, onMounted } from 'vue';
import { axios, Environment, EnumTools, Formater, DialogManager } from 'platform-core';
import ImportDialog from './ImportDialog.vue';
const attrs = useAttrs();
const props = defineProps({
lib: { type: Object, default: undefined },
});
const gridRef = ref();
const refresh = () => {
gridRef.value.refresh();
};
onMounted(() => {
gridRef.value.refresh();
});
defineExpose({
refresh,
});
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.IndicatorType', 'io.sc.engine.rule.core.enums.DeployStatus']);
let ValueTypeMap = {};
const ValueTypeList = [];
const response = await axios.get(Environment.apiContextPath('/api/re/dictionary/getAllDictionaryMap'));
if (response && response.data) {
ValueTypeMap = {};
ValueTypeList.splice(0, ValueTypeList.length);
for (const item of response.data) {
ValueTypeMap[item.key] = item.value;
ValueTypeList.push({ value: item.key, label: item.value });
}
}
</script>

99
io.sc.engine.rule.frontend/src/views/lib/Lib.vue

@ -1,4 +1,99 @@
<template>
<div>Lib</div>
<q-splitter :model-value="450" unit="px" separator-style="width: 3px;" class="w-full" style="height: 100%">
<template #before>
<LibGrid
ref="libTreeGridRef"
@row-click="
(evt, row, index) => {
if (row.type === 'INDICATOR') {
currentSelectedLibRef = row;
showStatus.detail = true;
indicatorGridRef?.refresh();
} else {
currentSelectedLibRef = {};
showStatus.detail = false;
}
}
"
@before-request-data="
() => {
showStatus.detail = false;
}
"
></LibGrid>
</template>
<template #after>
<div v-if="showStatus.detail" style="height: 100%" class="pl-1">
<q-tabs v-model="currentSelectedIndicatorOrTestcaseTabNameRef" no-caps inline-label align="left">
<q-tab name="indicator" :label="$t('re.lib.tab.indicator.title')" icon="bi-card-list" />
<q-tab name="testcase" :label="$t('re.lib.tab.testcase.title')" icon="bi-receipt" />
</q-tabs>
<q-tab-panels v-model="currentSelectedIndicatorOrTestcaseTabNameRef" animated style="height: calc(100% - 48px)">
<q-tab-panel name="indicator" class="px-0 pb-0" style="height: 100%">
<q-splitter :model-value="indicatorSplitterRef" unit="px" separator-style="width: 3px;" horizontal class="w-full" style="height: 100%">
<template #before>
<IndicatorGrid
ref="indicatorGridRef"
:lib="currentSelectedLibRef"
@row-click="
(evt, row, index) => {
currentSelectedIndicatorRef = row;
if (row.type === 'INTERFACE') {
showStatus.validator = true;
showStatus.processor = false;
validatorGridRef?.refresh();
} else if (row.type === 'INDICATOR') {
showStatus.validator = false;
showStatus.processor = true;
processorGridRef?.refresh();
} else {
showStatus.validator = false;
showStatus.processor = false;
}
}
"
@before-request-data="
() => {
showStatus.validator = false;
showStatus.processor = false;
}
"
></IndicatorGrid>
</template>
<template #after>
<ValidatorGrid v-if="showStatus.validator" ref="validatorGridRef" :indicator="currentSelectedIndicatorRef"></ValidatorGrid>
<ProcessorGrid v-if="showStatus.processor" ref="processorGridRef" :indicator="currentSelectedIndicatorRef"></ProcessorGrid>
</template>
</q-splitter>
</q-tab-panel>
<q-tab-panel name="testcase" class="px-0 pb-0" style="height: 100%"> </q-tab-panel>
</q-tab-panels>
</div>
</template>
</q-splitter>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import LibGrid from './LibGrid.vue';
import IndicatorGrid from './IndicatorGrid.vue';
import ValidatorGrid from './ValidatorGrid.vue';
import ProcessorGrid from './ProcessorGrid.vue';
const indicatorSplitterRef = ref(400); //
const testcaseSplitterRef = ref(300); //
const libTreeGridRef = ref(); //
const indicatorGridRef = ref(); //
const testcaseGridRef = ref(); //
const validatorGridRef = ref(); //
const processorGridRef = ref(); //
const currentSelectedIndicatorOrTestcaseTabNameRef = ref('indicator');
//
const showStatus = reactive({
detail: false, //
validator: false, //
processor: false, //
});
const currentSelectedLibRef = ref({});
const currentSelectedIndicatorRef = ref({});
</script>

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

@ -0,0 +1,275 @@
<template>
<div class="pr-1" style="height: 100%">
<w-grid
ref="treeGridRef"
:title="$t('re.lib.grid.title')"
dense-body
hide-bottom
:config-button="true"
selection="multiple"
:checkbox-selection="false"
:tree="true"
:tree-icon="
(row) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else {
return { name: 'bi-card-list' };
}
}
"
ticked-field="selected"
:data-url="Environment.apiContextPath('/api/re/lib')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
'expand',
[
{
name: 'addGroup',
label: $t('re.lib.grid.toolbar.addGroup'),
icon: 'add',
click: undefined,
},
{
extend: 'addTop',
name: 'addTop',
label: $t('re.lib.grid.toolbar.addTop'),
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'FOLDER');
},
},
{
extend: 'addChild',
name: 'addChild',
label: $t('re.lib.grid.toolbar.addChild'),
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'FOLDER';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'FOLDER');
},
},
'separator',
{
name: 'addLib',
extend: 'addChild',
label: $t('re.lib.grid.toolbar.addLib'),
icon: 'playlist_add',
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'FOLDER';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'INDICATOR');
},
},
],
[
{
name: 'cloneGroup',
label: $t('re.lib.grid.toolbar.cloneGroup'),
icon: 'content_copy',
click: undefined,
enableIf: (arg) => {
return arg.selected;
},
},
'clone',
{
extend: 'deepClone',
name: 'deepClone',
label: $t('re.lib.grid.toolbar.deepClone'),
icon: 'bi-copy',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
click: (arg) => {
DialogManager.confirm($t('re.lib.grid.toolbar.deepClone.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/lib/deepClone/' + arg.selected.id)).then(() => {
treeGridRef.refresh();
});
});
},
},
{
extend: 'clone',
name: 'deepCloneNew',
label: $t('re.lib.grid.toolbar.deepCloneNew'),
icon: 'bi-copy',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
click: (arg) => {
DialogManager.confirm($t('re.lib.grid.toolbar.deepCloneNew.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/lib/deepCloneNew/' + arg.selected.id)).then(() => {
treeGridRef.refresh();
});
});
},
},
],
'separator',
'edit',
'remove',
'separator',
{
name: 'generateGroovy',
label: $t('re.lib.grid.toolbar.generateGroovy'),
icon: 'bi-code',
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'INDICATOR';
},
click: (arg) => {
axios.post(Environment.apiContextPath('/api/re/lib/generateUserDefinedJavaClassDictionarySampleJsonCode/' + arg.selected.id)).then((response) => {
libGroovyDialogRef.open(response.data.source);
});
},
},
'separator',
{
name: 'deploy',
label: $t('re.lib.grid.toolbar.deploy'),
icon: 'bi-balloon',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER' && arg.selected.status === 'SKETCH';
},
click: (arg) => {
DialogManager.confirm($t('re.lib.grid.toolbar.deploy.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/lib/deploy/' + arg.selected.id)).then(() => {
treeGridRef.refresh();
});
});
},
},
'separator',
[
{
name: 'importGroup',
label: $t('re.lib.grid.toolbar.importGroup'),
icon: 'file_upload',
click: undefined,
},
{
name: 'import',
label: $t('re.lib.grid.toolbar.import'),
icon: 'file_upload',
click: () => {
importDialogRef.open();
},
},
{
name: 'importSample',
label: $t('re.lib.grid.toolbar.importSample'),
icon: 'bi-database-up',
click: () => {
importSampleDialogRef.open();
},
},
],
'separator',
'view',
'separator',
{
extend: 'export',
enableIf: (arg) => {
return arg.selected;
},
click: (arg) => {
let url = Environment.apiContextPath('/api/re/lib/export/' + arg.selected.id);
downloadIframe.src = url;
},
},
]"
:columns="[
{
width: '100%',
name: 'name',
label: $t('name'),
},
{
width: 80,
name: 'type',
label: $t('type'),
format: (value) => {
if (value !== 'FOLDER') {
return Formater.enum(Enums.LibType)(value);
}
},
},
{ width: 60, name: 'version', label: $t('version') },
{ width: 60, name: 'status', label: $t('status'), format: Formater.enum(Enums.DeployStatus) },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{ name: 'parent', label: $t('parent'), type: 'text', hidden: true },
{ name: 'type', label: $t('type'), type: 'text', hidden: true },
{
name: 'code',
label: $t('code'),
type: 'text',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type !== 'FOLDER';
},
},
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'text' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'type', label: $t('type') },
{ name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{ name: 'description', label: $t('description') },
{ name: 'order', label: $t('order') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
v-bind="attrs"
></w-grid>
<ImportDialog ref="importDialogRef"></ImportDialog>
<ImportSampleDialog ref="importSampleDialogRef"></ImportSampleDialog>
<iframe ref="downloadIframe" src="javascript:;" style="width: 0px; height: 0px"></iframe>
</div>
</template>
<script setup lang="ts">
import { useAttrs } from 'vue';
import { axios, Environment, Formater, EnumTools, DialogManager } from 'platform-core';
import ImportDialog from './ImportDialog.vue';
import ImportSampleDialog from './ImportSampleDialog.vue';
const attrs = useAttrs();
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.LibType', 'io.sc.engine.rule.core.enums.DeployStatus']);
let ValueTypeMap = {};
const ValueTypeList = [];
const response = await axios.get(Environment.apiContextPath('/api/re/dictionary/getAllDictionaryMap'));
if (response && response.data) {
ValueTypeMap = {};
ValueTypeList.splice(0, ValueTypeList.length);
for (const item of response.data) {
ValueTypeMap[item.key] = item.value;
ValueTypeList.push({ value: item.key, label: item.value });
}
}
</script>

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

@ -0,0 +1,337 @@
<template>
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.processor.grid.title')"
dense-body
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/indicator/processor?indicator=' + indicator.id)"
:data-url="Environment.apiContextPath('/api/re/indicator/processor')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
[
{
extend: 'add',
click: undefined,
},
{
extend: 'add',
name: 'arithmetic',
label: Formater.enum(Enums.ProcessorType)('ARITHMETIC'),
icon: 'bi-calculator',
enableIf: (arg) => {
return indicator.type !== 'RULE_RESULT' && indicator.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'ARITHMETIC');
},
},
{
extend: 'add',
name: 'ternary',
label: Formater.enum(Enums.ProcessorType)('TERNARY'),
icon: 'bi-question',
enableIf: (arg) => {
return indicator.type !== 'RULE_RESULT' && indicator.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'TERNARY');
},
},
{
extend: 'add',
name: 'whenThen',
label: Formater.enum(Enums.ProcessorType)('WHEN_THEN'),
icon: 'bi-sliders',
enableIf: (arg) => {
return indicator.type !== 'RULE_RESULT' && indicator.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'WHEN_THEN');
},
},
{
extend: 'add',
name: 'numberRange',
label: Formater.enum(Enums.ProcessorType)('NUMBER_RANGE'),
icon: 'bi-justify',
enableIf: (arg) => {
return indicator.type !== 'RULE_RESULT' && indicator.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'NUMBER_RANGE');
},
},
{
extend: 'add',
name: 'conditionRange',
label: Formater.enum(Enums.ProcessorType)('CONDITION_RANGE'),
icon: 'bi-rainbow',
enableIf: (arg) => {
return indicator.type !== 'RULE_RESULT' && indicator.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'CONDITION_RANGE');
},
},
{
extend: 'add',
name: 'groovyScript',
label: Formater.enum(Enums.ProcessorType)('GROOVY_SCRIPT'),
icon: 'bi-code',
enableIf: (arg) => {
return indicator.type !== 'RULE_RESULT' && indicator.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'GROOVY_SCRIPT');
},
},
{
extend: 'add',
name: 'sql',
label: Formater.enum(Enums.ProcessorType)('SQL'),
icon: 'bi-filetype-sql',
enableIf: (arg) => {
return indicator.type !== 'RULE_RESULT' && indicator.type !== 'SINGLE_RULE_RESULT';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'SQL');
},
},
],
'clone',
'edit',
'remove',
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' },
{ width: 120, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ProcessorType) },
{
width: '100%',
name: 'content',
label: $t('re.resources.designer.processor.grid.entity.content'),
sortable: false,
format: (value, row) => {
const type = row.type;
return '';
},
},
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{ name: 'indicator', label: 'indicator', type: 'text', defaultValue: indicator.id, hidden: true },
{ name: 'id', label: $t('id'), type: 'text', hidden: true },
{ name: 'order', label: $t('order'), type: 'number', hidden: true },
{ name: 'type', label: $t('type'), type: 'text', hidden: true },
{ name: 'description', label: $t('description'), type: 'text' },
{
name: 'arithmetic',
label: $t('re.resources.designer.processor.grid.entity.arithmetic'),
type: 'code-mirror',
showIf: (arg) => {
return 'ARITHMETIC' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryCondition',
label: $t('re.resources.designer.processor.grid.entity.ternaryCondition'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryTrue',
label: $t('re.resources.designer.processor.grid.entity.ternaryTrue'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'ternaryFalse',
label: $t('re.resources.designer.processor.grid.entity.ternaryFalse'),
type: 'code-mirror',
lang: 'groovy',
rows: 1,
showIf: (arg) => {
return 'TERNARY' === arg.form.getFieldValue('type');
},
},
{
name: 'when',
label: $t('re.resources.designer.processor.grid.entity.when'),
type: 'code-mirror',
lang: 'groovy',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'then',
label: $t('re.resources.designer.processor.grid.entity.then'),
type: 'code-mirror',
lang: 'groovy',
rows: 1,
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'isWhenThenShorted',
label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted'),
type: 'checkbox',
showIf: (arg) => {
return 'WHEN_THEN' === arg.form.getFieldValue('type');
},
},
{
name: 'numberRange',
label: $t('re.resources.designer.processor.grid.entity.numberRange'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'NUMBER_RANGE' === arg.form.getFieldValue('type');
},
},
{
name: 'conditionRange',
label: $t('re.resources.designer.processor.grid.entity.conditionRange'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'CONDITION_RANGE' === arg.form.getFieldValue('type');
},
},
{
name: 'groovyScript',
label: $t('re.resources.designer.processor.grid.entity.groovyScript'),
type: 'code-mirror',
rows: 1,
showIf: (arg) => {
return 'GROOVY_SCRIPT' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlDatasourceName',
label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sql',
label: $t('re.resources.designer.processor.grid.entity.sql'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlParameterValues',
label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
{
name: 'sqlFieldMapping',
label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping'),
type: 'select',
rows: 1,
showIf: (arg) => {
return 'SQL' === arg.form.getFieldValue('type');
},
},
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t(''), primaryKey: true },
{ name: 'parameter', label: $t('') },
{ name: 'description', label: $t('') },
{ name: 'order', label: $t('') },
{ name: 'enable', label: $t('') },
{ name: 'type', label: $t('') },
{ name: 'arithmetic', label: $t('re.resources.designer.processor.grid.entity.arithmetic') },
{ name: 'ternaryCondition', label: $t('re.resources.designer.processor.grid.entity.ternaryCondition') },
{ name: 'ternaryTrue', label: $t('re.resources.designer.processor.grid.entity.ternaryTrue') },
{ name: 'ternaryFalse', label: $t('re.resources.designer.processor.grid.entity.ternaryFalse') },
{ name: 'when', label: $t('re.resources.designer.processor.grid.entity.when') },
{ name: 'then', label: $t('re.resources.designer.processor.grid.entity.then') },
{ name: 'isWhenThenShorted', label: $t('re.resources.designer.processor.grid.entity.isWhenThenShorted') },
{ name: 'rule', label: $t('re.resources.designer.processor.grid.entity.rule') },
{ name: 'singleRule', label: $t('re.resources.designer.processor.grid.entity.singleRule') },
{ name: 'numberRange', label: $t('re.resources.designer.processor.grid.entity.numberRange') },
{ name: 'conditionRange', label: $t('re.resources.designer.processor.grid.entity.conditionRange') },
{ name: 'groovyScript', label: $t('re.resources.designer.processor.grid.entity.groovyScript') },
{ name: 'sqlDatasourceName', label: $t('re.resources.designer.processor.grid.entity.sqlDatasourceName') },
{ name: 'sql', label: $t('re.resources.designer.processor.grid.entity.sql') },
{ name: 'sqlParameterValues', label: $t('re.resources.designer.processor.grid.entity.sqlParameterValues') },
{ name: 'sqlFieldMapping', label: $t('re.resources.designer.processor.grid.entity.sqlFieldMapping') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { Environment, Formater, EnumTools, Options } from 'platform-core';
const props = defineProps({
indicator: { type: Object, default: undefined },
});
const gridRef = ref();
const refresh = () => {
gridRef.value.refresh();
};
onMounted(() => {
gridRef.value.refresh();
});
defineExpose({
refresh,
});
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ProcessorType']);
</script>

217
io.sc.engine.rule.frontend/src/views/lib/ValidatorGrid.vue

@ -0,0 +1,217 @@
<template>
<div style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('re.resources.designer.validator.grid.title')"
dense-body
hide-bottom
:config-button="false"
selection="multiple"
:checkbox-selection="false"
:tree="false"
:fetch-data-url="Environment.apiContextPath('/api/re/indicator/validator?indicator=' + indicator.id)"
:data-url="Environment.apiContextPath('/api/re/indicator/validator')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['refresh', 'separator', 'add', 'edit', 'remove', 'separator', 'view', 'separator', 'export']"
:columns="[
{ width: 60, name: 'order', label: $t('order'), sortable: false, align: 'right' },
{ width: 100, name: 'type', label: $t('type'), sortable: false, format: Formater.enum(Enums.ValidatorType) },
{
width: 300,
name: 'content',
label: $t('re.resources.designer.validator.grid.entity.content'),
sortable: false,
format: (value, row) => {
const type = row.type;
if (type == 'EMPTY' || type == 'NOT_EMPTY' || type == 'TRUE' || type == 'FALSE' || type == 'EMAIL') {
return '';
} else if (type == 'INTEGER_RANGE' || type == 'DECIMAL_RANGE' || type == 'LENGTH_RANGE' || type == 'DATE_RANGE') {
return Tools.generateIntervalRange(row.minInclude, row.minValue, row.maxValue, row.maxInclude);
} else if (type == 'PATTERN') {
return row.pattern;
}
return '';
},
},
{ width: '100%', name: 'tip', label: $t('re.resources.designer.validator.grid.entity.tip'), sortable: false },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [
{ name: 'indicator', label: 'indicator', type: 'text', defaultValue: indicator.id, hidden: true },
{ name: 'id', label: $t('id'), type: 'text', hidden: true },
{
name: 'description',
label: $t('description'),
type: 'text',
},
{
name: 'type',
label: $t('type'),
type: 'select',
required: true,
options:
ValueTypeAndValidatorTypeMapping[ValueTypeAndValidatorTypeMapping[indicator.valueType] == null ? 'java.lang.Object' : indicator.valueType],
},
{
name: 'minValue',
label: $t('minValue'),
type: 'text',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'INTEGER_RANGE' || type == 'DECIMAL_RANGE' || type == 'LENGTH_RANGE' || type == 'DATE_RANGE') {
return true;
}
return false;
},
},
{
name: 'minInclude',
label: $t('isMinValueInclude'),
type: 'checkbox',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'INTEGER_RANGE' || type == 'DECIMAL_RANGE' || type == 'LENGTH_RANGE' || type == 'DATE_RANGE') {
return true;
}
return false;
},
},
{
name: 'maxValue',
label: $t('maxValue'),
type: 'text',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'INTEGER_RANGE' || type == 'DECIMAL_RANGE' || type == 'LENGTH_RANGE' || type == 'DATE_RANGE') {
return true;
}
return false;
},
},
{
name: 'maxInclude',
label: $t('isMaxValueInclude'),
type: 'checkbox',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'INTEGER_RANGE' || type == 'DECIMAL_RANGE' || type == 'LENGTH_RANGE' || type == 'DATE_RANGE') {
return true;
}
return false;
},
},
{
name: 'pattern',
label: $t('RegExp'),
type: 'text',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
if (type == 'PATTERN') {
return true;
}
return false;
},
},
{
name: 'tip',
label: $t('re.resources.designer.validator.grid.entity.tip'),
type: 'text',
},
{ name: 'order', label: $t('order'), type: 'number', hidden: false },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'order', label: $t('order') },
{ name: 'type', label: $t('type'), format: Formater.none() },
{ name: 'description', label: $t('description') },
{ name: 'tip', label: $t('re.resources.designer.validator.grid.entity.tip') },
{ name: 'minInclude', label: $t('isMinValueInclude') },
{ name: 'minValue', label: $t('minValue') },
{ name: 'maxValue', label: $t('maxValue') },
{ name: 'maxInclude', label: $t('isMaxValueInclude') },
{ name: 'pattern', label: $t('RegExp') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, EnumTools, Formater, Tools } from 'platform-core';
const props = defineProps({
indicator: { type: Object, default: undefined },
});
const { t } = useI18n();
const gridRef = ref();
const ValueTypeAndValidatorTypeMapping = {
'java.lang.Boolean': [
{ value: 'NOT_EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.NOT_EMPTY') },
{ value: 'EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.EMPTY') },
{ value: 'TRUE', label: t('io.sc.engine.rule.core.enums.ValidatorType.TRUE') },
{ value: 'FALSE', label: t('io.sc.engine.rule.core.enums.ValidatorType.FALSE') },
],
'java.lang.Long': [
{ value: 'NOT_EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.NOT_EMPTY') },
{ value: 'EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.EMPTY') },
{ value: 'INTEGER_RANGE', label: t('io.sc.engine.rule.core.enums.ValidatorType.INTEGER_RANGE') },
],
'java.math.BigDecimal': [
{ value: 'NOT_EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.NOT_EMPTY') },
{ value: 'EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.EMPTY') },
{ value: 'DECIMAL_RANGE', label: t('io.sc.engine.rule.core.enums.ValidatorType.DECIMAL_RANGE') },
],
'java.lang.String': [
{ value: 'NOT_EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.NOT_EMPTY') },
{ value: 'EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.EMPTY') },
{ value: 'LENGTH_RANGE', label: t('io.sc.engine.rule.core.enums.ValidatorType.LENGTH_RANGE') },
{ value: 'EMAIL', label: t('io.sc.engine.rule.core.enums.ValidatorType.EMAIL') },
{ value: 'PATTERN', label: t('io.sc.engine.rule.core.enums.ValidatorType.PATTERN') },
],
'java.util.Date': [
{ value: 'NOT_EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.NOT_EMPTY') },
{ value: 'EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.EMPTY') },
{ value: 'DATE_RANGE', label: t('io.sc.engine.rule.core.enums.ValidatorType.DATE_RANGE') },
],
'java.lang.Object': [
{ value: 'NOT_EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.NOT_EMPTY') },
{ value: 'EMPTY', label: t('io.sc.engine.rule.core.enums.ValidatorType.EMPTY') },
],
};
const refresh = () => {
gridRef.value.refresh();
};
onMounted(() => {
gridRef.value.refresh();
});
defineExpose({
refresh,
});
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ValidatorType']);
</script>

147
io.sc.engine.rule.frontend/src/views/migration/Migration.vue

@ -1,4 +1,147 @@
<template>
<div>migeration</div>
<div>
<div class="row" style="padding-top: 50px">
<div class="col-1"></div>
<div class="col-4">
<q-card>
<q-card-section>
<div class="text-h6">{{ $t('re.migration.import.title') }}</div>
<div class="text-subtitle2">{{ $t('re.migration.import.subTitle') }}</div>
</q-card-section>
<q-separator />
<q-card-section>
<q-file ref="fileRef" v-model="fileValueRef" :label="$t('file.single.tip')" dense outlined clearable counter accept=".json">
<template #prepend>
<q-icon name="cloud_upload" />
</template>
</q-file>
</q-card-section>
<q-card-actions align="right">
<q-btn
color="primary"
:label="$t('re.migration.import.action')"
@click="
() => {
axios
.post(
Environment.apiContextPath('/api/re/migration/import'),
{
file: fileRef.value.nativeEl.files[0],
},
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
)
.then(() => {
NotifyManager.info($t('operationSuccess'));
});
}
"
></q-btn>
</q-card-actions>
</q-card>
</div>
<div class="col-1"></div>
<div class="col-5">
<q-card>
<q-card-section>
<div class="text-h6">{{ $t('re.migration.export.title') }}</div>
<div class="text-subtitle2">{{ $t('re.migration.export.subTitle') }}</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn
color="primary"
:label="$t('re.migration.export.action')"
@click="
() => {
let url = Environment.apiContextPath('/api/re/migration/export');
downloadIframeRef.src = url;
}
"
></q-btn>
</q-card-actions>
</q-card>
</div>
<div class="col-1"></div>
</div>
<div class="row" style="padding-top: 50px">
<div class="col-1"></div>
<div class="col-4">
<q-card>
<q-card-section>
<div class="text-h6">{{ $t('re.migration.importFromServer.title') }}</div>
<div class="text-subtitle2">{{ $t('re.migration.importFromServer.subTitle') }}</div>
</q-card-section>
<q-separator />
<q-card-section>
<q-input v-model="serverFilePathRef" outlined dense></q-input>
</q-card-section>
<q-card-actions align="right">
<q-btn
color="primary"
:label="$t('re.migration.importFromServer.action')"
@click="
() => {
axios
.post(Environment.apiContextPath('/api/re/migration/importFromServerFile?filePath=' + encodeURIComponent(serverFilePathRef)))
.then(() => {
NotifyManager.info($t('operationSuccess'));
});
}
"
></q-btn>
</q-card-actions>
</q-card>
</div>
<div class="col-1"></div>
<div class="col-5">
<q-card>
<q-card-section>
<div class="text-h6">{{ $t('re.migration.remove.title') }}</div>
<div class="text-subtitle2">{{ $t('re.migration.remove.subTitle') }}</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn
color="primary"
:label="$t('re.migration.remove.action')"
@click="
() => {
DialogManager.confirm($t('re.migration.remove.action.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/migration/removeAll')).then(() => {
NotifyManager.info($t('operationSuccess'));
});
});
}
"
></q-btn>
</q-card-actions>
</q-card>
</div>
<div class="col-1"></div>
</div>
<iframe ref="downloadIframeRef" src="javascript:;" style="width: 0px; height: 0px"></iframe>
</div>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, NotifyManager, DialogManager } from 'platform-core';
const fileRef = ref();
const fileValueRef = ref();
const serverFilePathRef = ref();
const downloadIframeRef = ref();
</script>

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

@ -1,5 +1,5 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.resources.importSample.dialog.title')" width="600px" :can-maximize="false">
<w-dialog ref="dialogRef" :title="$t('re.resources.import.dialog.title')" width="600px" :can-maximize="false">
<q-form action="post">
<div class="row py-1">
<div class="col-3"></div>
@ -24,14 +24,12 @@
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import { axios, Environment, DialogManager, Tools } from 'platform-core';
import { axios, Environment } from 'platform-core';
const emit = defineEmits<{
(e: 'afterImported', evt: Event): void;
}>();
const { t } = useI18n();
const dialogRef = ref();
const modelValue = reactive({
file: undefined,

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

@ -4,6 +4,7 @@
ref="treeGridRef"
:title="$t('re.resources.grid.title')"
dense-body
hide-bottom
:config-button="true"
selection="multiple"
:checkbox-selection="false"
@ -314,7 +315,7 @@
<DesignerDialog ref="designerDialogRef"></DesignerDialog>
<ImportDialog ref="importDialogRef" @after-imported="afterImported"></ImportDialog>
<ImportSampleDialog ref="importSampleDialogRef" @after-imported="afterImported"></ImportSampleDialog>
<iframe ref="downloadIframe" src="javascript:;" style="width: 100px; height: 100px"></iframe>
<iframe ref="downloadIframe" src="javascript:;" style="width: 0px; height: 0px"></iframe>
</div>
</template>
<script setup lang="ts">

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

@ -144,29 +144,18 @@
],
},
}"
@row-click="
(evt, row, index) => {
emit('rowClick', evt, row, index);
}
"
@before-request-data="
() => {
emit('beforeRequestData');
}
"
v-bind="attrs"
></w-grid>
</template>
<script setup lang="ts">
import { useAttrs } from 'vue';
import { Environment, EnumTools, Formater, Options } from 'platform-core';
const attrs = useAttrs();
const props = defineProps({
resource: { type: Object, default: undefined },
});
const emit = defineEmits<{
(e: 'rowClick', evt: Event, row: any, index: number): void;
(e: 'beforeRequestData', requestParams: URLSearchParams | any, callback: any): void;
}>();
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ModelCategory', 'io.sc.engine.rule.core.enums.ExecuteMode']);
</script>

16
io.sc.engine.rule.sample/src/main/resources/META-INF/platform/plugins/messages.json

@ -0,0 +1,16 @@
/*
*
* :
* 使:
* includes:
* excludes:
* : includes excludes , excludes ,
*/
{
"includes":[
"io/sc/engine/rule/sample/i18n/messages"
],
"excludes":[]
}

70
io.sc.engine.rule.sample/src/main/resources/META-INF/platform/plugins/rule-engine-sample-resource.json

@ -0,0 +1,70 @@
[
//
{"id":"re.engine.sample.resource.app","order":200},
///
{"id":"re.engine.sample.resource.app.irs","parentId":"re.engine.sample.resource.app","order":100},
////-()
{
"order" :100,
"parentId" :"re.engine.sample.resource.app.irs",
"id" :"re.engine.sample.resource.app.irs.hankou",
"file" :"classpath:/io/sc/engine/rule/sample/app/irs/hankou/汉口银行-内部评级模型(非零售).json"
},
///
{"id":"re.engine.sample.resource.app.rirs","parentId":"re.engine.sample.resource.app","order":200},
////-()
{
"order" :200,
"parentId" :"re.engine.sample.resource.app.rirs",
"id" :"re.engine.sample.resource.app.rirs.hankou",
"file" :"classpath:/io/sc/engine/rule/sample/app/rirs/hankou/汉口银行-内部评级模型(零售).json"
},
////-
{
"order" :100,
"parentId" :"re.engine.sample.resource.app.rirs",
"id" :"re.engine.sample.resource.app.rirs.tianfu",
"file" :"classpath:/io/sc/engine/rule/sample/app/rirs/tianfu/天府银行-风险定价模型.json"
},
///
{"id":"re.engine.sample.resource.app.warning","order":300},
////-
{
"order" :100,
"parentId" :"re.engine.sample.resource.app.warning",
"id" :"re.engine.sample.resource.app.warning.pingan.financial",
"file" :"classpath:/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警.json",
"dictionary":"classpath:/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警(数据字典).json",
"lib" :"classpath:/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警(指标库).json"
},
////-
{
"order" :200,
"parentId" :"re.engine.sample.resource.app.warning",
"id" :"re.engine.sample.resource.app.warning.pingan.after_lease",
"file" :"classpath:/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-租后预警规则.json"
},
///
{"id":"re.engine.sample.resource.app.other","order":400},
////-()
{
"order" :100,
"parentId" :"re.engine.sample.resource.app.other",
"id" :"re.engine.sample.resource.app.other.aml",
"file" :"classpath:/io/sc/engine/rule/sample/app/other/昆山农商行-反洗钱模型(机器学习模型).json"
},
////-()
{
"order" :200,
"parentId" :"re.engine.sample.resource.app.other",
"id" :"re.engine.sample.resource.app.other.illegal_saving",
"file" :"classpath:/io/sc/engine/rule/sample/app/other/昆山农商行-非法集资(规则).json"
},
////()
{
"order" :300,
"parentId" :"re.engine.sample.resource.app.other",
"id" :"re.engine.sample.resource.app.other.PersonalConsumptionLoanEnglish",
"file" :"classpath:/io/sc/engine/rule/sample/app/other/个人消费贷模型(英语).json"
}
]

150995
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/irs/hankou/汉口银行-内部评级模型(非零售).json

File diff suppressed because one or more lines are too long

14015
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/other/个人消费贷模型(英语).json

File diff suppressed because one or more lines are too long

536
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/other/昆山农商行-反洗钱模型(机器学习模型).json

File diff suppressed because one or more lines are too long

1695
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/other/昆山农商行-非法集资(规则).json

File diff suppressed because it is too large

2342
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/rirs/hankou/汉口银行-内部评级模型(零售).json

File diff suppressed because one or more lines are too long

8901
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/rirs/tianfu/天府银行-风险定价模型.json

File diff suppressed because it is too large

4908
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-租后预警规则.json

File diff suppressed because one or more lines are too long

74651
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警(指标库).json

File diff suppressed because one or more lines are too long

10572
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警(数据字典).json

File diff suppressed because it is too large

60321
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/app/warning/pingan/平安租赁-财报分析预警.json

File diff suppressed because one or more lines are too long

34
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/i18n/messages.properties

@ -0,0 +1,34 @@
re.engine.sample.resource.app=Application Sample
re.engine.sample.resource.app.description=
# \u975E\u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.irs=IRS Model Sample
re.engine.sample.resource.app.irs.description=
re.engine.sample.resource.app.irs.hankou=Not Retail Rate Model
re.engine.sample.resource.app.irs.hankou.description=Not Retail Rate Model
# \u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.rirs=RIRS Model Sample
re.engine.sample.resource.app.rirs.description=
re.engine.sample.resource.app.rirs.hankou=Retail Rate Model
re.engine.sample.resource.app.rirs.hankou.description=Retail Rate Model
re.engine.sample.resource.app.rirs.tianfu=Price Model
re.engine.sample.resource.app.rirs.tianfu.description=Price Model
# \u9884\u8B66
re.engine.sample.resource.app.warning=Warning Sample
re.engine.sample.resource.app.warning.description=
re.engine.sample.resource.app.warning.pingan.financial=Financial Warning Rule
re.engine.sample.resource.app.warning.pingan.financial.description=Financial Warning Rule
re.engine.sample.resource.app.warning.pingan.after_lease=Post-Loan Warning Rules
re.engine.sample.resource.app.warning.pingan.after_lease.description=Post-Loan Warning Rules
# \u5176\u4ED6
re.engine.sample.resource.app.other=Other Sample
re.engine.sample.resource.app.other.description=
re.engine.sample.resource.app.other.aml=AML (Machine Learning Model)
re.engine.sample.resource.app.other.aml.description=AML (Machine Learning Model)
re.engine.sample.resource.app.other.illegal_saving=Illegal Saving Rule
re.engine.sample.resource.app.other.illegal_saving.description=Illegal Saving Rule
re.engine.sample.resource.app.other.PersonalConsumptionLoanEnglish=Personal Consumption Loan Model
re.engine.sample.resource.app.other.PersonalConsumptionLoanEnglish.description=Personal Consumption Loan Model

35
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/i18n/messages_tw_CN.properties

@ -0,0 +1,35 @@
re.engine.sample.resource.app=\u61C9\u7528\u793A\u4F8B
re.engine.sample.resource.app.description=
# \u975E\u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.irs=\u975E\u96F6\u552E\u5167\u8A55
re.engine.sample.resource.app.irs.description=
re.engine.sample.resource.app.irs.hankou=\u5167\u90E8\u8A55\u7D1A\u6A21\u578B(\u975E\u96F6\u552E)
re.engine.sample.resource.app.irs.hankou.description=\u975E\u96F6\u552E\u5167\u8A55\u6A21\u578B(\u91D1\u878D\u6A5F\u69CB\u3001\u767C\u50B5\u4F01\u696D\u3001\u4E00\u822C\u4F01\u696D)
# \u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.rirs=\u96F6\u552E\u5167\u8A55
re.engine.sample.resource.app.rirs.description=
re.engine.sample.resource.app.rirs.hankou=\u5167\u90E8\u8A55\u7D1A\u6A21\u578B(\u96F6\u552E)
re.engine.sample.resource.app.rirs.hankou.description=\u96F6\u552E\u8A55\u5206\u5361
re.engine.sample.resource.app.rirs.tianfu=\u98A8\u96AA\u5B9A\u50F9\u6A21\u578B
re.engine.sample.resource.app.rirs.tianfu.description=\u98A8\u96AA\u5B9A\u50F9\u6A21\u578B(A\u3001B\u3001C\u5361;\u5B9A\u50F9\u6A21\u578B;\u9650\u984D\u6A21\u578B;\u8CC7\u7522\u7D44\u5408)
# \u9884\u8B66
re.engine.sample.resource.app.warning=\u9810\u8B66
re.engine.sample.resource.app.warning.description=
re.engine.sample.resource.app.warning.pingan.financial=\u8CA1\u52D9\u5206\u6790\u9810\u8B66
re.engine.sample.resource.app.warning.pingan.financial.description=\u8CA1\u52D9\u5206\u6790\u9810\u8B66\u898F\u5247
re.engine.sample.resource.app.warning.pingan.after_lease=\u8CB8\u5F8C\u9810\u8B66
re.engine.sample.resource.app.warning.pingan.after_lease.description=\u8CB8\u5F8C\u9810\u8B66\u898F\u5247
# \u5176\u4ED6
re.engine.sample.resource.app.other=\u5176\u4ED6
re.engine.sample.resource.app.other.description=
re.engine.sample.resource.app.other.aml=\u53CD\u6D17\u9322\u6A21\u578B(\u6A5F\u5668\u5B78\u7FD2\u6A21\u578B)
re.engine.sample.resource.app.other.aml.description=\u53CD\u6D17\u9322\u6A21\u578B(\u6A5F\u5668\u5B78\u7FD2\u6A21\u578B)
re.engine.sample.resource.app.other.illegal_saving=\u975E\u6CD5\u96C6\u8CC7(\u898F\u5247)
re.engine.sample.resource.app.other.illegal_saving.description=\u975E\u6CD5\u96C6\u8CC7(\u898F\u5247)
re.engine.sample.resource.app.other.PersonalConsumptionLoanEnglish=\u500B\u4EBA\u6D88\u8CBB\u8CB8\u6A21\u578B(\u82F1\u8A9E)
re.engine.sample.resource.app.other.PersonalConsumptionLoanEnglish.description=\u500B\u4EBA\u6D88\u8CBB\u8CB8\u6A21\u578B(\u82F1\u8A9E)

35
io.sc.engine.rule.sample/src/main/resources/io/sc/engine/rule/sample/i18n/messages_zh_CN.properties

@ -0,0 +1,35 @@
re.engine.sample.resource.app=\u5E94\u7528\u793A\u4F8B
re.engine.sample.resource.app.description=
# \u975E\u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.irs=\u975E\u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.irs.description=
re.engine.sample.resource.app.irs.hankou=\u5185\u90E8\u8BC4\u7EA7\u6A21\u578B(\u975E\u96F6\u552E)
re.engine.sample.resource.app.irs.hankou.description=\u975E\u96F6\u552E\u5185\u8BC4\u6A21\u578B(\u91D1\u878D\u673A\u6784\u3001\u53D1\u503A\u4F01\u4E1A\u3001\u4E00\u822C\u4F01\u4E1A)
# \u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.rirs=\u96F6\u552E\u5185\u8BC4
re.engine.sample.resource.app.rirs.description=
re.engine.sample.resource.app.rirs.hankou=\u5185\u90E8\u8BC4\u7EA7\u6A21\u578B(\u96F6\u552E)
re.engine.sample.resource.app.rirs.hankou.description=\u96F6\u552E\u8BC4\u5206\u5361
re.engine.sample.resource.app.rirs.tianfu=\u98CE\u9669\u5B9A\u4EF7\u6A21\u578B
re.engine.sample.resource.app.rirs.tianfu.description=\u98CE\u9669\u5B9A\u4EF7\u6A21\u578B(A\u3001B\u3001C\u5361;\u5B9A\u4EF7\u6A21\u578B;\u9650\u989D\u6A21\u578B;\u8D44\u4EA7\u7EC4\u5408)
# \u9884\u8B66
re.engine.sample.resource.app.warning=\u9884\u8B66
re.engine.sample.resource.app.warning.description=
re.engine.sample.resource.app.warning.pingan.financial=\u8D22\u52A1\u5206\u6790\u9884\u8B66
re.engine.sample.resource.app.warning.pingan.financial.description=\u8D22\u52A1\u5206\u6790\u9884\u8B66\u89C4\u5219
re.engine.sample.resource.app.warning.pingan.after_lease=\u8D37\u540E\u9884\u8B66
re.engine.sample.resource.app.warning.pingan.after_lease.description=\u8D37\u540E\u9884\u8B66\u89C4\u5219
# \u5176\u4ED6
re.engine.sample.resource.app.other=\u5176\u4ED6
re.engine.sample.resource.app.other.description=
re.engine.sample.resource.app.other.aml=\u53CD\u6D17\u94B1\u6A21\u578B(\u673A\u5668\u5B66\u4E60\u6A21\u578B)
re.engine.sample.resource.app.other.aml.description=\u53CD\u6D17\u94B1\u6A21\u578B(\u673A\u5668\u5B66\u4E60\u6A21\u578B)
re.engine.sample.resource.app.other.illegal_saving=\u975E\u6CD5\u96C6\u8D44(\u89C4\u5219)
re.engine.sample.resource.app.other.illegal_saving.description=\u975E\u6CD5\u96C6\u8D44(\u89C4\u5219)
re.engine.sample.resource.app.other.PersonalConsumptionLoanEnglish=\u4E2A\u4EBA\u6D88\u8D39\u8D37\u6A21\u578B(\u82F1\u8BED)
re.engine.sample.resource.app.other.PersonalConsumptionLoanEnglish.description=\u4E2A\u4EBA\u6D88\u8D39\u8D37\u6A21\u578B(\u82F1\u8BED)

16
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/controller/DictionaryWebController.java

@ -71,7 +71,7 @@ public class DictionaryWebController extends RestCrudController<DictionaryVo, Di
* @throws Exception 违例
*/
@PostMapping("deploy/{id}")
public DictionaryEntity deploy(@PathVariable(name="id",required=true)String id) throws Exception{
public DictionaryVo deploy(@PathVariable(name="id",required=true)String id) throws Exception{
return service.deploy(id);
}
@ -100,7 +100,7 @@ public class DictionaryWebController extends RestCrudController<DictionaryVo, Di
* @return 字典的所有版本
* @throws Exception 违例
*/
@GetMapping("isc/getVersionsByCode")
@GetMapping("getVersionsByCode")
public List<KeyValue<Integer, Integer>> getVersionsByCode(@RequestParam(name="code",required = false)String code) throws Exception {
if(StringUtils.hasText(code)) {
Map<Integer,Integer> map =service.getVersionsByCode(code);
@ -174,7 +174,7 @@ public class DictionaryWebController extends RestCrudController<DictionaryVo, Di
* @return 所有数据字典示例贡献项
* @throws Exception 违例
*/
@RequestMapping(value="isc/listDictionaryExampleContributionItems", method=RequestMethod.GET)
@RequestMapping(value="listDictionaryExampleContributionItems", method=RequestMethod.GET)
@ResponseBody
public List<DictionaryExampleWrapper> listDictionaryExampleContributionItems(HttpServletRequest request,HttpServletResponse response,Locale locale) throws Exception{
List<DictionaryExampleItem> items = PluginManager.getInstance().getDictionaryExampleItemEntries();
@ -183,7 +183,6 @@ public class DictionaryWebController extends RestCrudController<DictionaryVo, Di
for(DictionaryExampleItem item : items) {
result.add(DictionaryExampleWrapper.from(item));
}
updateDictionaryExampleContributionItemTitle(result,locale);
return result;
}
return Collections.emptyList();
@ -211,13 +210,4 @@ public class DictionaryWebController extends RestCrudController<DictionaryVo, Di
public SourceCode generateUserDefinedJavaClassDictionarySampleJsonCode(@PathVariable(name="dictionaryId",required=true)String dictionaryId) throws Exception{
return service.generateUserDefinedJavaClassDictionarySampleJsonCode(dictionaryId);
}
private void updateDictionaryExampleContributionItemTitle(List<DictionaryExampleWrapper> items,Locale locale) throws Exception{
if(items!=null && items.size()>0){
for(DictionaryExampleWrapper item : items){
item.setName(messageSource.getMessage(item.getId(), null, locale));
item.setDescription(messageSource.getMessage(item.getId()+".description", null,locale));
}
}
}
}

3
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/DictionaryService.java

@ -10,6 +10,7 @@ import io.sc.engine.rule.core.po.dictionary.Dictionary;
import io.sc.engine.rule.server.dictionary.entity.DictionaryEntity;
import io.sc.engine.rule.server.dictionary.entity.ReleasableDictionaryEntity;
import io.sc.engine.rule.server.dictionary.repository.DictionaryRepository;
import io.sc.engine.rule.server.dictionary.vo.DictionaryVo;
import io.sc.engine.rule.server.model.service.support.ParemterHints;
import io.sc.engine.rule.server.util.CodeAndNameMapping;
import io.sc.platform.orm.service.DaoService;
@ -41,7 +42,7 @@ public interface DictionaryService extends DaoService<DictionaryEntity, String,
* @return 发布数据字典实体
* @throws Exception 违例
*/
public DictionaryEntity deploy(String id) throws Exception;
public DictionaryVo deploy(String id) throws Exception;
/**
* 获取所有数据字典 Map(key: code; value: name),示例如下:

6
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/impl/DictionaryServiceImpl.java

@ -16,6 +16,7 @@ import io.sc.engine.rule.server.dictionary.exception.JavaClassNotExistsException
import io.sc.engine.rule.server.dictionary.repository.DictionaryRepository;
import io.sc.engine.rule.server.dictionary.service.DictionaryService;
import io.sc.engine.rule.server.dictionary.service.support.DictionaryEntityChangedEvent;
import io.sc.engine.rule.server.dictionary.vo.DictionaryVo;
import io.sc.engine.rule.server.lib.entity.IndicatorEntity;
import io.sc.engine.rule.server.lib.entity.IndicatorLibEntity;
import io.sc.engine.rule.server.lib.entity.LibEntity;
@ -35,6 +36,7 @@ import io.sc.platform.core.enums.AuditLogAction;
import io.sc.platform.core.util.ObjectMapper4Json;
import io.sc.platform.orm.entity.support.EntityChangedEventType;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.orm.util.EntityVoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.MessageSource;
@ -206,7 +208,7 @@ public class DictionaryServiceImpl extends DaoServiceImpl<DictionaryEntity, Stri
}
@Override
public DictionaryEntity deploy(String id) throws Exception {
public DictionaryVo deploy(String id) throws Exception {
if(StringUtils.hasText(id)) {
ReleasableDictionaryEntity entity =repository.findReleasableDictionaryById(id);
if(entity!=null) {
@ -219,7 +221,7 @@ public class DictionaryServiceImpl extends DaoServiceImpl<DictionaryEntity, Stri
}
entity.setStatus(DeployStatus.ON_LINE);
repository.save(entity);
return entity;
return entity.toVo();
}
}
return null;

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/controller/IndicatorValidatorWebController.java

@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
*
*/
@Controller
@RequestMapping("/re/indicator/validator")
@RequestMapping("/api/re/indicator/validator")
public class IndicatorValidatorWebController extends RestCrudController<IndicatorValidatorVo, IndicatorValidatorEntity,String,IndicatorValidatorRepository,IndicatorValidatorService> {
}

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/controller/IndicatorWebController.java

@ -19,7 +19,7 @@ import java.util.Map;
* 指标管理器 Controller
*/
@Controller
@RequestMapping("/re/indicator")
@RequestMapping("api/re/indicator")
public class IndicatorWebController extends RestCrudController<IndicatorVo,IndicatorEntity,String,IndicatorRepository,IndicatorService> {
@RequestMapping("isc/getIndicatorsByLibCodeAndVersion")

47
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/IndicatorEntity.java

@ -10,6 +10,7 @@ import io.sc.engine.rule.server.testcase.annotation.TestCaseParameterAble;
import io.sc.engine.rule.server.testcase.wrapper.TestCaseParameterWrapper;
import io.sc.platform.orm.DeepClone;
import io.sc.platform.orm.IdClearable;
import io.sc.platform.orm.api.vo.AuditorVo;
import io.sc.platform.orm.api.vo.BaseVo;
import io.sc.platform.orm.converter.NumericBooleanConverter;
import io.sc.platform.orm.entity.AuditorEntity;
@ -29,14 +30,19 @@ import java.util.List;
*/
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FD_TYPE",discriminatorType=DiscriminatorType.STRING,length=20)
@DiscriminatorColumn(name="TYPE_",discriminatorType=DiscriminatorType.STRING,length=20)
@Table(name="RE_LIB_INDICATOR")
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",defaultImpl=InterfaceIndicatorEntity.class)
@JsonSubTypes({
@JsonSubTypes.Type(value=InterfaceIndicatorEntity.class), //接口
@JsonSubTypes.Type(value=IndicatorIndicatorEntity.class) //指标
})
public abstract class IndicatorEntity extends AuditorEntity<IndicatorVo> implements DeepClone, IdClearable,TestCaseParameterAble {
public class IndicatorEntity extends AuditorEntity<IndicatorVo> implements DeepClone, IdClearable,TestCaseParameterAble {
//参数类型(用于区分子类)
@Column(name="TYPE_",insertable=false,updatable=false)
@Enumerated(EnumType.STRING)
protected IndicatorType type;
//ID,主键
@Id
@GeneratedValue(generator = "system-uuid")
@ -60,11 +66,6 @@ public abstract class IndicatorEntity extends AuditorEntity<IndicatorVo> impleme
@Size(max=255)
protected String description;
//参数类型(用于区分子类)
@Column(name="TYPE_",insertable=false,updatable=false)
@Enumerated(EnumType.STRING)
protected IndicatorType type;
//值类型
@Column(name="VALUE_TYPE_", length=255)
protected String valueType;
@ -110,11 +111,37 @@ public abstract class IndicatorEntity extends AuditorEntity<IndicatorVo> impleme
@JoinColumn(name="LIB_ID_")
protected LibEntity lib;
@Override
public void toVo(IndicatorVo vo) {
if(vo!=null) {
super.toVo(vo);
vo.setType(this.getType());
vo.setId(this.getId());
vo.setCode(this.getCode());
vo.setName(this.getName());
vo.setDescription(this.getDescription());
vo.setValueType(this.getValueType());
vo.setValueTypeVersion(this.getValueTypeVersion());
vo.setValueScale(this.getValueScale());
vo.setValueRoundingMode(this.getValueRoundingMode());
vo.setValueTypeIsList(this.getValueTypeIsList());
vo.setDefaultValue(this.getDefaultValue());
vo.setOrder(this.getOrder());
vo.setLib(this.getLib()==null?null:this.getLib().getId());
}
}
public IndicatorEntity() {}
public IndicatorEntity(String id) {
this.id =id;
}
public IndicatorType getType() {
return type;
}
public void setType(IndicatorType type) {
this.type = type;
}
public String getId() {
return id;
}
@ -139,12 +166,6 @@ public abstract class IndicatorEntity extends AuditorEntity<IndicatorVo> impleme
public void setDescription(String description) {
this.description = description;
}
public IndicatorType getType() {
return type;
}
public void setType(IndicatorType type) {
this.type = type;
}
public String getValueType() {
return valueType;
}

67
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/IndicatorProcessorEntity.java

@ -8,6 +8,7 @@ import io.sc.engine.rule.server.lib.entity.processor.*;
import io.sc.engine.rule.server.lib.vo.IndicatorProcessorVo;
import io.sc.platform.orm.DeepClone;
import io.sc.platform.orm.IdClearable;
import io.sc.platform.orm.api.vo.AuditorVo;
import io.sc.platform.orm.entity.AuditorEntity;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.beans.BeanUtils;
@ -23,7 +24,7 @@ import java.util.Map;
*/
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FD_TYPE",discriminatorType=DiscriminatorType.STRING,length=20)
@DiscriminatorColumn(name="TYPE_",discriminatorType=DiscriminatorType.STRING,length=20)
@Table(name="RE_LIB_INDICATOR_PROCESSOR")
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",defaultImpl=EmptyIndicatorProcessorEntity.class)
@JsonSubTypes({
@ -37,7 +38,12 @@ import java.util.Map;
@JsonSubTypes.Type(value=SqlIndicatorProcessorEntity.class), //SQL处理器
@JsonSubTypes.Type(value=HttpRequestIndicatorProcessorEntity.class) //Http请求处理器
})
public abstract class IndicatorProcessorEntity extends AuditorEntity<IndicatorProcessorVo> implements DeepClone, IdClearable, CodeAndNameReplacer{
public class IndicatorProcessorEntity extends AuditorEntity<IndicatorProcessorVo> implements DeepClone, IdClearable, CodeAndNameReplacer{
//类型(用于区分子类)
@Column(name="TYPE_", insertable=false,updatable=false)
@Enumerated(EnumType.STRING)
protected ProcessorType type;
//ID,主键
@Id
@GeneratedValue(generator = "system-uuid")
@ -46,16 +52,6 @@ public abstract class IndicatorProcessorEntity extends AuditorEntity<IndicatorPr
@Size(max=36)
protected String id;
//类型(用于区分子类)
@Column(name="TYPE_", insertable=false,updatable=false)
@Enumerated(EnumType.STRING)
protected ProcessorType type;
//所属指标
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="INDICATOR_ID_")
protected IndicatorEntity indicator;
//描述
@Column(name="DESCRIPTION_", length=255)
@Size(max=255)
@ -65,32 +61,37 @@ public abstract class IndicatorProcessorEntity extends AuditorEntity<IndicatorPr
@Column(name="ORDER_")
protected Integer order;
//所属指标
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="INDICATOR_ID_")
protected IndicatorEntity indicator;
@Override
public IndicatorProcessorVo toVo() {
IndicatorProcessorVo vo =new IndicatorProcessorVo();
super.toVo(vo);
vo.setId(this.getId());
vo.setType(this.getType());
vo.setDescription(this.getDescription());
vo.setOrder(this.getOrder());
vo.setIndicator(this.getIndicator()==null?null:this.getIndicator().getId());
return vo;
public void toVo(IndicatorProcessorVo vo) {
if(vo!=null) {
super.toVo(vo);
vo.setId(this.getId());
vo.setType(this.getType());
vo.setDescription(this.getDescription());
vo.setOrder(this.getOrder());
vo.setIndicator(this.getIndicator()==null?null:this.getIndicator().getId());
}
}
public String getId() {
return id;
public ProcessorType getType() {
return type;
}
public void setId(String id) {
this.id = id;
public void setType(ProcessorType type) {
this.type = type;
}
public IndicatorEntity getIndicator() {
return indicator;
public String getId() {
return id;
}
public void setIndicator(IndicatorEntity indicator) {
this.indicator = indicator;
public void setId(String id) {
this.id = id;
}
public String getDescription() {
@ -109,12 +110,12 @@ public abstract class IndicatorProcessorEntity extends AuditorEntity<IndicatorPr
this.order = order;
}
public ProcessorType getType() {
return type;
public IndicatorEntity getIndicator() {
return indicator;
}
public void setType(ProcessorType type) {
this.type = type;
public void setIndicator(IndicatorEntity indicator) {
this.indicator = indicator;
}
@Override

70
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/IndicatorValidatorEntity.java

@ -7,6 +7,7 @@ import io.sc.engine.rule.server.lib.entity.validator.*;
import io.sc.engine.rule.server.lib.vo.IndicatorValidatorVo;
import io.sc.platform.orm.DeepClone;
import io.sc.platform.orm.IdClearable;
import io.sc.platform.orm.api.vo.AuditorVo;
import io.sc.platform.orm.entity.AuditorEntity;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.beans.BeanUtils;
@ -20,7 +21,7 @@ import javax.validation.constraints.Size;
@Entity
@Table(name="RE_LIB_INDICATOR_VALIDATOR")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FD_TYPE",discriminatorType=DiscriminatorType.STRING,length=20)
@DiscriminatorColumn(name="TYPE_",discriminatorType=DiscriminatorType.STRING,length=20)
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",defaultImpl=NotEmptyIndicatorValidatorEntity.class)
@JsonSubTypes({
@JsonSubTypes.Type(value=DateRangeIndicatorValidatorEntity.class),
@ -35,6 +36,11 @@ import javax.validation.constraints.Size;
@JsonSubTypes.Type(value=TrueIndicatorValidatorEntity.class)
})
public class IndicatorValidatorEntity extends AuditorEntity<IndicatorValidatorVo> implements DeepClone, IdClearable {
//参数验证器类型
@Column(name="TYPE_", length=20, insertable = false,updatable = false)
@Enumerated(EnumType.STRING)
protected ValidatorType type;
//ID,主键
@Id
@GeneratedValue(generator = "system-uuid")
@ -43,11 +49,6 @@ public class IndicatorValidatorEntity extends AuditorEntity<IndicatorValidatorVo
@Size(max=36)
protected String id;
//所属接口
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="INDICATOR_ID_")
protected IndicatorEntity indicator;
//描述
@Column(name="DESCRIPTION_", length=255)
@Size(max=255)
@ -57,25 +58,25 @@ public class IndicatorValidatorEntity extends AuditorEntity<IndicatorValidatorVo
@Column(name="ORDER_")
protected Integer order;
//参数验证器类型
@Column(name="TYPE_", length=20, insertable = false,updatable = false)
@Enumerated(EnumType.STRING)
protected ValidatorType type;
//错误提示
@Column(name="TIP_",length=1024)
protected String tip;
//所属接口
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="INDICATOR_ID_")
protected IndicatorEntity indicator;
@Override
public IndicatorValidatorVo toVo() {
IndicatorValidatorVo vo =new IndicatorValidatorVo();
super.toVo(vo);
vo.setId(this.getId());
vo.setType(this.getType());
vo.setDescription(this.getDescription());
vo.setOrder(this.getOrder());
vo.setIndicator(this.getIndicator()==null?null:this.getIndicator().getId());
return null;
public void toVo(IndicatorValidatorVo vo) {
if(vo!=null) {
super.toVo(vo);
vo.setId(this.getId());
vo.setType(this.getType());
vo.setDescription(this.getDescription());
vo.setOrder(this.getOrder());
vo.setIndicator(this.getIndicator()==null?null:this.getIndicator().getId());
}
}
public IndicatorValidatorEntity() {}
@ -83,6 +84,13 @@ public class IndicatorValidatorEntity extends AuditorEntity<IndicatorValidatorVo
this.id =id;
}
public ValidatorType getType() {
return type;
}
public void setType(ValidatorType type) {
this.type = type;
}
public String getId() {
return id;
}
@ -91,12 +99,7 @@ public class IndicatorValidatorEntity extends AuditorEntity<IndicatorValidatorVo
this.id = id;
}
public IndicatorEntity getIndicator() {
return indicator;
}
public void setIndicator(IndicatorEntity indicator) {
this.indicator = indicator;
}
public String getDescription() {
return description;
}
@ -113,14 +116,6 @@ public class IndicatorValidatorEntity extends AuditorEntity<IndicatorValidatorVo
this.order = order;
}
public ValidatorType getType() {
return type;
}
public void setType(ValidatorType type) {
this.type = type;
}
public String getTip() {
return tip;
}
@ -129,6 +124,13 @@ public class IndicatorValidatorEntity extends AuditorEntity<IndicatorValidatorVo
this.tip = tip;
}
public IndicatorEntity getIndicator() {
return indicator;
}
public void setIndicator(IndicatorEntity indicator) {
this.indicator = indicator;
}
public Object deepClone() throws Exception{
IndicatorValidatorEntity entity =this.getClass().newInstance();
BeanUtils.copyProperties(this, entity);

4
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/LibEntity.java

@ -21,14 +21,14 @@ import java.util.List;
*/
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FD_TYPE",discriminatorType=DiscriminatorType.STRING,length=20)
@DiscriminatorColumn(name="TYPE_",discriminatorType=DiscriminatorType.STRING,length=20)
@Table(name="RE_LIB")
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",defaultImpl=FolderLibEntity.class)
@JsonSubTypes({
@JsonSubTypes.Type(value=FolderLibEntity.class), //文件夹实体类
@JsonSubTypes.Type(value=IndicatorLibEntity.class) //指标库实体类
})
public abstract class LibEntity extends AuditorEntity<LibVo> implements DeepClone, IdClearable {
public class LibEntity extends AuditorEntity<LibVo> implements DeepClone, IdClearable {
//类型(用于区分子类)
@Column(name="TYPE_",insertable=false,updatable=false)
@Enumerated(EnumType.STRING)

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/RangeIndicatorValidatorEntity.java

@ -8,8 +8,6 @@ import javax.persistence.Entity;
/**
* 指标范围验证器实体类
* @author wangshaoping
*
*/
@Entity
public class RangeIndicatorValidatorEntity extends IndicatorValidatorEntity {

1
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/entity/ReleasableLibEntity.java

@ -28,6 +28,7 @@ public abstract class ReleasableLibEntity extends LibEntity implements DeepClone
if(vo!=null){
super.toVo(vo);
vo.setStatus(this.getStatus());
vo.setVersion(this.getVersion());
}
}

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

@ -18,6 +18,11 @@ import java.util.List;
public class IndicatorProcessorServiceImpl extends DaoServiceImpl<IndicatorProcessorEntity, String, IndicatorProcessorRepository> implements IndicatorProcessorService{
@Autowired private IndicatorService indicatorService;
@Override
public String[] getDefaultSortBy() {
return new String[]{"order"};
}
@Override
public IndicatorProcessorEntity add(IndicatorProcessorEntity entity) throws Exception {
CodeAndNameMapping mapping =indicatorService.loadCodeAndNameMappingByIndicatorId(entity.getIndicator().getId());

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

@ -50,6 +50,11 @@ public class IndicatorServiceImpl extends DaoServiceImpl<IndicatorEntity, String
@Autowired private ApplicationContext applicationContext;
@Autowired private IndicatorProcessorService indicatorProcessorService;
@Override
public String[] getDefaultSortBy() {
return new String[]{"order"};
}
@Override
@Transactional
public void importFromCsv(String libId, String csvContent, String splitChar) throws Exception {

4
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/IndicatorValidatorServiceImpl.java

@ -9,6 +9,10 @@ import org.springframework.stereotype.Service;
@Service("reIndicatorValidatorService")
public class IndicatorValidatorServiceImpl extends DaoServiceImpl<IndicatorValidatorEntity, String, IndicatorValidatorRepository> implements IndicatorValidatorService{
public String[] getDefaultSortBy() {
return new String[]{"order"};
}
@Override
public IndicatorValidatorEntity add(IndicatorValidatorEntity entity) throws Exception {
Integer nextOrder =repository.getNextOrder(entity.getIndicator().getId());

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/lib/service/impl/LibServiceImpl.java

@ -352,7 +352,7 @@ public class LibServiceImpl extends DaoServiceImpl<LibEntity, String, LibReposit
* @return 是否存在同名的子文件夹(true:存在,false:不存在)
*/
private boolean isSameNameFolderInParentFolder(AuditLogAction action,LibEntity entity) {
String parentId =entity.getParent().getId();
String parentId =entity.getParent()==null?null:entity.getParent().getId();
List<FolderLibEntity> folderEntities =null;
if(StringUtils.hasText(parentId)) {
folderEntities =repository.findFolderByNameWithParentId(entity.getName(),parentId);

8
io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule Engine Database Schema DDL.xml

@ -492,7 +492,7 @@
<column name="ID_" type="NVARCHAR(36)" remarks="ID_">
<constraints primaryKey="true"/>
</column>
<column name="INDICATOR_ID" type="NVARCHAR(36)" remarks="指标ID">
<column name="INDICATOR_ID_" type="NVARCHAR(36)" remarks="指标ID">
<constraints nullable="false"/>
</column>
<column name="DESCRIPTION_" type="NVARCHAR(255)" remarks="描述"/>
@ -519,7 +519,7 @@
<addForeignKeyConstraint
constraintName="FK_RE_LIB_INDICATOR_VALIDATOR"
baseTableName="RE_LIB_INDICATOR_VALIDATOR"
baseColumnNames="INDICATOR_ID"
baseColumnNames="INDICATOR_ID_"
referencedTableName="RE_LIB_INDICATOR"
referencedColumnNames="ID_" onDelete="CASCADE"/>
@ -528,7 +528,7 @@
<column name="ID_" type="NVARCHAR(36)" remarks="ID_">
<constraints primaryKey="true"/>
</column>
<column name="INDICATOR_ID" type="NVARCHAR(36)" remarks="指标ID">
<column name="INDICATOR_ID_" type="NVARCHAR(36)" remarks="指标ID">
<constraints nullable="false"/>
</column>
<column name="DESCRIPTION_" type="NVARCHAR(255)" remarks="描述"></column>
@ -583,7 +583,7 @@
<addForeignKeyConstraint
constraintName="FK_RE_LIB_INDICATOR_PROCESSOR"
baseTableName="RE_LIB_INDICATOR_PROCESSOR"
baseColumnNames="INDICATOR_ID"
baseColumnNames="INDICATOR_ID_"
referencedTableName="RE_LIB_INDICATOR"
referencedColumnNames="ID_" onDelete="CASCADE"/>

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

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

9
io.sc.platform.core.frontend/src/platform/components-ext/formater/BooleanFormater.ts

@ -28,4 +28,11 @@ const successFailedTagFormater = (value) => {
};
};
export { yesNoFormater, trueFalseFormater, enableTagFormater, successFailedTagFormater };
const checkTagFormater = (value) => {
return {
componentType: 'WCheckTag',
attrs: { value: value },
};
};
export { yesNoFormater, trueFalseFormater, enableTagFormater, successFailedTagFormater, checkTagFormater };

6
io.sc.platform.core.frontend/src/platform/components-ext/formater/index.ts

@ -1,5 +1,5 @@
import type { EnumType, DictionaryType } from '@/platform/types';
import { yesNoFormater, trueFalseFormater, enableTagFormater, successFailedTagFormater } from './BooleanFormater';
import { yesNoFormater, trueFalseFormater, enableTagFormater, successFailedTagFormater, checkTagFormater } from './BooleanFormater';
import { dateOnlyFormater } from './DatetimeFormater';
import { menuTypeFormater } from './MenuTypeFormater';
import { EnumFormater } from './EnumFormater';
@ -27,6 +27,10 @@ class Formater {
return successFailedTagFormater;
}
public static checkTag() {
return checkTagFormater;
}
public static yesNo() {
return yesNoFormater;
}

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

@ -35,6 +35,7 @@ import WInfoPanel from './panel/WInfoPanel.vue';
import WProgress from './progress/WProgress.vue';
import WProgressBtn from './progress/WProgressBtn.vue';
import WCheckTag from './tag/WCheckTag.vue';
import WEnableTag from './tag/WEnableTag.vue';
import WSuccessFailedTag from './tag/WSuccessFailedTag.vue';
@ -82,6 +83,7 @@ export default {
app.component('WProgress', WProgress);
app.component('WProgressBtn', WProgressBtn);
app.component('WCheckTag', WCheckTag);
app.component('WEnableTag', WEnableTag);
app.component('WSuccessFailedTag', WSuccessFailedTag);
@ -121,6 +123,7 @@ export {
WInfoPanel,
WProgress,
WProgressBtn,
WCheckTag,
WEnableTag,
WSuccessFailedTag,
WToolbar,

8
io.sc.platform.core.frontend/src/platform/components/tag/WCheckTag.vue

@ -0,0 +1,8 @@
<template>
<q-icon v-if="value" name="bi-check-lg" size="xs"></q-icon>
</template>
<script setup lang="ts">
const props = defineProps({
value: { type: Boolean, default: true },
});
</script>

58
io.sc.platform.core.frontend/src/platform/components/workflow/WWorkflowAction.vue

@ -40,9 +40,15 @@ const props = defineProps({
/**
* 定义组件支持的自定义事件
*/
const emit = defineEmits([
'afterSubmit', //
]);
const emit = defineEmits<{
(
e: 'beforeSubmit', //
callback: any, //
): void;
(
e: 'afterSubmit', //
): void;
}>();
const { t } = useI18n();
const actionsRef = ref([]);
@ -99,17 +105,21 @@ const buildButtons = (gobacks) => {
};
const buttonClick = (action) => {
DialogManager.confirm(t('lcdp.bpm.completeTask.action.tip', { action: action.title }), () => {
currentActionRef.value = action;
axios.post(props.actionUrl + '/' + props.taskId, getData(action)).then((response) => {
if (response.data.code === 0) {
//
emit('afterSubmit');
} else if (response.data.code === 1) {
//
selectAssigneeDialogRef.value.open(response.data);
}
});
emit('beforeSubmit', (value) => {
if (value) {
DialogManager.confirm(t('lcdp.bpm.completeTask.action.tip', { action: action.title }), () => {
currentActionRef.value = action;
axios.post(props.actionUrl + '/' + props.taskId, getData(action)).then((response) => {
if (response.data.code === 0) {
//
emit('afterSubmit');
} else if (response.data.code === 1) {
//
selectAssigneeDialogRef.value.open(response.data);
}
});
});
}
});
};
@ -127,13 +137,29 @@ const getData = (action, assignee) => {
const data = {
variables: {},
transientVariables: {},
data: {},
};
if (!Tools.isUndefinedOrNull(props.data)) {
if (!Tools.isEmpty(props.data.variables)) {
data.variables = JSON.parse(props.data.variables);
if (Tools.isString(props.data.variables)) {
data.variables = JSON.parse(props.data.variables);
} else {
data.variables = props.data.variables;
}
}
if (!Tools.isEmpty(props.data.transientVariables)) {
data.transientVariables = JSON.parse(props.data.transientVariables);
if (Tools.isString(props.data.transientVariables)) {
data.transientVariables = JSON.parse(props.data.transientVariables);
} else {
data.transientVariables = props.data.transientVariables;
}
}
if (!Tools.isEmpty(props.data.data)) {
if (Tools.isString(props.data.data)) {
data.data = JSON.parse(props.data.data);
} else {
data.data = props.data.data;
}
}
}
if (!Tools.isUndefinedOrNull(action)) {

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

@ -135,6 +135,7 @@ export {
WInfoPanel,
WProgress,
WProgressBtn,
WCheckTag,
WEnableTag,
WSuccessFailedTag,
WToolbar,

115
io.sc.platform.core.frontend/src/views/FormElements.vue

@ -1,86 +1,39 @@
<template>
<w-dialog v-model="isShow">
<w-grid
ref="userGridRef"
:height="300"
:title="$t('system.user.grid.title')"
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/datasource')"
:pagination="{
sortBy: 'loginName',
descending: false,
}"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'loginName', label: $t('loginName'), type: 'text' },
{ name: 'userName', label: $t('userName'), type: 'text' },
{ name: 'enable', label: $t('isEnable'), type: 'select' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'query',
'refresh',
'separator',
'add',
'clone',
'edit',
'remove',
'separator',
{
name: 'setPassword',
label: $t('system.user.grid.toolbar.setPassword'),
icon: 'bi-shield-check',
enableIf: function (arg) {
return arg.selected;
},
click: function (arg) {},
},
{
name: 'setAllPassword',
label: $t('system.user.grid.toolbar.setAllPassword'),
icon: 'bi-shield',
click: function () {},
},
'separator',
{
name: 'resetPassword',
label: $t('system.user.grid.toolbar.resetPassword'),
icon: 'bi-shield-fill-check',
enableIf: function (arg) {
return arg.selected;
},
click: function (arg) {},
},
{
name: 'resetAllPassword',
label: $t('system.user.grid.toolbar.resetAllPassword'),
icon: 'bi-shield-fill',
click: function () {},
},
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 150, name: 'loginName', label: $t('loginName') },
{ width: '100%', name: 'userName', label: $t('userName') },
{
width: 150,
name: 'enable',
label: $t('status'),
},
{ width: 100, name: 'lastModifier', label: $t('lastModifier') },
{ width: 110, name: 'lastModifyDate', label: $t('lastModifyDate') },
]"
></w-grid>
</w-dialog>
<w-grid
ref="userGridRef"
:height="300"
:title="$t('system.user.grid.title')"
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/user')"
:pagination="{
sortBy: 'loginName',
descending: false,
}"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'loginName', label: $t('loginName'), type: 'text' },
{ name: 'userName', label: $t('userName'), type: 'text' },
{ name: 'enable', label: $t('isEnable'), type: 'select' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator']"
:columns="[
{ width: 150, name: 'loginName', label: $t('loginName') },
{ width: '100%', name: 'userName', label: $t('userName') },
{
width: 150,
name: 'enable',
label: $t('status'),
format: Formater.checkTag(),
},
{ width: 100, name: 'lastModifier', label: $t('lastModifier') },
{ width: 110, name: 'lastModifyDate', label: $t('lastModifyDate') },
]"
></w-grid>
</template>
<script setup lang="ts">
import { Environment } from '@/platform';
const isShow = true;
import { Environment, Formater } from '@/platform';
</script>

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

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

115
io.sc.platform.core.frontend/template-project/src/views/FormElements.vue

@ -1,86 +1,39 @@
<template>
<w-dialog v-model="isShow">
<w-grid
ref="userGridRef"
:height="300"
:title="$t('system.user.grid.title')"
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/datasource')"
:pagination="{
sortBy: 'loginName',
descending: false,
}"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'loginName', label: $t('loginName'), type: 'text' },
{ name: 'userName', label: $t('userName'), type: 'text' },
{ name: 'enable', label: $t('isEnable'), type: 'select' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'query',
'refresh',
'separator',
'add',
'clone',
'edit',
'remove',
'separator',
{
name: 'setPassword',
label: $t('system.user.grid.toolbar.setPassword'),
icon: 'bi-shield-check',
enableIf: function (arg) {
return arg.selected;
},
click: function (arg) {},
},
{
name: 'setAllPassword',
label: $t('system.user.grid.toolbar.setAllPassword'),
icon: 'bi-shield',
click: function () {},
},
'separator',
{
name: 'resetPassword',
label: $t('system.user.grid.toolbar.resetPassword'),
icon: 'bi-shield-fill-check',
enableIf: function (arg) {
return arg.selected;
},
click: function (arg) {},
},
{
name: 'resetAllPassword',
label: $t('system.user.grid.toolbar.resetAllPassword'),
icon: 'bi-shield-fill',
click: function () {},
},
'separator',
'view',
'separator',
'export',
]"
:columns="[
{ width: 150, name: 'loginName', label: $t('loginName') },
{ width: '100%', name: 'userName', label: $t('userName') },
{
width: 150,
name: 'enable',
label: $t('status'),
},
{ width: 100, name: 'lastModifier', label: $t('lastModifier') },
{ width: 110, name: 'lastModifyDate', label: $t('lastModifyDate') },
]"
></w-grid>
</w-dialog>
<w-grid
ref="userGridRef"
:height="300"
:title="$t('system.user.grid.title')"
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/user')"
:pagination="{
sortBy: 'loginName',
descending: false,
}"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'loginName', label: $t('loginName'), type: 'text' },
{ name: 'userName', label: $t('userName'), type: 'text' },
{ name: 'enable', label: $t('isEnable'), type: 'select' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator']"
:columns="[
{ width: 150, name: 'loginName', label: $t('loginName') },
{ width: '100%', name: 'userName', label: $t('userName') },
{
width: 150,
name: 'enable',
label: $t('status'),
format: Formater.checkTag(),
},
{ width: 100, name: 'lastModifier', label: $t('lastModifier') },
{ width: 110, name: 'lastModifyDate', label: $t('lastModifyDate') },
]"
></w-grid>
</template>
<script setup lang="ts">
import { Environment } from '@/platform';
const isShow = true;
import { Environment, Formater } from '@/platform';
</script>

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

@ -208,3 +208,4 @@ RegExp=Regular Expression
execute=Execute
executeAll=Execute All
moreQueryCondition=More Query Condition
valueType=Value Type

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

@ -208,3 +208,4 @@ RegExp=\u6B63\u5247\u8868\u9054\u5F0F
execute=\u57F7\u884C
executeAll=\u57F7\u884C\u6240\u6709
moreQueryCondition=\u66F4\u591A\u67E5\u8A62\u689D\u4EF6
valueType=\u503C\u985E\u578B

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

@ -208,3 +208,4 @@ RegExp=\u6B63\u5219\u8868\u8FBE\u5F0F
execute=\u6267\u884C
executeAll=\u6267\u884C\u6240\u6709
moreQueryCondition=\u66F4\u591A\u67E5\u8BE2\u6761\u4EF6
valueType=\u503C\u7C7B\u578B

7
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/support/ProcessProperties.java

@ -10,6 +10,7 @@ public class ProcessProperties {
private String bussinessKey;
private Map<String,Object> variables;
private Map<String,Object> transientVariables;
private Map<String,Object> data;
private boolean autoCompleteFirstTask;
public String getBussinessKey() {
@ -30,6 +31,12 @@ public class ProcessProperties {
public void setTransientVariables(Map<String, Object> transientVariables) {
this.transientVariables = transientVariables;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
public boolean getAutoCompleteFirstTask() {
return autoCompleteFirstTask;
}

2
io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/AuditorEntity.java

@ -21,7 +21,7 @@ import java.util.Date;
* 数据来源创建人创建时间最后修改人最后修改日期
*/
@EntityListeners(AuditingEntityListener.class)
//@MappedSuperclass
@MappedSuperclass
public class AuditorEntity<V extends AuditorVo> extends VersionEntity<V> {
// 数据来源
@Column(name="DATA_COME_FROM_",length=10)

Loading…
Cancel
Save