Browse Source

update

main
wangshaoping 11 months ago
parent
commit
2edef700d3
  1. 4
      erm.frontend/package.json
  2. 4
      gradle.properties
  3. 4
      io.sc.engine.mv.frontend/package.json
  4. 2
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/enums/DictionaryType.java
  5. 4
      io.sc.engine.rule.frontend/package.json
  6. 8
      io.sc.engine.rule.frontend/src/i18n/messages.json
  7. 7
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  8. 30
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  9. 131
      io.sc.engine.rule.frontend/src/views/authorization/Authorization.vue
  10. 410
      io.sc.engine.rule.frontend/src/views/dictionary/dictionary.vue
  11. 3
      io.sc.engine.rule.frontend/src/views/resources/AttachmentDialog.vue
  12. 73
      io.sc.engine.rule.frontend/src/views/resources/ImportDialog.vue
  13. 91
      io.sc.engine.rule.frontend/src/views/resources/ImportSampleDialog.vue
  14. 44
      io.sc.engine.rule.frontend/src/views/resources/Resources.vue
  15. 8
      io.sc.engine.rule.frontend/src/views/resources/designer/DesignerDialog.vue
  16. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/DictionaryEntity.java
  17. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/service/impl/DictionaryServiceImpl.java
  18. 6
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/plugins/PluginManager.java
  19. 7
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourcePermissionWebController.java
  20. 14
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourceWebController.java
  21. 7
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/ModelResourceEntity.java
  22. 17
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/ResourceEntity.java
  23. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/ResourceService.java
  24. 69
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/impl/ResourceServiceImpl.java
  25. 4
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/vo/ResourceVo.java
  26. 1
      io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/messages.json
  27. 12
      io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/rule-engine-example-resource.json
  28. 12
      io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/rule-engine-sample-resource.json
  29. 5
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/i18n/messages.properties
  30. 5
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/i18n/messages_zh_CN.properties
  31. 152
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎内置示例(数据字典).json
  32. 5793
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎内置示例.json
  33. 10
      io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule Engine Database Schema DDL.xml
  34. 17
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  35. 3
      io.sc.platform.core.frontend/src/views/FormElements.vue
  36. 4
      io.sc.platform.core.frontend/template-project/package.json
  37. 3
      io.sc.platform.core.frontend/template-project/src/views/FormElements.vue
  38. 1
      io.sc.platform.core/build.gradle
  39. 4
      io.sc.platform.developer.frontend/package.json
  40. 17
      io.sc.platform.gradle/templates/pgp/setup/build.gradle.txt
  41. 4
      io.sc.platform.gradle/templates/pgp/setup/gradle.properties
  42. 4
      io.sc.platform.lcdp.frontend/package.json
  43. 4
      io.sc.platform.mvc.frontend/package.json
  44. 8
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/support/RestCrudController.java
  45. 4
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/AuditorEntity.java
  46. 10
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/BaseEntity.java
  47. 4
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/VersionEntity.java
  48. 2
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/DaoService.java
  49. 36
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/impl/DaoServiceImpl.java
  50. 2
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/QueryParameter.java
  51. 4
      io.sc.platform.security.frontend/package.json
  52. 4
      io.sc.platform.system.frontend/package.json
  53. 4
      io.sc.standard.frontend/package.json

4
erm.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "erm.frontend", "name": "erm.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -78,7 +78,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

4
gradle.properties

@ -36,9 +36,9 @@ application_version=1.0.0
# platform # platform
########################################################### ###########################################################
platform_group=io.sc platform_group=io.sc
platform_version=8.1.29 platform_version=8.1.30
platform_plugin_version=8.1.13 platform_plugin_version=8.1.13
platform_core_frontend_version=8.1.158 platform_core_frontend_version=8.1.159
########################################################### ###########################################################
# dependencies version # dependencies version

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.engine.mv.frontend", "name": "io.sc.engine.mv.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -91,7 +91,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

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

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

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.engine.rule.frontend", "name": "io.sc.engine.rule.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -91,7 +91,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

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

@ -106,4 +106,12 @@
"re.resources.designer.testCaseParameter.grid.entity.expectValue": "Expect Value", "re.resources.designer.testCaseParameter.grid.entity.expectValue": "Expect Value",
"re.resources.designer.testCaseParameter.grid.entity.resultValue": "Result Value", "re.resources.designer.testCaseParameter.grid.entity.resultValue": "Result Value",
"re.resources.designer.testCaseParameter.grid.entity.skipCheck": "Skip Check", "re.resources.designer.testCaseParameter.grid.entity.skipCheck": "Skip Check",
"re.resources.designer.testCaseParameter.grid.entity.testResult": "Result",
"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",
} }

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

@ -107,4 +107,11 @@
"re.resources.designer.testCaseParameter.grid.entity.resultValue": "結果值", "re.resources.designer.testCaseParameter.grid.entity.resultValue": "結果值",
"re.resources.designer.testCaseParameter.grid.entity.skipCheck": "跳過檢查", "re.resources.designer.testCaseParameter.grid.entity.skipCheck": "跳過檢查",
"re.resources.designer.testCaseParameter.grid.entity.testResult": "測試結果", "re.resources.designer.testCaseParameter.grid.entity.testResult": "測試結果",
"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": "數據字典樹",
} }

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

@ -108,4 +108,34 @@
"re.resources.designer.testCaseParameter.grid.entity.skipCheck": "跳过检查", "re.resources.designer.testCaseParameter.grid.entity.skipCheck": "跳过检查",
"re.resources.designer.testCaseParameter.grid.entity.testResult": "测试结果", "re.resources.designer.testCaseParameter.grid.entity.testResult": "测试结果",
"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.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.deepCloneNew": "深度复制(新数据字典)",
"re.dictionary.grid.toolbar.generateJson": "生成示例 JSON",
"re.dictionary.grid.toolbar.deploy": "发布",
"re.dictionary.grid.toolbar.importGroup": "导入",
"re.dictionary.grid.toolbar.import": "导入",
"re.dictionary.grid.toolbar.importSample": "导入示例",
"re.dictionary.grid.entity.javaClassName": "Java 类全路径名称",
} }

131
io.sc.engine.rule.frontend/src/views/authorization/Authorization.vue

@ -1,4 +1,131 @@
<template> <template>
<div>authorization</div> <q-splitter :model-value="450" unit="px" separator-style="width: 3px;" class="w-full" style="height: 100%">
<template #before>
<div class="pr-1" style="height: 100%">
<w-grid
ref="roleGridRef"
:title="$t('system.role.grid.title')"
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/role')"
:pagination="{
sortBy: 'name',
descending: false,
}"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
{ name: 'enable', label: $t('isEnable'), type: 'select', options: Options.yesNo() },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'separator', 'refresh', 'separator', 'view', 'separator', 'export']"
:columns="[
{ width: 100, name: 'code', label: $t('code') },
{ width: '100%', name: 'name', label: $t('name') },
{ width: 80, name: 'enable', label: $t('status'), format: Formater.enableTag() },
]"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ 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'), format: Formater.none() },
{ 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') },
],
},
}"
@row-click="
(evt, row, index) => {
roleIdRef = row.id;
resourceTreeGridRef?.refresh();
}
"
@before-request-data="
() => {
roleIdRef = '';
resourceTreeGridRef?.refresh();
}
"
>
</w-grid>
</div>
</template> </template>
<script setup lang="ts"></script> <template #after>
<div class="pl-1" style="height: 100%">
<w-grid
ref="resourceTreeGridRef"
:title="$t('re.resources.grid.title')"
dense-body
hide-bottom
:config-button="true"
selection="multiple"
:checkbox-selection="true"
:tree="true"
:tree-icon="
(row) => {
if (row.type === 'FOLDER') {
return { name: 'folder', color: 'amber' };
} else if (row.type === 'MODEL') {
return { name: 'bi-boxes' };
} else if (row.type === 'SCORE_CARD') {
return { name: 'bi-card-list' };
} else {
return { name: row.icon };
}
}
"
ticked-field="selected"
:fetch-data-url="Environment.apiContextPath('/api/re/resource/listAllResourcesWithSelectedStatusByRole?roleId=' + roleIdRef)"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
'expand',
{
name: 'save',
label: $t('save'),
icon: 'sym_o_save',
click: (arg) => {
const data = {
one: roleIdRef,
many: Tools.extractProperties(arg.tickeds, 'id'),
};
axios.post(Environment.apiContextPath('/api/re/resource/updateRoles'), data).then((response) => {
NotifyManager.info($t('operationSuccess'));
});
},
},
]"
:columns="[
{ width: '100%', name: 'name', label: $t('name') },
{ width: 80, name: 'type', label: $t('type'), format: Formater.enum(Enums.ResourceType) },
{ width: 100, name: 'code', label: $t('code') },
{ width: 60, name: 'version', label: $t('version') },
{ width: 60, name: 'status', label: $t('status'), format: Formater.enum(Enums.DeployStatus) },
]"
></w-grid>
</div>
</template>
</q-splitter>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Environment, NotifyManager, axios, Tools, EnumTools, Options, Formater } from 'platform-core';
const roleGridRef = ref();
const resourceTreeGridRef = ref();
const roleIdRef = ref();
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ResourceType', 'io.sc.engine.rule.core.enums.DeployStatus']);
</script>

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

@ -1,4 +1,410 @@
<template> <template>
<div>dictionary</div> <q-splitter :model-value="500" unit="px" separator-style="width: 3px;" class="w-full" style="height: 100%">
<template #before>
<div class="pr-1" style="height: 100%">
<w-grid
ref="treeGridRef"
:title="$t('re.dictionary.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/dictionary')"
:pageable="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
'expand',
[
{
name: 'addGroup',
label: $t('re.dictionary.grid.toolbar.addGroup'),
icon: 'add',
click: undefined,
},
{
extend: 'addTop',
name: 'addTop',
label: $t('re.dictionary.grid.toolbar.addTop'),
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'FOLDER');
},
},
{
extend: 'addChild',
name: 'addChild',
label: $t('re.dictionary.grid.toolbar.addChild'),
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'FOLDER';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'FOLDER');
},
},
'separator',
{
name: 'addJavaType',
extend: 'addChild',
label: $t('re.dictionary.grid.toolbar.addJavaType'),
icon: 'playlist_add',
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'FOLDER';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'JAVA_CLASS');
},
},
{
name: 'addUserDefinedJavaClassType',
extend: 'addChild',
label: $t('re.dictionary.grid.toolbar.addUserDefinedJavaClassType'),
icon: 'playlist_add',
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'FOLDER';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'UD_JAVA_CLASS');
},
},
{
name: 'addEnumType',
extend: 'addChild',
label: $t('re.dictionary.grid.toolbar.addEnumType'),
icon: 'playlist_add',
enableIf: (arg) => {
return arg.selected && arg.selected.type === 'FOLDER';
},
afterClick: (arg) => {
arg.grid.getEditorForm().setFieldValue('type', 'ENUM');
},
},
],
[
{
name: 'cloneGroup',
label: $t('re.dictionary.grid.toolbar.cloneGroup'),
icon: 'content_copy',
click: undefined,
enableIf: (arg) => {
return arg.selected;
},
},
'clone',
{
extend: 'deepClone',
name: 'deepClone',
label: $t('re.dictionary.grid.toolbar.deepClone'),
icon: 'bi-copy',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
},
{
extend: 'clone',
name: 'deepCloneNew',
label: $t('re.dictionary.grid.toolbar.deepCloneNew'),
icon: 'bi-copy',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
},
],
'separator',
'edit',
'remove',
'separator',
{
name: 'generateJson',
label: $t('re.dictionary.grid.toolbar.generateJson'),
icon: 'bi-code',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
},
'separator',
{
name: 'deploy',
label: $t('re.dictionary.grid.toolbar.deploy'),
icon: 'bi-balloon',
enableIf: (arg) => {
return arg.selected && arg.selected.type !== 'FOLDER';
},
},
'separator',
[
{
name: 'importGroup',
label: $t('re.dictionary.grid.toolbar.importGroup'),
icon: 'file_upload',
click: undefined,
},
{
name: 'import',
label: $t('re.dictionary.grid.toolbar.import'),
icon: 'file_upload',
},
{
name: 'importSample',
label: $t('re.dictionary.grid.toolbar.importSample'),
icon: 'bi-database-up',
},
],
'separator',
'view',
'separator',
{
extend: 'export',
name: 'export',
enableIf: (arg) => {
return arg.selected;
},
},
]"
:columns="[
{ width: '100%', name: 'name', label: $t('name') },
{
width: 80,
name: 'type',
label: $t('type'),
format: (value) => {
if (value !== 'FOLDER') {
return Formater.enum(Enums.DictionaryType)(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' },
{
name: 'javaClassName',
label: $t('re.dictionary.grid.entity.javaClassName'),
type: 'text',
showIf: (arg) => {
const type = arg.form.getFieldValue('type');
return type === 'JAVA_CLASS';
},
},
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'order', label: $t('order') },
{ 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: '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') },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedDictionaryIdRef = row.id;
gridRef?.refresh();
}
"
@before-request-data="
() => {
currentSelectedDictionaryIdRef = '';
gridRef?.refresh();
}
"
></w-grid>
</div>
</template> </template>
<script setup lang="ts"></script> <template #after>
<!--字段-->
<div class="pl-1" style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('system.role.grid.title')"
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')"
:pageable="false"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'separator', 'refresh', 'separator', 'view', 'separator', 'export']"
: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: 80,
name: 'valueTypeIsList',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'),
sortable: false,
format: Formater.yesNo(),
},
{ 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: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.none() },
{ 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>
<!--选项-->
<div class="pl-1" style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('system.role.grid.title')"
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')"
:pageable="false"
:query-form-cols-num="3"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'separator', 'refresh', 'separator', 'view', 'separator', 'export']"
: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: 80,
name: 'valueTypeIsList',
label: $t('re.resources.designer.parameter.grid.entity.valueTypeIsList'),
sortable: false,
format: Formater.yesNo(),
},
{ 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: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.none() },
{ 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>
</q-splitter>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, Formater, EnumTools, Options } from 'platform-core';
const treeGridRef = ref();
const gridRef = ref();
const currentSelectedDictionaryIdRef = ref('');
const Enums = await EnumTools.fetch(['io.sc.engine.rule.core.enums.ResourceType', '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>

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

@ -1,8 +1,9 @@
<template> <template>
<w-dialog ref="dialogRef" :title="$t('re.resources.dialog.attachment.title')" width="900px" height="500px" :can-maximize="false"> <w-dialog ref="dialogRef" :title="$t('re.resources.dialog.attachment.title')" width="900px" :can-maximize="false">
<div class="px-2"> <div class="px-2">
<w-grid <w-grid
ref="gridRef" ref="gridRef"
:height="300"
:title="$t('re.resources.dialog.attachment.grid.title')" :title="$t('re.resources.dialog.attachment.grid.title')"
selection="multiple" selection="multiple"
:full-screen-button="false" :full-screen-button="false"

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

@ -0,0 +1,73 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.resources.importSample.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 { useI18n } from 'vue-i18n';
import { axios, Environment, DialogManager, Tools } from 'platform-core';
const emit = defineEmits<{
(e: 'afterImported', evt: Event): void;
}>();
const { t } = useI18n();
const dialogRef = ref();
const modelValue = reactive({
file: undefined,
});
const fileRef = ref();
const importData = () => {
axios
.post(
Environment.apiContextPath('/api/re/resource/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/resources/ImportSampleDialog.vue

@ -0,0 +1,91 @@
<template>
<w-dialog ref="dialogRef" :title="$t('re.resources.importSample.dialog.title')" width="900px" :can-maximize="false">
<div class="px-2">
<w-grid
ref="gridRef"
:height="300"
:title="$t('re.resources.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.resources.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.resources.importSample.grid.toolbar.import.tip'), () => {
axios.post(Environment.apiContextPath('/api/re/resource/createExample'), ids).then(() => {
close();
emit('afterImported');
});
});
}
},
},
]"
:query-form-fields="[]"
:auto-fetch-data="false"
:fetch-data-url="Environment.apiContextPath('/api/re/resource/listResourceExampleContributionItems')"
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>

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

@ -6,7 +6,7 @@
dense-body dense-body
:config-button="true" :config-button="true"
selection="multiple" selection="multiple"
:checkbox-selection="true" :checkbox-selection="false"
:tree="true" :tree="true"
:tree-icon=" :tree-icon="
(row) => { (row) => {
@ -189,19 +189,33 @@
name: 'import', name: 'import',
label: $t('import'), label: $t('import'),
icon: 'file_upload', icon: 'file_upload',
click: () => {}, click: () => {
importDialogRef.open();
},
}, },
{ {
name: 'importExample', name: 'importExample',
label: $t('re.resources.grid.toolbar.importExample'), label: $t('re.resources.grid.toolbar.importExample'),
icon: 'bi-cloud-arrow-up-fill', icon: 'bi-database-up',
click: () => {}, click: () => {
importSampleDialogRef.open();
},
}, },
], ],
'separator', 'separator',
'view', 'view',
'separator', 'separator',
'export', {
extend: 'export',
enableIf: (arg) => {
return arg.selected;
},
click: (arg) => {
//axios.get(Environment.apiContextPath('/api/re/resource/export/' + arg.selected.id));
let url = Environment.apiContextPath('/api/re/resource/export/' + arg.selected.id);
downloadIframe.src = url;
},
},
]" ]"
:columns="[ :columns="[
{ width: '100%', name: 'name', label: $t('name') }, { width: '100%', name: 'name', label: $t('name') },
@ -282,6 +296,13 @@
], ],
}, },
}" }"
@row-db-click="
(e, row) => {
if (row.type !== 'FOLDER') {
designerDialogRef.open(row);
}
}
"
></w-grid> ></w-grid>
<AttachmentDialog <AttachmentDialog
ref="attachmentDialogRef" ref="attachmentDialogRef"
@ -291,19 +312,28 @@
:foreign-value="foreignValueRef" :foreign-value="foreignValueRef"
></AttachmentDialog> ></AttachmentDialog>
<DesignerDialog ref="designerDialogRef"></DesignerDialog> <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>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { axios, Environment, DialogManager, Formater, EnumTools } from 'platform-core'; import { axios, Environment, DialogManager, Formater, EnumTools } from 'platform-core';
import AttachmentDialog from './AttachmentDialog.vue'; import AttachmentDialog from './AttachmentDialog.vue';
import DesignerDialog from './designer/DesignerDialog.vue'; import DesignerDialog from './designer/DesignerDialog.vue';
import ImportSampleDialog from './ImportSampleDialog.vue';
import ImportDialog from './ImportDialog.vue';
const router = useRouter();
const treeGridRef = ref(); const treeGridRef = ref();
const attachmentDialogRef = ref(); const attachmentDialogRef = ref();
const foreignValueRef = ref(''); const foreignValueRef = ref('');
const designerDialogRef = ref(); const designerDialogRef = ref();
const importDialogRef = ref();
const importSampleDialogRef = ref();
const downloadIframe = ref();
const afterImported = () => {
treeGridRef.value.refresh();
};
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.ResourceType', 'io.sc.engine.rule.core.enums.DeployStatus']);
</script> </script>

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

@ -55,7 +55,7 @@
</template> </template>
<template #after> <template #after>
<q-splitter v-model="horizontalSplitterRef" unit="px" separator-style="height: 3px" horizontal> <q-splitter v-model="horizontalSplitterRef" unit="px" separator-style="height: 3px" horizontal style="height: 100%">
<template #before> <template #before>
<q-tabs <q-tabs
v-model="statusReactive.parameterAndTestcaseTab" v-model="statusReactive.parameterAndTestcaseTab"
@ -75,8 +75,8 @@
<q-tab v-if="statusReactive.isShowParameter" name="parameter" icon="bi-p-square" :label="$t('re.resources.designer.parameter.tab.title')" /> <q-tab v-if="statusReactive.isShowParameter" name="parameter" icon="bi-p-square" :label="$t('re.resources.designer.parameter.tab.title')" />
<q-tab v-if="statusReactive.isShowTestCase" name="testcase" icon="bi-receipt" :label="$t('re.resources.designer.testcase.tab.title')" /> <q-tab v-if="statusReactive.isShowTestCase" name="testcase" icon="bi-receipt" :label="$t('re.resources.designer.testcase.tab.title')" />
</q-tabs> </q-tabs>
<q-tab-panels v-model="statusReactive.parameterAndTestcaseTab" animated style="height: calc(100% - 50px)"> <q-tab-panels v-model="statusReactive.parameterAndTestcaseTab" animated style="height: calc(100% - 48px)">
<q-tab-panel v-if="statusReactive.isShowParameter" name="parameter" class="px-0" style="height: 100%"> <q-tab-panel v-if="statusReactive.isShowParameter" name="parameter" class="px-0 pb-0" style="height: 100%">
<Parameter <Parameter
ref="parameterGridRef" ref="parameterGridRef"
:model="currentSelectedModelRef" :model="currentSelectedModelRef"
@ -119,7 +119,7 @@
" "
></Parameter> ></Parameter>
</q-tab-panel> </q-tab-panel>
<q-tab-panel v-if="statusReactive.isShowTestCase" name="testcase" class="px-0"> <q-tab-panel v-if="statusReactive.isShowTestCase" name="testcase" class="px-0 pb-0" style="height: 100%">
<TestCase <TestCase
ref="testCaseGridRef" ref="testCaseGridRef"
:model="currentSelectedModelRef" :model="currentSelectedModelRef"

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/dictionary/entity/DictionaryEntity.java

@ -29,7 +29,7 @@ import java.util.List;
@JsonSubTypes.Type(value=UserDefinedJavaClassDictionaryEntity.class), //自定义 Java Class 类型的数据字典 @JsonSubTypes.Type(value=UserDefinedJavaClassDictionaryEntity.class), //自定义 Java Class 类型的数据字典
@JsonSubTypes.Type(value=EnumDictionaryEntity.class) //枚举类型的数据字典 @JsonSubTypes.Type(value=EnumDictionaryEntity.class) //枚举类型的数据字典
}) })
public abstract class DictionaryEntity extends AuditorEntity<DictionaryVo> implements DeepClone, IdClearable { public class DictionaryEntity extends AuditorEntity<DictionaryVo> implements DeepClone, IdClearable {
//类型(用于区分子类) //类型(用于区分子类)
@Column(name="TYPE_", insertable=false,updatable=false) @Column(name="TYPE_", insertable=false,updatable=false)
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)

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

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

6
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/plugins/PluginManager.java

@ -16,9 +16,9 @@ import java.util.List;
* 插件管理器 * 插件管理器
*/ */
public class PluginManager { public class PluginManager {
private static final String RESOURCE_EXAMPLE_ITEM_RESOURCE_LOCATION ="META-INF/platform/plugins/rule-engine-example-resource.json"; private static final String RESOURCE_EXAMPLE_ITEM_RESOURCE_LOCATION ="META-INF/platform/plugins/rule-engine-sample-resource.json";
private static final String DICTIONARY_EXAMPLE_ITEM_RESOURCE_LOCATION ="META-INF/platform/plugins/rule-engine-example-dictionary.json"; private static final String DICTIONARY_EXAMPLE_ITEM_RESOURCE_LOCATION ="META-INF/platform/plugins/rule-engine-sample-dictionary.json";
private static final String LIB_EXAMPLE_ITEM_RESOURCE_LOCATION ="META-INF/platform/plugins/rule-engine-example-lib.json"; private static final String LIB_EXAMPLE_ITEM_RESOURCE_LOCATION ="META-INF/platform/plugins/rule-engine-sample-lib.json";
//决策引擎资源示例贡献项相关 //决策引擎资源示例贡献项相关
private List<Plugin<List<ResourceExampleItem>>> resourceExampleItems; private List<Plugin<List<ResourceExampleItem>>> resourceExampleItems;

7
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourcePermissionWebController.java

@ -2,6 +2,7 @@ package io.sc.engine.rule.server.resource.controller;
import io.sc.engine.rule.server.resource.entity.ResourceEntity; import io.sc.engine.rule.server.resource.entity.ResourceEntity;
import io.sc.engine.rule.server.resource.service.ResourceService; import io.sc.engine.rule.server.resource.service.ResourceService;
import io.sc.engine.rule.server.resource.vo.ResourceVo;
import io.sc.platform.mvc.support.One2Many; import io.sc.platform.mvc.support.One2Many;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -29,9 +30,9 @@ public class ResourcePermissionWebController {
* @return 所有资源,并且将角色所拥有的资源列表作出标记 * @return 所有资源,并且将角色所拥有的资源列表作出标记
* @throws Exception 违例 * @throws Exception 违例
*/ */
@RequestMapping(value="isc/listAllResourcesWithSelectedStatusByRole",method=RequestMethod.GET) @RequestMapping(value="listAllResourcesWithSelectedStatusByRole",method=RequestMethod.GET)
@ResponseBody @ResponseBody
public List<ResourceEntity> listAllResourcesWithSelectedStatusByRole(HttpServletRequest request,HttpServletResponse response,@RequestParam(name="roleId",required=false)String roleId) throws Exception{ public List<ResourceVo> listAllResourcesWithSelectedStatusByRole(HttpServletRequest request, HttpServletResponse response, @RequestParam(name="roleId",required=false)String roleId) throws Exception{
if(StringUtils.hasText(roleId)){ if(StringUtils.hasText(roleId)){
return service.listAllResourcesWithSelectedStatusByRole(roleId); return service.listAllResourcesWithSelectedStatusByRole(roleId);
} }
@ -43,7 +44,7 @@ public class ResourcePermissionWebController {
* @param one2Many 一对多关系(ID关系)封装器, one: 代表角色代码, many: 代表资源集合 * @param one2Many 一对多关系(ID关系)封装器, one: 代表角色代码, many: 代表资源集合
* @throws Exception 违例 * @throws Exception 违例
*/ */
@RequestMapping(value="isc/updateRoles", method=RequestMethod.POST) @RequestMapping(value="updateRoles", method=RequestMethod.POST)
@ResponseBody @ResponseBody
public void updateRoles(@RequestBody One2Many<String,String> one2Many) throws Exception{ public void updateRoles(@RequestBody One2Many<String,String> one2Many) throws Exception{
if(one2Many!=null){ if(one2Many!=null){

14
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/controller/ResourceWebController.java

@ -24,7 +24,6 @@ import io.sc.platform.mvc.support.FileDownloader;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -44,7 +43,6 @@ import java.util.*;
@RequestMapping("/api/re/resource") @RequestMapping("/api/re/resource")
public class ResourceWebController extends RestCrudController<ResourceVo, ResourceEntity,String,ResourceRepository,ResourceService> { public class ResourceWebController extends RestCrudController<ResourceVo, ResourceEntity,String,ResourceRepository,ResourceService> {
private static final Logger log =LoggerFactory.getLogger(ResourceWebController.class); private static final Logger log =LoggerFactory.getLogger(ResourceWebController.class);
@Autowired private MessageSource messageSource;
@Autowired private ExecutorFactoryService executorFactoryService; @Autowired private ExecutorFactoryService executorFactoryService;
@RequestMapping(value="getDefineById",method=RequestMethod.GET) @RequestMapping(value="getDefineById",method=RequestMethod.GET)
@ -265,7 +263,7 @@ public class ResourceWebController extends RestCrudController<ResourceVo, Resour
* @return 所有资源示例项 * @return 所有资源示例项
* @throws Exception 违例 * @throws Exception 违例
*/ */
@RequestMapping(value="isc/listResourceExampleContributionItems", method=RequestMethod.GET) @GetMapping(value="listResourceExampleContributionItems")
@ResponseBody @ResponseBody
public List<ResourceExampleWrapper> listResourceExampleContributionItems(HttpServletRequest request, HttpServletResponse response, Locale locale) throws Exception{ public List<ResourceExampleWrapper> listResourceExampleContributionItems(HttpServletRequest request, HttpServletResponse response, Locale locale) throws Exception{
List<ResourceExampleItem> items = PluginManager.getInstance().getResourceExampleItemEntries(); List<ResourceExampleItem> items = PluginManager.getInstance().getResourceExampleItemEntries();
@ -274,7 +272,6 @@ public class ResourceWebController extends RestCrudController<ResourceVo, Resour
for(ResourceExampleItem item : items) { for(ResourceExampleItem item : items) {
result.add(ResourceExampleWrapper.from(item)); result.add(ResourceExampleWrapper.from(item));
} }
updateResourceExampleContributionItemTitle(result,locale);
return result; return result;
} }
return Collections.emptyList(); return Collections.emptyList();
@ -290,13 +287,4 @@ public class ResourceWebController extends RestCrudController<ResourceVo, Resour
public void createExample(@RequestBody Set<String> contributionIds) throws Exception{ public void createExample(@RequestBody Set<String> contributionIds) throws Exception{
service.createExample(contributionIds); service.createExample(contributionIds);
} }
private void updateResourceExampleContributionItemTitle(List<ResourceExampleWrapper> items,Locale locale) throws Exception{
if(items!=null && items.size()>0){
for(ResourceExampleWrapper item : items){
item.setName(messageSource.getMessage(item.getId(), null, locale));
item.setDescription(messageSource.getMessage(item.getId()+".description", null,locale));
}
}
}
} }

7
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/ModelResourceEntity.java

@ -7,10 +7,7 @@ import io.sc.engine.rule.server.resource.vo.ModelResourceVo;
import io.sc.engine.rule.server.testcase.entity.ResourceTestCaseEntity; import io.sc.engine.rule.server.testcase.entity.ResourceTestCaseEntity;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import javax.persistence.CascadeType; import javax.persistence.*;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.OneToOne;
import java.util.List; import java.util.List;
/** /**
@ -21,7 +18,7 @@ import java.util.List;
@JsonTypeName("MODEL") @JsonTypeName("MODEL")
public class ModelResourceEntity extends ReleasableResourceEntity { public class ModelResourceEntity extends ReleasableResourceEntity {
//模型 //模型
@OneToOne(mappedBy="resource") @OneToOne(mappedBy="resource",cascade= {CascadeType.PERSIST}, fetch = FetchType.LAZY)
private ModelEntity model; private ModelEntity model;
@Override @Override

17
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/entity/ResourceEntity.java

@ -57,7 +57,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonSubTypes.Type(value=ModelResourceEntity.class), //模型实体 @JsonSubTypes.Type(value=ModelResourceEntity.class), //模型实体
@JsonSubTypes.Type(value=ScoreCardResourceEntity.class) //评分卡实体 @JsonSubTypes.Type(value=ScoreCardResourceEntity.class) //评分卡实体
}) })
public abstract class ResourceEntity extends AuditorEntity<ResourceVo> implements DeepClone, IdClearable { public class ResourceEntity extends AuditorEntity<ResourceVo> implements DeepClone, IdClearable {
//ID,主键 //ID,主键
@Id @Id
@GeneratedValue(generator = "system-uuid") @GeneratedValue(generator = "system-uuid")
@ -113,10 +113,6 @@ public abstract class ResourceEntity extends AuditorEntity<ResourceVo> implement
) )
private List<RoleEntity> roles =new ArrayList<>(); private List<RoleEntity> roles =new ArrayList<>();
//是否被选择,主要用于展示某个角色或机构拥有的菜单,本属性不进行持久化
@Transient
protected Boolean selected;
public void toVo(ResourceVo vo) { public void toVo(ResourceVo vo) {
if(vo!=null) { if(vo!=null) {
super.toVo(vo); super.toVo(vo);
@ -130,6 +126,11 @@ public abstract class ResourceEntity extends AuditorEntity<ResourceVo> implement
} }
} }
@Override
public ResourceVo toVo() {
return null;
}
public ResourceEntity() {} public ResourceEntity() {}
public ResourceEntity(String id) { public ResourceEntity(String id) {
this.id =id; this.id =id;
@ -195,12 +196,6 @@ public abstract class ResourceEntity extends AuditorEntity<ResourceVo> implement
public void setRoles(List<RoleEntity> roles) { public void setRoles(List<RoleEntity> roles) {
this.roles = roles; this.roles = roles;
} }
public Boolean getSelected() {
return selected;
}
public void setSelected(Boolean selected) {
this.selected = selected;
}
/** /**
* 重新设置父 * 重新设置父

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/ResourceService.java

@ -127,7 +127,7 @@ public interface ResourceService extends DaoService<ResourceEntity, String, Reso
* @return 所有资源,并且将角色所拥有的资源列表作出标记 * @return 所有资源,并且将角色所拥有的资源列表作出标记
* @throws Exception 违例 * @throws Exception 违例
*/ */
public List<ResourceEntity> listAllResourcesWithSelectedStatusByRole(String roleId) throws Exception; public List<ResourceVo> listAllResourcesWithSelectedStatusByRole(String roleId) throws Exception;
/** /**
* 更新角色包含的资源 * 更新角色包含的资源

69
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/service/impl/ResourceServiceImpl.java

@ -44,21 +44,27 @@ import io.sc.platform.mvc.service.SystemParameterService;
import io.sc.platform.orm.entity.support.EntityChangedEventType; import io.sc.platform.orm.entity.support.EntityChangedEventType;
import io.sc.platform.orm.service.impl.DaoServiceImpl; import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.orm.service.support.QueryParameter; import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.orm.service.support.criteria.impl.InSet; import io.sc.platform.orm.service.support.criteria.impl.InSet;
import io.sc.platform.orm.util.EntityVoUtil;
import io.sc.platform.security.util.SecurityUtil; import io.sc.platform.security.util.SecurityUtil;
import io.sc.platform.system.role.jpa.entity.RoleEntity; import io.sc.platform.system.role.jpa.entity.RoleEntity;
import io.sc.platform.system.role.service.RoleService; import io.sc.platform.system.role.service.RoleService;
import io.sc.platform.system.user.jpa.entity.UserEntity;
import org.flowable.engine.ProcessEngine; import org.flowable.engine.ProcessEngine;
import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Subquery;
import java.util.*; import java.util.*;
@Service("reResourceService") @Service("reResourceService")
@ -530,46 +536,45 @@ public class ResourceServiceImpl extends DaoServiceImpl<ResourceEntity, String,
} }
@Override @Override
public List<ResourceEntity> listAllResourcesWithSelectedStatusByRole(String roleId) throws Exception { public List<ResourceVo> listAllResourcesWithSelectedStatusByRole(String roleId) throws Exception {
return Collections.emptyList(); RoleEntity role =roleService.findById(roleId);
if(role!=null){
List<ResourceVo> all =EntityVoUtil.toVo(repository.findAll());
if(all!=null && all.size()>0){
Map<String,ResourceVo> cache =new HashMap<>(all.size());
for(ResourceVo resourceVo : all){
cache.put(resourceVo.getId(), resourceVo);
} }
Specification<ResourceEntity> specification = (root, query, criteriaBuilder) -> {
Subquery<Integer> subquery =query.subquery(Integer.class);
Join<ResourceEntity,RoleEntity> join = subquery.correlate(root).join("roles");
// @Override subquery.select(criteriaBuilder.literal(1));
// public List<ResourceEntity> listAllResourcesWithSelectedStatusByRole(String roleId) throws Exception { subquery.where(criteriaBuilder.equal(join.get("id"), roleId));
// Role role =roleService.findById(roleId); return criteriaBuilder.exists(subquery);
// if(role!=null){ };
// List<ResourceEntity> all =repository.findAll(); List<ResourceEntity> selecteds =repository.findAll(specification);
// if(all!=null && all.size()>0){ if(selecteds!=null && selecteds.size()>0){
// Map<String,ResourceEntity> cache =new HashMap<String,ResourceEntity>(all.size()); for(ResourceEntity selected : selecteds){
// for(ResourceEntity resourceEntity : all){ ResourceVo cached =cache.get(selected.getId());
// cache.put(resourceEntity.getId(), resourceEntity); if(cached!=null){
// } cached.setSelected(true);
// }
// BooleanBuilder builder =new BooleanBuilder(); }
// builder.and(QResourceEntity.resourceEntity.roles.any().eq(role)); }
// List<ResourceEntity> selecteds =IterableUtil.toList(repository.findAll(builder.getValue())); }
// if(selecteds!=null && selecteds.size()>0){ return all;
// for(ResourceEntity selected : selecteds){ }
// ResourceEntity _org =cache.get(selected.getId()); return Collections.emptyList();
// if(_org!=null){ }
// _org.setSelected(true);
// }
// }
//
// }
// }
// return all;
// }
// return null;
// }
@Override @Override
@Transactional @Transactional
public void updateResources(String roleId, Set<String> resourceIds) throws Exception { public void updateResources(String roleId, Set<String> resourceIds) throws Exception {
if(StringUtils.hasText(roleId)){ if(StringUtils.hasText(roleId)){
jdbcTemplate.update("delete from RE_RESOURCE_ROLE where FD_ROLE_ID=?", roleId); jdbcTemplate.update("delete from RE_RESOURCE_ROLE where ROLE_ID_=?", roleId);
if(resourceIds!=null && resourceIds.size()>0) { if(resourceIds!=null && resourceIds.size()>0) {
SqlBatcher sqlBatcher =new SqlBatcher("insert into RE_RESOURCE_ROLE(FD_RESOURCE_ID,FD_ROLE_ID) values(?,?)"); SqlBatcher sqlBatcher =new SqlBatcher("insert into RE_RESOURCE_ROLE(RESOURCE_ID_,ROLE_ID_) values(?,?)");
for(String resourceId : resourceIds){ for(String resourceId : resourceIds){
sqlBatcher.addArg(new Object[]{resourceId,roleId}); sqlBatcher.addArg(new Object[]{resourceId,roleId});
} }

4
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/resource/vo/ResourceVo.java

@ -1,9 +1,13 @@
package io.sc.engine.rule.server.resource.vo; package io.sc.engine.rule.server.resource.vo;
import io.sc.engine.rule.core.enums.ResourceType; import io.sc.engine.rule.core.enums.ResourceType;
import io.sc.engine.rule.core.po.resource.Resource;
import io.sc.engine.rule.core.po.testcase.ResourceTestCase;
import io.sc.platform.orm.api.vo.AuditorVo; import io.sc.platform.orm.api.vo.AuditorVo;
import javax.persistence.Transient; import javax.persistence.Transient;
import java.util.ArrayList;
import java.util.List;
/** /**
* 资源实体类 * 资源实体类

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

@ -10,6 +10,7 @@
{ {
"includes":[ "includes":[
"io/sc/engine/rule/server/sample/i18n/messages",
"org/wsp/engine/rule/server/i18n/enums", "org/wsp/engine/rule/server/i18n/enums",
"org/wsp/engine/rule/server/i18n/example", "org/wsp/engine/rule/server/i18n/example",
"org/wsp/engine/rule/server/i18n/exception", "org/wsp/engine/rule/server/i18n/exception",

12
io.sc.engine.rule.server/src/main/resources/META-INF/platform/plugins/rule-engine-example-resource.json

@ -1,12 +0,0 @@
[
//
{"id":"re.engine.example.resource.engine","order":100},
///
{
"order" :100,
"parentId" :"re.engine.example.resource.engine",
"id" :"re.engine.example.resource.engine.base",
"file" :"classpath:/org/wsp/engine/rule/example/resource/engine/引擎内置示例.json",
"dictionary":"classpath:/org/wsp/engine/rule/example/resource/engine/引擎内置示例(数据字典).json"
}
]

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

@ -0,0 +1,12 @@
[
//
{"id":"re.engine.sample.resource.engine","order":100},
///
{
"order" :100,
"parentId" :"re.engine.sample.resource.engine",
"id" :"re.engine.sample.resource.engine.base",
"file" :"classpath:/io/sc/engine/rule/server/sample/引擎内置示例.json",
"dictionary":"classpath:/io/sc/engine/rule/server/sample/引擎内置示例(数据字典).json"
}
]

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

@ -0,0 +1,5 @@
re.engine.sample.resource.engine=Engine Sample
re.engine.sample.resource.engine.description=Engine Sample
re.engine.sample.resource.engine.base=Base Sample
re.engine.sample.resource.engine.base.description=Engine Base Sample

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

@ -0,0 +1,5 @@
re.engine.sample.resource.engine=\u5F15\u64CE\u793A\u4F8B
re.engine.sample.resource.engine.description=
re.engine.sample.resource.engine.base=\u57FA\u672C\u793A\u4F8B
re.engine.sample.resource.engine.base.description=\u5F15\u64CE\u81EA\u5E26\u57FA\u672C\u793A\u4F8B

152
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎内置示例(数据字典).json

@ -0,0 +1,152 @@
{
"type" : "FOLDER",
"id" : "e28a4f3b-25b3-457a-a473-c0a30d834469",
"code" : "D25173642570409",
"name" : "引擎内置示例(数据字典)",
"description" : null,
"order" : null,
"children" : [ {
"type" : "FOLDER",
"id" : "28cd2fc7-b837-4c9c-af40-00947dab4a7c",
"code" : "D25355646002659",
"name" : "日历",
"description" : null,
"order" : null,
"children" : [ {
"type" : "JAVA_CLASS",
"id" : "145e9e62-0e2e-42eb-9a60-e866c419f4aa",
"code" : "D25509529048589",
"name" : "日历",
"description" : null,
"order" : null,
"children" : null,
"status" : "SKETCH",
"version" : 1,
"javaClassName" : "java.util.Calendar"
} ]
}, {
"type" : "FOLDER",
"id" : "9e13f57c-22df-40d3-bd36-56cfa682bc6e",
"code" : "D25739980183495",
"name" : "个人客户基本信息",
"description" : null,
"order" : null,
"children" : [ {
"type" : "UD_JAVA_CLASS",
"id" : "cc9589cd-28c9-4752-bacd-0293bcdb63c7",
"code" : "D25776493023470",
"name" : "个人客户基本信息",
"description" : null,
"order" : null,
"children" : null,
"status" : "SKETCH",
"version" : 1,
"fields" : [ {
"id" : "8121cce5-91fe-4fc3-8e91-e5a8a1105d02",
"code" : "name",
"name" : "姓名",
"description" : null,
"valueType" : "java.lang.String",
"valueTypeIsList" : false,
"defaultValue" : null,
"valueCalculation" : null,
"order" : 1
}, {
"id" : "9ac0a8b3-59a1-4c03-a4f2-d501d1651506",
"code" : "age",
"name" : "年龄",
"description" : null,
"valueType" : "java.lang.Long",
"valueTypeIsList" : false,
"defaultValue" : null,
"valueCalculation" : null,
"order" : 2
}, {
"id" : "b6b45882-3812-4686-bcd5-ad0a1c9b46ec",
"code" : "education",
"name" : "学历",
"description" : null,
"valueType" : "D25564292618908",
"valueTypeIsList" : false,
"defaultValue" : null,
"valueCalculation" : null,
"order" : 3
} ]
} ]
}, {
"type" : "FOLDER",
"id" : "d48e8de8-1036-4b40-a16f-8ff0a4e46588",
"code" : "D25546624448897",
"name" : "学历",
"description" : null,
"order" : null,
"children" : [ {
"type" : "ENUM",
"id" : "d4040459-25c7-4e9a-a64e-81981f1ca51d",
"code" : "D25564292618908",
"name" : "学历",
"description" : null,
"order" : null,
"children" : null,
"status" : "SKETCH",
"version" : 1,
"items" : [ {
"id" : "0077a9fc-0089-425f-b210-3d2d9562d78a",
"value" : "05",
"title" : "专科/中专",
"description" : null,
"order" : 4,
"config" : null
}, {
"id" : "0670b3f9-1bc8-41b9-aa83-3cd84a2a86c4",
"value" : "08",
"title" : "博士研究生",
"description" : null,
"order" : 7,
"config" : null
}, {
"id" : "27a3efb1-b0c9-40db-9190-fac5749fcf43",
"value" : "07",
"title" : "硕士研究生",
"description" : null,
"order" : 6,
"config" : null
}, {
"id" : "4040d009-f2eb-4c8d-83fe-36498b5bae15",
"value" : "04",
"title" : "高中",
"description" : null,
"order" : 3,
"config" : null
}, {
"id" : "42febcda-ecc4-4285-823c-0c9fed119ecb",
"value" : "03",
"title" : "初中",
"description" : null,
"order" : 2,
"config" : null
}, {
"id" : "6b0f746e-7c35-430a-ad21-0b049d1da729",
"value" : "06",
"title" : "本科",
"description" : null,
"order" : 5,
"config" : null
}, {
"id" : "c4836a75-c9bb-4cbe-a462-4ade0eac0dbe",
"value" : "02",
"title" : "小学",
"description" : null,
"order" : 1,
"config" : null
}, {
"id" : "c9881266-0f49-483e-89e5-e21e250829a2",
"value" : "01",
"title" : "文盲",
"description" : null,
"order" : 0,
"config" : null
} ]
} ]
} ]
}

5793
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎内置示例.json

File diff suppressed because one or more lines are too long

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

@ -362,9 +362,9 @@
<column name="VALUE_TYPE_VERSION_" type="INTEGER" remarks="值数据类型版本"/> <column name="VALUE_TYPE_VERSION_" type="INTEGER" remarks="值数据类型版本"/>
<column name="VALUE_TYPE_IS_LIST_" type="SMALLINT" remarks="值数据类型是否是列表"/> <column name="VALUE_TYPE_IS_LIST_" type="SMALLINT" remarks="值数据类型是否是列表"/>
<column name="DEFAULT_VALUE_" type="NVARCHAR(255)" remarks="默认值"/> <column name="DEFAULT_VALUE_" type="NVARCHAR(255)" remarks="默认值"/>
<column name="VALUE_CALCULATION" type="CLOB" remarks="值计算逻辑"/> <column name="VALUE_CALCULATION_" type="CLOB" remarks="值计算逻辑"/>
<column name="ORDER_" type="INTEGER" remarks="排序"/> <column name="ORDER_" type="INTEGER" remarks="排序"/>
<column name="DICTIONARY_ID" type="NVARCHAR(36)" remarks="所属数据字典ID"/> <column name="DICTIONARY_ID_" type="NVARCHAR(36)" remarks="所属数据字典ID"/>
<!-- 审计字段 --> <!-- 审计字段 -->
<column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/> <column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/>
@ -380,7 +380,7 @@
<addForeignKeyConstraint <addForeignKeyConstraint
constraintName="FK_RE_UD_JC_FIELD_AND_DIC" constraintName="FK_RE_UD_JC_FIELD_AND_DIC"
baseTableName="RE_DICTIONARY_UD_JC_FIELD" baseTableName="RE_DICTIONARY_UD_JC_FIELD"
baseColumnNames="DICTIONARY_ID" baseColumnNames="DICTIONARY_ID_"
referencedTableName="RE_DICTIONARY" referencedTableName="RE_DICTIONARY"
referencedColumnNames="ID_" onDelete="CASCADE"/> referencedColumnNames="ID_" onDelete="CASCADE"/>
@ -396,7 +396,7 @@
<column name="TITLE_" type="NVARCHAR(1024)" remarks="文本"/> <column name="TITLE_" type="NVARCHAR(1024)" remarks="文本"/>
<column name="ORDER_" type="INTEGER" remarks="顺序"/> <column name="ORDER_" type="INTEGER" remarks="顺序"/>
<column name="CONFIG_" type="CLOB" remarks="配置"/> <column name="CONFIG_" type="CLOB" remarks="配置"/>
<column name="DICTIONARY_ID" type="NVARCHAR(36)" remarks="所属数据字典ID"/> <column name="DICTIONARY_ID_" type="NVARCHAR(36)" remarks="所属数据字典ID"/>
<!-- 审计字段 --> <!-- 审计字段 -->
<column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/> <column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/>
@ -412,7 +412,7 @@
<addForeignKeyConstraint <addForeignKeyConstraint
constraintName="FK_RE_ENUM_ITEM_AND_DIC" constraintName="FK_RE_ENUM_ITEM_AND_DIC"
baseTableName="RE_DICTIONARY_ENUM_ITEM" baseTableName="RE_DICTIONARY_ENUM_ITEM"
baseColumnNames="DICTIONARY_ID" baseColumnNames="DICTIONARY_ID_"
referencedTableName="RE_DICTIONARY" referencedTableName="RE_DICTIONARY"
referencedColumnNames="ID_" onDelete="CASCADE"/> referencedColumnNames="ID_" onDelete="CASCADE"/>

17
io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

@ -1162,21 +1162,26 @@ const tableHeightComputed = () => {
const noDataTrHeightComputed = () => { const noDataTrHeightComputed = () => {
let availableHeight = 0; let availableHeight = 0;
let otherHeight = 0;
let otherHeight2 = 0;
const parentHtmlElement = tableRef?.value?.$el?.parentElement; const parentHtmlElement = tableRef?.value?.$el?.parentElement;
if (parentHtmlElement) { if (parentHtmlElement) {
availableHeight = Math.floor(parentHtmlElement.clientHeight); availableHeight = Math.floor(parentHtmlElement.clientHeight);
} }
availableHeight -= state.refHeightWidth.topHeight || 0; otherHeight += state.refHeightWidth.topHeight || 0;
availableHeight -= state.refHeightWidth.bottomHeight || 0; otherHeight += state.refHeightWidth.bottomHeight || 0;
availableHeight -= table.spaceHeight || 0; otherHeight += table.spaceHeight || 0;
otherHeight2 += state.refHeightWidth.titleTotalHeight;
otherHeight2 += state.refHeightWidth.middleScrollWidth - state.refHeightWidth.middleWidth > 0 ? 15 : 0;
availableHeight -= state.refHeightWidth.titleTotalHeight; availableHeight -= otherHeight + otherHeight2;
availableHeight -= state.refHeightWidth.middleScrollWidth - state.refHeightWidth.middleWidth > 0 ? 15 : 0;
availableHeight -= 1; //title availableHeight -= 1; //title
const style = { const style = {
height: props.height > 0 ? props.height + 'px' : availableHeight > 0 ? availableHeight + 'px' : '0px', height: props.height > 0 ? props.height - otherHeight2 + 'px' : availableHeight > 0 ? availableHeight + 'px' : '0px',
}; };
return style; return style;
}; };

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

@ -2,11 +2,12 @@
<w-dialog v-model="isShow"> <w-dialog v-model="isShow">
<w-grid <w-grid
ref="userGridRef" ref="userGridRef"
:height="300"
:title="$t('system.user.grid.title')" :title="$t('system.user.grid.title')"
:config-button="true" :config-button="true"
selection="multiple" selection="multiple"
:checkbox-selection="true" :checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/user')" :data-url="Environment.apiContextPath('/api/system/datasource')"
:pagination="{ :pagination="{
sortBy: 'loginName', sortBy: 'loginName',
descending: false, descending: false,

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

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

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

@ -2,11 +2,12 @@
<w-dialog v-model="isShow"> <w-dialog v-model="isShow">
<w-grid <w-grid
ref="userGridRef" ref="userGridRef"
:height="300"
:title="$t('system.user.grid.title')" :title="$t('system.user.grid.title')"
:config-button="true" :config-button="true"
selection="multiple" selection="multiple"
:checkbox-selection="true" :checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/user')" :data-url="Environment.apiContextPath('/api/system/datasource')"
:pagination="{ :pagination="{
sortBy: 'loginName', sortBy: 'loginName',
descending: false, descending: false,

1
io.sc.platform.core/build.gradle

@ -8,6 +8,7 @@ dependencies {
"org.springframework.statemachine:spring-statemachine-starter", "org.springframework.statemachine:spring-statemachine-starter",
"com.github.ulisesbocchio:jasypt-spring-boot-starter:${jasypt_version}", "com.github.ulisesbocchio:jasypt-spring-boot-starter:${jasypt_version}",
"org.springframework.cloud:spring-cloud-context:${spring_cloud_context_version}", "org.springframework.cloud:spring-cloud-context:${spring_cloud_context_version}",
"com.fasterxml.jackson.dataformat:jackson-dataformat-xml",
"jakarta.servlet:jakarta.servlet-api", "jakarta.servlet:jakarta.servlet-api",
"org.apache.commons:commons-lang3", "org.apache.commons:commons-lang3",

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.developer.frontend", "name": "io.sc.platform.developer.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -91,7 +91,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

17
io.sc.platform.gradle/templates/pgp/setup/build.gradle.txt

@ -269,6 +269,22 @@ subprojects {
*----------------------------------------------------------------*/ *----------------------------------------------------------------*/
task jrebelIdea() {} task jrebelIdea() {}
tasks.jrebelIdea.doLast { tasks.jrebelIdea.doLast {
if(file('package.json').exists()){
File resourcesFile = file('java-src/main/resources')
if (resourcesFile != null && resourcesFile.exists()) {
File rebelFile = file('java-src/main/resources/rebel.xml')
rebelFile.withWriter('UTF-8') { writer ->
writer.write('<?xml version="1.0" encoding="UTF-8"?>\n');
writer.write('<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd">\n');
writer.write('\t<classpath>\n');
if (file(project.name + '/java-src/main').exists()) {
writer.write('\t\t<dir name="' + project.rootProject.projectDir + '/out/production/' + project.name + '"/>\n');
}
writer.write('\t</classpath>\n');
writer.write('</application>');
}
}
}else {
File resourcesFile = file('src/main/resources') File resourcesFile = file('src/main/resources')
if (resourcesFile != null && resourcesFile.exists()) { if (resourcesFile != null && resourcesFile.exists()) {
File rebelFile = file('src/main/resources/rebel.xml') File rebelFile = file('src/main/resources/rebel.xml')
@ -284,6 +300,7 @@ subprojects {
} }
} }
} }
}
/*----------------------------------------------------------------- /*-----------------------------------------------------------------
* maven publish 插件配置 * maven publish 插件配置

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

@ -36,9 +36,9 @@ application_version=1.0.0
# platform # platform
########################################################### ###########################################################
platform_group=io.sc platform_group=io.sc
platform_version=8.1.29 platform_version=8.1.30
platform_plugin_version=8.1.13 platform_plugin_version=8.1.13
platform_core_frontend_version=8.1.152 platform_core_frontend_version=8.1.159
########################################################### ###########################################################
# dependencies version # dependencies version

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.lcdp.frontend", "name": "io.sc.platform.lcdp.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -91,7 +91,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.mvc.frontend", "name": "io.sc.platform.mvc.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -78,7 +78,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

8
io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/support/RestCrudController.java

@ -10,6 +10,7 @@ import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.orm.service.DaoService; import io.sc.platform.orm.service.DaoService;
import io.sc.platform.orm.service.support.QueryParameter; import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult; import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.orm.service.support.criteria.Criteria;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
@ -20,6 +21,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -155,7 +157,11 @@ public abstract class RestCrudController<V extends BaseVo, E extends BaseEntity<
@AuditLog(action=AuditLogAction.QUERY) @AuditLog(action=AuditLogAction.QUERY)
@GetMapping("") @GetMapping("")
@ResponseBody @ResponseBody
public Page<V> _query(HttpServletRequest request,HttpServletResponse response,QueryParameter queryParameter) throws Exception{ public Page<V> _query(HttpServletRequest request,HttpServletResponse response,E entity,QueryParameter queryParameter) throws Exception{
List<Criteria> criterias =service.buildCriteriaFromEntity(entity);
if(criterias!=null && !criterias.isEmpty()){
queryParameter.addCriterias(criterias);
}
return query(request,response,queryParameter); return query(request,response,queryParameter);
} }

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

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

10
io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/BaseEntity.java

@ -8,13 +8,15 @@ import java.io.Serializable;
* 基本实体抽象类 * 基本实体抽象类
*/ */
public abstract class BaseEntity<V extends BaseVo> implements Serializable { public abstract class BaseEntity<V extends BaseVo> implements Serializable {
public abstract V toVo(); public void toVo(V vo){
public V desensitize(){
return toVo();
} }
public void toVo(V vo){ public V toVo(){
return null;
}
public V desensitize(){
return toVo();
} }
} }

4
io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/VersionEntity.java

@ -13,8 +13,8 @@ import javax.persistence.Version;
/** /**
* 版本化实体类,可实现乐观锁 * 版本化实体类,可实现乐观锁
*/ */
@MappedSuperclass //@MappedSuperclass
public abstract class VersionEntity<V extends VersionVo> extends BaseEntity<V>{ public class VersionEntity<V extends VersionVo> extends BaseEntity<V>{
@Version @Version
@Column(name="JPA_VERSION_") @Column(name="JPA_VERSION_")
protected Integer jpaVersion; protected Integer jpaVersion;

2
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/DaoService.java

@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import io.sc.platform.orm.service.support.criteria.Criteria;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.orm.repository.DaoRepository;
@ -37,6 +38,7 @@ public interface DaoService<E,ID extends Serializable,R extends DaoRepository<E,
public List<E> list(Specification<E> specification, QueryParameter queryParameter) throws Exception; public List<E> list(Specification<E> specification, QueryParameter queryParameter) throws Exception;
public Page<E> query(QueryParameter queryParameter) throws Exception; public Page<E> query(QueryParameter queryParameter) throws Exception;
public Page<E> query(Specification<E> specification, QueryParameter queryParameter) throws Exception; public Page<E> query(Specification<E> specification, QueryParameter queryParameter) throws Exception;
public List<Criteria> buildCriteriaFromEntity(E entity) throws Exception;
public List<E> getDefaultValues() throws Exception; public List<E> getDefaultValues() throws Exception;
public void resetDefaultValues() throws Exception; public void resetDefaultValues() throws Exception;
} }

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

@ -4,6 +4,7 @@ import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.orm.service.DaoService; import io.sc.platform.orm.service.DaoService;
import io.sc.platform.orm.service.support.*; import io.sc.platform.orm.service.support.*;
import io.sc.platform.orm.service.support.criteria.Criteria; import io.sc.platform.orm.service.support.criteria.Criteria;
import io.sc.platform.orm.service.support.criteria.impl.Equals;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
@ -21,6 +22,7 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.metamodel.PluralAttribute; import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.SingularAttribute;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepository<E,ID>> implements DaoService<E,ID,R>{ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepository<E,ID>> implements DaoService<E,ID,R>{
@ -418,6 +420,40 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
return QueryResult.emptyPage(); return QueryResult.emptyPage();
} }
@Override
public List<Criteria> buildCriteriaFromEntity(E entity) throws Exception {
if(entity==null){
return Collections.emptyList();
}
if(Modifier.isAbstract(entity.getClass().getModifiers())){
return Collections.emptyList();
}
List<Criteria> result =new ArrayList<>();
ManagedTypeAttributes managedTypeAttributes =repository.getManagedTypeAttributes(entity.getClass());
if(managedTypeAttributes==null){ return result; }
DirectFieldAccessFallbackBeanWrapper wrapper = new DirectFieldAccessFallbackBeanWrapper(entity);
Map<String,SingularAttribute<?,?>> attributes =managedTypeAttributes.getSingularAssociationAttributes();
if(attributes==null || attributes.isEmpty()){ return result;}
attributes.keySet().forEach(fieldName ->{
Object value =wrapper.getPropertyValue(fieldName);
if(value!=null){
Class<?> javaType =attributes.get(fieldName).getJavaType();
EntityInformation<Object, ?> entityInformation =repositories.getEntityInformationFor(javaType);
Object id =entityInformation.getId(value);
if(id!=null){
Equals equals =new Equals();
equals.setFieldName(fieldName);
equals.setValue(id.toString());
result.add(equals);
}
}
});
return result;
}
@Override @Override
public List<E> getDefaultValues() throws Exception{ public List<E> getDefaultValues() throws Exception{
return null; return null;

2
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/QueryParameter.java

@ -103,7 +103,7 @@ public class QueryParameter {
} }
public void addCriterias(List<Criteria> criterias){ public void addCriterias(List<Criteria> criterias){
criterias.addAll(criterias); this.criterias.addAll(criterias);
} }
public Boolean getPageable() { public Boolean getPageable() {

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.security.frontend", "name": "io.sc.platform.security.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [ "keywords": [
@ -92,7 +92,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.2", "quasar": "2.14.2",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.system.frontend", "name": "io.sc.platform.system.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -91,7 +91,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.standard.frontend", "name": "io.sc.standard.frontend",
"version": "8.1.29", "version": "8.1.30",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -91,7 +91,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.158", "platform-core": "8.1.159",
"quasar": "2.14.5", "quasar": "2.14.5",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

Loading…
Cancel
Save