Browse Source

fix pageable bug

main
wangshaoping 1 year ago
parent
commit
4bc1feec25
  1. 3
      gradle.properties
  2. 2
      io.sc.platform.core.frontend/package.json
  3. 10
      io.sc.platform.core.frontend/src/platform/components-ext/formater/MenuTypeFormater.ts
  4. 5
      io.sc.platform.core.frontend/src/platform/components-ext/formater/index.ts
  5. 6
      io.sc.platform.core.frontend/src/platform/components-ext/options/index.ts
  6. 91
      io.sc.platform.core.frontend/src/platform/components/form/elements/WEditor.vue
  7. 4
      io.sc.platform.core.frontend/src/platform/components/tag/WEnableTag.vue
  8. 2
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/ExpansionMenuItem.vue
  9. 4
      io.sc.platform.core.frontend/template-project/package.json
  10. 11
      io.sc.platform.core.frontend/template-project/src/views/likm/RoleStatusTag.vue
  11. 17
      io.sc.platform.core.frontend/template-project/src/views/likm/SelectRoleDialog.vue
  12. 2
      io.sc.platform.core.frontend/template-project/src/views/likm/SelectUserDialog.vue
  13. 69
      io.sc.platform.core.frontend/template-project/src/views/likm/SetPasswordDialog.vue
  14. 0
      io.sc.platform.core.frontend/template-project/src/views/likm/UserStatusTag.vue
  15. 1
      io.sc.platform.core/build.gradle
  16. 55
      io.sc.platform.core/src/main/java/io/sc/platform/core/util/PinyinUtil.java
  17. 2
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  18. 2
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  19. 4
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties
  20. 4
      io.sc.platform.developer.frontend/package.json
  21. 14
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java
  22. 11
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/AgentServiceImpl.java
  23. 4
      io.sc.platform.lcdp.frontend/package.json
  24. 33
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/converter/ConfigureEntityVoConverter.java
  25. 6
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/service/impl/ConfigureServiceImpl.java
  26. 4
      io.sc.platform.mvc.frontend/package.json
  27. 29
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/plugins/item/FrontEndRouteMetaAction.java
  28. 10
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/plugins/item/FrontEndRouteMetaActionPermission.java
  29. 2
      io.sc.platform.orm.api/src/main/java/io/sc/platform/orm/api/vo/CorporationAuditorVo.java
  30. 72
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/EntityVoConverter.java
  31. 16
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/AuditorEntity.java
  32. 8
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/CorporationAuditorEntity.java
  33. 13
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/EntityVoConverter.java
  34. 7
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/VersionEntity.java
  35. 12
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/QueryParameter.java
  36. 54
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/util/EntityVoConvertor.java
  37. 106
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/util/EntityVoUtil.java
  38. 6
      io.sc.platform.security.frontend/package.json
  39. 59
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuRouteActionVo.java
  40. 4
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuSeparatorVo.java
  41. 4
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuSeperatorVo.java
  42. 7
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuVo.java
  43. 71
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/notification/NotificationVo.java
  44. 2
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/enums/MenuType.java
  45. 2
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/enums/UrlOpenType.java
  46. 5
      io.sc.platform.system.api/src/main/resources/META-INF/platform/plugins/messages.json
  47. 9
      io.sc.platform.system.api/src/main/resources/io/sc/platform/system/api/i18n/enums.properties
  48. 9
      io.sc.platform.system.api/src/main/resources/io/sc/platform/system/api/i18n/enums_tw_CN.properties
  49. 9
      io.sc.platform.system.api/src/main/resources/io/sc/platform/system/api/i18n/enums_zh_CN.properties
  50. 4
      io.sc.platform.system.frontend/package.json
  51. 10
      io.sc.platform.system.frontend/src/components/index.ts
  52. 74
      io.sc.platform.system.frontend/src/i18n/messages.json
  53. 68
      io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json
  54. 78
      io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json
  55. 12
      io.sc.platform.system.frontend/src/menus/menus.json
  56. 22
      io.sc.platform.system.frontend/src/routes/routes.json
  57. 4
      io.sc.platform.system.frontend/src/views/AnnouncementManager.vue
  58. 4
      io.sc.platform.system.frontend/src/views/I18n.vue
  59. 4
      io.sc.platform.system.frontend/src/views/Log.vue
  60. 4
      io.sc.platform.system.frontend/src/views/Menu.vue
  61. 4
      io.sc.platform.system.frontend/src/views/NotificationManager.vue
  62. 4
      io.sc.platform.system.frontend/src/views/Org.vue
  63. 4
      io.sc.platform.system.frontend/src/views/Role.vue
  64. 59
      io.sc.platform.system.frontend/src/views/announcement/AnnouncementManager.vue
  65. 76
      io.sc.platform.system.frontend/src/views/announcement/WEditor.vue
  66. 176
      io.sc.platform.system.frontend/src/views/corporation/Corporation.vue
  67. 0
      io.sc.platform.system.frontend/src/views/department/Department.vue
  68. 0
      io.sc.platform.system.frontend/src/views/license/License.vue
  69. 513
      io.sc.platform.system.frontend/src/views/menu/Menu.vue
  70. 212
      io.sc.platform.system.frontend/src/views/menu/SelectRoleDialog.vue
  71. 60
      io.sc.platform.system.frontend/src/views/notification/NotificationManager.vue
  72. 365
      io.sc.platform.system.frontend/src/views/org/Org.vue
  73. 154
      io.sc.platform.system.frontend/src/views/org/SelectUserDialog.vue
  74. 297
      io.sc.platform.system.frontend/src/views/role/Role.vue
  75. 108
      io.sc.platform.system.frontend/src/views/shared/SelectMenuTreeGrid.vue
  76. 81
      io.sc.platform.system.frontend/src/views/shared/SelectOrgTreeGrid.vue
  77. 102
      io.sc.platform.system.frontend/src/views/shared/SelectRoleDialog.vue
  78. 138
      io.sc.platform.system.frontend/src/views/shared/SelectRoleGrid.vue
  79. 106
      io.sc.platform.system.frontend/src/views/shared/SelectUserDialog.vue
  80. 150
      io.sc.platform.system.frontend/src/views/shared/SelectUserGrid.vue
  81. 17
      io.sc.platform.system.frontend/src/views/shared/UserStatusTag.vue
  82. 14
      io.sc.platform.system.frontend/src/views/user/SetPasswordDialog.vue
  83. 624
      io.sc.platform.system.frontend/src/views/user/User.vue
  84. 2
      io.sc.platform.system/src/main/java/io/sc/platform/system/announcement/jpa/entity/AnnouncementEntity.java
  85. 49
      io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/controller/CorporationWebController.java
  86. 6
      io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/jpa/entity/CorporationEntity.java
  87. 31
      io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/service/CorporationService.java
  88. 47
      io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/service/impl/CorporationServiceImpl.java
  89. 4
      io.sc.platform.system/src/main/java/io/sc/platform/system/initializer/OrgInitializer.java
  90. 4
      io.sc.platform.system/src/main/java/io/sc/platform/system/initializer/RoleAndMenuInitializer.java
  91. 47
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/controller/MenuWebController.java
  92. 28
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/convertor/MenuEntityPluginConvertor.java
  93. 41
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuEntity.java
  94. 2
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuGroupEntity.java
  95. 2
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuJavascriptEntity.java
  96. 2
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuRouteEntity.java
  97. 26
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuSeparatorEntity.java
  98. 27
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuSeperatorEntity.java
  99. 3
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuUrlEntity.java
  100. 69
      io.sc.platform.system/src/main/java/io/sc/platform/system/menu/mapper/MenuEntityMapper.java

3
gradle.properties

@ -38,7 +38,7 @@ application_version=1.0.0
platform_group=io.sc platform_group=io.sc
platform_version=8.1.20 platform_version=8.1.20
platform_plugin_version=8.1.13 platform_plugin_version=8.1.13
platform_core_frontend_version=8.1.75 platform_core_frontend_version=8.1.83
########################################################### ###########################################################
# dependencies version # dependencies version
@ -65,6 +65,7 @@ mybatis_version=3.5.10
opencsv_version=5.7.1 opencsv_version=5.7.1
oshi_version=6.4.2 oshi_version=6.4.2
p6spy_version=3.9.1 p6spy_version=3.9.1
pinyin4j_version=2.5.1
poi_ooxml_version=3.17 poi_ooxml_version=3.17
schemacrawler_version=16.19.11 schemacrawler_version=16.19.11
#schemacrawler_version=14.21.02 #schemacrawler_version=14.21.02

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

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

10
io.sc.platform.core.frontend/src/platform/components-ext/formater/MenuTypeFormater.ts

@ -0,0 +1,10 @@
import { i18n } from '@/platform/plugin';
const menuTypeFormater = (value) => {
if (value) {
return i18n.global.t('io.sc.platform.system.enums.MenuType.' + value);
}
return '';
};
export { menuTypeFormater };

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

@ -1,6 +1,7 @@
import type { EnumType } from '@/platform/types'; import type { EnumType } from '@/platform/types';
import { yesNoFormater, trueFalseFormater, enableTagFormater } from './BooleanFormater'; import { yesNoFormater, trueFalseFormater, enableTagFormater } from './BooleanFormater';
import { dateOnlyFormater } from './DatetimeFormater'; import { dateOnlyFormater } from './DatetimeFormater';
import { menuTypeFormater } from './MenuTypeFormater';
import { EnumFormater } from './EnumFormater'; import { EnumFormater } from './EnumFormater';
class Formater { class Formater {
@ -22,6 +23,10 @@ class Formater {
return dateOnlyFormater; return dateOnlyFormater;
} }
public static menuType() {
return menuTypeFormater;
}
public static enum(enumType: EnumType) { public static enum(enumType: EnumType) {
if (enumType) { if (enumType) {
let enumFormater = Formater.#enumFormaterMap[enumType.name]; let enumFormater = Formater.#enumFormaterMap[enumType.name];

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

@ -9,18 +9,18 @@ class Options {
return yesNo(); return yesNo();
} }
public static truefalse(t: any) { public static truefalse() {
return trueFalse(); return trueFalse();
} }
public static enum(enumType: EnumType) { public static enum(enumType: EnumType, includeEmpty: boolean = true) {
if (enumType) { if (enumType) {
let enumOptions = Options.#enumOptionsMap[enumType.name]; let enumOptions = Options.#enumOptionsMap[enumType.name];
if (!enumOptions) { if (!enumOptions) {
enumOptions = new EnumOptions(enumType.items); enumOptions = new EnumOptions(enumType.items);
Options.#enumOptionsMap[enumType.name] = enumOptions; Options.#enumOptionsMap[enumType.name] = enumOptions;
} }
return enumOptions.options(); return enumOptions.options(includeEmpty);
} }
} }
} }

91
io.sc.platform.core.frontend/src/platform/components/form/elements/WEditor.vue

@ -0,0 +1,91 @@
<template>
<div>
<q-input
v-show="!hideIfComputed"
ref="textareaRef"
:hide-bottom-space="true"
:hide-hint="true"
:outlined="true"
:dense="true"
v-bind="attrs"
type="textarea"
:rules="rulesComputed"
:readonly="readonlyIfComputed"
:disable="disableIfComputed"
>
<template #label> <span v-if="requiredIfComputed" style="color: red">*</span> {{ attrs.label }}</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, computed, defineProps, useAttrs } from 'vue';
import { FormValidators } from '@/platform/components';
const textareaRef = ref();
const attrs = useAttrs();
const inRules = attrs.rules;
const props = defineProps({
hideIf: {
type: Function,
default: () => {
return false;
},
},
required: {
type: Boolean,
default: false,
},
requiredIf: {
type: Function,
default: undefined,
},
readonlyIf: {
type: Function,
default: () => {
return false;
},
},
disableIf: {
type: Function,
default: () => {
return false;
},
},
form: {
type: Object,
default: undefined,
},
});
const rulesComputed = computed(() => {
let rules = inRules || <any>[];
if (!hideIfComputed.value && requiredIfComputed.value) {
rules.push(FormValidators.required());
} else if (hideIfComputed.value) {
rules = [];
}
if (textareaRef?.value) {
textareaRef.value.resetValidation();
}
return rules;
});
const hideIfComputed = computed(() => {
return props.hideIf(props.form);
});
const requiredIfComputed = computed(() => {
if (props.requiredIf) {
return props.requiredIf(props.form) || false;
} else if (props.required) {
return true;
}
return false;
});
const readonlyIfComputed = computed(() => {
return props.readonlyIf(props.form);
});
const disableIfComputed = computed(() => {
return props.disableIf(props.form);
});
</script>

4
io.sc.platform.core.frontend/src/platform/components/tag/WEnableTag.vue

@ -1,10 +1,12 @@
<template> <template>
<div> <div v-if="!Tools.isUndefinedOrNull(enable)">
<q-chip v-if="enable" color="green" text-color="white" :label="$t('normal')" dense></q-chip> <q-chip v-if="enable" color="green" text-color="white" :label="$t('normal')" dense></q-chip>
<q-chip v-if="!enable" color="red" text-color="white" :label="$t('disable')" dense></q-chip> <q-chip v-if="!enable" color="red" text-color="white" :label="$t('disable')" dense></q-chip>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Tools } from '@/platform/utils';
const props = defineProps({ const props = defineProps({
enable: { type: Boolean, default: true }, enable: { type: Boolean, default: true },
}); });

2
io.sc.platform.core.frontend/src/platform/layout/sub-layout/ExpansionMenuItem.vue

@ -49,7 +49,7 @@
<!-- 菜单项 --> <!-- 菜单项 -->
<q-item <q-item
v-else-if="item.type !== 'SEPERATOR'" v-else-if="item.type !== 'SEPARATOR'"
:key="item.id" :key="item.id"
clickable clickable
:dense="$gc.theme.sider.dense" :dense="$gc.theme.sider.dense"

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

@ -1,6 +1,6 @@
{ {
"name": "platform-core", "name": "platform-core",
"version": "8.1.76", "version": "8.1.87",
"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.76", "platform-core": "8.1.87",
"quasar": "2.14.2", "quasar": "2.14.2",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",

11
io.sc.platform.core.frontend/template-project/src/views/likm/RoleStatusTag.vue

@ -0,0 +1,11 @@
<template>
<div>
<q-chip v-if="enable" color="green" text-color="white" :label="$t('normal')" dense></q-chip>
<q-chip v-if="!enable" color="red" text-color="white" :label="$t('disable')" dense></q-chip>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
enable: { type: Boolean, default: true },
});
</script>

17
io.sc.platform.system.frontend/src/views/user/SelectRoleDialog.vue → io.sc.platform.core.frontend/template-project/src/views/likm/SelectRoleDialog.vue

@ -16,7 +16,9 @@
many: roleIds, many: roleIds,
}) })
.then((response) => { .then((response) => {
roleGridRef?.refresh(); axios.get(Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + userId).then((response) => {
roleGridRef.replaceRows(response.data.content);
});
close(); close();
}); });
}, },
@ -57,7 +59,12 @@
{ {
name: 'status', name: 'status',
label: t('status'), label: t('status'),
format: Formater.enableTag(), format: (value, row) => {
return {
componentType: RoleStatusTag,
attrs: row,
};
},
}, },
{ name: 'lastModifier', label: t('lastModifier') }, { name: 'lastModifier', label: t('lastModifier') },
{ name: 'lastModifyDate', label: t('lastModifyDate') }, { name: 'lastModifyDate', label: t('lastModifyDate') },
@ -69,7 +76,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, nextTick } from 'vue'; import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { axios, Environment, Tools, EnumTools, Options, Formater } from 'platform-core'; import { axios, Environment, Tools, EnumTools, Options, Formater } from '@/platform';
import RoleStatusTag from './RoleStatusTag.vue';
const { t } = useI18n(); const { t } = useI18n();
@ -81,10 +89,11 @@ EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom').then((data) => {
DataComeFromEnum.value = data; DataComeFromEnum.value = data;
}); });
let userId, roleGridRef; let userId, userGridRef, roleGridRef;
const open = (param: object) => { const open = (param: object) => {
userId = param.userId; userId = param.userId;
userGridRef = param.userGrid;
roleGridRef = param.roleGrid; roleGridRef = param.roleGrid;
dialogRef.value.show(); dialogRef.value.show();

2
io.sc.platform.system.frontend/src/views/role/SelectUserDialog.vue → io.sc.platform.core.frontend/template-project/src/views/likm/SelectUserDialog.vue

@ -69,7 +69,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, nextTick } from 'vue'; import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { axios, Environment, Tools, EnumTools, Options, Formater } from 'platform-core'; import { axios, Environment, Tools, EnumTools, Options, Formater } from '@/platform';
const { t } = useI18n(); const { t } = useI18n();
const dialogRef = ref(); const dialogRef = ref();

69
io.sc.platform.core.frontend/template-project/src/views/likm/SetPasswordDialog.vue

@ -0,0 +1,69 @@
<template>
<w-dialog
ref="setPasswordDialogRef"
:title="$t('system.user.action.' + actionType)"
width="500px"
height="230px"
:can-maximize="false"
:buttons="[
{
label: $t('submit'),
click: () => {
axios
.post(Environment.apiContextPath('/api/system/user/' + actionType), {
userIds: userIds,
password: setPasswordFormRef.getData().password,
})
.then(() => {
setPasswordDialogRef.hide();
NotifyManager.info($t('operationSuccess'));
});
},
},
]"
>
<w-form
ref="setPasswordFormRef"
:cols-num="1"
:fields="[
{ name: 'password', label: $t('password'), type: 'password', required: true },
{
name: 'confirmPassword',
label: $t('confirmPassword'),
type: 'password',
required: true,
rules: [
(value) => {
return Tools.stringEquals(setPasswordFormRef.getData().password, value) ? true : $t('passwordAndConfirmPasswordMustEqual');
},
],
},
]"
class="p-2"
></w-form>
</w-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment, NotifyManager, Tools } from '@/platform';
const setPasswordDialogRef = ref();
const setPasswordFormRef = ref();
let actionType = ref();
let userIds = [];
const open = (type, users) => {
actionType.value = type;
userIds = Tools.extractProperties(users, 'id');
setPasswordDialogRef.value.show();
};
const close = () => {
setPasswordDialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

0
io.sc.platform.system.frontend/src/views/user/UserStatusTag.vue → io.sc.platform.core.frontend/template-project/src/views/likm/UserStatusTag.vue

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

@ -15,5 +15,6 @@ dependencies {
"com.beust:jcommander:${jcommander_version}", "com.beust:jcommander:${jcommander_version}",
"net.lingala.zip4j:zip4j:${zip4j_version}", "net.lingala.zip4j:zip4j:${zip4j_version}",
"com.github.seancfoley:ipaddress:${ipaddress_version}", "com.github.seancfoley:ipaddress:${ipaddress_version}",
"com.belerweb:pinyin4j:${pinyin4j_version}",
) )
} }

55
io.sc.platform.core/src/main/java/io/sc/platform/core/util/PinyinUtil.java

@ -0,0 +1,55 @@
package io.sc.platform.core.util;
import net.sourceforge.pinyin4j.PinyinHelper;
/**
* 汉语拼音辅助类
* @author wangshaoping
*
*/
public class PinyinUtil {
/**
* 采用汉语拼音比较两个字符串
* @param o1 字符串1
* @param o2 字符串2
* @return 汉语拼音比较结果
*/
public static int compare(String o1, String o2) {
for (int i = 0; i < o1.length() && i < o2.length(); i++) {
int codePoint1 = o1.charAt(i);
int codePoint2 = o2.charAt(i);
if (Character.isSupplementaryCodePoint(codePoint1)
|| Character.isSupplementaryCodePoint(codePoint2)) {
i++;
}
if (codePoint1 != codePoint2) {
if (Character.isSupplementaryCodePoint(codePoint1)
|| Character.isSupplementaryCodePoint(codePoint2)) {
return codePoint1 - codePoint2;
}
String pinyin1 = hanyuPinyin((char) codePoint1);
String pinyin2 = hanyuPinyin((char) codePoint2);
if (pinyin1 != null && pinyin2 != null) {
if (!pinyin1.equals(pinyin2)) {
return pinyin1.compareTo(pinyin2);
}
} else {
return codePoint1 - codePoint2;
}
}
}
return o1.length() - o2.length();
}
private static String hanyuPinyin(char c) {
String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
if (pinyins == null) {
return null;
}
return pinyins[0];
}
}

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

@ -139,6 +139,7 @@ top-left=Top Left
top-right=Top Right top-right=Top Right
top=Top top=Top
true=True true=True
type=Type
upToTop=Up to Top upToTop=Up to Top
url=URL url=URL
user=User user=User
@ -155,3 +156,4 @@ confirmNewPassword=Confirm New Password
accountExpired=Expired accountExpired=Expired
accountLocked=Locked accountLocked=Locked
credentialsExpired=Credentials Expired credentialsExpired=Credentials Expired
javascript=JavaScript

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

@ -139,6 +139,7 @@ top-left=\u5DE6\u4E0A
top-right=\u53F3\u4E0A top-right=\u53F3\u4E0A
top=\u4E0A\u908A top=\u4E0A\u908A
true=\u771F true=\u771F
type=\u985E\u578B
upToTop=\u56DE\u5230\u9802\u90E8 upToTop=\u56DE\u5230\u9802\u90E8
url=URL url=URL
user=\u7528\u6237 user=\u7528\u6237
@ -155,3 +156,4 @@ confirmNewPassword=\u78BA\u8A8D\u65B0\u5BC6\u78BC
accountExpired=\u904E\u671F accountExpired=\u904E\u671F
accountLocked=\u9396\u5B9A accountLocked=\u9396\u5B9A
credentialsExpired=\u5BC6\u78BC\u904E\u671F credentialsExpired=\u5BC6\u78BC\u904E\u671F
javascript=JavaScript

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

@ -139,6 +139,7 @@ top-left=\u5DE6\u4E0A
top-right=\u53F3\u4E0A top-right=\u53F3\u4E0A
top=\u4E0A\u8FB9 top=\u4E0A\u8FB9
true=\u771F true=\u771F
type=\u7C7B\u578B
upToTop=\u56DE\u5230\u9876\u90E8 upToTop=\u56DE\u5230\u9876\u90E8
url=URL url=URL
user=\u7528\u6237 user=\u7528\u6237
@ -154,4 +155,5 @@ newPassword=\u65B0\u5BC6\u7801
confirmNewPassword=\u786E\u8BA4\u65B0\u5BC6\u7801 confirmNewPassword=\u786E\u8BA4\u65B0\u5BC6\u7801
accountExpired=\u8FC7\u671F accountExpired=\u8FC7\u671F
accountLocked=\u9501\u5B9A accountLocked=\u9501\u5B9A
credentialsExpired=\u5BC6\u7801\u8FC7\u671F credentialsExpired=\u5BC6\u7801\u8FC7\u671F
javascript=JavaScript

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

@ -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.75", "platform-core": "8.1.83",
"quasar": "2.14.2", "quasar": "2.14.2",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",
@ -100,4 +100,4 @@
"codemirror": "6.0.1", "codemirror": "6.0.1",
"vue-codemirror6": "1.2.0" "vue-codemirror6": "1.2.0"
} }
} }

14
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java

@ -1,8 +1,6 @@
package io.sc.platform.flowable.controller; package io.sc.platform.flowable.controller;
import java.util.List; import com.fasterxml.jackson.databind.JsonNode;
import java.util.Map;
import io.sc.platform.core.Environment; import io.sc.platform.core.Environment;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice; import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.flowable.service.FlowableModelerService; import io.sc.platform.flowable.service.FlowableModelerService;
@ -11,10 +9,9 @@ import io.sc.platform.flowable.support.FlowableGroupList;
import io.sc.platform.flowable.support.FlowableUser; import io.sc.platform.flowable.support.FlowableUser;
import io.sc.platform.flowable.support.FlowableUserList; import io.sc.platform.flowable.support.FlowableUserList;
import io.sc.platform.orm.service.support.QueryParameter; import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.util.EntityVoConvertor; import io.sc.platform.orm.util.EntityVoUtil;
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.convertor.UserEntityVoConverter;
import io.sc.platform.system.user.jpa.entity.UserEntity; import io.sc.platform.system.user.jpa.entity.UserEntity;
import io.sc.platform.system.user.service.UserService; import io.sc.platform.system.user.service.UserService;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@ -30,7 +27,8 @@ import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.fasterxml.jackson.databind.JsonNode; import java.util.List;
import java.util.Map;
/** /**
* 流程设计器控制器 * 流程设计器控制器
@ -118,7 +116,7 @@ public class FlowableModelerEditorWebController {
return criteriaBuilder.like(root.get("loginName"),filter); return criteriaBuilder.like(root.get("loginName"),filter);
}; };
Page<UserEntity> userEntities =userService.query(specification,queryParameter); Page<UserEntity> userEntities =userService.query(specification,queryParameter);
return FlowableUserList.fromUsers(new UserEntityVoConverter().toVo(userEntities)); return FlowableUserList.fromUsers(EntityVoUtil.toVo(userEntities));
} }
/** /**
@ -131,6 +129,6 @@ public class FlowableModelerEditorWebController {
@IgnoreResponseBodyAdvice @IgnoreResponseBodyAdvice
public FlowableGroupList editorGroups(@RequestParam(name="filter",required=false) String filter,QueryParameter queryParameter) throws Exception{ public FlowableGroupList editorGroups(@RequestParam(name="filter",required=false) String filter,QueryParameter queryParameter) throws Exception{
Page<RoleEntity> roleEntities =roleService.queryRolesByCodeOrName(filter,queryParameter); Page<RoleEntity> roleEntities =roleService.queryRolesByCodeOrName(filter,queryParameter);
return FlowableGroupList.fromGroups(EntityVoConvertor.toVo(roleEntities)); return FlowableGroupList.fromGroups(EntityVoUtil.toVo(roleEntities));
} }
} }

11
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/AgentServiceImpl.java

@ -1,17 +1,13 @@
package io.sc.platform.flowable.service.impl; package io.sc.platform.flowable.service.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import io.sc.platform.flowable.jpa.entity.AgentEntity; import io.sc.platform.flowable.jpa.entity.AgentEntity;
import io.sc.platform.flowable.jpa.repository.AgentRepository; import io.sc.platform.flowable.jpa.repository.AgentRepository;
import io.sc.platform.flowable.service.AgentService; import io.sc.platform.flowable.service.AgentService;
import io.sc.platform.orm.service.impl.DaoServiceImpl; import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.orm.util.EntityVoUtil;
import io.sc.platform.system.api.user.UserVo; import io.sc.platform.system.api.user.UserVo;
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.convertor.UserEntityVoConverter;
import io.sc.platform.system.user.jpa.entity.UserEntity; import io.sc.platform.system.user.jpa.entity.UserEntity;
import io.sc.platform.system.user.service.UserService; import io.sc.platform.system.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -19,6 +15,9 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.persistence.criteria.Join; import javax.persistence.criteria.Join;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Service @Service
public class AgentServiceImpl extends DaoServiceImpl<AgentEntity, String, AgentRepository> implements AgentService { public class AgentServiceImpl extends DaoServiceImpl<AgentEntity, String, AgentRepository> implements AgentService {
@ -52,7 +51,7 @@ public class AgentServiceImpl extends DaoServiceImpl<AgentEntity, String, AgentR
result.add(userEntity); result.add(userEntity);
} }
} }
return new UserEntityVoConverter().toVo(result); return new EntityVoUtil().toVo(result);
} }
return Collections.emptyList(); return Collections.emptyList();
} }

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

@ -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.75", "platform-core": "8.1.83",
"quasar": "2.14.2", "quasar": "2.14.2",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",
@ -100,4 +100,4 @@
"vue-router": "4.2.5", "vue-router": "4.2.5",
"vue-codemirror6": "1.2.0" "vue-codemirror6": "1.2.0"
} }
} }

33
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/converter/ConfigureEntityVoConverter.java

@ -1,33 +0,0 @@
package io.sc.platform.lcdp.configure.converter;
import io.sc.platform.lcdp.configure.jpa.entity.ConfigureEntity;
import io.sc.platform.lcdp.configure.api.Configure;
import io.sc.platform.orm.EntityVoConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConfigureEntityVoConverter implements EntityVoConverter<ConfigureEntity, Configure> {
private static final Logger log = LoggerFactory.getLogger(ConfigureEntityVoConverter.class);
@Override
public Configure toVo(ConfigureEntity entity) {
if(entity==null){
return null;
}
Configure result =new Configure();
result.setSetting(entity.getSetting());
result.setTheme(entity.getTheme());
return result;
}
@Override
public ConfigureEntity fromVo(Configure vo) {
if(vo==null){
return null;
}
ConfigureEntity entity =new ConfigureEntity();
entity.setSetting(vo.getSetting());
entity.setTheme(vo.getTheme());
return entity;
}
}

6
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/service/impl/ConfigureServiceImpl.java

@ -2,7 +2,6 @@ package io.sc.platform.lcdp.configure.service.impl;
import io.sc.platform.lcdp.configure.api.Setting; import io.sc.platform.lcdp.configure.api.Setting;
import io.sc.platform.lcdp.configure.api.Theme; import io.sc.platform.lcdp.configure.api.Theme;
import io.sc.platform.lcdp.configure.converter.ConfigureEntityVoConverter;
import io.sc.platform.lcdp.configure.jpa.entity.ConfigureEntity; import io.sc.platform.lcdp.configure.jpa.entity.ConfigureEntity;
import io.sc.platform.lcdp.configure.jpa.repository.ConfigureRepository; import io.sc.platform.lcdp.configure.jpa.repository.ConfigureRepository;
import io.sc.platform.lcdp.configure.service.ConfigureService; import io.sc.platform.lcdp.configure.service.ConfigureService;
@ -18,7 +17,6 @@ import javax.transaction.Transactional;
@Service @Service
public class ConfigureServiceImpl extends DaoServiceImpl<ConfigureEntity, String, ConfigureRepository> implements ConfigureService { public class ConfigureServiceImpl extends DaoServiceImpl<ConfigureEntity, String, ConfigureRepository> implements ConfigureService {
private ConfigureEntityVoConverter converter =new ConfigureEntityVoConverter();
@Autowired private JdbcTemplate jdbcTemplate; @Autowired private JdbcTemplate jdbcTemplate;
@Autowired private SystemParameterService systemParameterService; @Autowired private SystemParameterService systemParameterService;
@ -26,7 +24,9 @@ public class ConfigureServiceImpl extends DaoServiceImpl<ConfigureEntity, String
public Configure getActiveConfigure() { public Configure getActiveConfigure() {
ConfigureEntity entity =repository.findActiveConfigure(); ConfigureEntity entity =repository.findActiveConfigure();
if(entity!=null) { if(entity!=null) {
Configure configure =converter.toVo(entity); Configure configure = new Configure();
configure.setSetting(entity.getSetting());
configure.setTheme(entity.getTheme());
String homePage =systemParameterService.getParameter("parameter.system.homePage"); String homePage =systemParameterService.getParameter("parameter.system.homePage");
if(StringUtils.hasText(homePage)) { if(StringUtils.hasText(homePage)) {
configure.getSetting().setHomePage(homePage); configure.getSetting().setHomePage(homePage);

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

@ -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.75", "platform-core": "8.1.83",
"quasar": "2.14.2", "quasar": "2.14.2",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",
@ -100,4 +100,4 @@
"codemirror": "6.0.1", "codemirror": "6.0.1",
"vue-codemirror6": "1.2.0" "vue-codemirror6": "1.2.0"
} }
} }

29
io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/plugins/item/FrontEndRouteMetaAction.java

@ -5,9 +5,10 @@ import java.util.List;
public class FrontEndRouteMetaAction { public class FrontEndRouteMetaAction {
private String name; private String name;
private String descriptionI18nKey; private String i18nKey;
private boolean enable =true;
private List<FrontEndRouteMetaActionPermission> permissions =new ArrayList<>(); private List<FrontEndRouteMetaActionPermission> permissions =new ArrayList<>();
private boolean enable;
public String getName() { public String getName() {
return name; return name;
@ -17,20 +18,12 @@ public class FrontEndRouteMetaAction {
this.name = name; this.name = name;
} }
public String getDescriptionI18nKey() { public String getI18nKey() {
return descriptionI18nKey; return i18nKey;
}
public void setDescriptionI18nKey(String descriptionI18nKey) {
this.descriptionI18nKey = descriptionI18nKey;
} }
public List<FrontEndRouteMetaActionPermission> getPermissions() { public void setI18nKey(String i18nKey) {
return permissions; this.i18nKey = i18nKey;
}
public void setPermissions(List<FrontEndRouteMetaActionPermission> permissions) {
this.permissions = permissions;
} }
public boolean isEnable() { public boolean isEnable() {
@ -40,4 +33,12 @@ public class FrontEndRouteMetaAction {
public void setEnable(boolean enable) { public void setEnable(boolean enable) {
this.enable = enable; this.enable = enable;
} }
public List<FrontEndRouteMetaActionPermission> getPermissions() {
return permissions;
}
public void setPermissions(List<FrontEndRouteMetaActionPermission> permissions) {
this.permissions = permissions;
}
} }

10
io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/plugins/item/FrontEndRouteMetaActionPermission.java

@ -4,7 +4,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
public class FrontEndRouteMetaActionPermission { public class FrontEndRouteMetaActionPermission {
private RequestMethod method; private RequestMethod method;
private String url; private String matcher;
public RequestMethod getMethod() { public RequestMethod getMethod() {
return method; return method;
@ -14,11 +14,11 @@ public class FrontEndRouteMetaActionPermission {
this.method = method; this.method = method;
} }
public String getUrl() { public String getMatcher() {
return url; return matcher;
} }
public void setUrl(String url) { public void setMatcher(String matcher) {
this.url = url; this.matcher = matcher;
} }
} }

2
io.sc.platform.orm.api/src/main/java/io/sc/platform/orm/api/vo/CorporationAuditorVo.java

@ -15,6 +15,8 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
"corporationCode" "corporationCode"
}) })
public class CorporationAuditorVo extends AuditorVo { public class CorporationAuditorVo extends AuditorVo {
public static final String DEFAULT_CODE ="_PRIMARY_";
/** /**
* 法人代码 * 法人代码
*/ */

72
io.sc.platform.orm/src/main/java/io/sc/platform/orm/EntityVoConverter.java

@ -1,72 +0,0 @@
package io.sc.platform.orm;
import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.orm.service.support.QueryResult;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public interface EntityVoConverter<E,V> {
public V toVo(E entity);
public E fromVo(V vo);
/**
* 脱敏实体对象
* @param entity 实体对象
* @return Vo对象
*/
public default V desensitize(E entity){
return toVo(entity);
}
public default void detach(DaoRepository repository, E entity){
if(entity!=null) {
repository.getEntityManager().detach(entity);
}
}
public default void detach(DaoRepository repository, List<E> entities){
if(entities!=null && !entities.isEmpty()) {
for(E entity : entities) {
detach(repository,entity);
}
}
}
public default List<V> toVo(List<E> entities){
if(entities==null || entities.isEmpty()){
return Collections.emptyList();
}
List<V> result =new ArrayList<>();
for(E entity : entities){
result.add(toVo(entity));
}
return result;
}
public default Page<V> toVo(Page<E> page){
if(page==null){
return QueryResult.emptyPage();
}
List<E> entities =page.getContent();
List<V> vos =toVo(entities);
return new PageImpl<>(vos,page.getPageable(),page.getTotalElements());
}
public default List<E> fromVo(List<V> vos){
if(vos==null || vos.isEmpty()){
return Collections.emptyList();
}
List<E> result =new ArrayList<>();
for(V vo : vos){
result.add(fromVo(vo));
}
return result;
}
}

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

@ -55,14 +55,14 @@ public abstract class AuditorEntity<V extends AuditorVo> extends VersionEntity<V
@JsonProperty(index = 1005) @JsonProperty(index = 1005)
protected Date lastModifyDate; protected Date lastModifyDate;
public static void toVo(AuditorVo vo, AuditorEntity entity){ public void toVo(AuditorVo vo){
if(vo!=null && entity!=null) { if(vo!=null){
VersionEntity.toVo(vo,entity); super.toVo(vo);
vo.setDataComeFrom(entity.getDataComeFrom()); vo.setDataComeFrom(this.getDataComeFrom());
vo.setCreator(entity.getCreator()); vo.setCreator(this.getCreator());
vo.setCreateDate(entity.getCreateDate()); vo.setCreateDate(this.getCreateDate());
vo.setLastModifier(entity.getLastModifier()); vo.setLastModifier(this.getLastModifier());
vo.setLastModifyDate(entity.getLastModifyDate()); vo.setLastModifyDate(this.getLastModifyDate());
} }
} }

8
io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/CorporationAuditorEntity.java

@ -16,10 +16,10 @@ public abstract class CorporationAuditorEntity<V extends CorporationAuditorVo> e
@Column(name="CORP_CODE_",length=36) @Column(name="CORP_CODE_",length=36)
protected String corporationCode ="_PRIMARY_"; protected String corporationCode ="_PRIMARY_";
public static void toVo(CorporationAuditorVo vo, CorporationAuditorEntity entity){ public void toVo(CorporationAuditorVo vo){
if(vo!=null && entity!=null) { if(vo!=null){
AuditorEntity.toVo(vo,entity); super.toVo(vo);
vo.setCorporationCode(entity.getCorporationCode()); vo.setCorporationCode(this.getCorporationCode());
} }
} }

13
io.sc.platform.orm/src/main/java/io/sc/platform/orm/entity/EntityVoConverter.java

@ -1,13 +0,0 @@
package io.sc.platform.orm.entity;
public class EntityVoConverter implements io.sc.platform.orm.EntityVoConverter {
@Override
public Object toVo(Object entity) {
return null;
}
@Override
public Object fromVo(Object vo) {
return null;
}
}

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

@ -17,10 +17,9 @@ public abstract class VersionEntity<V extends VersionVo> extends BaseEntity<V>{
@Column(name="JPA_VERSION_") @Column(name="JPA_VERSION_")
protected int jpaVersion; protected int jpaVersion;
public static void toVo(VersionVo vo,VersionEntity entity){ public void toVo(VersionVo vo){
if(vo!=null && entity!=null) { if(vo!=null){
BaseEntity.toVo(vo,entity); vo.setJpaVersion(this.getJpaVersion());
vo.setJpaVersion(entity.getJpaVersion());
} }
} }

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

@ -1,6 +1,7 @@
package io.sc.platform.orm.service.support; package io.sc.platform.orm.service.support;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import io.sc.platform.orm.service.support.criteria.Criteria; import io.sc.platform.orm.service.support.criteria.Criteria;
@ -35,6 +36,17 @@ public class QueryParameter {
return PageRequest.of(jpaPage,size); return PageRequest.of(jpaPage,size);
} }
} }
public Order getFirstSort(){
Sort sort =getSort();
if(sort!=null){
Iterator<Order> iterator =sort.iterator();
if(iterator!=null && iterator.hasNext()){
return iterator.next();
}
}
return null;
}
public Sort getSort(){ public Sort getSort(){
if(sortBy==null || sortBy.size()==0){ if(sortBy==null || sortBy.size()==0){

54
io.sc.platform.orm/src/main/java/io/sc/platform/orm/util/EntityVoConvertor.java

@ -1,54 +0,0 @@
package io.sc.platform.orm.util;
import io.sc.platform.orm.api.vo.BaseVo;
import io.sc.platform.orm.entity.BaseEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 实体和值对象转换器
*/
public class EntityVoConvertor {
/**
* 将实体分页对象转换成值分页对象
* @param page 实体分页对象
* @return 值分页对象
* @param <E> 实体类型
* @param <V> 值类型
*/
public static <E extends BaseEntity,V extends BaseVo> Page<V> toVo(Page<E> page){
if(page!=null && !page.getContent().isEmpty()) {
List<E> entities =page.getContent();
List<V> list =new ArrayList<>(entities.size());
for(E entity : entities){
list.add((V)entity.toVo());
}
return new PageImpl<V>(list,page.getPageable(),page.getTotalElements());
}else{
return new PageImpl<V>(Collections.emptyList());
}
}
/**
* 将实体列表转换成值列表
* @param entities 实体列表
* @return 值列表
* @param <E> 实体类型
* @param <V> 值类型
*/
public static <E extends BaseEntity,V extends BaseVo> List<V> toVo(List<E> entities){
if(entities!=null && !entities.isEmpty()) {
List<V> list =new ArrayList<>(entities.size());
for(E entity : entities){
list.add((V)entity.toVo());
}
return list;
}else{
return Collections.emptyList();
}
}
}

106
io.sc.platform.orm/src/main/java/io/sc/platform/orm/util/EntityVoUtil.java

@ -0,0 +1,106 @@
package io.sc.platform.orm.util;
import io.sc.platform.orm.api.vo.BaseVo;
import io.sc.platform.orm.entity.BaseEntity;
import io.sc.platform.orm.repository.DaoRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 实体和值对象转换器
*/
public class EntityVoUtil {
/**
* 将实体脱离持久化(即将实体和持久化 Session 脱钩)
* @param repository 持久化
* @param entity 实体
* @param <E> 实体类型
*/
public static <E> void detach(DaoRepository repository, E entity){
if(entity!=null) {
repository.getEntityManager().detach(entity);
}
}
/**
* 将实体集合脱离持久化(即将实体和持久化 Session 脱钩)
* @param repository 持久化
* @param entities 实体集合
* @param <E> 实体类型
*/
public static <E> void detach(DaoRepository repository, List<E> entities){
if(entities!=null && !entities.isEmpty()) {
for(E entity : entities) {
detach(repository,entity);
}
}
}
/**
* 将实体分页对象转换成值分页对象
* @param page 实体分页对象
* @return 值分页对象
* @param <E> 实体类型
* @param <V> 值类型
*/
public static <E extends BaseEntity,V extends BaseVo> Page<V> toVo(Page<E> page){
if(page!=null && !page.getContent().isEmpty()) {
List<E> entities =page.getContent();
List<V> list =new ArrayList<>(entities.size());
for(E entity : entities){
list.add((V)entity.toVo());
}
return new PageImpl<V>(list,page.getPageable(),page.getTotalElements());
}else{
return new PageImpl<V>(Collections.emptyList());
}
}
public static <T> Page<T> sort(Page<T> page, Comparator<T> comparator){
if(page!=null){
List<T> content =page.getContent();
if(content!=null && !content.isEmpty()){
List<T> result =new ArrayList<>(content.size());
for(T e : content){
result.add(e);
}
result.sort(comparator);
return new PageImpl<T>(result,page.getPageable(),page.getTotalElements());
}
}
return page;
}
/**
* 将实体列表转换成值列表
* @param entities 实体列表
* @return 值列表
* @param <E> 实体类型
* @param <V> 值类型
*/
public static <E extends BaseEntity,V extends BaseVo> List<V> toVo(List<E> entities){
if(entities!=null && !entities.isEmpty()) {
List<V> list =new ArrayList<>(entities.size());
for(E entity : entities){
list.add((V)entity.toVo());
}
return list;
}else{
return Collections.emptyList();
}
}
/**
* 脱敏实体对象
* @param entity 实体对象
* @return Vo对象
*/
public static <E extends BaseEntity,V extends BaseVo> V desensitize(E entity){
return (V)entity.desensitize();
}
}

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

@ -4,7 +4,7 @@
"description": "", "description": "",
"private": false, "private": false,
"keywords": [ "keywords": [
], ],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
@ -99,6 +99,6 @@
"vue-dompurify-html": "5.0.1", "vue-dompurify-html": "5.0.1",
"vue-i18n": "9.8.0", "vue-i18n": "9.8.0",
"vue-router": "4.2.5", "vue-router": "4.2.5",
"platform-core": "8.1.75" "platform-core": "8.1.83"
} }
} }

59
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuRouteActionVo.java

@ -0,0 +1,59 @@
package io.sc.platform.system.api.menu;
import io.sc.platform.system.enums.MenuType;
import java.util.HashMap;
import java.util.Map;
public class MenuRouteActionVo extends MenuRouteVo {
private String id;
private String name;
private String i18nKey;
private String parent;
public MenuRouteActionVo(){}
public MenuRouteActionVo(String id,String name,String i18nKey,String parent){
this.id =id;
this.name =name;
this.i18nKey =i18nKey;
this.parent =parent;
}
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
public String getI18nKey() {
return i18nKey;
}
public void setI18nKey(String i18nKey) {
this.i18nKey = i18nKey;
}
@Override
public String getParent() {
return parent;
}
@Override
public void setParent(String parent) {
this.parent = parent;
}
}

4
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuSeparatorVo.java

@ -0,0 +1,4 @@
package io.sc.platform.system.api.menu;
public class MenuSeparatorVo extends MenuVo {
}

4
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuSeperatorVo.java

@ -1,4 +0,0 @@
package io.sc.platform.system.api.menu;
public class MenuSeperatorVo extends MenuVo {
}

7
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuVo.java

@ -1,9 +1,10 @@
package io.sc.platform.system.api.menu; package io.sc.platform.system.api.menu;
import io.sc.platform.orm.api.vo.CorporationAuditorVo; import io.sc.platform.orm.api.vo.CorporationAuditorVo;
import io.sc.platform.system.enums.MenuType;
public abstract class MenuVo extends CorporationAuditorVo { public abstract class MenuVo extends CorporationAuditorVo {
protected String type; protected MenuType type;
protected String parent; protected String parent;
protected String id; protected String id;
protected String name; protected String name;
@ -14,11 +15,11 @@ public abstract class MenuVo extends CorporationAuditorVo {
protected String authorizeExpression; protected String authorizeExpression;
protected boolean selected; protected boolean selected;
public String getType() { public MenuType getType() {
return type; return type;
} }
public void setType(String type) { public void setType(MenuType type) {
this.type = type; this.type = type;
} }

71
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/notification/NotificationVo.java

@ -0,0 +1,71 @@
package io.sc.platform.system.api.notification;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
import java.util.Date;
public class NotificationVo extends CorporationAuditorVo {
private String id;
private String title;
private String content;
private String sender;
protected Date sendDate;
private String receiver;
private Date receiveDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public Date getSendDate() {
return sendDate;
}
public void setSendDate(Date sendDate) {
this.sendDate = sendDate;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public Date getReceiveDate() {
return receiveDate;
}
public void setReceiveDate(Date receiveDate) {
this.receiveDate = receiveDate;
}
}

2
io.sc.platform.system.api/src/main/java/io/sc/platform/system/enums/MenuType.java

@ -3,7 +3,7 @@ package io.sc.platform.system.enums;
public enum MenuType { public enum MenuType {
GROUP, GROUP,
ROUTE, ROUTE,
SEPERATOR, SEPARATOR,
URL, URL,
JAVASCRIPT; JAVASCRIPT;
} }

2
io.sc.platform.system.api/src/main/java/io/sc/platform/system/enums/UrlOpenType.java

@ -4,7 +4,7 @@ package io.sc.platform.system.enums;
* URL 菜单项打开 URL 方式枚举 * URL 菜单项打开 URL 方式枚举
*/ */
public enum UrlOpenType{ public enum UrlOpenType{
DEFAULT, /* 默认打开方式(在当前窗口打开) */ SELF, /* 默认打开方式(在当前窗口打开) */
NEW_WINDOW, /* 在新窗口打开 */ NEW_WINDOW, /* 在新窗口打开 */
EMBEDDED; /* 嵌入式方式(通常在一个 tab 中打开) */ EMBEDDED; /* 嵌入式方式(通常在一个 tab 中打开) */
} }

5
io.sc.platform.system.api/src/main/resources/META-INF/platform/plugins/messages.json

@ -0,0 +1,5 @@
{
"includes":[
"io/sc/platform/system/api/i18n/enums"
]
}

9
io.sc.platform.system.api/src/main/resources/io/sc/platform/system/api/i18n/enums.properties

@ -0,0 +1,9 @@
io.sc.platform.system.enums.MenuType.GROUP=Group
io.sc.platform.system.enums.MenuType.ROUTE=Route
io.sc.platform.system.enums.MenuType.SEPARATOR=Seperator
io.sc.platform.system.enums.MenuType.URL=URL
io.sc.platform.system.enums.MenuType.JAVASCRIPT=JavaScript
io.sc.platform.system.enums.UrlOpenType.SELF=Selft
io.sc.platform.system.enums.UrlOpenType.NEW_WINDOW=New Window
io.sc.platform.system.enums.UrlOpenType.EMBEDDED=Embedded

9
io.sc.platform.system.api/src/main/resources/io/sc/platform/system/api/i18n/enums_tw_CN.properties

@ -0,0 +1,9 @@
io.sc.platform.system.enums.MenuType.GROUP=\u83DC\u55AE\u7EC4
io.sc.platform.system.enums.MenuType.ROUTE=\u8DEF\u7531
io.sc.platform.system.enums.MenuType.SEPARATOR=\u5206\u9694\u7B26
io.sc.platform.system.enums.MenuType.URL=URL
io.sc.platform.system.enums.MenuType.JAVASCRIPT=JavaScript
io.sc.platform.system.enums.UrlOpenType.SELF=\u7576\u524D\u7A97\u53E3
io.sc.platform.system.enums.UrlOpenType.NEW_WINDOW=\u65B0\u7A97\u53E3
io.sc.platform.system.enums.UrlOpenType.EMBEDDED=\u5D4C\u5165\u5F0F

9
io.sc.platform.system.api/src/main/resources/io/sc/platform/system/api/i18n/enums_zh_CN.properties

@ -0,0 +1,9 @@
io.sc.platform.system.enums.MenuType.GROUP=\u83DC\u5355\u7EC4
io.sc.platform.system.enums.MenuType.ROUTE=\u8DEF\u7531
io.sc.platform.system.enums.MenuType.SEPARATOR=\u5206\u9694\u7B26
io.sc.platform.system.enums.MenuType.URL=URL
io.sc.platform.system.enums.MenuType.JAVASCRIPT=JavaScript
io.sc.platform.system.enums.UrlOpenType.SELF=\u5F53\u524D\u7A97\u53E3
io.sc.platform.system.enums.UrlOpenType.NEW_WINDOW=\u65B0\u7A97\u53E3
io.sc.platform.system.enums.UrlOpenType.EMBEDDED=\u5D4C\u5165\u5F0F

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

@ -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.76", "platform-core": "8.1.87",
"quasar": "2.14.2", "quasar": "2.14.2",
"tailwindcss": "3.4.0", "tailwindcss": "3.4.0",
"vue": "3.4.3", "vue": "3.4.3",
@ -100,4 +100,4 @@
"codemirror": "6.0.1", "codemirror": "6.0.1",
"vue-codemirror6": "1.2.0" "vue-codemirror6": "1.2.0"
} }
} }

10
io.sc.platform.system.frontend/src/components/index.ts

@ -6,17 +6,17 @@ import Corporation from '@/views/corporation/Corporation.vue';
import User from '@/views/user/User.vue'; import User from '@/views/user/User.vue';
import Role from '@/views/role/Role.vue'; import Role from '@/views/role/Role.vue';
import Org from '@/views/org/Org.vue'; import Org from '@/views/org/Org.vue';
import Department from '@/views/Department.vue'; import Department from '@/views/department/Department.vue';
import Menu from '@/views/menu/Menu.vue'; import Menu from '@/views/menu/Menu.vue';
import announcement from '@/views/announcement/Announcement.vue'; import announcementManager from '@/views/announcement/AnnouncementManager.vue';
import NotificationManager from '@/views/NotificationManager.vue'; import NotificationManager from '@/views/notification/NotificationManager.vue';
import Parameter from '@/views/parameter/Parameter.vue'; import Parameter from '@/views/parameter/Parameter.vue';
import Dictionary from '@/views/dictionary/Dictionary.vue'; import Dictionary from '@/views/dictionary/Dictionary.vue';
import I18n from '@/views/i18n/I18n.vue'; import I18n from '@/views/i18n/I18n.vue';
import AuditLog from '@/views/monitor/AuditLog.vue'; import AuditLog from '@/views/monitor/AuditLog.vue';
import Log from '@/views/monitor/Log.vue'; import Log from '@/views/monitor/Log.vue';
import Resources from '@/views/monitor/Resources.vue'; import Resources from '@/views/monitor/Resources.vue';
import License from '@/views/License.vue'; import License from '@/views/license/License.vue';
const localComponents = { const localComponents = {
'component.system.Corporation': Corporation, 'component.system.Corporation': Corporation,
@ -25,7 +25,7 @@ const localComponents = {
'component.system.Org': Org, 'component.system.Org': Org,
'component.system.Department': Department, 'component.system.Department': Department,
'component.system.Menu': Menu, 'component.system.Menu': Menu,
'component.system.announcement': announcement, 'component.system.announcementManager': announcementManager,
'component.system.NotificationManager': NotificationManager, 'component.system.NotificationManager': NotificationManager,
'component.system.Parameter': Parameter, 'component.system.Parameter': Parameter,
'component.system.Dictionary': Dictionary, 'component.system.Dictionary': Dictionary,

74
io.sc.platform.system.frontend/src/i18n/messages.json

@ -10,8 +10,8 @@
"menu.system.org" : "Organization", "menu.system.org" : "Organization",
"menu.system.department" : "Department", "menu.system.department" : "Department",
"menu.system.menu" : "Menu", "menu.system.menu" : "Menu",
"menu.system.announcement" : "Announcement", "menu.system.announcementManager" : "Announcement Manager",
"menu.system.notificationManager" : "Notification", "menu.system.notificationManager" : "Notification Manager",
"menu.system.parameter" : "Parameter", "menu.system.parameter" : "Parameter",
"menu.system.dictionary" : "Dictionary", "menu.system.dictionary" : "Dictionary",
"menu.system.i18n" : "I18n Messages", "menu.system.i18n" : "I18n Messages",
@ -21,6 +21,40 @@
"menu.system.monitor.resources" : "Resources", "menu.system.monitor.resources" : "Resources",
"menu.system.license" : "License", "menu.system.license" : "License",
"system.shared.selectUser.grid.title": "User List",
"system.shared.selectUser.grid.toolbar.add":"Add User",
"system.shared.selectUser.grid.toolbar.remove":"Remove User",
"system.shared.selectUser.grid.toolbar.remove.tip":"Are you sure to remove the users?",
"system.shared.selectUser.grid.toolbar.addAll":"Add All User",
"system.shared.selectUser.grid.toolbar.addAll.tip":"Are you sure to add ALL users?",
"system.shared.selectUser.grid.toolbar.removeAll":"Remove All User",
"system.shared.selectUser.grid.toolbar.removeAll.tip":"Are you sure to remove ALL users?",
"system.shared.selectUser.dialog.title": "Select Users",
"system.shared.selectUser.dialog.grid.title": "Available User List",
"system.shared.selectRole.grid.title": "Role List",
"system.shared.selectRole.grid.toolbar.add":"Add Role",
"system.shared.selectRole.grid.toolbar.remove":"Remove Role",
"system.shared.selectRole.grid.toolbar.remove.tip":"Are you sure to remove the roles?",
"system.shared.selectRole.grid.toolbar.addAll":"Add All Role",
"system.shared.selectRole.grid.toolbar.addAll.tip":"Are you sure to add ALL roles?",
"system.shared.selectRole.grid.toolbar.removeAll":"Remove All Role",
"system.shared.selectRole.grid.toolbar.removeAll.tip":"Are you sure to remove ALL roles?",
"system.shared.selectRole.dialog.title": "Select Roles",
"system.shared.selectRole.dialog.grid.title": "Available Role List",
"system.shared.selectOrg.grid.title": "Organization Tree",
"system.shared.selectOrg.grid.toolbar.save":"Save",
"system.shared.selectOrg.grid.toolbar.save.tip":"Are you sure to update organizations?",
"system.shared.selectMenu.grid.title": "Menu Tree",
"system.shared.selectMenu.grid.toolbar.save":"Save",
"system.shared.selectMenu.grid.toolbar.save.tip":"Are you sure to update menus?",
"system.corporation.grid.title":"Corporation Tree",
"system.corporation.grid.toolbar.addTop":"Add Top Corporation",
"system.corporation.grid.toolbar.addChild":"Add Child Corporation",
"system.user.grid.title":"User List", "system.user.grid.title":"User List",
"system.user.grid.toolbar.setPassword":"Set Password", "system.user.grid.toolbar.setPassword":"Set Password",
"system.user.grid.toolbar.setAllPassword":"Set All Password", "system.user.grid.toolbar.setAllPassword":"Set All Password",
@ -28,39 +62,25 @@
"system.user.grid.toolbar.resetPassword.tip":"Are you sure to reset the user's password?", "system.user.grid.toolbar.resetPassword.tip":"Are you sure to reset the user's password?",
"system.user.grid.toolbar.resetAllPassword":"Reset All Password", "system.user.grid.toolbar.resetAllPassword":"Reset All Password",
"system.user.grid.toolbar.resetAllPassword.tip":"Are you sure to reset ALL user's password?", "system.user.grid.toolbar.resetAllPassword.tip":"Are you sure to reset ALL user's password?",
"system.user.selectRole.grid.title":"Role List",
"system.user.selectRole.grid.toolbar.addRole":"Add Role",
"system.user.selectRole.grid.toolbar.addAllRole":"Add All Role",
"system.user.selectRole.grid.toolbar.addAllRole.tip":"Are you sure to add ALL roles to user?",
"system.user.selectRole.grid.toolbar.removeRole":"Remove Role",
"system.user.selectRole.grid.toolbar.removeRole.tip":"Are you sure to remove user's role?",
"system.user.selectRole.grid.toolbar.removeAllRole":"Remove All Role",
"system.user.selectRole.grid.toolbar.removeAllRole.tip":"Are you sure to remove user's ALL roles?",
"system.user.selectRole.dialog.title":"Available Role List",
"system.role.grid.title":"Role List", "system.role.grid.title":"Role List",
"system.role.selectUser.grid.title":"User List",
"system.role.selectUser.grid.toolbar.addUser":"Add User",
"system.role.selectUser.grid.toolbar.addAllUser":"Add All User",
"system.role.selectUser.grid.toolbar.addAllUser.tip":"Are you sure to add ALL users to role?",
"system.role.selectUser.grid.toolbar.removeUser":"Remove User",
"system.role.selectUser.grid.toolbar.removeUser.tip":"Are you sure to remove role's user?",
"system.role.selectUser.grid.toolbar.removeAllUser":"Remove All User",
"system.role.selectUser.grid.toolbar.removeAllUser.tip":"Are you sure to remove role's ALL users?",
"system.role.selectUser.dialog.title":"Available User List",
"system.org.grid.title":"Org Tree", "system.org.grid.title":"Organization Tree",
"system.org.grid.toolbar.addTop":"Add Top Org",
"system.org.grid.toolbar.addChild":"Add Child Org",
"system.menu.grid.title":"Menu Tree",
"system.menu.grid.toolbar.addTop":"Add Top Menu",
"system.menu.grid.toolbar.addChild":"Add Child Menu",
"system.menu.grid.entity.titleI18nKey":"Title i18n Key",
"system.menu.grid.entity.routeName":"Title i18n Key",
"system.menu.action.addTop":"Add Top Menu", "system.announcementManager.grid.title":"Announcement List",
"system.menu.action.addChild":"Add Child Menu",
"system.corporation.action.addTop":"Add Top Corporation", "system.notification.grid.title":"Messages List",
"system.corporation.action.addChild":"Add Child Corporation",
"system.monitor.log.tab.view":"Log View", "system.monitor.log.tab.view":"Log View",
"system.monitor.log.tab.download":"Log Download", "system.monitor.log.tab.download":"Log Download",
"system.monitor.log.tab.level":"Log Level", "system.monitor.log.tab.level":"Log Level"
} }

68
io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json

@ -10,7 +10,7 @@
"menu.system.org" : "機構管理", "menu.system.org" : "機構管理",
"menu.system.department" : "部門管理", "menu.system.department" : "部門管理",
"menu.system.menu" : "菜單管理", "menu.system.menu" : "菜單管理",
"menu.system.announcement" : "公告管理", "menu.system.announcementManager" : "公告管理",
"menu.system.notificationManager" : "消息管理", "menu.system.notificationManager" : "消息管理",
"menu.system.parameter" : "參數管理", "menu.system.parameter" : "參數管理",
"menu.system.dictionary" : "數據字典", "menu.system.dictionary" : "數據字典",
@ -25,39 +25,79 @@
"system.user.grid.toolbar.setPassword":"設置密碼", "system.user.grid.toolbar.setPassword":"設置密碼",
"system.user.grid.toolbar.setAllPassword":"設置所有密碼", "system.user.grid.toolbar.setAllPassword":"設置所有密碼",
"system.user.grid.toolbar.resetPassword":"重置密碼", "system.user.grid.toolbar.resetPassword":"重置密碼",
"system.user.grid.toolbar.resetPassword.tip":"您确定要重置用密碼嗎?", "system.user.grid.toolbar.resetPassword.tip":"您确定要重置用密碼嗎?",
"system.user.grid.toolbar.resetAllPassword":"重置所有密碼", "system.user.grid.toolbar.resetAllPassword":"重置所有密碼",
"system.user.grid.toolbar.resetAllPassword.tip":"您确定要重置所有用密碼嗎?", "system.user.grid.toolbar.resetAllPassword.tip":"您确定要重置所有用密碼嗎?",
"system.user.selectRole.grid.title":"角色列表", "system.user.selectRole.grid.title":"角色列表",
"system.user.selectRole.grid.toolbar.addRole":"添加角色", "system.user.selectRole.grid.toolbar.addRole":"添加角色",
"system.user.selectRole.grid.toolbar.addAllRole":"添加所有角色", "system.user.selectRole.grid.toolbar.addAllRole":"添加所有角色",
"system.user.selectRole.grid.toolbar.addAllRole.tip":"您确定要给用添加所有角色嗎?", "system.user.selectRole.grid.toolbar.addAllRole.tip":"您确定要给用添加所有角色嗎?",
"system.user.selectRole.grid.toolbar.removeRole":"移除角色", "system.user.selectRole.grid.toolbar.removeRole":"移除角色",
"system.user.selectRole.grid.toolbar.removeRole.tip":"您确定要移除用的角色嗎?", "system.user.selectRole.grid.toolbar.removeRole.tip":"您确定要移除用的角色嗎?",
"system.user.selectRole.grid.toolbar.removeAllRole":"移除所有角色", "system.user.selectRole.grid.toolbar.removeAllRole":"移除所有角色",
"system.user.selectRole.grid.toolbar.removeAllRole.tip":"您确定要將用的所有角色移除嗎?", "system.user.selectRole.grid.toolbar.removeAllRole.tip":"您确定要將用的所有角色移除嗎?",
"system.user.selectRole.dialog.title":"可選角色列表", "system.user.selectRole.dialog.title":"可選角色列表",
"system.user.selectOrg.grid.title":"機構樹",
"system.role.grid.title":"角色列表", "system.role.grid.title":"角色列表",
"system.role.selectUser.grid.title":"用戶列表", "system.role.selectUser.grid.title":"用戶列表",
"system.role.selectUser.grid.toolbar.addUser":"添加用", "system.role.selectUser.grid.toolbar.addUser":"添加用",
"system.role.selectUser.grid.toolbar.addAllUser":"添加所有用", "system.role.selectUser.grid.toolbar.addAllUser":"添加所有用",
"system.role.selectUser.grid.toolbar.addAllUser.tip":"您确定要给角色添加所有用嗎?", "system.role.selectUser.grid.toolbar.addAllUser.tip":"您确定要给角色添加所有用嗎?",
"system.role.selectUser.grid.toolbar.removeUser":"移除用", "system.role.selectUser.grid.toolbar.removeUser":"移除用",
"system.role.selectUser.grid.toolbar.removeUser.tip":"您确定要移除角色的用嗎?", "system.role.selectUser.grid.toolbar.removeUser.tip":"您确定要移除角色的用嗎?",
"system.role.selectUser.grid.toolbar.removeAllUser":"移除所有用", "system.role.selectUser.grid.toolbar.removeAllUser":"移除所有用",
"system.role.selectUser.grid.toolbar.removeAllUser.tip":"您确定要移除角色的所有用嗎?", "system.role.selectUser.grid.toolbar.removeAllUser.tip":"您确定要移除角色的所有用嗎?",
"system.role.selectUser.dialog.title":"可選用戶列表", "system.role.selectUser.dialog.title":"可選用戶列表",
"system.role.selectMenu.grid.title":"菜單樹",
"system.org.grid.title":"機構樹",
"system.org.grid.toolbar.addTop":"新增頂級機構",
"system.org.grid.toolbar.addChild":"新增子機構",
"system.shared.selectUser.grid.title": "用戶列表",
"system.shared.selectUser.grid.toolbar.add":"添加用戶",
"system.shared.selectUser.grid.toolbar.remove":"移除用戶",
"system.shared.selectUser.grid.toolbar.remove.tip":"您确定要移除用戶嗎?",
"system.shared.selectUser.grid.toolbar.addAll":"添加所有用戶",
"system.shared.selectUser.grid.toolbar.addAll.tip":"您确定要添加所有用戶嗎?",
"system.shared.selectUser.grid.toolbar.removeAll":"移除所有用戶",
"system.shared.selectUser.grid.toolbar.removeAll.tip":"您确定要移除所有用戶嗎?",
"system.shared.selectUser.dialog.title": "選擇用戶",
"system.shared.selectUser.dialog.grid.title": "可選用戶列表",
"system.shared.selectRole.grid.title": "角色列表",
"system.shared.selectRole.grid.toolbar.add":"添加角色",
"system.shared.selectRole.grid.toolbar.remove":"移除角色",
"system.shared.selectRole.grid.toolbar.remove.tip":"您确定要移除角色嗎?",
"system.shared.selectRole.grid.toolbar.addAll":"添加所有角色",
"system.shared.selectRole.grid.toolbar.addAll.tip":"您确定要添加所有角色嗎?",
"system.shared.selectRole.grid.toolbar.removeAll":"移除所有角色",
"system.shared.selectRole.grid.toolbar.removeAll.tip":"您确定要移除所有角色嗎?",
"system.shared.selectRole.dialog.title": "選擇角色",
"system.shared.selectRole.dialog.grid.title": "可選角色列表",
"system.shared.selectOrg.grid.title": "機構樹",
"system.shared.selectOrg.grid.toolbar.save":"保存",
"system.shared.selectOrg.grid.toolbar.save.tip":"您确定要更新機構吗?",
"system.shared.selectMenu.grid.title": "菜單树",
"system.shared.selectMenu.grid.toolbar.save":"保存",
"system.shared.selectMenu.grid.toolbar.save.tip":"您确定要更新菜單吗?",
"system.org.gridTitle":"機構樹",
"system.announcement.gridTitle":"公告列表", "system.announcement.gridTitle":"公告列表",
"system.monitor.auditlog.gridTitle":"審計日誌列表", "system.monitor.auditlog.gridTitle":"審計日誌列表",
"system.menu.action.addTop":"新增頂級菜單", "system.menu.action.addTop":"新增頂級菜單",
"system.menu.action.addChild":"新增子菜單", "system.menu.action.addChild":"新增子菜單",
"system.announcementManager.grid.title":"公告列表",
"system.notification.grid.title":"消息列表",
"system.corporation.action.addTop":"新增頂級法人", "system.corporation.action.addTop":"新增頂級法人",
"system.corporation.action.addChild":"新增子法人", "system.corporation.action.addChild":"新增子法人",

78
io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json

@ -10,7 +10,7 @@
"menu.system.org" : "机构管理", "menu.system.org" : "机构管理",
"menu.system.department" : "部门管理", "menu.system.department" : "部门管理",
"menu.system.menu" : "菜单管理", "menu.system.menu" : "菜单管理",
"menu.system.announcement" : "公告管理", "menu.system.announcementManager" : "公告管理",
"menu.system.notificationManager" : "消息管理", "menu.system.notificationManager" : "消息管理",
"menu.system.parameter" : "参数管理", "menu.system.parameter" : "参数管理",
"menu.system.dictionary" : "数据字典", "menu.system.dictionary" : "数据字典",
@ -21,6 +21,40 @@
"menu.system.monitor.resources" : "系统资源", "menu.system.monitor.resources" : "系统资源",
"menu.system.license" : "许可证管理", "menu.system.license" : "许可证管理",
"system.shared.selectUser.grid.title": "用户列表",
"system.shared.selectUser.grid.toolbar.add":"添加用户",
"system.shared.selectUser.grid.toolbar.remove":"移除用户",
"system.shared.selectUser.grid.toolbar.remove.tip":"您确定要移除用户吗?",
"system.shared.selectUser.grid.toolbar.addAll":"添加所有用户",
"system.shared.selectUser.grid.toolbar.addAll.tip":"您确定要添加所有用户吗?",
"system.shared.selectUser.grid.toolbar.removeAll":"移除所有用户",
"system.shared.selectUser.grid.toolbar.removeAll.tip":"您确定要移除所有用户吗?",
"system.shared.selectUser.dialog.title": "选择用户",
"system.shared.selectUser.dialog.grid.title": "可选用户列表",
"system.shared.selectRole.grid.title": "角色列表",
"system.shared.selectRole.grid.toolbar.add":"添加角色",
"system.shared.selectRole.grid.toolbar.remove":"移除角色",
"system.shared.selectRole.grid.toolbar.remove.tip":"您确定要移除角色吗?",
"system.shared.selectRole.grid.toolbar.addAll":"添加所有角色",
"system.shared.selectRole.grid.toolbar.addAll.tip":"您确定要添加所有角色吗?",
"system.shared.selectRole.grid.toolbar.removeAll":"移除所有角色",
"system.shared.selectRole.grid.toolbar.removeAll.tip":"您确定要移除所有角色吗?",
"system.shared.selectRole.dialog.title": "选择角色",
"system.shared.selectRole.dialog.grid.title": "可选角色列表",
"system.shared.selectOrg.grid.title": "机构树",
"system.shared.selectOrg.grid.toolbar.save":"保存",
"system.shared.selectOrg.grid.toolbar.save.tip":"您确定要更新机构吗?",
"system.shared.selectMenu.grid.title": "菜单树",
"system.shared.selectMenu.grid.toolbar.save":"保存",
"system.shared.selectMenu.grid.toolbar.save.tip":"您确定要更新菜单吗?",
"system.corporation.grid.title":"法人树",
"system.corporation.grid.toolbar.addTop":"新增顶级法人",
"system.corporation.grid.toolbar.addChild":"新增子法人",
"system.user.grid.title":"用户列表", "system.user.grid.title":"用户列表",
"system.user.grid.toolbar.setPassword":"设置密码", "system.user.grid.toolbar.setPassword":"设置密码",
"system.user.grid.toolbar.setAllPassword":"设置所有密码", "system.user.grid.toolbar.setAllPassword":"设置所有密码",
@ -28,46 +62,30 @@
"system.user.grid.toolbar.resetPassword.tip":"您确定要重置用户密码吗?", "system.user.grid.toolbar.resetPassword.tip":"您确定要重置用户密码吗?",
"system.user.grid.toolbar.resetAllPassword":"重置所有密码", "system.user.grid.toolbar.resetAllPassword":"重置所有密码",
"system.user.grid.toolbar.resetAllPassword.tip":"您确定要重置所有用户密码吗?", "system.user.grid.toolbar.resetAllPassword.tip":"您确定要重置所有用户密码吗?",
"system.user.selectRole.grid.title":"角色列表",
"system.user.selectRole.grid.toolbar.addRole":"添加角色",
"system.user.selectRole.grid.toolbar.addAllRole":"添加所有角色",
"system.user.selectRole.grid.toolbar.addAllRole.tip":"您确定要给用户添加所有角色吗?",
"system.user.selectRole.grid.toolbar.removeRole":"移除角色",
"system.user.selectRole.grid.toolbar.removeRole.tip":"您确定要移除用户的角色吗?",
"system.user.selectRole.grid.toolbar.removeAllRole":"移除所有角色",
"system.user.selectRole.grid.toolbar.removeAllRole.tip":"您确定要将用户的所有角色移除吗?",
"system.user.selectRole.dialog.title":"可选角色列表",
"system.role.grid.title":"角色列表", "system.role.grid.title":"角色列表",
"system.role.selectUser.grid.title":"用户列表",
"system.role.selectUser.grid.toolbar.addUser":"添加用户",
"system.role.selectUser.grid.toolbar.addAllUser":"添加所有用户",
"system.role.selectUser.grid.toolbar.addAllUser.tip":"您确定要给角色添加所有用户吗?",
"system.role.selectUser.grid.toolbar.removeUser":"移除用户",
"system.role.selectUser.grid.toolbar.removeUser.tip":"您确定要移除角色的用户吗?",
"system.role.selectUser.grid.toolbar.removeAllUser":"移除所有用户",
"system.role.selectUser.grid.toolbar.removeAllUser.tip":"您确定要移除角色的所有用户吗?",
"system.role.selectUser.dialog.title":"可选用户列表",
"system.org.gridTitle":"机构树",
"system.announcement.gridTitle":"公告列表",
"system.monitor.auditlog.gridTitle":"审计日志列表",
"system.org.grid.title":"机构树", "system.org.grid.title":"机构树",
"system.org.grid.toolbar.addTop":"新增顶级机构",
"system.org.grid.toolbar.addChild":"新增子机构",
"system.menu.grid.title":"菜单树",
"system.menu.grid.toolbar.addTop":"新增顶级菜单",
"system.menu.grid.toolbar.addChild":"新增子菜单",
"system.menu.action.addTop":"新增顶级菜单", "system.announcementManager.grid.title":"公告列表",
"system.menu.action.addChild":"新增子菜单",
"system.corporation.action.addTop":"新增顶级法人", "system.notification.grid.title":"消息列表",
"system.corporation.action.addChild":"新增子法人",
"system.announcement.gridTitle":"公告列表",
"system.monitor.auditlog.gridTitle":"审计日志列表",
"system.monitor.log.tab.view":"日志查看", "system.monitor.log.tab.view":"日志查看",
"system.monitor.log.tab.download":"日志下载", "system.monitor.log.tab.download":"日志下载",
"system.monitor.log.tab.level":"日志级别", "system.monitor.log.tab.level":"日志级别",
} }

12
io.sc.platform.system.frontend/src/menus/menus.json

@ -6,7 +6,7 @@
* ROUTE: * ROUTE:
* JAVASCRIPT: Javascript * JAVASCRIPT: Javascript
* URL: url * URL: url
* SEPERATOR: * SEPARATOR:
* order: * order:
* parentId: ID * parentId: ID
* id: ID * id: ID
@ -21,7 +21,7 @@
/*/*/ /*/*/
{"type":"ROUTE", "order":200, "parentId":"menu.system", "id":"menu.system.corporation", "titleI18nKey":"menu.system.corporation", "icon":"bi-share", "routeName":"route.system.corporation", "routeQuery": {"query":"query"}, "authorizeExpression":"T(org.wsp.framework.core.Environment).isEnableMultiCorporation()"}, {"type":"ROUTE", "order":200, "parentId":"menu.system", "id":"menu.system.corporation", "titleI18nKey":"menu.system.corporation", "icon":"bi-share", "routeName":"route.system.corporation", "routeQuery": {"query":"query"}, "authorizeExpression":"T(org.wsp.framework.core.Environment).isEnableMultiCorporation()"},
/*/*/ /*/*/
{"type":"SEPERATOR", "order":300, "parentId":"menu.system"}, {"type":"SEPARATOR", "order":300, "parentId":"menu.system"},
/*/*/ /*/*/
{"type":"ROUTE", "order":400, "parentId":"menu.system", "id":"menu.system.user", "titleI18nKey":"menu.system.user", "icon":"bi-person", "routeName":"route.system.user"}, {"type":"ROUTE", "order":400, "parentId":"menu.system", "id":"menu.system.user", "titleI18nKey":"menu.system.user", "icon":"bi-person", "routeName":"route.system.user"},
/*/*/ /*/*/
@ -33,13 +33,13 @@
/*/*/ /*/*/
{"type":"ROUTE", "order":800, "parentId":"menu.system", "id":"menu.system.menu", "titleI18nKey":"menu.system.menu", "icon":"bi-menu-app", "routeName":"route.system.menu"}, {"type":"ROUTE", "order":800, "parentId":"menu.system", "id":"menu.system.menu", "titleI18nKey":"menu.system.menu", "icon":"bi-menu-app", "routeName":"route.system.menu"},
/*/*/ /*/*/
{"type":"SEPERATOR", "order":900, "parentId":"menu.system"}, {"type":"SEPARATOR", "order":900, "parentId":"menu.system"},
/*/*/ /*/*/
{"type":"ROUTE", "order":1000, "parentId":"menu.system", "id":"menu.system.announcementManager", "titleI18nKey":"menu.system.announcement", "icon":"bi-megaphone", "routeName":"route.system.announcement"}, {"type":"ROUTE", "order":1000, "parentId":"menu.system", "id":"menu.system.announcementManager", "titleI18nKey":"menu.system.announcementManager", "icon":"bi-megaphone", "routeName":"route.system.announcementManager"},
/*/*/ /*/*/
{"type":"ROUTE", "order":1100, "parentId":"menu.system", "id":"menu.system.notificationManager", "titleI18nKey":"menu.system.notificationManager", "icon":"bi-chat-dots", "routeName":"route.system.notificationManager"}, {"type":"ROUTE", "order":1100, "parentId":"menu.system", "id":"menu.system.notificationManager", "titleI18nKey":"menu.system.notificationManager", "icon":"bi-chat-dots", "routeName":"route.system.notificationManager"},
/*/*/ /*/*/
{"type":"SEPERATOR", "order":1200, "parentId":"menu.system"}, {"type":"SEPARATOR", "order":1200, "parentId":"menu.system"},
/*/*/ /*/*/
{"type":"ROUTE", "order":1300, "parentId":"menu.system", "id":"menu.system.parameter", "titleI18nKey":"menu.system.parameter", "icon":"bi-postcard", "routeName":"route.system.parameter"}, {"type":"ROUTE", "order":1300, "parentId":"menu.system", "id":"menu.system.parameter", "titleI18nKey":"menu.system.parameter", "icon":"bi-postcard", "routeName":"route.system.parameter"},
/*/*/ /*/*/
@ -47,7 +47,7 @@
/*/*/ /*/*/
{"type":"ROUTE", "order":1500, "parentId":"menu.system", "id":"menu.system.i18n", "titleI18nKey":"menu.system.i18n", "icon":"bi-globe", "routeName":"route.system.i18n"}, {"type":"ROUTE", "order":1500, "parentId":"menu.system", "id":"menu.system.i18n", "titleI18nKey":"menu.system.i18n", "icon":"bi-globe", "routeName":"route.system.i18n"},
/*/*/ /*/*/
{"type":"SEPERATOR", "order":1600, "parentId":"menu.system"}, {"type":"SEPARATOR", "order":1600, "parentId":"menu.system"},
/*/*/ /*/*/
{"type":"GROUP", "order":1700, "parentId":"menu.system", "id":"menu.system.monitor", "titleI18nKey":"menu.system.monitor", "icon":"bi-speedometer2"}, {"type":"GROUP", "order":1700, "parentId":"menu.system", "id":"menu.system.monitor", "titleI18nKey":"menu.system.monitor", "icon":"bi-speedometer2"},
/*//*/ /*//*/

22
io.sc.platform.system.frontend/src/routes/routes.json

@ -11,6 +11,12 @@
"meta": { "meta": {
"permissions": [ "permissions": [
"/system/corporation/**/*" "/system/corporation/**/*"
],
"actions": [
{"name":"query", "i18nKey":"query", "permissions":[{"method": "GET", "matcher": "/api/system/corporation"}]},
{"name":"add", "i18nKey":"add", "permissions":[{"method": "POST", "matcher": "/api/system/corporation"}]},
{"name":"remove", "i18nKey":"remove", "permissions":[{"method": "DELETE", "matcher": "/api/system/corporation"}]},
{"name":"edit", "i18nKey":"edit", "permissions":[{"method": "PUT", "matcher": "/api/system/corporation"}]}
] ]
} }
}, },
@ -66,7 +72,7 @@
"priority": 0, "priority": 0,
"module": "io.sc.platform.system.frontend", "module": "io.sc.platform.system.frontend",
"component": "component.system.Department", "component": "component.system.Department",
"componentPath":"@/views/Department.vue", "componentPath":"@/views/department/Department.vue",
"redirect": null, "redirect": null,
"meta": { "meta": {
"permissions": [ "permissions": [
@ -90,13 +96,13 @@
} }
}, },
{ {
"name": "route.system.announcement", "name": "route.system.announcementManager",
"path": "system/announcement", "path": "system/announcementManager",
"parent": "/", "parent": "/",
"priority": 0, "priority": 0,
"module": "io.sc.platform.system.frontend", "module": "io.sc.platform.system.frontend",
"component": "component.system.announcement", "component": "component.system.announcementManager",
"componentPath":"@/views/announcement/Announcement.vue", "componentPath":"@/views/announcement/AnnouncementManager.vue",
"redirect": null, "redirect": null,
"meta": { "meta": {
"permissions": [ "permissions": [
@ -111,7 +117,7 @@
"priority": 0, "priority": 0,
"module": "io.sc.platform.system.frontend", "module": "io.sc.platform.system.frontend",
"component": "component.system.NotificationManager", "component": "component.system.NotificationManager",
"componentPath":"@/views/NotificationManager.vue", "componentPath":"@/views/notification/NotificationManager.vue",
"redirect": null, "redirect": null,
"meta": { "meta": {
"permissions": [ "permissions": [
@ -216,7 +222,7 @@
"priority": 0, "priority": 0,
"module": "io.sc.platform.system.frontend", "module": "io.sc.platform.system.frontend",
"component": "component.system.License", "component": "component.system.License",
"componentPath":"@/views/License.vue", "componentPath":"@/views/license/License.vue",
"redirect": null, "redirect": null,
"meta": { "meta": {
"permissions": [ "permissions": [
@ -224,4 +230,4 @@
] ]
} }
} }
] ]

4
io.sc.platform.system.frontend/src/views/AnnouncementManager.vue

@ -1,4 +0,0 @@
<template>
<div>AnnouncementManager</div>
</template>
<script setup lang="ts"></script>

4
io.sc.platform.system.frontend/src/views/I18n.vue

@ -1,4 +0,0 @@
<template>
<div>I18n</div>
</template>
<script setup lang="ts"></script>

4
io.sc.platform.system.frontend/src/views/Log.vue

@ -1,4 +0,0 @@
<template>
<div>Log</div>
</template>
<script setup lang="ts"></script>

4
io.sc.platform.system.frontend/src/views/Menu.vue

@ -1,4 +0,0 @@
<template>
<div>Menu</div>
</template>
<script setup lang="ts"></script>

4
io.sc.platform.system.frontend/src/views/NotificationManager.vue

@ -1,4 +0,0 @@
<template>
<div>NotificationManager</div>
</template>
<script setup lang="ts"></script>

4
io.sc.platform.system.frontend/src/views/Org.vue

@ -1,4 +0,0 @@
<template>
<div>User</div>
</template>
<script setup lang="ts"></script>

4
io.sc.platform.system.frontend/src/views/Role.vue

@ -1,4 +0,0 @@
<template>
<div>Role</div>
</template>
<script setup lang="ts"></script>

59
io.sc.platform.system.frontend/src/views/announcement/AnnouncementManager.vue

@ -0,0 +1,59 @@
<template>
<w-grid
ref="announcementGridRef"
:title="$t('system.announcementManager.grid.title')"
selection="multiple"
:data-url="Environment.apiContextPath('/api/system/announcement')"
:pagination="{
sortBy: 'lastModifyDate',
descending: true,
}"
:query-form-fields="[
{ name: 'title', label: $t('title'), type: 'text' },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum), queryOperator: 'equals' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'export']"
:columns="[
{ width: 300, name: 'title', label: $t('title') },
{ width: '100%', name: 'content', label: $t('content') },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
]"
:editor="{
dialog: {
width: '600px',
height: '380px',
},
form: {
colsNum: 1,
fields: [
{ name: 'title', label: $t('title'), type: 'text', required: true },
{ name: 'content', label: $t('content'), type: 'q-editor', required: true, minHeight: '10rem' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'title', label: $t('title') },
{ name: 'content', label: $t('content') },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</template>
<script setup lang="ts">
import { Environment, EnumTools, Options, Formater } from 'platform-core';
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
</script>

76
io.sc.platform.system.frontend/src/views/announcement/WEditor.vue

@ -0,0 +1,76 @@
<template>
<q-editor v-model="editor" min-height="5rem" v-bind="attrs" />
</template>
<script setup lang="ts">
import { ref, computed, defineProps, useAttrs } from 'vue';
import { FormValidators } from 'platform-core';
const editor = ref();
const textareaRef = ref();
const attrs = useAttrs();
const inRules = attrs.rules;
const props = defineProps({
hideIf: {
type: Function,
default: () => {
return false;
},
},
required: {
type: Boolean,
default: false,
},
requiredIf: {
type: Function,
default: undefined,
},
readonlyIf: {
type: Function,
default: () => {
return false;
},
},
disableIf: {
type: Function,
default: () => {
return false;
},
},
form: {
type: Object,
default: undefined,
},
});
const rulesComputed = computed(() => {
let rules = inRules || <any>[];
if (!hideIfComputed.value && requiredIfComputed.value) {
rules.push(FormValidators.required());
} else if (hideIfComputed.value) {
rules = [];
}
if (textareaRef?.value) {
textareaRef.value.resetValidation();
}
return rules;
});
const hideIfComputed = computed(() => {
return props.hideIf(props.form);
});
const requiredIfComputed = computed(() => {
if (props.requiredIf) {
return props.requiredIf(props.form) || false;
} else if (props.required) {
return true;
}
return false;
});
const readonlyIfComputed = computed(() => {
return props.readonlyIf(props.form);
});
const disableIfComputed = computed(() => {
return props.disableIf(props.form);
});
</script>

176
io.sc.platform.system.frontend/src/views/corporation/Corporation.vue

@ -1,54 +1,144 @@
<template> <template>
<div> <q-splitter :model-value="65" class="w-full h-full">
<w-tree-grid ref="corporationTreeGridRef" title="法人树" label-key="name" :actions="corporationConfigure.actions" /> <template #before>
</div> <div class="pr-1">
<w-grid
ref="corporationTreeGridRef"
:tree="true"
dense-body
:title="$t('system.corporation.grid.title')"
:data-url="Environment.apiContextPath('/api/system/corporation')"
selection="multiple"
:checkbox-selection="false"
:pageable="false"
:full-screen-button="false"
:tree-icon="
(row) => {
return { name: 'folder', color: 'amber' };
}
"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['refresh', 'separator', ['addTop', 'addChild'], 'edit', 'remove', 'separator', 'view']"
:columns="[
{ width: 250, name: 'name', label: $t('name') },
{ name: 'code', label: $t('code') },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
{ width: 100, name: 'enable', label: $t('status'), format: Formater.enableTag() },
]"
:editor="{
dialog: {
width: '600px',
height: '300px',
},
form: {
colsNum: 1,
fields: [
{ name: 'code', label: $t('code'), type: 'text', required: true },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 },
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
],
},
}"
: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: (value) => value },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: (value) => value },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: (value) => value },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedCorporationCode = row.code;
userGridRef?.refresh();
}
"
></w-grid>
</div>
</template>
<template #after>
<div class="pl-1">
<SelectUserGrid
ref="userGridRef"
:fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByCorporation')"
:fetch-other-data-url="Environment.apiContextPath('/api/system/user/queryOtherUsersByCorporation')"
foreign-key="corporationCode"
:foreign-value="currentSelectedCorporationCode"
@add="add"
@remove="remove"
@add-all="addAll"
@remove-all="removeAll"
>
</SelectUserGrid>
</div>
</template>
</q-splitter>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, toRaw } from 'vue'; import { ref } from 'vue';
import { useRoute } from 'vue-router'; import { axios, Environment, Formater, EnumTools } from 'platform-core';
import { useI18n } from 'vue-i18n'; import SelectUserGrid from '../shared/SelectUserGrid.vue';
import { Environment, axios } from 'platform-core';
const route = useRoute(); const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
console.log(toRaw(route));
const { t } = useI18n();
const corporationTreeGridRef = ref(); const corporationTreeGridRef = ref();
const userGridRef = ref();
const currentSelectedCorporationCode = ref('');
const corporationConfigure = { const add = (ids: string[], gridComponent, dialogComponent) => {
actions: [ axios
{ .post(Environment.apiContextPath('/api/system/corporation/addUsers'), {
name: 'refresh', one: corporationTreeGridRef.value.getSelectedRows()[0].code,
label: t('refresh'), many: ids,
click: () => {}, })
}, .then(() => {
gridComponent?.refresh();
dialogComponent?.close();
});
};
const remove = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/corporation/removeUsers'), {
one: corporationTreeGridRef.value.getSelectedRows()[0].code,
many: ids,
})
.then(() => {
gridComponent?.refresh();
});
};
{ const addAll = (gridComponent) => {
name: 'addRoot', axios
label: t('system.corporation.action.addTop'), .post(Environment.apiContextPath('/api/system/corporation/addAllUsers'), {
click: () => {}, one: corporationTreeGridRef.value.getSelectedRows()[0].code,
}, many: [],
{ })
name: 'addChild', .then(() => {
label: t('system.corporation.action.addChild'), gridComponent?.refresh();
click: () => {}, });
},
{
name: 'edit',
label: t('edit'),
click: () => {},
},
{
name: 'delete',
label: t('delete'),
click: () => {},
},
],
}; };
onMounted(() => { const removeAll = (gridComponent) => {
axios.get(Environment.apiContextPath('/api/system/corporation?pageable=false&sortBy=name')).then((response) => { axios
corporationTreeGridRef.value.setNodes(response.data.content); .post(Environment.apiContextPath('/api/system/corporation/removeAllUsers'), {
}); one: corporationTreeGridRef.value.getSelectedRows()[0].code,
}); many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
</script> </script>

0
io.sc.platform.system.frontend/src/views/Department.vue → io.sc.platform.system.frontend/src/views/department/Department.vue

0
io.sc.platform.system.frontend/src/views/License.vue → io.sc.platform.system.frontend/src/views/license/License.vue

513
io.sc.platform.system.frontend/src/views/menu/Menu.vue

@ -1,332 +1,255 @@
<template> <template>
<q-splitter :model-value="70" class="w-full h-full"> <q-splitter :model-value="60" class="w-full h-full">
<template #before> <template #before>
<w-tree-grid <div class="pr-1">
ref="menuTreeGridRef" <w-grid
title="菜单树" ref="menuTreeGridRef"
label-key="titleI18nKey" :tree="true"
label-i18n dense-body
label-empty="--------------------" :title="$t('system.menu.grid.title')"
:actions="menuConfigure.actions" :data-url="Environment.apiContextPath('/api/system/menu')"
tick-strategy="none" selection="multiple"
@update:selected="menuSelected" :checkbox-selection="false"
/> :pageable="false"
:full-screen-button="false"
:tree-icon="
(row) => {
if (row.type === 'SEPARATOR') {
return { name: 'bi-dash-lg' };
} else if (row.type === 'ROUTE_ACTION') {
return { name: 'sym_o_crop_16_9' };
} else {
return { name: row.icon };
}
}
"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
'refresh',
'separator',
['addTop', 'addChild'],
'edit',
'remove',
'separator',
{
name: 'import',
label: $t('import'),
click: () => {},
},
'separator',
'view',
'export',
]"
:columns="[
{
width: '100%',
name: 'titleI18nKey',
label: $t('name'),
sortable: false,
format: (value, row) => {
if (row.type === 'SEPARATOR') {
return `<hr style='width:100px'/>`;
} else if (row.type === 'ROUTE_ACTION') {
return $t(row.i18nKey);
} else {
return $t(value);
}
},
},
{ name: 'type', label: $t('type'), sortable: false, format: Formater.menuType() },
{ name: 'order', label: $t('order'), align: 'right', sortable: false },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), sortable: false, format: Formater.enum(DataComeFromEnum) },
{ name: 'lastModifier', label: $t('lastModifier'), sortable: false },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), sortable: false, format: Formater.dateOnly() },
{ width: 100, name: 'enable', label: $t('status'), sortable: false, format: Formater.enableTag() },
]"
:editor="{
dialog: {
width: '600px',
height: '550px',
},
form: {
colsNum: 1,
fields: [
{ name: 'type', label: $t('type'), type: 'select', required: true, options: Options.enum(MenuTypeEnum, false) },
{ name: 'titleI18nKey', label: $t('titleI18nKey'), type: 'text', required: true },
{ name: 'icon', label: $t('icon'), type: 'text' },
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
{ name: 'order', label: $t('order'), type: 'text' },
{
name: 'javaScript',
label: $t('javascript'),
type: 'text',
enableIf: (row) => {
console.log(row);
},
},
{ name: 'routeName', label: $t('routeName'), type: 'text' },
{ name: 'routeQuery', label: $t('routeQuery'), type: 'text' },
{ name: 'url', label: $t('url'), type: 'text' },
{
name: 'urlOpenType',
label: $t('urlOpenType'),
type: 'select',
options: Options.enum(UrlOpenTypeEnum, false),
defaultValue: 'NEW_WINDOW',
},
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'type', label: $t('type') },
{ name: 'name', label: $t('name') },
{ name: 'titleI18nKey', label: $t('titleI18nKey') },
{ name: 'icon', label: $t('icon') },
{ name: 'enable', label: $t('enable') },
{ name: 'order', label: $t('order') },
{ name: 'javaScript', label: $t('javaScript') },
{ name: 'url', label: $t('url') },
{ name: 'urlOpenType', label: $t('urlOpenType') },
{ name: 'routeName', label: $t('routeName') },
{ name: 'routeQuery', label: $t('routeQuery') },
{ 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') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedMenuId = row.id;
roleGridRef?.refresh();
orgTreeGridRef?.refresh();
}
"
></w-grid>
</div>
</template> </template>
<template #after> <template #after>
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> <div class="pl-1">
<q-tab name="role" icon="bi-diagram-3" :label="$t('role')" /> <q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0">
<q-tab name="org" icon="bi-people" :label="$t('org')" /> <q-tab name="role" icon="bi-diagram-3" :label="$t('role')" />
</q-tabs> <q-tab name="org" icon="bi-people" :label="$t('org')" />
</q-tabs>
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> <q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive>
<q-tab-panel name="user"> <q-tab-panel name="role" class="px-0">
<platform-grid <SelectRoleGrid
ref="roleGridRef" ref="roleGridRef"
:table-props="{ borderded: false, flat: true }" :fetch-data-url="Environment.apiContextPath('/api/system/role/queryRolesByMenu')"
:query-form-cols-number="roleConfigure.queryFormColsNumber" :fetch-other-data-url="Environment.apiContextPath('/api/system/role/queryOtherRolesByMenu')"
:hide-bottom="roleConfigure.hideBottom" foreign-key="menuId"
:query-form-cols-auto="roleConfigure.queryFormColsAuto" :foreign-value="currentSelectedMenuId"
:table-title="roleConfigure.tableTitle" @add="add"
:table-row-key="roleConfigure.tableRowKey" @remove="remove"
:table-init-load-data="roleConfigure.tableInitLoadData" @add-all="addAll"
:table-data-url="roleConfigure.tableDataUrl" @remove-all="removeAll"
:table-show-sort-no="false" ></SelectRoleGrid>
:table-columns="roleConfigure.tableColumns" </q-tab-panel>
:table-left-column-sticky-number="roleConfigure.tableLeftColumnStickyNumber"
:table-buttons="roleConfigure.tableButtons"
:query-form-fields="roleConfigure.queryFormFields"
:table-pagination="roleConfigure.tablePagination"
table-selection="multiple"
:table-dense="false"
>
</platform-grid>
</q-tab-panel>
<q-tab-panel name="org"> <q-tab-panel name="org" class="px-0">
<w-tree-grid <SelectOrgTreeGrid
ref="orgTreeGridRef" ref="orgTreeGridRef"
title="机构树" :fetch-data-url="Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByMenu')"
label-key="titleI18nKey" foreign-key="menuId"
label-i18n :foreign-value="currentSelectedMenuId"
label-empty="--------------------" @update="update"
:actions="orgConfigure.actions" ></SelectOrgTreeGrid>
/> </q-tab-panel>
</q-tab-panel> </q-tab-panels>
</q-tab-panels> </div>
</template> </template>
<SelectRoleDialog ref="selectRoleDialog" title="可选角色列表" :maximized="false" width="50%" height="500px"></SelectRoleDialog>
<AddTopMenuDialog ref="addTopMenuDialog" title="菜单" :maximized="false" width="50%" height="340px"></AddTopMenuDialog> <AddTopMenuDialog ref="addTopMenuDialog" title="菜单" :maximized="false" width="50%" height="340px"></AddTopMenuDialog>
<AddMenuDialog ref="addMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></AddMenuDialog> <AddMenuDialog ref="addMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></AddMenuDialog>
<EditMenuDialog ref="editMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></EditMenuDialog> <EditMenuDialog ref="editMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></EditMenuDialog>
</q-splitter> </q-splitter>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { Environment, axios, EnumTools, Formater, Options } from 'platform-core';
import { useQuasar } from 'quasar'; import SelectRoleGrid from '../shared/SelectRoleGrid.vue';
import { Environment, axios } from 'platform-core'; import SelectOrgTreeGrid from '../shared/SelectOrgTreeGrid.vue';
import SelectRoleDialog from './SelectRoleDialog.vue';
import AddTopMenuDialog from './AddTopMenuDialog.vue'; import AddTopMenuDialog from './AddTopMenuDialog.vue';
import AddMenuDialog from './AddMenuDialog.vue'; import AddMenuDialog from './AddMenuDialog.vue';
import EditMenuDialog from './EditMenuDialog.vue'; import EditMenuDialog from './EditMenuDialog.vue';
const { t } = useI18n(); const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
const quasar = useQuasar(); const MenuTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.MenuType');
const UrlOpenTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.UrlOpenType');
console.log(Options.enum(UrlOpenTypeEnum, false));
const menuTreeGridRef = ref(); const menuTreeGridRef = ref();
const roleGridRef = ref(); const roleGridRef = ref();
const orgTreeGridRef = ref(); const orgTreeGridRef = ref();
const selectRoleDialog = ref(); const selectedTabRef = ref('role');
const currentSelectedMenuId = ref('');
const addTopMenuDialog = ref(); const addTopMenuDialog = ref();
const addMenuDialog = ref(); const addMenuDialog = ref();
const editMenuDialog = ref(); const editMenuDialog = ref();
const selectedTabRef = ref('user');
let selectedMenuId = '';
const roleConfigure = { const add = (ids: string[], gridComponent, dialogComponent) => {
queryFormColsNumber: 4, axios
queryFormColsAuto: false, .post(Environment.apiContextPath('/api/system/menu/addRoles'), {
queryFormFields: [], one: menuTreeGridRef.value.getSelectedRows()[0].id,
hideBottom: true, many: ids,
tableInitLoadData: false, })
tableLeftColumnStickyNumber: 0, .then(() => {
tableTitle: t('system.role.gridTitle'), gridComponent?.refresh();
tableRowKey: 'id', dialogComponent?.close();
tableDataUrl: '', });
tablePagination: {
sortBy: 'lastModifyDate',
descending: true,
reqPageStart: 0,
rowsPerPage: 0,
},
tableButtons: [
'refresh',
'inFullscreen',
{
name: 'addRole',
label: t('system.role.action.addRole'),
icon: '',
enable: () => {},
click: () => {
selectRoleDialog.value.show({ roleGridRef: roleGridRef, menuTreeGridRef: menuTreeGridRef });
},
},
{
name: 'addAllRole',
label: t('system.role.action.addAllRole'),
icon: '',
enable: () => {},
click: () => {
const menuId = menuTreeGridRef.value.getSelected();
axios
.post(Environment.apiContextPath('/api/system/menu/addAllRoles'), {
source: menuId,
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId),
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId),
targets: [],
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => {
roleGridRef.value.replaceRowsFun(response.data.content);
});
});
},
},
{
name: 'removeRole',
label: t('system.role.action.removeRole'),
icon: '',
enable: () => {},
click: () => {
const menuId = menuTreeGridRef.value.getSelected();
const roleIds = [];
for (const role of roleGridRef.value.getSelectedRows()) {
roleIds.push(role.id);
}
axios
.post(Environment.apiContextPath('/api/system/menu/removeRoles'), {
source: menuId,
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId),
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId),
targets: roleIds,
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => {
roleGridRef.value.replaceRowsFun(response.data.content);
});
});
},
},
{
name: 'removeAllRole',
label: t('system.role.action.removeAllRole'),
icon: '',
enable: () => {},
click: () => {
const menuId = menuTreeGridRef.value.getSelected();
axios
.post(Environment.apiContextPath('/api/system/menu/removeAllRoles'), {
source: menuId,
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId),
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId),
targets: [],
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => {
roleGridRef.value.replaceRowsFun(response.data.content);
});
});
},
},
],
tableColumns: [
{ width: 100, name: 'code', label: t('code') },
{ width: 100, name: 'name', label: t('name') },
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) },
],
}; };
const menuConfigure = { const remove = (ids, gridComponent) => {
actions: [ axios
{ .post(Environment.apiContextPath('/api/system/menu/removeRoles'), {
name: 'refresh', one: menuTreeGridRef.value.getSelectedRows()[0].id,
label: t('refresh'), many: ids,
enable: () => { })
return true; .then(() => {
}, gridComponent?.refresh();
click: () => { });
refresh();
},
},
{
name: 'addRoot',
label: t('system.menu.action.addTop'),
enable: () => {
return true;
},
click: () => {
addTopMenuDialog.value.show(refresh);
},
},
{
name: 'addChild',
label: t('system.menu.action.addChild'),
enable: () => {
return true;
},
click: () => {
const node = menuTreeGridRef.value.getNodeById(selectedMenuId);
if (node && node.type === 'GROUP') {
addMenuDialog.value.show(selectedMenuId, refresh);
} else {
quasar
.dialog({
title: '提示',
message: '请在菜单组中添加子菜单',
persistent: true,
})
.onOk(() => {});
}
},
},
{
name: 'edit',
label: t('edit'),
enable: () => {
return true;
},
click: () => {
const node = menuTreeGridRef.value.getNodeById(selectedMenuId);
if (node && node.type === 'ROUTE') {
editMenuDialog.value.show(menuTreeGridRef.value.getNodeById(selectedMenuId), refresh);
} else {
quasar
.dialog({
title: '提示',
message: '请选择一个菜单项',
persistent: true,
})
.onOk(() => {});
}
},
},
{
name: 'delete',
label: t('delete'),
enable: () => {
return true;
},
click: () => {
const node = menuTreeGridRef.value.getNodeById(selectedMenuId);
if (node) {
quasar
.dialog({
title: t('confirm'),
message: '您确定要删除该菜单吗?',
cancel: true,
persistent: true,
})
.onOk(() => {
axios.delete(Environment.apiContextPath('/api/system/menu/' + selectedMenuId)).then((response) => {
refresh();
});
});
} else {
quasar
.dialog({
title: '提示',
message: '请选择一个菜单项',
persistent: true,
})
.onOk(() => {});
}
},
},
],
}; };
const orgConfigure = { const addAll = (gridComponent) => {
actions: [ axios
{ .post(Environment.apiContextPath('/api/system/menu/addAllRoles'), {
name: 'save', one: menuTreeGridRef.value.getSelectedRows()[0].id,
label: '保存', many: [],
click: () => { })
const orgId = menuTreeGridRef.value.getSelected()[0]; .then(() => {
axios gridComponent?.refresh();
.post(Environment.apiContextPath('/api/system/menu/updateOrgs'), { });
one: orgId,
many: menuTreeGridRef.value.getTicked(),
})
.then((response) => {});
},
},
],
}; };
const menuSelected = (target) => { const removeAll = (gridComponent) => {
selectedMenuId = target; axios
if (roleGridRef.value) { .post(Environment.apiContextPath('/api/system/menu/removeAllRoles'), {
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + selectedMenuId).then((response) => { one: menuTreeGridRef.value.getSelectedRows()[0].id,
roleGridRef.value.replaceRowsFun(response.data.content); many: [],
})
.then(() => {
gridComponent?.refresh();
}); });
}
// if (orgTreeGridRef.value) {
// axios.get(Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByMenu?menuId=') + selectedMenuId).then((response) => {
// orgTreeGridRef.value.setNodes(response.data);
// });
// }
}; };
const refresh = () => { const update = (ids, gridComponent) => {
axios.get(Environment.apiContextPath('/api/system/menu?pageable=false&sortBy=order')).then((response) => { axios
menuTreeGridRef.value.setNodes(response.data.content); .post(Environment.apiContextPath('/api/system/menu/updateOrgs'), {
}); one: menuTreeGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent.refresh();
});
}; };
onMounted(() => {
refresh();
});
</script> </script>

212
io.sc.platform.system.frontend/src/views/menu/SelectRoleDialog.vue

@ -1,155 +1,105 @@
<template> <template>
<div> <w-dialog
<q-dialog ref="dialogRef" allow-focus-outside v-bind="attrs"> ref="dialogRef"
<q-card :title="$t('system.selectRoleByUserDialog.title')"
:style="{ width="800px"
width: attrs.maximized ? '100vw' : width, height="500px"
'max-width': '100vw', :can-maximize="false"
height: attrs.maximized ? '100vh' : height, :buttons="[
'max-height': '100vh', {
}" label: $t('confirm'),
> click: () => {
<q-card-section :style="headerStyle"> const roleIds = Tools.extractProperties(gridRef.getSelectedRows(), 'id');
<div class="flex justify-between"> axios
<div class="text-h6">{{ title }}</div> .post(Environment.apiContextPath('/api/system/user/addRoles'), {
<div class="flex justify-end q-gutter-md"> one: parentId,
<q-btn :label="$t('confirm')" dense color="primary" style="width: 100px" @click="addRoles" /> many: roleIds,
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn> })
</div> .then((response) => {
</div> parentComponent?.refresh();
</q-card-section> close();
<q-card-section class="q-pt-none" :style="bodyStyle"> });
<platform-grid },
ref="gridRef" },
:table-props="{ borderded: false, flat: true }" ]"
:query-form-cols-number="roleConfigure.queryFormColsNumber" >
:hide-bottom="roleConfigure.hideBottom" <div class="px-2">
:query-form-cols-auto="roleConfigure.queryFormColsAuto" <w-grid
:table-title="roleConfigure.tableTitle" ref="gridRef"
:table-row-key="roleConfigure.tableRowKey" :title="$t('system.role.grid.title')"
:table-init-load-data="roleConfigure.tableInitLoadData" selection="multiple"
:table-data-url="roleConfigure.tableDataUrl" :full-screen-button="false"
:table-show-sort-no="false" :toolbar-configure="{ noIcon: false }"
:table-columns="roleConfigure.tableColumns" :toolbar-actions="['query', 'refresh']"
:table-left-column-sticky-number="roleConfigure.tableLeftColumnStickyNumber" :query-form-fields="[
:table-buttons="roleConfigure.tableButtons" { name: 'code', label: $t('code'), type: 'text' },
:query-form-fields="roleConfigure.queryFormFields" { name: 'name', label: $t('name'), type: 'text' },
:table-pagination="roleConfigure.tablePagination" {
table-selection="multiple" name: 'enable',
:table-dense="false" label: $t('enable'),
> type: 'select',
</platform-grid> options: Options.yesNo(),
</q-card-section> queryOperator: 'equals',
</q-card> },
</q-dialog> {
</div> name: 'dataComeFrom',
label: $t('dataComeFrom'),
type: 'select',
options: Options.enum(DataComeFromEnum),
queryOperator: 'equals',
},
]"
:auto-fetch-data="false"
:fetch-data-url="Environment.apiContextPath('/api/system/role/queryOtherRolesByUser?userId=' + parentId)"
:columns="[
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{
name: 'status',
label: t('status'),
format: Formater.enableTag(),
},
{ name: 'lastModifier', label: t('lastModifier') },
{ name: 'lastModifyDate', label: t('lastModifyDate') },
]"
></w-grid>
</div>
</w-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useAttrs, ref, onMounted, nextTick } from 'vue'; import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { axios, Environment } from 'platform-core'; import { axios, Environment, Tools, EnumTools, Options, Formater } from 'platform-core';
const attrs = useAttrs();
const props = defineProps({
headerStyle: { type: String, default: 'width:100%;padding: 16px 8px 4px 16px' },
bodyStyle: { type: String, default: 'padding: 0px 8px 0px 8px;height:calc(100%)' },
title: { type: String, default: '' },
width: { type: String, default: '70%' },
height: { type: String, default: '70%' },
});
const { t } = useI18n(); const { t } = useI18n();
const dialogRef = ref(); const dialogRef = ref();
const gridRef = ref(); const gridRef = ref();
let menuTreeGridRef, roleGridRef;
const roleConfigure = { let DataComeFromEnum = ref();
queryFormColsNumber: 4, EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom').then((data) => {
queryFormColsAuto: false, DataComeFromEnum.value = data;
hideBottom: true, });
tableInitLoadData: false,
tableLeftColumnStickyNumber: 0,
tableTitle: '',
tableRowKey: 'id',
tableDataUrl: '',
tablePagination: {
sortBy: 'lastModifyDate',
descending: true,
reqPageStart: 0,
rowsPerPage: 0,
},
tableButtons: ['query', 'refresh'],
queryFormFields: [
{ label: t('code'), modelName: 'code', type: 'text' },
{ label: t('name'), modelName: 'name', type: 'text' },
{
label: t('enable'),
modelName: 'enable',
type: 'select',
options: [
{ value: true, label: '是' },
{ value: false, label: '否' },
],
},
{
label: t('dataComeFrom'),
modelName: 'dataComeFrom',
type: 'select',
options: [
{ value: 'MANUAL', label: t('io.sc.platform.orm.api.enums.DataComeFrom.MANUAL') },
{ value: 'AUTO', label: t('io.sc.platform.orm.api.enums.DataComeFrom.AUTO') },
],
},
],
tableColumns: [
{ width: 100, name: 'code', label: t('code') },
{ width: 100, name: 'name', label: t('name') },
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) },
],
};
const addRoles = () => { let parentId, parentComponent;
const menuId = menuTreeGridRef.value.getSelected();
const roleIds = [];
for (const role of gridRef.value.getSelectedRows()) {
roleIds.push(role.id);
}
axios
.post(Environment.apiContextPath('/api/system/menu/addRoles'), {
source: menuId,
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId),
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId),
targets: roleIds,
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => {
roleGridRef.value.replaceRowsFun(response.data.content);
});
dialogRef.value.hide();
});
};
const show = (param: object) => { const open = (param: object) => {
menuTreeGridRef = param.menuTreeGridRef; parentId = param.parentId;
roleGridRef = param.roleGridRef; parentComponent = param.parentComponent;
const currentMenuId = menuTreeGridRef.value.getSelected()[0];
dialogRef.value.show(); dialogRef.value.show();
nextTick(() => { nextTick(() => {
axios.get(Environment.apiContextPath('/api/system/role/queryOtherRolesByMenu?menuId=') + currentMenuId).then((response) => { gridRef.value.refresh();
gridRef.value.replaceRowsFun(response.data.content);
});
}); });
}; };
const hide = () => { const close = () => {
dialogRef.value.hide(); dialogRef.value.hide();
}; };
defineExpose({ defineExpose({
show, open,
hide, close,
}); });
</script> </script>

60
io.sc.platform.system.frontend/src/views/notification/NotificationManager.vue

@ -0,0 +1,60 @@
<template>
<w-grid
ref="notificationGridRef"
:title="$t('system.notification.grid.title')"
selection="multiple"
:data-url="Environment.apiContextPath('/api/system/notification')"
:pagination="{
sortBy: 'lastModifyDate',
descending: true,
}"
:query-form-fields="[
{ name: 'title', label: $t('title'), type: 'text' },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum), queryOperator: 'equals' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'export']"
:columns="[
{ width: 300, name: 'title', label: $t('title') },
{ width: '100%', name: 'content', label: $t('content') },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
]"
:editor="{
dialog: {
width: '600px',
height: '380px',
},
form: {
colsNum: 1,
fields: [
{ name: 'receiver', label: $t('receiver'), type: 'text', required: true },
{ name: 'title', label: $t('title'), type: 'text', required: true },
{ name: 'content', label: $t('content'), type: 'q-editor', required: true, minHeight: '10rem' },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'title', label: $t('title') },
{ name: 'content', label: $t('content') },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</template>
<script setup lang="ts">
import { Environment, EnumTools, Options, Formater } from 'platform-core';
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
</script>

365
io.sc.platform.system.frontend/src/views/org/Org.vue

@ -1,244 +1,175 @@
<template> <template>
<q-splitter :model-value="70" class="w-full h-full"> <q-splitter :model-value="60" class="w-full h-full">
<template #before> <template #before>
<w-tree-grid ref="orgTreeGridRef" title="机构树" label-key="name" :actions="orgConfigure.actions" @update:selected="orgSelected" /> <div class="pr-1">
<w-grid
ref="orgTreeGridRef"
:tree="true"
:title="$t('system.org.grid.title')"
dense-body
:data-url="Environment.apiContextPath('/api/system/org')"
selection="multiple"
:checkbox-selection="false"
:pageable="false"
:tree-icon="
(row) => {
return { name: 'folder', color: 'amber' };
}
"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['refresh', 'separator', ['addTop', 'addChild'], 'edit', 'remove', 'separator', 'view', 'export']"
:columns="[
{ width: '100%', name: 'name', label: $t('name') },
{ width: 200, name: 'code', label: $t('code') },
{ width: 100, name: 'enable', label: $t('status'), sortable: false, format: Formater.enableTag() },
]"
:editor="{
dialog: {
width: '600px',
height: '300px',
},
form: {
colsNum: 1,
fields: [
{ name: 'code', label: $t('code'), type: 'text', required: true },
{ name: 'name', label: $t('name'), type: 'text', required: true },
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 },
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
],
},
}"
: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.yesNo() },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedOrgId = row.id;
userGridRef?.refresh();
menuTreeGridRef?.refresh();
}
"
></w-grid>
</div>
</template> </template>
<template #after> <template #after>
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> <div class="pl-1">
<q-tab name="user" icon="bi-diagram-3" :label="$t('user')" /> <q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0">
<q-tab name="menu" icon="bi-people" :label="$t('menu')" /> <q-tab name="user" icon="bi-diagram-3" :label="$t('user')" />
</q-tabs> <q-tab name="menu" icon="bi-people" :label="$t('menu')" />
</q-tabs>
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> <q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive>
<q-tab-panel name="user"> <q-tab-panel name="user" class="px-0">
<platform-grid <SelectUserGrid
ref="userGridRef" ref="userGridRef"
:table-props="{ borderded: false, flat: true }" :fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByOrg')"
:query-form-cols-number="userConfigure.queryFormColsNumber" :fetch-other-data-url="Environment.apiContextPath('/api/system/user/queryOtherUsersByOrg')"
:hide-bottom="userConfigure.hideBottom" foreign-key="orgId"
:query-form-cols-auto="userConfigure.queryFormColsAuto" :foreign-value="currentSelectedOrgId"
:table-title="userConfigure.tableTitle" @add="add"
:table-row-key="userConfigure.tableRowKey" @remove="remove"
:table-init-load-data="userConfigure.tableInitLoadData" @add-all="addAll"
:table-data-url="userConfigure.tableDataUrl" @remove-all="removeAll"
:table-show-sort-no="false" >
:table-columns="userConfigure.tableColumns" </SelectUserGrid>
:table-left-column-sticky-number="userConfigure.tableLeftColumnStickyNumber" </q-tab-panel>
:table-buttons="userConfigure.tableButtons" <q-tab-panel name="menu" class="px-0">
:query-form-fields="userConfigure.queryFormFields" <SelectMenuTreeGrid
:table-pagination="userConfigure.tablePagination" ref="menuTreeGridRef"
table-selection="multiple" :fetch-data-url="Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByOrg')"
:table-dense="false" foreign-key="orgId"
> :foreign-value="currentSelectedOrgId"
</platform-grid> @update="update"
</q-tab-panel> ></SelectMenuTreeGrid>
</q-tab-panel>
<q-tab-panel name="menu"> </q-tab-panels>
<w-tree-grid </div>
ref="menuTreeGridRef"
title="菜单树"
label-key="titleI18nKey"
label-i18n
label-empty="--------------------"
tick-strategy="leaf"
:actions="menuConfigure.actions"
/>
</q-tab-panel>
</q-tab-panels>
</template> </template>
<SelectUserDialog ref="selectUserDialog" title="可选用户列表" :maximized="false" width="50%" height="500px"></SelectUserDialog>
</q-splitter> </q-splitter>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { Environment, axios, EnumTools, Formater } from 'platform-core';
import { Environment, axios } from 'platform-core'; import SelectUserGrid from '../shared/SelectUserGrid.vue';
import SelectUserDialog from './SelectUserDialog.vue'; import SelectMenuTreeGrid from '../shared/SelectMenuTreeGrid.vue';
const { t } = useI18n(); const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
const orgTreeGridRef = ref(); const orgTreeGridRef = ref();
const userGridRef = ref(); const userGridRef = ref();
const menuTreeGridRef = ref(); const menuTreeGridRef = ref();
const selectUserDialog = ref();
const selectedTabRef = ref('user'); const selectedTabRef = ref('user');
let selectedOrgId = ''; const currentSelectedOrgId = ref('');
const userConfigure = { const add = (ids: string[], gridComponent, dialogComponent) => {
queryFormColsNumber: 4, axios
queryFormColsAuto: false, .post(Environment.apiContextPath('/api/system/org/addUsers'), {
queryFormFields: [], one: orgTreeGridRef.value.getSelectedRows()[0].id,
hideBottom: true, many: ids,
tableInitLoadData: false, })
tableLeftColumnStickyNumber: 0, .then(() => {
tableTitle: t('system.user.gridTitle'), gridComponent?.refresh();
tableRowKey: 'id', dialogComponent?.close();
tableDataUrl: '', });
tablePagination: {
sortBy: 'lastModifyDate',
descending: true,
reqPageStart: 0,
rowsPerPage: 0,
},
tableButtons: [
'refresh',
'inFullscreen',
{
name: 'addUser',
label: t('system.user.action.addUser'),
icon: '',
enable: () => {},
click: () => {
selectUserDialog.value.show({ userGrid: userGridRef, orgTreeGridRef: orgTreeGridRef });
},
},
{
name: 'addAllUser',
label: t('system.user.action.addAllUser'),
icon: '',
enable: () => {},
click: () => {
const orgId = orgTreeGridRef.value.getSelected()[0];
axios
.post(Environment.apiContextPath('/api/system/org/addAllUsers'), {
one: orgId,
many: [],
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => {
userGridRef.value.replaceRowsFun(response.data.content);
});
});
},
},
{
name: 'removeUser',
label: t('system.user.action.removeUser'),
icon: '',
enable: () => {},
click: () => {
const orgId = orgTreeGridRef.value.getSelected()[0];
const userIds = [];
for (const user of userGridRef.value.getSelectedRows()) {
userIds.push(user.id);
}
axios
.post(Environment.apiContextPath('/api/system/org/removeUsers'), {
one: orgId,
many: userIds,
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => {
userGridRef.value.replaceRowsFun(response.data.content);
});
});
},
},
{
name: 'removeAllUser',
label: t('system.user.action.removeAllUser'),
icon: '',
enable: () => {},
click: () => {
const orgId = orgTreeGridRef.value.getSelected()[0];
axios
.post(Environment.apiContextPath('/api/system/org/removeAllUsers'), {
one: orgId,
many: [],
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => {
userGridRef.value.replaceRowsFun(response.data.content);
});
});
},
},
],
tableColumns: [
{ width: 100, name: 'loginName', label: t('loginName') },
{ width: 100, name: 'userName', label: t('userName') },
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) },
],
}; };
const orgConfigure = { const remove = (ids, gridComponent) => {
actions: [ axios
/* .post(Environment.apiContextPath('/api/system/org/removeUsers'), {
{ one: orgTreeGridRef.value.getSelectedRows()[0].id,
name: 'refresh', many: ids,
label: t('refresh'), })
click: () => {}, .then(() => {
}, gridComponent?.refresh();
{ });
name: 'expandAll',
label: t('expandAll'),
click: () => {},
},
{
name: 'selectAll',
label: t('selectAll'),
click: () => {},
},
*/
{
name: 'addRoot',
label: t('添加顶级机构'),
click: () => {},
},
{
name: 'addChild',
label: t('添加子机构'),
click: () => {},
},
{
name: 'edit',
label: t('edit'),
click: () => {},
},
{
name: 'delete',
label: t('delete'),
click: () => {},
},
],
}; };
const menuConfigure = { const addAll = (gridComponent) => {
actions: [ axios
{ .post(Environment.apiContextPath('/api/system/org/addAllUsers'), {
name: 'save', one: orgTreeGridRef.value.getSelectedRows()[0].id,
label: '保存', many: [],
click: () => { })
const orgId = orgTreeGridRef.value.getSelected()[0]; .then(() => {
axios gridComponent?.refresh();
.post(Environment.apiContextPath('/api/system/org/updateMenus'), { });
one: orgId,
many: menuTreeGridRef.value.getTicked(),
})
.then((response) => {});
},
},
],
}; };
const orgSelected = (target) => { const removeAll = (gridComponent) => {
selectedOrgId = target; axios
if (userGridRef.value) { .post(Environment.apiContextPath('/api/system/org/removeAllUsers'), {
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + selectedOrgId).then((response) => { one: orgTreeGridRef.value.getSelectedRows()[0].id,
userGridRef.value.replaceRowsFun(response.data.content); many: [],
})
.then(() => {
gridComponent?.refresh();
}); });
}
if (menuTreeGridRef.value) {
axios.get(Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByOrg?orgId=') + selectedOrgId).then((response) => {
menuTreeGridRef.value.setNodes(response.data);
});
}
}; };
onMounted(() => { const update = (ids, gridComponent) => {
axios.get(Environment.apiContextPath('/api/system/org?pageable=false&sortBy=name')).then((response) => { axios
orgTreeGridRef.value.setNodes(response.data.content); .post(Environment.apiContextPath('/api/system/org/updateMenus'), {
}); one: orgTreeGridRef.value.getSelectedRows()[0].id,
}); many: ids,
})
.then(() => {
gridComponent.refresh();
});
};
</script> </script>

154
io.sc.platform.system.frontend/src/views/org/SelectUserDialog.vue

@ -1,154 +0,0 @@
<template>
<div>
<q-dialog ref="dialogRef" allow-focus-outside v-bind="attrs">
<q-card
:style="{
width: attrs.maximized ? '100vw' : width,
'max-width': '100vw',
height: attrs.maximized ? '100vh' : height,
'max-height': '100vh',
}"
>
<q-card-section :style="headerStyle">
<div class="flex justify-between">
<div class="text-h6">{{ title }}</div>
<div class="flex justify-end q-gutter-md">
<q-btn :label="$t('confirm')" dense color="primary" style="width: 100px" @click="addUsers" />
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn>
</div>
</div>
</q-card-section>
<q-card-section class="q-pt-none" :style="bodyStyle">
<platform-grid
ref="gridRef"
:table-props="{ borderded: false, flat: true }"
:query-form-cols-number="userConfigure.queryFormColsNumber"
:hide-bottom="userConfigure.hideBottom"
:query-form-cols-auto="userConfigure.queryFormColsAuto"
:table-title="userConfigure.tableTitle"
:table-row-key="userConfigure.tableRowKey"
:table-init-load-data="userConfigure.tableInitLoadData"
:table-data-url="userConfigure.tableDataUrl"
:table-show-sort-no="false"
:table-columns="userConfigure.tableColumns"
:table-left-column-sticky-number="userConfigure.tableLeftColumnStickyNumber"
:table-buttons="userConfigure.tableButtons"
:query-form-fields="userConfigure.queryFormFields"
:table-pagination="userConfigure.tablePagination"
table-selection="multiple"
:table-dense="false"
>
</platform-grid>
</q-card-section>
</q-card>
</q-dialog>
</div>
</template>
<script setup lang="ts">
import { useAttrs, ref, onMounted, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { axios, Environment } from 'platform-core';
const attrs = useAttrs();
const props = defineProps({
headerStyle: { type: String, default: 'width:100%;padding: 16px 8px 4px 16px' },
bodyStyle: { type: String, default: 'padding: 0px 8px 0px 8px;height:calc(100%)' },
title: { type: String, default: '' },
width: { type: String, default: '70%' },
height: { type: String, default: '70%' },
});
const { t } = useI18n();
const dialogRef = ref();
const gridRef = ref();
let userGridRef, orgTreeGridRef;
const userConfigure = {
queryFormColsNumber: 4,
queryFormColsAuto: false,
hideBottom: true,
tableInitLoadData: false,
tableLeftColumnStickyNumber: 0,
tableTitle: '',
tableRowKey: 'id',
tableDataUrl: '',
tablePagination: {
sortBy: 'lastModifyDate',
descending: true,
reqPageStart: 0,
rowsPerPage: 0,
},
tableButtons: ['query', 'refresh'],
queryFormFields: [
{ label: t('loginName'), modelName: 'loginName', type: 'text' },
{ label: t('userName'), modelName: 'userName', type: 'text' },
{
label: t('enable'),
modelName: 'enable',
type: 'select',
options: [
{ value: true, label: '是' },
{ value: false, label: '否' },
],
},
{
label: t('dataComeFrom'),
modelName: 'dataComeFrom',
type: 'select',
options: [
{ value: 'MANUAL', label: t('io.sc.platform.orm.api.enums.DataComeFrom.MANUAL') },
{ value: 'AUTO', label: t('io.sc.platform.orm.api.enums.DataComeFrom.AUTO') },
],
},
],
tableColumns: [
{ width: 100, name: 'loginName', label: t('loginName') },
{ width: 100, name: 'userName', label: t('userName') },
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) },
],
};
const addUsers = () => {
const orgId = orgTreeGridRef.value.getSelected()[0];
const userIds = [];
for (const user of gridRef.value.getSelectedRows()) {
userIds.push(user.id);
}
axios
.post(Environment.apiContextPath('/api/system/org/addUsers'), {
one: orgId,
many: userIds,
})
.then((response) => {
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => {
userGridRef.value.replaceRowsFun(response.data.content);
});
dialogRef.value.hide();
});
};
const show = (param: object) => {
userGridRef = param.userGrid;
orgTreeGridRef = param.orgTreeGridRef;
const currentOrgId = orgTreeGridRef.value.getSelected()[0];
dialogRef.value.show();
nextTick(() => {
axios.get(Environment.apiContextPath('/api/system/user/queryOtherUsersByOrg?orgId=') + currentOrgId).then((response) => {
gridRef.value.replaceRowsFun(response.data.content);
});
});
};
const hide = () => {
dialogRef.value.hide();
};
defineExpose({
show,
hide,
});
</script>

297
io.sc.platform.system.frontend/src/views/role/Role.vue

@ -1,7 +1,7 @@
<template> <template>
<q-splitter :model-value="60" class="w-full h-full"> <q-splitter :model-value="60" class="w-full h-full">
<template #before> <template #before>
<div class="px-1"> <div class="pr-1">
<w-grid <w-grid
ref="roleGridRef" ref="roleGridRef"
:title="$t('system.role.grid.title')" :title="$t('system.role.grid.title')"
@ -18,7 +18,7 @@
:columns="[ :columns="[
{ name: 'code', label: $t('code') }, { name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') }, { name: 'name', label: $t('name') },
{ width: 80, name: 'status', label: $t('status'), format: Formater.enableTag() }, { width: 80, name: 'enable', label: $t('status'), format: Formater.enableTag() },
{ width: 100, name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, { width: 100, name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ width: 120, name: 'lastModifier', label: $t('lastModifier') }, { width: 120, name: 'lastModifier', label: $t('lastModifier') },
{ width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, { width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
@ -68,200 +68,47 @@
</div> </div>
</template> </template>
<template #after> <template #after>
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0" no-caps> <div class="pl-1">
<q-tab name="menu" icon="bi-people" :label="$t('menu')" /> <q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0" no-caps>
<q-tab name="user" icon="bi-diagram-3" :label="$t('user')" /> <q-tab name="menu" icon="bi-menu-app" :label="$t('menu')" />
</q-tabs> <q-tab name="user" icon="bi-person" :label="$t('user')" />
</q-tabs>
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> <q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive>
<q-tab-panel name="menu" class="px-0"> <q-tab-panel name="menu" class="px-0">
<w-grid <SelectMenuTreeGrid
ref="menuTreeGridRef" ref="menuTreeGridRef"
:tree="true" :fetch-data-url="Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByRole')"
:title="$t('system.org.grid.title')" foreign-key="roleId"
:data-url="Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByRole?roleId=') + currentSelectedRoleId" :foreign-value="currentSelectedRoleId"
selection="multiple" @update="update"
:pageable="false" ></SelectMenuTreeGrid>
:full-screen-button="false" </q-tab-panel>
:toolbar-configure="{ noIcon: true }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'save',
label: $t('save'),
click: () => {
axios
.post(Environment.apiContextPath('/api/system/role/updateMenus'), {
one: userGridRef.getSelectedRows()[0].id,
many: menuTreeGridRef.getTicked(),
})
.then((response) => {});
},
},
'view',
]"
:columns="[
{
width: 100,
name: 'titleI18nKey',
label: $t('name'),
format: (value, row) => {
return $t(value);
},
},
{ width: 60, 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.yesNo() },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</q-tab-panel>
<q-tab-panel name="user" class="px-0"> <q-tab-panel name="user" class="px-0">
<w-grid <SelectUserGrid
ref="userGridRef" ref="userGridRef"
:title="$t('system.role.selectUser.grid.title')" :fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByRole')"
:fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByRole?roleId=') + currentSelectedRoleId" :fetch-other-data-url="Environment.apiContextPath('/api/system/user/queryOtherUsersByRole')"
:auto-fetch-data="false" foreign-key="roleId"
selection="multiple" :foreign-value="currentSelectedRoleId"
:full-screen-button="false" @add="add"
:toolbar-configure="{ noIcon: true }" @remove="remove"
:toolbar-actions="[ @add-all="addAll"
'refresh', @remove-all="removeAll"
'separator', >
{ </SelectUserGrid>
name: 'addUser', </q-tab-panel>
label: $t('system.role.selectUser.grid.toolbar.addUser'), </q-tab-panels>
enableIf: () => { </div>
if (roleGridRef) {
return roleGridRef.getSelectedRows().length > 0;
}
return false;
},
click: () => {
selectUserDialog.open({ roleId: roleGridRef.getSelectedRows()[0].id, userGrid: userGridRef });
},
},
{
name: 'addAllUser',
label: $t('system.role.selectUser.grid.toolbar.addAllUser'),
enableIf: () => {
if (roleGridRef) {
return roleGridRef.getSelectedRows().length > 0;
}
return false;
},
click: () => {
const selectedRole = roleGridRef.getSelectedRows()[0];
DialogManager.confirm($t('system.role.selectUser.grid.toolbar.addAllUser.tip'), () => {
axios
.post(Environment.apiContextPath('/api/system/role/addAllUsers'), {
one: selectedRole.id,
many: [],
})
.then((response) => {
userGridRef?.refresh();
});
});
},
},
'separator',
{
name: 'removeUser',
label: $t('system.role.selectUser.grid.toolbar.removeUser'),
enableIf: () => {
if (roleGridRef && userGridRef) {
return roleGridRef.getSelectedRows().length > 0 && userGridRef.getSelectedRows().length > 0;
}
return false;
},
click: (selecteds) => {
const selectedRole = roleGridRef.getSelectedRows()[0];
const userIds = Tools.extractProperties(selecteds, 'id');
DialogManager.confirm($t('system.role.selectUser.grid.toolbar.removeUser.tip'), () => {
axios
.post(Environment.apiContextPath('/api/system/role/removeUsers'), {
one: selectedRole.id,
many: userIds,
})
.then((response) => {
userGridRef?.refresh();
});
});
},
},
{
name: 'removeAllUser',
label: $t('system.role.selectUser.grid.toolbar.removeAllUser'),
enableIf: () => {
if (roleGridRef) {
return roleGridRef.getSelectedRows().length > 0;
}
return false;
},
click: () => {
const selectedRole = roleGridRef.getSelectedRows()[0];
DialogManager.confirm($t('system.role.selectUser.grid.toolbar.removeAllUser.tip'), () => {
axios
.post(Environment.apiContextPath('/api/system/role/removeAllUsers'), {
one: selectedRole.id,
many: [],
})
.then((response) => {
userGridRef?.refresh();
});
});
},
},
'separator',
'view',
]"
:columns="[
{ width: 100, name: 'loginName', label: t('loginName') },
{ width: 100, name: 'userName', label: t('userName') },
{
name: 'status',
label: $t('status'),
format: (value, row) => {
return {
componentType: UserStatusTag,
attrs: row,
};
},
},
]"
>
</w-grid>
</q-tab-panel>
</q-tab-panels>
</template> </template>
<SelectUserDialog ref="selectUserDialog"></SelectUserDialog>
</q-splitter> </q-splitter>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { Environment, axios, EnumTools, Options, Formater } from 'platform-core';
import { Environment, axios, DialogManager, Tools, EnumTools, Options, Formater } from 'platform-core'; import SelectUserGrid from '../shared/SelectUserGrid.vue';
import SelectUserDialog from './SelectUserDialog.vue'; import SelectMenuTreeGrid from '../shared/SelectMenuTreeGrid.vue';
import UserStatusTag from '../user/UserStatusTag.vue';
const { t } = useI18n();
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
@ -269,24 +116,62 @@ const roleGridRef = ref();
const userGridRef = ref(); const userGridRef = ref();
const menuTreeGridRef = ref(); const menuTreeGridRef = ref();
const selectUserDialog = ref(); const selectedTabRef = ref('menu');
const selectedTabRef = ref('user');
const currentSelectedRoleId = ref(''); const currentSelectedRoleId = ref('');
const menuConfigure = { const add = (ids: string[], gridComponent, dialogComponent) => {
actions: [ axios
{ .post(Environment.apiContextPath('/api/system/role/addUsers'), {
name: 'save', one: roleGridRef.value.getSelectedRows()[0].id,
label: '保存', many: ids,
click: () => { })
axios .then(() => {
.post(Environment.apiContextPath('/api/system/role/updateMenus'), { gridComponent?.refresh();
one: roleGridRef.value.getSelectedRows()[0].id, dialogComponent?.close();
many: menuTreeGridRef.value.getTicked(), });
}) };
.then((response) => {});
}, const remove = (ids, gridComponent) => {
}, axios
], .post(Environment.apiContextPath('/api/system/role/removeUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent?.refresh();
});
};
const addAll = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/addAllUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const removeAll = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/removeAllUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const update = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/updateMenus'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent.refresh();
});
}; };
</script> </script>

108
io.sc.platform.system.frontend/src/views/shared/SelectMenuTreeGrid.vue

@ -0,0 +1,108 @@
<template>
<w-grid
ref="treeGridRef"
:tree="true"
:title="$t('system.shared.selectMenu.grid.title')"
dense-body
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue"
selection="multiple"
:tree-icon="
(row) => {
if (row.type === 'SEPARATOR') {
return { name: 'bi-dash-lg' };
} else if (row.type === 'ROUTE_ACTION') {
return { name: 'sym_o_crop_16_9' };
} else {
return { name: row.icon };
}
}
"
:pageable="false"
:full-screen-button="false"
:toolbar-configure="{ noIcon: true }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'save',
label: $t('system.shared.selectMenu.grid.toolbar.save'),
click: (selecteds) => {
DialogManager.confirm($t('system.shared.selectMenu.grid.toolbar.save.tip'), () => {
const ids = Tools.extractProperties(selecteds, 'id');
emit('update', ids, treeGridRef);
});
},
},
'separator',
'view',
]"
:columns="[
{
width: '100%',
name: 'titleI18nKey',
label: $t('name'),
sortable: false,
format: (value, row) => {
if (row.type === 'SEPARATOR') {
return `<hr style='width:100px'/>`;
} else if (row.type === 'ROUTE_ACTION') {
return $t(row.i18nKey);
} else {
return $t(value);
}
},
},
{ width: 100, name: 'enable', label: $t('status'), format: Formater.enableTag(), sortable: false },
]"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'type', label: $t('type') },
{ name: 'name', label: $t('name') },
{ name: 'titleI18nKey', label: $t('titleI18nKey') },
{ name: 'icon', label: $t('icon') },
{ name: 'enable', label: $t('enable') },
{ name: 'order', label: $t('order') },
{ name: 'javaScript', label: $t('javaScript') },
{ name: 'url', label: $t('url') },
{ name: 'urlOpenType', label: $t('urlOpenType') },
{ name: 'routeName', label: $t('routeName') },
{ name: 'routeQuery', label: $t('routeQuery') },
{ 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') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { DialogManager, Formater, Tools } from 'platform-core';
const props = defineProps({
fetchDataUrl: { type: String, default: '' },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'update', ids: string[], gridComponent: any): void;
}>();
const treeGridRef = ref();
const refresh = () => {
treeGridRef.value.refresh();
};
defineExpose({
refresh,
});
</script>

81
io.sc.platform.system.frontend/src/views/shared/SelectOrgTreeGrid.vue

@ -0,0 +1,81 @@
<template>
<w-grid
ref="treeGridRef"
:tree="true"
:title="$t('system.shared.selectOrg.grid.title')"
dense-body
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue"
selection="multiple"
:tree-icon="
(row) => {
return { name: 'folder', color: 'amber' };
}
"
:pageable="false"
:full-screen-button="false"
:toolbar-configure="{ noIcon: true }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'save',
label: $t('system.shared.selectOrg.grid.toolbar.save'),
click: (selecteds) => {
DialogManager.confirm($t('system.shared.selectOrg.grid.toolbar.save.tip'), () => {
const ids = Tools.extractProperties(selecteds, 'id');
emit('update', ids, treeGridRef);
});
},
},
'separator',
'view',
]"
:columns="[
{ width: '100%', name: 'name', label: $t('name') },
{ width: 100, name: 'code', label: $t('code') },
{ width: 60, name: 'enable', label: $t('status'), format: Formater.enableTag(), 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') },
{ 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') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Environment, DialogManager, Formater, Tools } from 'platform-core';
const props = defineProps({
fetchDataUrl: { type: String, default: '' },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'update', ids: string[], gridComponent: any): void;
}>();
const treeGridRef = ref();
const refresh = () => {
treeGridRef.value.refresh();
};
defineExpose({
refresh,
});
</script>

102
io.sc.platform.system.frontend/src/views/shared/SelectRoleDialog.vue

@ -0,0 +1,102 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('system.shared.selectRole.dialog.title')"
width="800px"
height="500px"
:can-maximize="false"
:buttons="[
{
label: $t('confirm'),
click: () => {
const ids = Tools.extractProperties(gridRef.getSelectedRows(), 'id');
emit('afterSelected', ids, dialogRef);
},
},
]"
>
<div class="px-2">
<w-grid
ref="gridRef"
:title="$t('system.shared.selectRole.dialog.grid.title')"
selection="multiple"
:full-screen-button="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh']"
:query-form-fields="[
{ name: 'code', label: $t('code'), type: 'text' },
{ name: 'name', label: $t('name'), type: 'text' },
{
name: 'enable',
label: $t('enable'),
type: 'select',
options: Options.yesNo(),
queryOperator: 'equals',
},
{
name: 'dataComeFrom',
label: $t('dataComeFrom'),
type: 'select',
options: Options.enum(DataComeFromEnum),
queryOperator: 'equals',
},
]"
:auto-fetch-data="false"
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue"
:columns="[
{ name: 'code', label: $t('code') },
{ name: 'name', label: $t('name') },
{
name: 'status',
label: t('status'),
format: Formater.enableTag(),
},
{ name: 'lastModifier', label: t('lastModifier') },
{ name: 'lastModifyDate', label: t('lastModifyDate') },
]"
></w-grid>
</div>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, Tools, EnumTools, Options, Formater } from 'platform-core';
const props = defineProps({
opener: { type: Object, default: undefined },
fetchDataUrl: { type: String, default: '' },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'afterSelected', ids: string[], dialogComponent: any): void;
}>();
const { t } = useI18n();
const dialogRef = ref();
const gridRef = ref();
const foreignKeyRef = ref();
const open = (foreignKey: string) => {
foreignKeyRef.value = foreignKey;
dialogRef.value.show();
nextTick(() => {
gridRef.value.refresh();
});
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
</script>

138
io.sc.platform.system.frontend/src/views/shared/SelectRoleGrid.vue

@ -0,0 +1,138 @@
<template>
<w-grid
ref="gridRef"
:title="$t('system.shared.selectRole.grid.title')"
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue"
:auto-fetch-data="false"
selection="multiple"
:full-screen-button="false"
:toolbar-configure="{ noIcon: true }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'addRoles',
label: $t('system.shared.selectRole.grid.toolbar.add'),
enableIf: () => {
return foreignValue ? true : false;
},
click: () => {
dialogRef.open(foreignValue);
},
},
{
name: 'removeRoles',
label: $t('system.shared.selectRole.grid.toolbar.remove'),
enableIf: () => {
return foreignValue && gridRef?.getSelectedRows()?.length > 0;
},
click: (selecteds) => {
const ids = Tools.extractProperties(selecteds, 'id');
DialogManager.confirm($t('system.shared.selectRole.grid.toolbar.remove.tip'), () => {
emit('remove', ids, gridRef);
});
},
},
'separator',
{
name: 'addAllRoles',
label: $t('system.shared.selectRole.grid.toolbar.addAll'),
enableIf: () => {
return foreignValue ? true : false;
},
click: () => {
DialogManager.confirm($t('system.shared.selectRole.grid.toolbar.addAll.tip'), () => {
emit('addAll', gridRef);
});
},
},
{
name: 'removeAllRoles',
label: $t('system.shared.selectRole.grid.toolbar.removeAll'),
enableIf: () => {
return foreignValue && gridRef?.getRows()?.length > 0;
},
click: () => {
DialogManager.confirm($t('system.shared.selectRole.grid.toolbar.removeAll.tip'), () => {
emit('removeAll', gridRef);
});
},
},
'separator',
'view',
]"
:columns="[
{ width: 100, name: 'code', label: $t('code') },
{ width: 100, name: 'name', label: $t('name') },
{
width: 60,
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.yesNo() },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
<SelectRoleDialog
ref="dialogRef"
:opener="gridRef"
:fetch-data-url="fetchOtherDataUrl"
:foreign-key="foreignKey"
:foreign-value="foreignValue"
@after-selected="
(ids: string[]) => {
emit('add', ids, gridRef, dialogRef);
}
"
></SelectRoleDialog>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, axios, EnumTools, NotifyManager, DialogManager, Formater, Options, Tools, OperatorTypeEnum } from 'platform-core';
import SelectRoleDialog from './SelectRoleDialog.vue';
const props = defineProps({
fetchDataUrl: { type: String, default: '' },
fetchOtherDataUrl: { type: String, default: '' },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'add', ids: string[], gridComponent: any, dialogComponent: any): void;
(e: 'remove', ids: string[], gridComponent: any): void;
(e: 'addAll', gridComponent: any): void;
(e: 'removeAll', gridComponent: any): void;
}>();
const gridRef = ref();
const dialogRef = ref();
const refresh = () => {
gridRef.value.refresh();
};
defineExpose({
refresh,
});
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
</script>

106
io.sc.platform.system.frontend/src/views/shared/SelectUserDialog.vue

@ -0,0 +1,106 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('system.shared.selectUser.dialog.title')"
width="800px"
height="500px"
:can-maximize="false"
:buttons="[
{
label: $t('confirm'),
click: () => {
const ids = Tools.extractProperties(gridRef.getSelectedRows(), 'id');
emit('afterSelected', ids, dialogRef);
},
},
]"
>
<div class="px-2">
<w-grid
ref="gridRef"
:title="$t('system.shared.selectUser.dialog.grid.title')"
selection="multiple"
:full-screen-button="false"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh']"
:query-form-fields="[
{ name: 'loginName', label: $t('loginName'), type: 'text' },
{ name: 'userName', label: $t('userName'), type: 'text' },
{
name: 'enable',
label: $t('enable'),
type: 'select',
options: Options.yesNo(),
queryOperator: 'equals',
},
{
name: 'dataComeFrom',
label: $t('dataComeFrom'),
type: 'select',
options: Options.enum(DataComeFromEnum),
queryOperator: 'equals',
},
]"
:auto-fetch-data="false"
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue"
:columns="[
{ width: 100, name: 'loginName', label: t('loginName') },
{ width: 100, name: 'userName', label: t('userName') },
{
name: 'status',
label: $t('status'),
format: (value, row) => {
return {
componentType: UserStatusTag,
attrs: row,
};
},
},
]"
></w-grid>
</div>
</w-dialog>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, Tools, EnumTools, Options, Formater } from 'platform-core';
import UserStatusTag from './UserStatusTag.vue';
const props = defineProps({
opener: { type: Object, default: undefined },
fetchDataUrl: { type: String, default: '' },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'afterSelected', ids: string[], dialogComponent: any): void;
}>();
const { t } = useI18n();
const dialogRef = ref();
const gridRef = ref();
const foreignKeyRef = ref();
const open = (foreignKey: string) => {
foreignKeyRef.value = foreignKey;
dialogRef.value.show();
nextTick(() => {
gridRef.value.refresh();
});
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
</script>

150
io.sc.platform.system.frontend/src/views/shared/SelectUserGrid.vue

@ -0,0 +1,150 @@
<template>
<w-grid
ref="gridRef"
:title="$t('system.shared.selectUser.grid.title')"
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue"
:auto-fetch-data="false"
selection="multiple"
:full-screen-button="false"
:toolbar-configure="{ noIcon: true }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'addUsers',
label: $t('system.shared.selectUser.grid.toolbar.add'),
enableIf: () => {
return foreignValue ? true : false;
},
click: () => {
dialogRef.open(foreignValue);
},
},
{
name: 'removeUsers',
label: $t('system.shared.selectUser.grid.toolbar.remove'),
enableIf: () => {
return foreignValue && gridRef?.getSelectedRows()?.length > 0;
},
click: (selecteds) => {
const ids = Tools.extractProperties(selecteds, 'id');
DialogManager.confirm($t('system.shared.selectUser.grid.toolbar.remove.tip'), () => {
emit('remove', ids, gridRef);
});
},
},
'separator',
{
name: 'addAllUsers',
label: $t('system.shared.selectUser.grid.toolbar.addAll'),
enableIf: () => {
return foreignValue ? true : false;
},
click: () => {
DialogManager.confirm($t('system.shared.selectUser.grid.toolbar.addAll.tip'), () => {
emit('addAll', gridRef);
});
},
},
{
name: 'removeAllUsers',
label: $t('system.shared.selectUser.grid.toolbar.removeAll'),
enableIf: () => {
return foreignValue && gridRef?.getRows()?.length > 0;
},
click: () => {
DialogManager.confirm($t('system.shared.selectUser.grid.toolbar.removeAll.tip'), () => {
emit('removeAll', gridRef);
});
},
},
'separator',
'view',
]"
:columns="[
{ width: 100, name: 'loginName', label: $t('loginName') },
{ width: 100, name: 'userName', label: $t('userName') },
{
name: 'enable',
label: $t('status'),
format: (value, row) => {
return {
componentType: UserStatusTag,
attrs: row,
};
},
},
]"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'loginName', label: $t('loginName') },
{ name: 'userName', label: $t('userName') },
{ name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() },
{ name: 'accountExpired', label: $t('accountExpired'), format: Formater.yesNo() },
{ name: 'accountLocked', label: $t('accountLocked'), format: Formater.yesNo() },
{ name: 'credentialsExpired', label: $t('credentialsExpired'), format: Formater.yesNo() },
{ name: 'email', label: $t('email') },
{ name: 'phone', label: $t('phone') },
{ name: 'mobile', label: $t('mobile') },
{ name: 'weixin', label: $t('weixin') },
{ name: 'qq', label: $t('qq') },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
></w-grid>
<SelectUserDialog
ref="dialogRef"
:opener="gridRef"
:fetch-data-url="fetchOtherDataUrl"
:foreign-key="foreignKey"
:foreign-value="foreignValue"
@after-selected="
(ids: string[]) => {
emit('add', ids, gridRef, dialogRef);
}
"
></SelectUserDialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { EnumTools, DialogManager, Formater, Tools } from 'platform-core';
import SelectUserDialog from './SelectUserDialog.vue';
import UserStatusTag from './UserStatusTag.vue';
const props = defineProps({
fetchDataUrl: { type: String, default: '' },
fetchOtherDataUrl: { type: String, default: '' },
foreignKey: { type: String, default: '' },
foreignValue: { type: String, default: '' },
});
const emit = defineEmits<{
(e: 'add', ids: string[], gridComponent: any, dialogComponent: any): void;
(e: 'remove', ids: string[], gridComponent: any): void;
(e: 'addAll', gridComponent: any): void;
(e: 'removeAll', gridComponent: any): void;
}>();
const gridRef = ref();
const dialogRef = ref();
const refresh = () => {
gridRef.value.refresh();
};
defineExpose({
refresh,
});
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
</script>

17
io.sc.platform.system.frontend/src/views/shared/UserStatusTag.vue

@ -0,0 +1,17 @@
<template>
<div>
<q-chip v-if="enable && !accountExpired && !accountLocked && !credentialsExpired" color="green" text-color="white" :label="$t('normal')" dense></q-chip>
<q-chip v-if="!enable" color="red" text-color="white" :label="$t('disable')" dense></q-chip>
<q-chip v-if="accountExpired" color="red" text-color="white" :label="$t('accountExpired')" dense></q-chip>
<q-chip v-if="accountLocked" color="red" text-color="white" :label="$t('accountLocked')" dense></q-chip>
<q-chip v-if="credentialsExpired" color="red" text-color="white" :label="$t('credentialsExpired')" dense></q-chip>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
enable: { type: Boolean, default: true },
accountExpired: { type: Boolean, default: false },
accountLocked: { type: Boolean, default: false },
credentialsExpired: { type: Boolean, default: false },
});
</script>

14
io.sc.platform.system.frontend/src/views/user/SetPasswordDialog.vue

@ -1,7 +1,7 @@
<template> <template>
<w-dialog <w-dialog
ref="setPasswordDialogRef" ref="setPasswordDialogRef"
:title="$t('system.user.action.' + actionType)" :title="$t('system.user.action.' + actionTypeRef)"
width="500px" width="500px"
height="230px" height="230px"
:can-maximize="false" :can-maximize="false"
@ -11,8 +11,8 @@
noCaps: true, noCaps: true,
click: () => { click: () => {
axios axios
.post(Environment.apiContextPath('/api/system/user/' + actionType), { .post(Environment.apiContextPath('/api/system/user/' + actionTypeRef), {
userIds: userIds, userIds: currentSelectedUserIds,
password: setPasswordFormRef.getData().password, password: setPasswordFormRef.getData().password,
}) })
.then(() => { .then(() => {
@ -50,12 +50,12 @@ import { axios, Environment, NotifyManager, Tools } from 'platform-core';
const setPasswordDialogRef = ref(); const setPasswordDialogRef = ref();
const setPasswordFormRef = ref(); const setPasswordFormRef = ref();
let actionType = ref(); const actionTypeRef = ref();
let userIds = []; let currentSelectedUserIds = [];
const open = (type, users) => { const open = (type, users) => {
actionType.value = type; actionTypeRef.value = type;
userIds = Tools.extractProperties(users, 'id'); currentSelectedUserIds = Tools.extractProperties(users, 'id');
setPasswordDialogRef.value.show(); setPasswordDialogRef.value.show();
}; };

624
io.sc.platform.system.frontend/src/views/user/User.vue

@ -1,380 +1,225 @@
<template> <template>
<q-splitter :model-value="65" class="w-full h-full"> <div>
<template #before> <q-splitter :model-value="60" class="w-full h-full">
<div class="px-1"> <template #before>
<w-grid <div class="pr-1">
ref="userGridRef" <w-grid
:title="$t('system.user.grid.title')" ref="userGridRef"
selection="multiple" :title="$t('system.user.grid.title')"
:data-url="Environment.apiContextPath('/api/system/user')" selection="multiple"
:query-form-fields="[ :data-url="Environment.apiContextPath('/api/system/user')"
{ name: 'loginName', label: $t('loginName'), type: 'text' }, :pagination="{
{ name: 'userName', label: $t('userName'), type: 'text' }, sortBy: 'loginName',
{ name: 'enable', label: $t('isEnable'), type: 'select', options: Options.yesNo(), queryOperator: 'equals' }, descending: false,
{ name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum), queryOperator: 'equals' }, }"
]" :query-form-fields="[
:toolbar-configure="{ noIcon: false }" { name: 'loginName', label: $t('loginName'), type: 'text' },
:toolbar-actions="[ { name: 'userName', label: $t('userName'), type: 'text' },
'query', { name: 'enable', label: $t('isEnable'), type: 'select', options: Options.yesNo(), queryOperator: 'equals' },
'refresh', { name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum), queryOperator: 'equals' },
'separator', ]"
'add', :toolbar-configure="{ noIcon: false }"
'clone', :toolbar-actions="[
'edit', 'query',
'remove', 'refresh',
'separator', 'separator',
{ 'add',
name: 'setPassword', 'clone',
label: $t('system.user.grid.toolbar.setPassword'), 'edit',
icon: 'bi-shield-check', 'remove',
enableIf: function (selecteds) { 'separator',
return selecteds.length > 0; {
}, name: 'setPassword',
click: function (selecteds) { label: $t('system.user.grid.toolbar.setPassword'),
setPasswordDialogRef.open('setPassword', selecteds); icon: 'bi-shield-check',
}, enableIf: function (selecteds) {
}, return selecteds.length > 0;
{ },
name: 'setAllPassword', click: function (selecteds) {
label: $t('system.user.grid.toolbar.setAllPassword'), setPasswordDialogRef.open('setPassword', selecteds);
icon: 'bi-shield', },
enableIf: function (selecteds) {
return true;
},
click: function () {
setPasswordDialogRef.open('setAllPassword');
},
},
'separator',
{
name: 'resetPassword',
label: $t('system.user.grid.toolbar.resetPassword'),
icon: 'bi-shield-fill-check',
enableIf: function (selecteds) {
return selecteds.length > 0;
},
click: function (selecteds) {
DialogManager.confirm($t('system.user.grid.toolbar.resetPassword.tip'), () => {
const userIds = Tools.extractProperties(selecteds, 'id');
axios.post(Environment.apiContextPath('/api/system/user/resetPassword'), userIds).then(() => {
NotifyManager.info($t('operationSuccess'));
});
});
},
},
{
name: 'resetAllPassword',
label: $t('system.user.grid.toolbar.resetAllPassword'),
icon: 'bi-shield-fill',
enableIf: function (selecteds) {
return true;
},
click: function () {
DialogManager.confirm($t('system.user.grid.toolbar.resetAllPassword.tip'), () => {
axios.post(Environment.apiContextPath('/api/system/user/resetAllPassword')).then(() => {
setPasswordDialogRef.value.hide();
NotifyManager.info($t('operationSuccess'));
});
});
},
},
'separator',
'view',
'export',
]"
:columns="[
{ name: 'loginName', label: $t('loginName') },
{ name: 'userName', label: $t('userName') },
{
name: 'status',
label: $t('status'),
format: (value, row) => {
return {
componentType: UserStatusTag,
attrs: row,
};
}, },
}, {
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, name: 'setAllPassword',
{ name: 'lastModifier', label: $t('lastModifier') }, label: $t('system.user.grid.toolbar.setAllPassword'),
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, icon: 'bi-shield',
]" enableIf: function (selecteds) {
:editor="{ return true;
dialog: {
width: '600px',
height: '610px',
},
form: {
colsNum: 4,
fields: [
{ name: 'loginName', label: $t('loginName'), type: 'text', required: true, colspan: 4 },
{ name: 'userName', label: $t('userName'), type: 'text', required: true, colspan: 4 },
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1, colspan: 4 },
{ name: 'password', label: $t('password'), type: 'password', colspan: 4 },
{
name: 'confirmPassword',
label: $t('confirmPassword'),
type: 'password',
colspan: 4,
rules: [
(value) => {
return Tools.stringEquals(userGridRef.getAddEditFormRef().value.getData().password, value)
? true
: $t('passwordAndConfirmPasswordMustEqual');
},
],
}, },
{ name: 'mobile', label: $t('mobile'), type: 'text', colsFirst: true, colspan: 4 }, click: function () {
{ name: 'phone', label: $t('phone'), type: 'text', colsFirst: true, colspan: 4 }, setPasswordDialogRef.open('setAllPassword');
{ name: 'email', label: $t('email'), type: 'text', colsFirst: true, colspan: 4 },
{ name: 'weixin', label: $t('weixin'), type: 'text', colsFirst: true, colspan: 4 },
{ name: 'qq', label: $t('qq'), type: 'text', colsFirst: true, colspan: 4 },
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
{ name: 'accountExpired', label: $t('accountExpired'), type: 'checkbox', defaultValue: false },
{ name: 'accountLocked', label: $t('accountLocked'), type: 'checkbox', defaultValue: false },
{ name: 'credentialsExpired', label: $t('credentialsExpired'), type: 'checkbox', defaultValue: false },
],
},
}"
:viewer="{
panel: {
columnNum: 1,
fields: [
{ name: 'id', label: $t('id') },
{ name: 'loginName', label: $t('loginName') },
{ name: 'userName', label: $t('userName') },
{ name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() },
{ name: 'accountExpired', label: $t('accountExpired'), format: Formater.yesNo() },
{ name: 'accountLocked', label: $t('accountLocked'), format: Formater.yesNo() },
{ name: 'credentialsExpired', label: $t('credentialsExpired'), format: Formater.yesNo() },
{ name: 'email', label: $t('email') },
{ name: 'phone', label: $t('phone') },
{ name: 'mobile', label: $t('mobile') },
{ name: 'weixin', label: $t('weixin') },
{ name: 'qq', label: $t('qq') },
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
{ name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedUserId = row.id;
roleGridRef?.refresh();
orgTreeGridRef?.refresh();
}
"
></w-grid>
</div>
</template>
<template #after>
<div class="px-1">
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0" no-caps>
<q-tab name="role" icon="bi-people" :label="$t('role')" />
<q-tab name="org" icon="bi-diagram-3" :label="$t('org')" />
</q-tabs>
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive>
<q-tab-panel name="role" class="px-0">
<w-grid
ref="roleGridRef"
:title="$t('system.user.selectRole.grid.title')"
:fetch-data-url="Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + currentSelectedUserId"
:auto-fetch-data="false"
selection="multiple"
:full-screen-button="false"
:toolbar-configure="{ noIcon: true }"
:toolbar-actions="[
'refresh',
'separator',
{
name: 'addRole',
label: $t('system.user.selectRole.grid.toolbar.addRole'),
enableIf: () => {
if (userGridRef) {
return userGridRef.getSelectedRows().length > 0;
}
return false;
},
click: () => {
selectRoleDialog.open({ userId: userGridRef.getSelectedRows()[0].id, roleGrid: roleGridRef });
},
}, },
{ },
name: 'addAllRole', 'separator',
label: $t('system.user.selectRole.grid.toolbar.addAllRole'), {
enableIf: () => { name: 'resetPassword',
if (userGridRef) { label: $t('system.user.grid.toolbar.resetPassword'),
return userGridRef.getSelectedRows().length > 0; icon: 'bi-shield-fill-check',
} enableIf: function (selecteds) {
return false; return selecteds.length > 0;
},
click: () => {
const selectedUser = userGridRef.getSelectedRows()[0];
DialogManager.confirm($t('system.user.selectRole.grid.toolbar.addAllRole.tip'), () => {
axios
.post(Environment.apiContextPath('/api/system/user/addAllRoles'), {
one: selectedUser.id,
many: [],
})
.then((response) => {
roleGridRef?.refresh();
});
});
},
}, },
'separator', click: function (selecteds) {
{ DialogManager.confirm($t('system.user.grid.toolbar.resetPassword.tip'), () => {
name: 'removeRole', const userIds = Tools.extractProperties(selecteds, 'id');
label: $t('system.user.selectRole.grid.toolbar.removeRole'), axios.post(Environment.apiContextPath('/api/system/user/resetPassword'), userIds).then(() => {
enableIf: () => { NotifyManager.info($t('operationSuccess'));
if (userGridRef && roleGridRef) {
return userGridRef.getSelectedRows().length > 0 && roleGridRef.getSelectedRows().length > 0;
}
return false;
},
click: (selecteds) => {
const selectedUser = userGridRef.getSelectedRows()[0];
const roleIds = Tools.extractProperties(selecteds, 'id');
DialogManager.confirm($t('system.user.selectRole.grid.toolbar.removeRole.tip'), () => {
axios
.post(Environment.apiContextPath('/api/system/user/removeRoles'), {
one: selectedUser.id,
many: roleIds,
})
.then((response) => {
roleGridRef?.refresh();
});
}); });
}, });
}, },
{ },
name: 'removeAllRole', {
label: $t('system.user.selectRole.grid.toolbar.removeAllRole'), name: 'resetAllPassword',
enableIf: () => { label: $t('system.user.grid.toolbar.resetAllPassword'),
if (userGridRef && roleGridRef) { icon: 'bi-shield-fill',
return userGridRef.getSelectedRows().length > 0 && roleGridRef.getRows().length > 0; enableIf: function (selecteds) {
} return true;
return false;
},
click: () => {
const selectedUser = userGridRef.getSelectedRows()[0];
DialogManager.confirm($t('system.user.selectRole.grid.toolbar.removeAllRole.tip'), () => {
axios
.post(Environment.apiContextPath('/api/system/user/removeAllRoles'), {
one: selectedUser.id,
many: [],
})
.then((response) => {
roleGridRef?.refresh();
});
});
},
}, },
'separator', click: function () {
'view', DialogManager.confirm($t('system.user.grid.toolbar.resetAllPassword.tip'), () => {
]" axios.post(Environment.apiContextPath('/api/system/user/resetAllPassword')).then(() => {
:columns="[ setPasswordDialogRef.value.hide();
{ width: 100, name: 'code', label: $t('code') }, NotifyManager.info($t('operationSuccess'));
{ width: 100, name: 'name', label: $t('name') }, });
{ });
width: 60,
name: 'status',
label: $t('status'),
format: Formater.enableTag(),
}, },
]" },
:viewer="{ 'separator',
panel: { 'view',
columnNum: 1, 'export',
fields: [ ]"
{ name: 'id', label: $t('id') }, :columns="[
{ name: 'code', label: $t('code') }, { name: 'loginName', label: $t('loginName') },
{ name: 'name', label: $t('name') }, { name: 'userName', label: $t('userName') },
{ name: 'description', label: $t('description') }, {
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() }, name: 'enable',
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, label: $t('status'),
{ name: 'creator', label: $t('creator') }, format: (value, row) => {
{ name: 'createDate', label: $t('createDate') }, return {
{ name: 'lastModifier', label: $t('lastModifier') }, componentType: UserStatusTag,
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, attrs: row,
{ name: 'corporationCode', label: $t('corporationCode') }, };
],
}, },
}" },
></w-grid> { name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
</q-tab-panel> { name: 'lastModifier', label: $t('lastModifier') },
<q-tab-panel name="org" class="px-0"> { name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
<w-grid ]"
ref="orgTreeGridRef" :editor="{
:tree="true" dialog: {
:title="$t('system.org.grid.title')" width: '600px',
:data-url="Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser?userId=') + currentSelectedUserId" height: '610px',
selection="multiple" },
:pageable="false" form: {
:full-screen-button="false" colsNum: 4,
:toolbar-configure="{ noIcon: true }" fields: [
:toolbar-actions="[ { name: 'loginName', label: $t('loginName'), type: 'text', required: true, colspan: 4 },
'refresh', { name: 'userName', label: $t('userName'), type: 'text', required: true, colspan: 4 },
'separator', { name: 'description', label: $t('description'), type: 'textarea', rows: 1, colspan: 4 },
{ { name: 'password', label: $t('password'), type: 'password', colspan: 4 },
name: 'save', {
label: $t('save'), name: 'confirmPassword',
click: () => { label: $t('confirmPassword'),
axios type: 'password',
.post(Environment.apiContextPath('/api/system/user/updateOrgs'), { colspan: 4,
one: userGridRef.getSelectedRows()[0].id, rules: [
many: orgTreeGridRef.getTicked(), (value) => {
}) return Tools.stringEquals(userGridRef.getEditorForm().getData().password, value) ? true : $t('passwordAndConfirmPasswordMustEqual');
.then((response) => {}); },
],
}, },
}, { name: 'mobile', label: $t('mobile'), type: 'text', colsFirst: true, colspan: 4 },
'view', { name: 'phone', label: $t('phone'), type: 'text', colsFirst: true, colspan: 4 },
]" { name: 'email', label: $t('email'), type: 'text', colsFirst: true, colspan: 4 },
:columns="[ { name: 'weixin', label: $t('weixin'), type: 'text', colsFirst: true, colspan: 4 },
{ width: 80, name: 'code', label: $t('code') }, { name: 'qq', label: $t('qq'), type: 'text', colsFirst: true, colspan: 4 },
{ width: 100, name: 'name', label: $t('name') },
{ width: 60, name: 'status', label: $t('status'), format: Formater.enableTag() }, { name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true },
]" { name: 'accountExpired', label: $t('accountExpired'), type: 'checkbox', defaultValue: false },
:viewer="{ { name: 'accountLocked', label: $t('accountLocked'), type: 'checkbox', defaultValue: false },
panel: { { name: 'credentialsExpired', label: $t('credentialsExpired'), type: 'checkbox', defaultValue: false },
columnNum: 1, ],
fields: [ },
{ name: 'id', label: $t('id') }, }"
{ name: 'code', label: $t('code') }, :viewer="{
{ name: 'name', label: $t('name') }, panel: {
{ name: 'description', label: $t('description') }, columnNum: 1,
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() }, fields: [
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, { name: 'id', label: $t('id') },
{ name: 'creator', label: $t('creator') }, { name: 'loginName', label: $t('loginName') },
{ name: 'createDate', label: $t('createDate') }, { name: 'userName', label: $t('userName') },
{ name: 'lastModifier', label: $t('lastModifier') }, { name: 'description', label: $t('description') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, { name: 'enable', label: $t('enable'), format: Formater.yesNo() },
{ name: 'corporationCode', label: $t('corporationCode') }, { name: 'accountExpired', label: $t('accountExpired'), format: Formater.yesNo() },
], { name: 'accountLocked', label: $t('accountLocked'), format: Formater.yesNo() },
}, { name: 'credentialsExpired', label: $t('credentialsExpired'), format: Formater.yesNo() },
}" { name: 'email', label: $t('email') },
></w-grid> { name: 'phone', label: $t('phone') },
</q-tab-panel> { name: 'mobile', label: $t('mobile') },
</q-tab-panels> { name: 'weixin', label: $t('weixin') },
</div> { name: 'qq', label: $t('qq') },
</template> { name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) },
<SelectRoleDialog ref="selectRoleDialog"></SelectRoleDialog> { name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') },
{ name: 'lastModifier', label: $t('lastModifier') },
{ name: 'lastModifyDate', label: $t('lastModifyDate') },
{ name: 'corporationCode', label: $t('corporationCode') },
],
},
}"
@row-click="
(evt, row, index) => {
currentSelectedUserId = row.id;
roleGridRef?.refresh();
orgTreeGridRef?.refresh();
}
"
></w-grid>
</div>
</template>
<template #after>
<div class="pl-1">
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0" no-caps>
<q-tab name="role" icon="bi-people" :label="$t('role')" />
<q-tab name="org" icon="bi-diagram-3" :label="$t('org')" />
</q-tabs>
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive>
<q-tab-panel name="role" class="px-0">
<SelectRoleGrid
ref="roleGridRef"
:fetch-data-url="Environment.apiContextPath('/api/system/role/queryRolesByUser')"
:fetch-other-data-url="Environment.apiContextPath('/api/system/role/queryOtherRolesByUser')"
foreign-key="userId"
:foreign-value="currentSelectedUserId"
@add="add"
@remove="remove"
@add-all="addAll"
@remove-all="removeAll"
></SelectRoleGrid>
</q-tab-panel>
<q-tab-panel name="org" class="px-0">
<SelectOrgTreeGrid
ref="orgTreeGridRef"
:fetch-data-url="Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser')"
foreign-key="userId"
:foreign-value="currentSelectedUserId"
@update="update"
></SelectOrgTreeGrid>
</q-tab-panel>
</q-tab-panels>
</div>
</template>
</q-splitter>
<SetPasswordDialog ref="setPasswordDialogRef"></SetPasswordDialog> <SetPasswordDialog ref="setPasswordDialogRef"></SetPasswordDialog>
</q-splitter> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { Environment, axios, EnumTools, NotifyManager, DialogManager, Formater, Options, Tools, OperatorTypeEnum } from 'platform-core'; import { Environment, axios, EnumTools, NotifyManager, DialogManager, Formater, Options, Tools } from 'platform-core';
import SelectRoleDialog from './SelectRoleDialog.vue'; import SelectRoleGrid from '../shared/SelectRoleGrid.vue';
import SelectOrgTreeGrid from '../shared/SelectOrgTreeGrid.vue';
import UserStatusTag from '../shared/UserStatusTag.vue';
import SetPasswordDialog from './SetPasswordDialog.vue'; import SetPasswordDialog from './SetPasswordDialog.vue';
import UserStatusTag from './UserStatusTag.vue';
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
@ -382,8 +227,63 @@ const userGridRef = ref();
const roleGridRef = ref(); const roleGridRef = ref();
const orgTreeGridRef = ref(); const orgTreeGridRef = ref();
const selectRoleDialog = ref();
const selectedTabRef = ref('role'); const selectedTabRef = ref('role');
const setPasswordDialogRef = ref(); const setPasswordDialogRef = ref();
const currentSelectedUserId = ref(''); const currentSelectedUserId = ref('');
const add = (ids: string[], gridComponent, dialogComponent) => {
axios
.post(Environment.apiContextPath('/api/system/user/addRoles'), {
one: userGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent?.refresh();
dialogComponent?.close();
});
};
const remove = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/user/removeRoles'), {
one: userGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent?.refresh();
});
};
const addAll = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/user/addAllRoles'), {
one: userGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const removeAll = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/user/removeAllRoles'), {
one: userGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const update = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/user/updateOrgs'), {
one: userGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent.refresh();
});
};
</script> </script>

2
io.sc.platform.system/src/main/java/io/sc/platform/system/announcement/jpa/entity/AnnouncementEntity.java

@ -31,7 +31,7 @@ public class AnnouncementEntity extends CorporationAuditorEntity<AnnouncementVo>
@Override @Override
public AnnouncementVo toVo() { public AnnouncementVo toVo() {
AnnouncementVo vo =new AnnouncementVo(); AnnouncementVo vo =new AnnouncementVo();
CorporationAuditorEntity.toVo(vo,this); super.toVo(vo);
vo.setId(this.getId()); vo.setId(this.getId());
vo.setTitle(this.getTitle()); vo.setTitle(this.getTitle());
vo.setContent(this.getContent()); vo.setContent(this.getContent());

49
io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/controller/CorporationWebController.java

@ -1,15 +1,64 @@
package io.sc.platform.system.corporation.controller; package io.sc.platform.system.corporation.controller;
import io.sc.platform.mvc.controller.support.RestCrudController; import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.mvc.support.One2Many;
import io.sc.platform.system.api.corporation.CorporationVo; import io.sc.platform.system.api.corporation.CorporationVo;
import io.sc.platform.system.corporation.jpa.entity.CorporationEntity; import io.sc.platform.system.corporation.jpa.entity.CorporationEntity;
import io.sc.platform.system.corporation.jpa.repository.CorporationRepository; import io.sc.platform.system.corporation.jpa.repository.CorporationRepository;
import io.sc.platform.system.corporation.service.CorporationService; import io.sc.platform.system.corporation.service.CorporationService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("api/system/corporation") @RequestMapping("api/system/corporation")
public class CorporationWebController extends RestCrudController<CorporationVo,CorporationEntity,String,CorporationRepository, CorporationService> { public class CorporationWebController extends RestCrudController<CorporationVo,CorporationEntity,String,CorporationRepository, CorporationService> {
/**
* 给法人添加用户
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many: 代表用户ID集合
* @throws Exception 违例
*/
@PostMapping("addUsers")
public void addCorporations(@RequestBody One2Many<String,String> wrapper) throws Exception{
if(wrapper!=null){
service.addUsers(wrapper.getOne(),wrapper.getMany());
}
}
/**
* 给法人添加所有用户
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many:
* @throws Exception 违例
*/
@PostMapping("addAllUsers")
public void addAllUsers(@RequestBody One2Many<String,String> wrapper) throws Exception{
if(wrapper!=null){
service.addAllUsers(wrapper.getOne());
}
}
/**
* 移除法人下的用户
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many: 代表用户ID集合
* @throws Exception 违例
*/
@PostMapping("removeUsers")
public void removeUsers(@RequestBody One2Many<String,String> wrapper) throws Exception{
if(wrapper!=null){
service.removeUsers(wrapper.getOne(),wrapper.getMany());
}
}
/**
* 移除法人下的所有用户
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many:
* @throws Exception 违例
*/
@PostMapping("removeAllUsers")
public void removeAllUsers(@RequestBody One2Many<String,String> wrapper) throws Exception{
if(wrapper!=null){
service.removeAllUsers(wrapper.getOne());
}
}
} }

6
io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/jpa/entity/CorporationEntity.java

@ -49,14 +49,14 @@ public class CorporationEntity extends AuditorEntity<CorporationVo> {
public CorporationEntity(){} public CorporationEntity(){}
public CorporationEntity(String code){ public CorporationEntity(String id){
this.code =code; this.id =id;
} }
@Override @Override
public CorporationVo toVo() { public CorporationVo toVo() {
CorporationVo vo =new CorporationVo(); CorporationVo vo =new CorporationVo();
AuditorEntity.toVo(vo,this); super.toVo(vo);
vo.setId(this.getId()); vo.setId(this.getId());
vo.setCode(this.getCode()); vo.setCode(this.getCode());
vo.setName(this.getName()); vo.setName(this.getName());

31
io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/service/CorporationService.java

@ -4,5 +4,36 @@ import io.sc.platform.orm.service.DaoService;
import io.sc.platform.system.corporation.jpa.entity.CorporationEntity; import io.sc.platform.system.corporation.jpa.entity.CorporationEntity;
import io.sc.platform.system.corporation.jpa.repository.CorporationRepository; import io.sc.platform.system.corporation.jpa.repository.CorporationRepository;
import java.util.Set;
public interface CorporationService extends DaoService<CorporationEntity, String, CorporationRepository> { public interface CorporationService extends DaoService<CorporationEntity, String, CorporationRepository> {
/**
* 给法人添加用户
* @param corporationCode 角色ID
* @param userIds 需要添加的用户ID列表
* @throws Exception 违例
*/
public void addUsers(String corporationCode, Set<String> userIds) throws Exception;
/**
* 给法人添加所有用户
* @param corporationCode 法人代码
* @throws Exception 违例
*/
public void addAllUsers(String corporationCode) throws Exception;
/**
* 移除法人包含的用户
* @param corporationCode 法人代码
* @param userIds 需要移除的用户ID列表
* @throws Exception 违例
*/
public void removeUsers(String corporationCode,Set<String> userIds) throws Exception;
/**
* 移除法人包含的所有用户
* @param corporationCode 法人代码
* @throws Exception 违例
*/
public void removeAllUsers(String corporationCode) throws Exception;
} }

47
io.sc.platform.system/src/main/java/io/sc/platform/system/corporation/service/impl/CorporationServiceImpl.java

@ -1,12 +1,59 @@
package io.sc.platform.system.corporation.service.impl; package io.sc.platform.system.corporation.service.impl;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
import io.sc.platform.orm.service.impl.DaoServiceImpl; import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.system.corporation.jpa.entity.CorporationEntity; import io.sc.platform.system.corporation.jpa.entity.CorporationEntity;
import io.sc.platform.system.corporation.jpa.repository.CorporationRepository; import io.sc.platform.system.corporation.jpa.repository.CorporationRepository;
import io.sc.platform.system.corporation.service.CorporationService; import io.sc.platform.system.corporation.service.CorporationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Service @Service
public class CorporationServiceImpl extends DaoServiceImpl<CorporationEntity, String, CorporationRepository> implements CorporationService { public class CorporationServiceImpl extends DaoServiceImpl<CorporationEntity, String, CorporationRepository> implements CorporationService {
@Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Override
public void addUsers(String corporationCode, Set<String> userIds) throws Exception {
if(StringUtils.hasText(corporationCode) && userIds!=null && !userIds.isEmpty()){
Map<String, Object> params = new HashMap<String, Object>();
params.put("corporationCode", corporationCode);
params.put("userIds", userIds);
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:corporationCode where ID_ in (:userIds)",params);
}
}
@Override
public void addAllUsers(String corporationCode) throws Exception {
if(StringUtils.hasText(corporationCode)) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("corporationCode", corporationCode);
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:corporationCode", params);
}
}
@Override
public void removeUsers(String corporationCode, Set<String> userIds) throws Exception {
if(StringUtils.hasText(corporationCode) && userIds!=null && !userIds.isEmpty()){
Map<String, Object> params = new HashMap<String, Object>();
params.put("defaultCorporationCode", CorporationAuditorVo.DEFAULT_CODE);
params.put("userIds", userIds);
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:defaultCorporationCode where ID_ in (:userIds)",params);
}
}
@Override
public void removeAllUsers(String corporationCode) throws Exception {
if(StringUtils.hasText(corporationCode)) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("defaultCorporationCode", CorporationAuditorVo.DEFAULT_CODE);
params.put("corporationCode", corporationCode);
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:defaultCorporationCode where CORP_CODE_=:corporationCode",params);
}
}
} }

4
io.sc.platform.system/src/main/java/io/sc/platform/system/initializer/OrgInitializer.java

@ -83,7 +83,7 @@ public class OrgInitializer implements ApplicationInitializer {
.table("SYS_ORG") .table("SYS_ORG")
.field("ID_",parentOrgId) .field("ID_",parentOrgId)
.field("PARENT_ID_",null) .field("PARENT_ID_",null)
.field("CODE_","") .field("CODE_","0000")
.field("NAME_","沪农商村镇银行") .field("NAME_","沪农商村镇银行")
.field("ENABLE_",1) .field("ENABLE_",1)
.field("DATA_COME_FROM_","INPUT") .field("DATA_COME_FROM_","INPUT")
@ -98,7 +98,7 @@ public class OrgInitializer implements ApplicationInitializer {
.table("SYS_ORG") .table("SYS_ORG")
.field("ID_", UUID.randomUUID().toString()) .field("ID_", UUID.randomUUID().toString())
.field("PARENT_ID_", parentOrgId) .field("PARENT_ID_", parentOrgId)
.field("CODE_", "000" + i) .field("CODE_", "010" + i)
.field("NAME_", childNames[i]) .field("NAME_", childNames[i])
.field("ENABLE_", 1) .field("ENABLE_", 1)
.field("DATA_COME_FROM_", "INPUT") .field("DATA_COME_FROM_", "INPUT")

4
io.sc.platform.system/src/main/java/io/sc/platform/system/initializer/RoleAndMenuInitializer.java

@ -4,8 +4,8 @@ import io.sc.platform.core.initializer.ApplicationInitializer;
import io.sc.platform.core.initializer.ApplicationInitializerExecuteException; import io.sc.platform.core.initializer.ApplicationInitializerExecuteException;
import io.sc.platform.jdbc.sql.builder.SqlBuilder; import io.sc.platform.jdbc.sql.builder.SqlBuilder;
import io.sc.platform.security.service.support.Role; import io.sc.platform.security.service.support.Role;
import io.sc.platform.system.menu.convertor.MenuEntityVoConvertor;
import io.sc.platform.system.menu.jpa.entity.MenuEntity; import io.sc.platform.system.menu.jpa.entity.MenuEntity;
import io.sc.platform.system.menu.mapper.MenuEntityMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -65,7 +65,7 @@ public class RoleAndMenuInitializer implements ApplicationInitializer{
} }
private List<MenuEntity> findMenus(){ private List<MenuEntity> findMenus(){
return jdbcTemplate.query("select * from SYS_MENU",new MenuEntityVoConvertor()); return jdbcTemplate.query("select * from SYS_MENU",new MenuEntityMapper());
} }
private void insertRoleAndMenu(String roleId,String menuId){ private void insertRoleAndMenu(String roleId,String menuId){

47
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/controller/MenuWebController.java

@ -1,16 +1,28 @@
package io.sc.platform.system.menu.controller; package io.sc.platform.system.menu.controller;
import io.sc.platform.mvc.controller.support.RestCrudController; import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.mvc.plugins.PluginManager;
import io.sc.platform.mvc.plugins.item.FrontEndRoute;
import io.sc.platform.mvc.plugins.item.FrontEndRouteMeta;
import io.sc.platform.mvc.plugins.item.FrontEndRouteMetaAction;
import io.sc.platform.mvc.support.CascadeMany2Many; import io.sc.platform.mvc.support.CascadeMany2Many;
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.system.api.menu.MenuRouteActionVo;
import io.sc.platform.system.api.menu.MenuRouteVo;
import io.sc.platform.system.api.menu.MenuVo; import io.sc.platform.system.api.menu.MenuVo;
import io.sc.platform.system.menu.jpa.entity.MenuEntity; import io.sc.platform.system.menu.jpa.entity.MenuEntity;
import io.sc.platform.system.menu.jpa.repository.MenuRepository; import io.sc.platform.system.menu.jpa.repository.MenuRepository;
import io.sc.platform.system.menu.service.MenuService; import io.sc.platform.system.menu.service.MenuService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -18,6 +30,41 @@ import java.util.Map;
@RequestMapping("/api/system/menu") @RequestMapping("/api/system/menu")
public class MenuWebController extends RestCrudController<MenuVo,MenuEntity,String, MenuRepository, MenuService> { public class MenuWebController extends RestCrudController<MenuVo,MenuEntity,String, MenuRepository, MenuService> {
@Override
protected Page<MenuVo> query(HttpServletRequest request, HttpServletResponse response, QueryParameter queryParameter) throws Exception {
Sort sort =queryParameter.getSort();
if(sort==null){
queryParameter.addSortBy("order");
}
String widthRouteActionString =request.getParameter("widthRouteAction");
if(!"true".equalsIgnoreCase(widthRouteActionString)){
return super.query(request, response, queryParameter);
}
Page<MenuVo> result =super.query(request, response, queryParameter);
if(result!=null && result.getContent()!=null && result.getContent().size()>0){
List<MenuVo> vos =new ArrayList<>();
for(MenuVo vo : result.getContent()){
vos.add(vo);
if(vo instanceof MenuRouteVo){
MenuRouteVo routeVo =(MenuRouteVo)vo;
String routeName =routeVo.getRouteName();
FrontEndRoute frontEndRoute =PluginManager.getInstance().getFrontEndRouteByName(routeName);
FrontEndRouteMeta frontEndRouteMeta =frontEndRoute.getMeta();
List<FrontEndRouteMetaAction> frontEndRouteMetaActions =frontEndRouteMeta.getActions();
if(frontEndRouteMetaActions!=null && frontEndRouteMetaActions.size()>0){
for(FrontEndRouteMetaAction frontEndRouteMetaAction : frontEndRouteMetaActions){
String name =frontEndRouteMetaAction.getName();
String i18nKey =frontEndRouteMetaAction.getI18nKey();
vos.add(new MenuRouteActionVo(vo.getId()+"."+name,name,i18nKey,vo.getId()));
}
}
}
}
return new PageImpl<>(vos,result.getPageable(),result.getTotalElements());
}
return QueryResult.emptyPage();
}
@PostMapping("addMenu") @PostMapping("addMenu")
public void addMenu(@RequestBody Map<String,String> map) throws Exception{ public void addMenu(@RequestBody Map<String,String> map) throws Exception{
service.addMenu(map); service.addMenu(map);

28
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/convertor/MenuEntityPluginConvertor.java

@ -1,23 +1,29 @@
package io.sc.platform.system.menu.convertor; package io.sc.platform.system.menu.convertor;
import io.sc.platform.orm.EntityVoConverter;
import io.sc.platform.system.api.menu.MenuVo;
import io.sc.platform.system.menu.jpa.entity.*; import io.sc.platform.system.menu.jpa.entity.*;
import io.sc.platform.system.plugins.item.*; import io.sc.platform.system.plugins.item.*;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
* 菜单 Entity 对象和菜单插件 Item 对象之间的转换器类 * 菜单 Entity 对象和菜单插件 Item 对象之间的转换器类
*/ */
public class MenuEntityPluginConvertor implements EntityVoConverter<MenuEntity, MenuItem> { public class MenuEntityPluginConvertor {
@Override public List<MenuEntity> fromVo(List<MenuItem> vos) {
public MenuItem toVo(MenuEntity entity) { if(vos!=null && !vos.isEmpty()){
return null; List<MenuEntity> result =new ArrayList<>(vos.size());
for(MenuItem menuItem : vos){
result.add(fromVo(menuItem));
}
return result;
}
return Collections.emptyList();
} }
@Override
public MenuEntity fromVo(MenuItem vo) { public MenuEntity fromVo(MenuItem vo) {
if(vo==null){ if(vo==null){
return null; return null;
@ -38,9 +44,9 @@ public class MenuEntityPluginConvertor implements EntityVoConverter<MenuEntity,
entity.setRouteName(item.getRouteName()); entity.setRouteName(item.getRouteName());
entity.setRouteQuery(item.getRouteQuery()); entity.setRouteQuery(item.getRouteQuery());
result =entity; result =entity;
}else if(vo instanceof MenuItemSeperator){ }else if(vo instanceof MenuItemSeparator){
MenuItemSeperator item =(MenuItemSeperator)vo; MenuItemSeparator item =(MenuItemSeparator)vo;
MenuSeperatorEntity entity =new MenuSeperatorEntity(); MenuSeparatorEntity entity =new MenuSeparatorEntity();
result =entity; result =entity;
}else if(vo instanceof MenuItemUrl){ }else if(vo instanceof MenuItemUrl){
MenuItemUrl item =(MenuItemUrl)vo; MenuItemUrl item =(MenuItemUrl)vo;
@ -51,7 +57,7 @@ public class MenuEntityPluginConvertor implements EntityVoConverter<MenuEntity,
} }
if(result!=null) { if(result!=null) {
result.setId(vo.getId()); result.setId(vo.getId());
result.setName((vo instanceof MenuItemSeperator) ? "seperator-" + UUID.randomUUID().toString() : vo.getId()); result.setName((vo instanceof MenuItemSeparator) ? "seperator-" + UUID.randomUUID().toString() : vo.getId());
result.setTitleI18nKey(vo.getTitleI18nKey()); result.setTitleI18nKey(vo.getTitleI18nKey());
result.setIcon(vo.getIcon()); result.setIcon(vo.getIcon());
result.setOrder(vo.getOrder()); result.setOrder(vo.getOrder());

41
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuEntity.java

@ -3,16 +3,13 @@ package io.sc.platform.system.menu.jpa.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.sc.platform.orm.IdClearable; import io.sc.platform.orm.IdClearable;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
import io.sc.platform.orm.converter.NumericBooleanConverter; import io.sc.platform.orm.converter.NumericBooleanConverter;
import io.sc.platform.orm.entity.AuditorEntity;
import io.sc.platform.orm.entity.CorporationAuditorEntity; import io.sc.platform.orm.entity.CorporationAuditorEntity;
import io.sc.platform.system.api.menu.MenuVo; import io.sc.platform.system.api.menu.MenuVo;
import io.sc.platform.system.menu.jpa.support.MenuEntityJsonSerializer; import io.sc.platform.system.enums.MenuType;
import io.sc.platform.system.org.jpa.entity.OrgEntity; import io.sc.platform.system.org.jpa.entity.OrgEntity;
import io.sc.platform.system.org.jpa.support.OrgEntityJsonSerializer;
import io.sc.platform.system.plugins.item.*;
import io.sc.platform.system.role.jpa.entity.RoleEntity; import io.sc.platform.system.role.jpa.entity.RoleEntity;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
@ -34,7 +31,7 @@ import java.util.Objects;
@JsonSubTypes({ @JsonSubTypes({
@JsonSubTypes.Type(value = MenuGroupEntity.class, name = "GROUP"), @JsonSubTypes.Type(value = MenuGroupEntity.class, name = "GROUP"),
@JsonSubTypes.Type(value = MenuRouteEntity.class, name = "ROUTE"), @JsonSubTypes.Type(value = MenuRouteEntity.class, name = "ROUTE"),
@JsonSubTypes.Type(value = MenuSeperatorEntity.class, name = "SEPERATOR"), @JsonSubTypes.Type(value = MenuSeparatorEntity.class, name = "SEPARATOR"),
@JsonSubTypes.Type(value = MenuUrlEntity.class, name = "URL"), @JsonSubTypes.Type(value = MenuUrlEntity.class, name = "URL"),
@JsonSubTypes.Type(value = MenuJavascriptEntity.class, name = "JAVASCRIPT") @JsonSubTypes.Type(value = MenuJavascriptEntity.class, name = "JAVASCRIPT")
}) })
@ -49,8 +46,8 @@ public abstract class MenuEntity extends CorporationAuditorEntity<MenuVo> implem
//类型 //类型
@Column(name="TYPE_", length=20, insertable=false,updatable=false) @Column(name="TYPE_", length=20, insertable=false,updatable=false)
@Size(max=20) @Enumerated(EnumType.STRING)
protected String type; protected MenuType type;
//名称 //名称
@Column(name="NAME_", length=255) @Column(name="NAME_", length=255)
@ -104,18 +101,18 @@ public abstract class MenuEntity extends CorporationAuditorEntity<MenuVo> implem
@JoinColumn(name="PARENT_ID_") @JoinColumn(name="PARENT_ID_")
protected MenuGroupEntity parent; protected MenuGroupEntity parent;
public static void toVo(MenuVo vo, MenuEntity entity){ public void toVo(MenuVo vo){
if(vo!=null && entity!=null){ if(vo!=null){
CorporationAuditorEntity.toVo(vo,entity); super.toVo(vo);
vo.setId(entity.getId()); vo.setId(this.getId());
vo.setType(entity.getType()); vo.setType(this.getType());
vo.setName(entity.getName()); vo.setName(this.getName());
vo.setTitleI18nKey(entity.getTitleI18nKey()); vo.setTitleI18nKey(this.getTitleI18nKey());
vo.setIcon(entity.getIcon()); vo.setIcon(this.getIcon());
vo.setEnable(entity.getEnable()); vo.setEnable(this.getEnable());
vo.setOrder(entity.getOrder()); vo.setOrder(this.getOrder());
vo.setAuthorizeExpression(entity.getAuthorizeExpression()); vo.setAuthorizeExpression(this.getAuthorizeExpression());
vo.setParent(entity.getParent()==null?null:entity.getParent().getId()); vo.setParent(this.getParent()==null?null:this.getParent().getId());
} }
} }
@ -127,11 +124,11 @@ public abstract class MenuEntity extends CorporationAuditorEntity<MenuVo> implem
this.id = id; this.id = id;
} }
public String getType() { public MenuType getType() {
return type; return type;
} }
public void setType(String type) { public void setType(MenuType type) {
this.type = type; this.type = type;
} }

2
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuGroupEntity.java

@ -26,7 +26,7 @@ public class MenuGroupEntity extends MenuEntity {
@Override @Override
public MenuVo toVo() { public MenuVo toVo() {
MenuGroupVo vo =new MenuGroupVo(); MenuGroupVo vo =new MenuGroupVo();
MenuEntity.toVo(vo,this); super.toVo(vo);
return vo; return vo;
} }

2
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuJavascriptEntity.java

@ -27,7 +27,7 @@ public class MenuJavascriptEntity extends MenuEntity {
@Override @Override
public MenuVo toVo() { public MenuVo toVo() {
MenuJavascriptVo vo =new MenuJavascriptVo(); MenuJavascriptVo vo =new MenuJavascriptVo();
MenuEntity.toVo(vo,this); super.toVo(vo);
vo.setJavaScript(this.getJavaScript()); vo.setJavaScript(this.getJavaScript());
return vo; return vo;
} }

2
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuRouteEntity.java

@ -39,7 +39,7 @@ public class MenuRouteEntity extends MenuEntity {
@Override @Override
public MenuVo toVo() { public MenuVo toVo() {
MenuRouteVo vo =new MenuRouteVo(); MenuRouteVo vo =new MenuRouteVo();
MenuEntity.toVo(vo,this); super.toVo(vo);
vo.setRouteName(this.getRouteName()); vo.setRouteName(this.getRouteName());
vo.setRouteQuery(this.getRouteQuery()); vo.setRouteQuery(this.getRouteQuery());
return vo; return vo;

26
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuSeparatorEntity.java

@ -0,0 +1,26 @@
package io.sc.platform.system.menu.jpa.entity;
import io.sc.platform.system.api.menu.MenuSeparatorVo;
import io.sc.platform.system.api.menu.MenuVo;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
/**
* 分隔符菜单项实体类
*/
@Entity
@DiscriminatorValue("SEPARATOR")
public class MenuSeparatorEntity extends MenuEntity {
public MenuSeparatorEntity() {}
public MenuSeparatorEntity(String id) {
this.id =id;
}
@Override
public MenuVo toVo() {
MenuSeparatorVo vo =new MenuSeparatorVo();
super.toVo(vo);
return vo;
}
}

27
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuSeperatorEntity.java

@ -1,27 +0,0 @@
package io.sc.platform.system.menu.jpa.entity;
import io.sc.platform.system.api.menu.MenuRouteVo;
import io.sc.platform.system.api.menu.MenuSeperatorVo;
import io.sc.platform.system.api.menu.MenuVo;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
/**
* 分隔符菜单项实体类
*/
@Entity
@DiscriminatorValue("SEPERATOR")
public class MenuSeperatorEntity extends MenuEntity {
public MenuSeperatorEntity() {}
public MenuSeperatorEntity(String id) {
this.id =id;
}
@Override
public MenuVo toVo() {
MenuSeperatorVo vo =new MenuSeperatorVo();
MenuEntity.toVo(vo,this);
return vo;
}
}

3
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/jpa/entity/MenuUrlEntity.java

@ -1,6 +1,5 @@
package io.sc.platform.system.menu.jpa.entity; package io.sc.platform.system.menu.jpa.entity;
import io.sc.platform.system.api.menu.MenuSeperatorVo;
import io.sc.platform.system.api.menu.MenuUrlVo; import io.sc.platform.system.api.menu.MenuUrlVo;
import io.sc.platform.system.api.menu.MenuVo; import io.sc.platform.system.api.menu.MenuVo;
import io.sc.platform.system.enums.UrlOpenType; import io.sc.platform.system.enums.UrlOpenType;
@ -32,7 +31,7 @@ public class MenuUrlEntity extends MenuEntity {
@Override @Override
public MenuVo toVo() { public MenuVo toVo() {
MenuUrlVo vo =new MenuUrlVo(); MenuUrlVo vo =new MenuUrlVo();
MenuEntity.toVo(vo,this); super.toVo(vo);
vo.setUrl(this.getUrl()); vo.setUrl(this.getUrl());
vo.setUrlOpenType(this.getUrlOpenType()); vo.setUrlOpenType(this.getUrlOpenType());
return vo; return vo;

69
io.sc.platform.system/src/main/java/io/sc/platform/system/menu/convertor/MenuEntityVoConvertor.java → io.sc.platform.system/src/main/java/io/sc/platform/system/menu/mapper/MenuEntityMapper.java

@ -1,10 +1,8 @@
package io.sc.platform.system.menu.convertor; package io.sc.platform.system.menu.mapper;
import io.sc.platform.core.util.EnumUtil; import io.sc.platform.core.util.EnumUtil;
import io.sc.platform.core.util.ObjectMapper4Json; import io.sc.platform.core.util.ObjectMapper4Json;
import io.sc.platform.orm.EntityVoConverter;
import io.sc.platform.orm.api.enums.DataComeFrom; import io.sc.platform.orm.api.enums.DataComeFrom;
import io.sc.platform.system.api.menu.*;
import io.sc.platform.system.enums.MenuType; import io.sc.platform.system.enums.MenuType;
import io.sc.platform.system.enums.UrlOpenType; import io.sc.platform.system.enums.UrlOpenType;
import io.sc.platform.system.menu.jpa.entity.*; import io.sc.platform.system.menu.jpa.entity.*;
@ -16,22 +14,21 @@ import org.springframework.util.StringUtils;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* 菜单 Entity 对象和菜单 Vo 对象对象之间的转换器类 * 菜单 Entity 对象和菜单 Vo 对象对象之间的转换器类
*/ */
public class MenuEntityVoConvertor implements EntityVoConverter<MenuEntity, MenuVo>, RowMapper<MenuEntity> { public class MenuEntityMapper implements RowMapper<MenuEntity> {
private static final Logger log = LoggerFactory.getLogger(MenuEntityVoConvertor.class); private static final Logger log = LoggerFactory.getLogger(MenuEntityMapper.class);
@Override @Override
public MenuEntity mapRow(ResultSet rs, int rowNum) throws SQLException { public MenuEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
MenuType type =MenuType.valueOf(rs.getString("TYPE_")); MenuType type =MenuType.valueOf(rs.getString("TYPE_"));
String parentId =rs.getString("PARENT_ID_"); String parentId =rs.getString("PARENT_ID_");
MenuEntity menuEntity =null; MenuEntity menuEntity =null;
if(MenuType.SEPERATOR.equals(type)){ if(MenuType.SEPARATOR.equals(type)){
MenuSeperatorEntity entity =new MenuSeperatorEntity(); MenuSeparatorEntity entity =new MenuSeparatorEntity();
menuEntity =entity; menuEntity =entity;
}else if(MenuType.GROUP.equals(type)){ }else if(MenuType.GROUP.equals(type)){
MenuGroupEntity entity =new MenuGroupEntity(); MenuGroupEntity entity =new MenuGroupEntity();
@ -63,7 +60,7 @@ public class MenuEntityVoConvertor implements EntityVoConverter<MenuEntity, Menu
} }
if(menuEntity!=null){ if(menuEntity!=null){
menuEntity.setId(rs.getString("ID_")); menuEntity.setId(rs.getString("ID_"));
menuEntity.setType(rs.getString("TYPE_")); menuEntity.setType(EnumUtil.toEnum(rs.getString("TYPE_"),MenuType.class));
menuEntity.setName(rs.getString("NAME_")); menuEntity.setName(rs.getString("NAME_"));
menuEntity.setTitleI18nKey(rs.getString("TITLE_I18N_KEY_")); menuEntity.setTitleI18nKey(rs.getString("TITLE_I18N_KEY_"));
menuEntity.setIcon(rs.getString("ICON_")); menuEntity.setIcon(rs.getString("ICON_"));
@ -81,58 +78,4 @@ public class MenuEntityVoConvertor implements EntityVoConverter<MenuEntity, Menu
} }
return menuEntity; return menuEntity;
} }
@Override
public MenuVo toVo(MenuEntity menuEntity) {
if(menuEntity==null){
return null;
}
MenuVo result =null;
if(menuEntity instanceof MenuGroupEntity){
MenuGroupEntity entity =(MenuGroupEntity)menuEntity;
MenuGroupVo vo =new MenuGroupVo();
result =vo;
}else if(menuEntity instanceof MenuJavascriptEntity){
MenuJavascriptEntity entity =(MenuJavascriptEntity)menuEntity;
MenuJavascriptVo vo =new MenuJavascriptVo();
vo.setJavaScript(entity.getJavaScript());
result =vo;
}else if(menuEntity instanceof MenuRouteEntity){
MenuRouteEntity entity =(MenuRouteEntity)menuEntity;
MenuRouteVo vo =new MenuRouteVo();
vo.setRouteName(entity.getRouteName());
vo.setRouteQuery(entity.getRouteQuery());
result =vo;
}else if(menuEntity instanceof MenuSeperatorEntity){
MenuSeperatorEntity entity =(MenuSeperatorEntity)menuEntity;
MenuSeperatorVo vo =new MenuSeperatorVo();
result =vo;
}else if(menuEntity instanceof MenuUrlEntity){
MenuUrlEntity entity =(MenuUrlEntity)menuEntity;
MenuUrlVo vo =new MenuUrlVo();
vo.setUrl(entity.getUrl());
vo.setUrlOpenType(entity.getUrlOpenType());
result =vo;
}
if(result!=null) {
result.setParent(menuEntity.getParent()==null?null:menuEntity.getParent().getId());
result.setId(menuEntity.getId());
result.setType(menuEntity.getType());
result.setName(menuEntity.getName());
result.setTitleI18nKey(menuEntity.getTitleI18nKey());
result.setIcon(menuEntity.getIcon());
result.setEnable(menuEntity.getEnable());
result.setAuthorizeExpression(menuEntity.getAuthorizeExpression());
result.setOrder(menuEntity.getOrder());
}
return result;
}
@Override
public MenuEntity fromVo(MenuVo vo) {
if(vo==null){
return null;
}
return null;
}
} }

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save