Forráskód Böngészése

Merge branch 'master' into springboot3

# Conflicts:
#	db/tables_nacos.sql
#	jeecg-boot-base-core/pom.xml
#	jeecg-boot-base-core/src/main/java/org/jeecg/config/Swagger2Config.java
#	jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
#	jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysFilesController.java
#	jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java
#	jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysFiles.java
#	jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java
#	jeecg-module-system/jeecg-system-start/pom.xml
#	jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml
#	jeecg-server-cloud/jeecg-cloud-gateway/pom.xml
#	jeecg-server-cloud/jeecg-visual/jeecg-cloud-sentinel/pom.xml
#	pom.xml
EightMonth 1 éve
szülő
commit
06b41ae479
100 módosított fájl, 19791 hozzáadás és 14100 törlés
  1. 1 0
      .gitignore
  2. 7 3
      README-EN.md
  3. 9 5
      README.md
  4. 864 115
      db/jeecgboot-mysql-5.7.sql
  5. 135 134
      db/tables_nacos.sql
  6. BIN
      db/其他数据库/jeecgboot-oracle11g.dmp
  7. 3443 2157
      db/其他数据库/jeecgboot-oracle11g.sql
  8. 13769 10717
      db/其他数据库/jeecgboot-sqlserver2019.sql
  9. 2 2
      jeecg-boot-base-core/pom.xml
  10. 2 2
      jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java
  11. 2 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/DataLogDTO.java
  12. 7 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/OnlineAuthDTO.java
  13. 7 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java
  14. 2 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
  15. 6 2
      jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/RoleIndexConfigEnum.java
  16. 10 0
      jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/SysFilesModel.java
  17. 23 3
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java
  18. 2 2
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DySmsHelper.java
  19. 18 50
      jeecg-boot-base-core/src/main/java/org/jeecg/common/util/sqlInjection/parse/ConstAnalyzer.java
  20. 16 0
      jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/IgnoreAuth.java
  21. 108 6
      jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
  22. 3 1
      jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java
  23. 10 2
      jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java
  24. 7 1
      jeecg-module-demo/pom.xml
  25. 34 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/cache/LocalCache.java
  26. 74 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/controller/ChatController.java
  27. 136 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/listeners/OpenAISSEEventSourceListener.java
  28. 56 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/service/ChatService.java
  29. 199 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/service/impl/ChatServiceImpl.java
  30. 25 0
      jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/vo/ChatHistoryVO.java
  31. 1 1
      jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/pom.xml
  32. 7 21
      jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
  33. 5 16
      jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java
  34. 1 1
      jeecg-module-system/jeecg-system-api/jeecg-system-local-api/pom.xml
  35. 3 16
      jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
  36. 1 1
      jeecg-module-system/jeecg-system-api/pom.xml
  37. 1 1
      jeecg-module-system/jeecg-system-biz/pom.xml
  38. 17 25
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java
  39. 1 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/enums/RangeDateEnum.java
  40. 25 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/constant/DefIndexConst.java
  41. 0 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java
  42. 38 35
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java
  43. 5 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java
  44. 3 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
  45. 0 152
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysFilesController.java
  46. 57 25
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java
  47. 10 7
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java
  48. 28 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java
  49. 5 3
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java
  50. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java
  51. 45 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java
  52. 0 142
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysFiles.java
  53. 6 6
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysPermission.java
  54. 13 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java
  55. 0 14
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysFilesMapper.java
  56. 2 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysPermissionMapper.java
  57. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepartMapper.java
  58. 2 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserMapper.java
  59. 22 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml
  60. 88 30
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysPermissionMapper.xml
  61. 7 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserDepartMapper.xml
  62. 8 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserMapper.xml
  63. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserTenantMapper.xml
  64. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDictService.java
  65. 0 14
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysFilesService.java
  66. 31 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysRoleIndexService.java
  67. 7 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysRoleService.java
  68. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java
  69. 8 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java
  70. 1 1
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserTenantService.java
  71. 20 33
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java
  72. 17 22
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCommentServiceImpl.java
  73. 43 32
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java
  74. 0 19
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysFilesServiceImpl.java
  75. 21 9
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java
  76. 76 4
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysRoleIndexServiceImpl.java
  77. 14 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysRoleServiceImpl.java
  78. 12 7
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java
  79. 19 8
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java
  80. 14 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java
  81. 33 6
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/PermissionDataUtil.java
  82. 0 57
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysFileLogVo.java
  83. 0 142
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysFilesVo.java
  84. 3 1
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl
  85. 6 2
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl
  86. 3 1
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl
  87. 6 2
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl
  88. 12 4
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/utils.ftl
  89. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/uniapp/${entityName}Form.vue
  90. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/uniapp/${entityName}List.vue
  91. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql
  92. 18 6
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
  93. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql
  94. 18 6
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
  95. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql
  96. 8 2
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
  97. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql
  98. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql
  99. 18 6
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
  100. 0 0
      jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql

+ 1 - 0
.gitignore

@@ -12,3 +12,4 @@ rebel.xml
 os_del.cmd
 os_del_doc.cmd
 .svn
+derby.log

+ 7 - 3
README-EN.md

@@ -7,13 +7,13 @@
 JEECG BOOT Low Code Development Platform
 ===============
 
-当前最新版本: 3.6.2(发布日期:2024-01-08
+当前最新版本: 3.6.3(发布日期:2024-03-11
 
 
 [![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
 [![](https://img.shields.io/badge/Author-guojusoft-orange.svg)](http://www.jeecg.com)
 [![](https://img.shields.io/badge/Blog-blog-blue.svg)](https://jeecg.blog.csdn.net)
-[![](https://img.shields.io/badge/version-3.6.2-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
+[![](https://img.shields.io/badge/version-3.6.3-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
 [![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot)
 [![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)
 
@@ -76,7 +76,7 @@ Docker starts the project
 - [Docker starts the monomer background](https://help.jeecg.com/java/setup/docker/up.html)
 - [Docker starts the Vue3 front-end](http://help.jeecg.com/publish/docker.html)
 - [Docker starts the micro-service background](https://help.jeecg.com/java/springcloud/docker.html)
-
+- [ChatGPT AI Config](https://help.jeecg.com/java/chatgpt.html)
 
 
 
@@ -441,6 +441,10 @@ Technical Architecture:
 
 ### Effect of system
 
+##### ChatGPT AI Dialog
+> Go to the JeecgBoot background home page and click "AI Assistant" in the middle of the right side of the home page. The AI Assistant dialog screen is displayed.
+![](https://oscimg.oschina.net/oscnet/up-7c6405641a40f56638999d52da0cb5b4343.png)
+
 
 ##### PC
 ![](https://oscimg.oschina.net/oscnet/up-000530d95df337b43089ac77e562494f454.png)

+ 9 - 5
README.md

@@ -7,13 +7,13 @@
 JEECG BOOT 低代码开发平台
 ===============
 
-当前最新版本: 3.6.2(发布日期:2024-01-08
+当前最新版本: 3.6.3(发布日期:2024-03-11
 
 
 [![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
 [![](https://img.shields.io/badge/Author-北京国炬软件-orange.svg)](http://jeecg.com/aboutusIndex)
 [![](https://img.shields.io/badge/Blog-官方博客-blue.svg)](https://jeecg.blog.csdn.net)
-[![](https://img.shields.io/badge/version-3.6.2-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
+[![](https://img.shields.io/badge/version-3.6.3-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
 [![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot)
 [![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)
 
@@ -69,7 +69,7 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
 - [通过IDEA启动前后端项目](https://help.jeecg.com/java/setup/idea/startup.html)
 - [Vue3前端项目快速启动](http://help.jeecg.com/setup/startup.html)
 - [单体快速切换为微服务版](https://help.jeecg.com/java/springcloud/switchcloud/monomer.html)
-
+- [ChatGPT AI助手配置文档](https://help.jeecg.com/java/chatgpt.html)
 
 Docker快速启动项目
 -----------------------------------
@@ -196,8 +196,8 @@ Star走势图
 * 17.支持SAAS服务模式,提供SaaS多租户架构方案。
 * 18.分布式文件服务,集成minio、阿里OSS等优秀的第三方,提供便捷的文件上传与管理,同时也支持本地存储。
 * 19.主流数据库兼容,一套代码完全兼容Mysql、Postgresql、Oracle、Sqlserver、MariaDB、达梦等主流数据库。
-* 20.集成工作流activiti、flowable,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码;
-* 21.低代码能力:在线流程设计,采用开源Activiti流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转
+* 20.集成工作流flowable、activiti,并实现了只需在页面配置流程转向,可极大的简化bpm工作流的开发;用bpm的流程设计器画出了流程走向,一个工作流基本就完成了,只需写很少量的java代码;
+* 21.低代码能力:在线流程设计,采用开源flowable、activiti流程引擎,实现在线画流程,自定义表单,表单挂靠,业务流转
 * 22.多数据源:及其简易的使用方式,在线配置数据源配置,便捷的从其他数据抓取数据;
 * 23.提供单点登录CAS集成方案,项目中已经提供完善的对接代码
 * 24.低代码能力:表单设计器,支持用户自定义表单布局,支持单表,一对多表单、支持select、radio、checkbox、textarea、date、popup、列表、宏等控件
@@ -477,6 +477,10 @@ JeecgBoot企业版本默认集成了activiti和flowable两套方案,大家在
 ### 系统效果
 
 
+##### ChatGPT AI交互
+> 进入JeecgBoot后台首页,点击首页右侧中间“AI助手”,弹出AI助手对话界面。
+![](https://oscimg.oschina.net/oscnet/up-7c6405641a40f56638999d52da0cb5b4343.png)
+
 
 ##### PC端
 ![](https://oscimg.oschina.net/oscnet/up-000530d95df337b43089ac77e562494f454.png)

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 864 - 115
db/jeecgboot-mysql-5.7.sql


+ 135 - 134
db/tables_nacos.sql

@@ -1,5 +1,6 @@
 CREATE database if NOT EXISTS `nacos` default character set utf8mb4 collate utf8mb4_general_ci;
 use `nacos`;
+
 /*
  Navicat Premium Data Transfer
 
@@ -13,7 +14,7 @@ use `nacos`;
  Target Server Version : 50738
  File Encoding         : 65001
 
- Date: 01/03/2024 15:36:53
+ Date: 06/03/2024 15:44:59
 */
 
 SET NAMES utf8mb4;
@@ -24,25 +25,25 @@ SET FOREIGN_KEY_CHECKS = 0;
 -- ----------------------------
 DROP TABLE IF EXISTS `config_info`;
 CREATE TABLE `config_info`  (
-  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
-  `group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
-  `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
-  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
-  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
-  `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
-  `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
-  `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
-  `c_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `c_use` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `effect` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `c_schema` text CHARACTER SET utf8 COLLATE utf8_bin NULL,
-  `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE INDEX `uk_configinfo_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE
+                                `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+                                `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+                                `group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
+                                `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
+                                `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+                                `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+                                `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
+                                `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
+                                `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
+                                `c_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                `c_use` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                `effect` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                `type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                `c_schema` text CHARACTER SET utf8 COLLATE utf8_bin NULL,
+                                `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
+                                PRIMARY KEY (`id`) USING BTREE,
+                                UNIQUE INDEX `uk_configinfo_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 44 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -72,16 +73,16 @@ INSERT INTO `config_info` VALUES (42, 'jeecg-sharding-multi.yaml', 'DEFAULT_GROU
 -- ----------------------------
 DROP TABLE IF EXISTS `config_info_aggr`;
 CREATE TABLE `config_info_aggr`  (
-  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
-  `group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
-  `datum_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'datum_id',
-  `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '内容',
-  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
-  `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE INDEX `uk_configinfoaggr_datagrouptenantdatum`(`data_id`, `group_id`, `tenant_id`, `datum_id`) USING BTREE
+                                     `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+                                     `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+                                     `group_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+                                     `datum_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'datum_id',
+                                     `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '内容',
+                                     `gmt_modified` datetime NOT NULL COMMENT '修改时间',
+                                     `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                     `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
+                                     PRIMARY KEY (`id`) USING BTREE,
+                                     UNIQUE INDEX `uk_configinfoaggr_datagrouptenantdatum`(`data_id`, `group_id`, `tenant_id`, `datum_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '增加租户字段' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -93,21 +94,21 @@ CREATE TABLE `config_info_aggr`  (
 -- ----------------------------
 DROP TABLE IF EXISTS `config_info_beta`;
 CREATE TABLE `config_info_beta`  (
-  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
-  `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
-  `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
-  `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
-  `beta_ips` varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'betaIps',
-  `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
-  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
-  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
-  `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
-  `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
-  `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE INDEX `uk_configinfobeta_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE
+                                     `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+                                     `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+                                     `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+                                     `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
+                                     `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
+                                     `beta_ips` varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'betaIps',
+                                     `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
+                                     `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+                                     `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+                                     `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
+                                     `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
+                                     `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
+                                     `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
+                                     PRIMARY KEY (`id`) USING BTREE,
+                                     UNIQUE INDEX `uk_configinfobeta_datagrouptenant`(`data_id`, `group_id`, `tenant_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info_beta' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -119,21 +120,21 @@ CREATE TABLE `config_info_beta`  (
 -- ----------------------------
 DROP TABLE IF EXISTS `config_info_tag`;
 CREATE TABLE `config_info_tag`  (
-  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
-  `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
-  `tag_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_id',
-  `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
-  `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
-  `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
-  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
-  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
-  `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
-  `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
-  `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE INDEX `uk_configinfotag_datagrouptenanttag`(`data_id`, `group_id`, `tenant_id`, `tag_id`) USING BTREE
+                                    `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+                                    `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+                                    `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+                                    `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
+                                    `tag_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_id',
+                                    `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
+                                    `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'content',
+                                    `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'md5',
+                                    `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+                                    `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+                                    `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT 'source user',
+                                    `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip',
+                                    `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
+                                    PRIMARY KEY (`id`) USING BTREE,
+                                    UNIQUE INDEX `uk_configinfotag_datagrouptenanttag`(`data_id`, `group_id`, `tenant_id`, `tag_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_info_tag' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -145,16 +146,16 @@ CREATE TABLE `config_info_tag`  (
 -- ----------------------------
 DROP TABLE IF EXISTS `config_tags_relation`;
 CREATE TABLE `config_tags_relation`  (
-  `id` bigint(20) NOT NULL COMMENT 'id',
-  `tag_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_name',
-  `tag_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tag_type',
-  `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
-  `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
-  `nid` bigint(20) NOT NULL AUTO_INCREMENT,
-  PRIMARY KEY (`nid`) USING BTREE,
-  UNIQUE INDEX `uk_configtagrelation_configidtag`(`id`, `tag_name`, `tag_type`) USING BTREE,
-  INDEX `idx_tenant_id`(`tenant_id`) USING BTREE
+                                         `id` bigint(20) NOT NULL COMMENT 'id',
+                                         `tag_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'tag_name',
+                                         `tag_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tag_type',
+                                         `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'data_id',
+                                         `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'group_id',
+                                         `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
+                                         `nid` bigint(20) NOT NULL AUTO_INCREMENT,
+                                         PRIMARY KEY (`nid`) USING BTREE,
+                                         UNIQUE INDEX `uk_configtagrelation_configidtag`(`id`, `tag_name`, `tag_type`) USING BTREE,
+                                         INDEX `idx_tenant_id`(`tenant_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'config_tag_relation' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -166,18 +167,18 @@ CREATE TABLE `config_tags_relation`  (
 -- ----------------------------
 DROP TABLE IF EXISTS `group_capacity`;
 CREATE TABLE `group_capacity`  (
-  `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
-  `quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值',
-  `usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量',
-  `max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
-  `max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数,,0表示使用默认值',
-  `max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
-  `max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量',
-  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
-  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE INDEX `uk_group_id`(`group_id`) USING BTREE
+                                   `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+                                   `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
+                                   `quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值',
+                                   `usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量',
+                                   `max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
+                                   `max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数,,0表示使用默认值',
+                                   `max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
+                                   `max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量',
+                                   `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+                                   `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+                                   PRIMARY KEY (`id`) USING BTREE,
+                                   UNIQUE INDEX `uk_group_id`(`group_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '集群、各Group容量信息表' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -189,24 +190,24 @@ CREATE TABLE `group_capacity`  (
 -- ----------------------------
 DROP TABLE IF EXISTS `his_config_info`;
 CREATE TABLE `his_config_info`  (
-  `id` bigint(20) UNSIGNED NOT NULL,
-  `nid` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-  `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
-  `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
-  `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
-  `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
-  `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
-  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
-  `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL,
-  `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `op_type` char(10) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
-  `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
-  PRIMARY KEY (`nid`) USING BTREE,
-  INDEX `idx_gmt_create`(`gmt_create`) USING BTREE,
-  INDEX `idx_gmt_modified`(`gmt_modified`) USING BTREE,
-  INDEX `idx_did`(`data_id`) USING BTREE
+                                    `id` bigint(20) UNSIGNED NOT NULL,
+                                    `nid` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
+                                    `data_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+                                    `group_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+                                    `app_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'app_name',
+                                    `content` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+                                    `md5` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                    `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
+                                    `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
+                                    `src_user` text CHARACTER SET utf8 COLLATE utf8_bin NULL,
+                                    `src_ip` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                    `op_type` char(10) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
+                                    `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT '租户字段',
+                                    `encrypted_data_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '加密key',
+                                    PRIMARY KEY (`nid`) USING BTREE,
+                                    INDEX `idx_gmt_create`(`gmt_create`) USING BTREE,
+                                    INDEX `idx_gmt_modified`(`gmt_modified`) USING BTREE,
+                                    INDEX `idx_did`(`data_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 50 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '多租户改造' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -234,10 +235,10 @@ INSERT INTO `his_config_info` VALUES (41, 49, 'jeecg-gateway-dev.yaml', 'DEFAULT
 -- ----------------------------
 DROP TABLE IF EXISTS `permissions`;
 CREATE TABLE `permissions`  (
-  `role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  `resource` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  `action` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  UNIQUE INDEX `uk_role_permission`(`role`, `resource`, `action`) USING BTREE
+                                `role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+                                `resource` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+                                `action` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+                                UNIQUE INDEX `uk_role_permission`(`role`, `resource`, `action`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -249,9 +250,9 @@ CREATE TABLE `permissions`  (
 -- ----------------------------
 DROP TABLE IF EXISTS `roles`;
 CREATE TABLE `roles`  (
-  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  `role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  UNIQUE INDEX `uk_username_role`(`username`, `role`) USING BTREE
+                          `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+                          `role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+                          UNIQUE INDEX `uk_username_role`(`username`, `role`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -264,18 +265,18 @@ INSERT INTO `roles` VALUES ('nacos', 'ROLE_ADMIN');
 -- ----------------------------
 DROP TABLE IF EXISTS `tenant_capacity`;
 CREATE TABLE `tenant_capacity`  (
-  `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID',
-  `quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值',
-  `usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量',
-  `max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
-  `max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数',
-  `max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
-  `max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量',
-  `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
-  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE INDEX `uk_tenant_id`(`tenant_id`) USING BTREE
+                                    `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+                                    `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID',
+                                    `quota` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '配额,0表示使用默认值',
+                                    `usage` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用量',
+                                    `max_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
+                                    `max_aggr_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '聚合子配置最大个数',
+                                    `max_aggr_size` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
+                                    `max_history_count` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大变更历史数量',
+                                    `gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
+                                    `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
+                                    PRIMARY KEY (`id`) USING BTREE,
+                                    UNIQUE INDEX `uk_tenant_id`(`tenant_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '租户容量信息表' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -287,17 +288,17 @@ CREATE TABLE `tenant_capacity`  (
 -- ----------------------------
 DROP TABLE IF EXISTS `tenant_info`;
 CREATE TABLE `tenant_info`  (
-  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `kp` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'kp',
-  `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
-  `tenant_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_name',
-  `tenant_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tenant_desc',
-  `create_source` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'create_source',
-  `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
-  `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE INDEX `uk_tenant_info_kptenantid`(`kp`, `tenant_id`) USING BTREE,
-  INDEX `idx_tenant_id`(`tenant_id`) USING BTREE
+                                `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+                                `kp` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'kp',
+                                `tenant_id` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_id',
+                                `tenant_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT '' COMMENT 'tenant_name',
+                                `tenant_desc` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'tenant_desc',
+                                `create_source` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'create_source',
+                                `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
+                                `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
+                                PRIMARY KEY (`id`) USING BTREE,
+                                UNIQUE INDEX `uk_tenant_info_kptenantid`(`kp`, `tenant_id`) USING BTREE,
+                                INDEX `idx_tenant_id`(`tenant_id`) USING BTREE
 ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = 'tenant_info' ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------
@@ -311,10 +312,10 @@ INSERT INTO `tenant_info` VALUES (2, '1', 'efc4e412-b1a1-498f-ba01-b31807649a9a'
 -- ----------------------------
 DROP TABLE IF EXISTS `users`;
 CREATE TABLE `users`  (
-  `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  `password` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  `enabled` tinyint(1) NOT NULL,
-  PRIMARY KEY (`username`) USING BTREE
+                          `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+                          `password` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+                          `enabled` tinyint(1) NOT NULL,
+                          PRIMARY KEY (`username`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
 
 -- ----------------------------

BIN
db/其他数据库/jeecgboot-oracle11g.dmp


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 3443 - 2157
db/其他数据库/jeecgboot-oracle11g.sql


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 13769 - 10717
db/其他数据库/jeecgboot-sqlserver2019.sql


+ 2 - 2
jeecg-boot-base-core/pom.xml

@@ -4,7 +4,7 @@
 	<parent>
 		<groupId>org.jeecgframework.boot</groupId>
 		<artifactId>jeecg-boot-parent</artifactId>
-		<version>3.6.2</version>
+		<version>3.6.3</version>
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 	<artifactId>jeecg-boot-base-core</artifactId>
@@ -96,7 +96,7 @@
 		<dependency>
 			<groupId>commons-io</groupId>
 			<artifactId>commons-io</artifactId>
-			<version>${commons.version}</version>
+			<version>${commons-io.version}</version>
 		</dependency>
 		<dependency>
 			<groupId>commons-lang</groupId>

+ 2 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java

@@ -22,10 +22,10 @@ public interface CommonAPI {
 
     /**
      * 2查询用户权限信息
-     * @param username
+     * @param userId
      * @return
      */
-    Set<String> queryUserAuths(String username);
+    Set<String> queryUserAuths(String userId);
 
     /**
      * 3根据 id 查询数据库中存储的 DynamicDataSourceModel

+ 2 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/DataLogDTO.java

@@ -17,6 +17,8 @@ public class DataLogDTO {
 
     private String type;
 
+    private String createName;
+
     public DataLogDTO(){
 
     }

+ 7 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/api/dto/OnlineAuthDTO.java

@@ -30,6 +30,13 @@ public class OnlineAuthDTO implements Serializable {
      */
     private String onlineFormUrl;
 
+    //update-begin---author:chenrui ---date:20240123  for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
+    /**
+     * online工单的地址
+     */
+    private String onlineWorkOrderUrl;
+    //update-end---author:chenrui ---date:20240123  for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
+
     public OnlineAuthDTO(){
 
     }

+ 7 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java

@@ -293,6 +293,13 @@ public class DictAspect {
                 log.debug("translateDictFromTableByKeys.dictCode:" + dictCode);
                 log.debug("translateDictFromTableByKeys.values:" + values);
                 //update-begin---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
+                
+                //update-begin---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串---
+                if(null == dataSource){
+                    dataSource = "";
+                }
+                //update-end---author:wangshuai---date:2024-01-09---for:微服务下为空报错没有参数需要传递空字符串---
+                
                 List<DictModel> texts = commonApi.translateDictFromTableByKeys(table, text, code, values, dataSource);
                 //update-end---author:chenrui ---date:20231221  for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
                 log.debug("translateDictFromTableByKeys.result:" + texts);

+ 2 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java

@@ -377,6 +377,8 @@ public interface CommonConstant {
     /**前端vue3版本Header参数名*/
     String VERSION="X-Version";
 
+    String VERSION_V3 = "v3";
+
     /**存储在线程变量里的动态表名*/
     String DYNAMIC_TABLE_NAME="DYNAMIC_TABLE_NAME";
     /**

+ 6 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/enums/RoleIndexConfigEnum.java

@@ -13,12 +13,16 @@ import java.util.List;
 public enum RoleIndexConfigEnum {
 
     /**首页自定义 admin*/
-    ADMIN("admin", "dashboard/Analysis"),
+//    ADMIN("admin", "dashboard/Analysis"),
     //TEST("test",  "dashboard/IndexChart"),
     /**首页自定义 hr*/
-    HR("hr", "dashboard/IndexBdc");
+//    HR("hr", "dashboard/IndexBdc");
+  
     //DM("dm", "dashboard/IndexTask"),
 
+    // 注:此值仅为防止报错,无任何实际意义
+    ROLE_INDEX_CONFIG_ENUM("RoleIndexConfigEnumDefault", "dashboard/Analysis");
+
     /**
      * 角色编码
      */

+ 10 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/common/system/vo/SysFilesModel.java

@@ -19,6 +19,8 @@ public class SysFilesModel {
     private String storeType;
     /**文件大小(kb)*/
     private Double fileSize;
+    /**租户id*/
+    private String tenantId;
 
     public String getId() {
         return id;
@@ -67,4 +69,12 @@ public class SysFilesModel {
     public void setFileSize(Double fileSize) {
         this.fileSize = fileSize;
     }
+
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(String tenantId) {
+        this.tenantId = tenantId;
+    }
 }

+ 23 - 3
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/CommonUtils.java

@@ -28,7 +28,9 @@ import java.io.InputStream;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -346,8 +348,11 @@ public class CommonUtils {
 
         //返回 host domain
         String baseDomainPath = null;
-        int length = 80;
-        if(length == serverPort){
+        //update-begin---author:wangshuai---date:2024-03-15---for:【QQYUN-8561】企业微信登陆请求接口设置上下文不一致,导致接口404---
+        int httpPort = 80;
+        int httpsPort = 443;
+        if(httpPort == serverPort || httpsPort == serverPort){
+        //update-end---author:wangshuai---date:2024-03-15---for:【QQYUN-8561】企业微信登陆请求接口设置上下文不一致,导致接口404---~
             baseDomainPath = scheme + "://" + serverName  + contextPath ;
         }else{
             baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ;
@@ -467,4 +472,19 @@ public class CommonUtils {
         }
         return false;
     }
+
+    /**
+     * 输出info日志,会捕获异常,防止因为日志问题导致程序异常
+     *
+     * @param msg
+     * @param objects
+     */
+    public static void logInfo(String msg, Object... objects) {
+        try {
+            log.info(msg, objects);
+        } catch (Exception e) {
+            log.warn("{} —— {}", msg, e.getMessage());
+        }
+    }
+
 }

+ 2 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DySmsHelper.java

@@ -62,8 +62,8 @@ public class DySmsHelper {
 
         //update-begin-author:taoyan date:20200811 for:配置类数据获取
         StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
-        logger.info("阿里大鱼短信秘钥 accessKeyId:" + staticConfig.getAccessKeyId());
-        logger.info("阿里大鱼短信秘钥 accessKeySecret:"+ staticConfig.getAccessKeySecret());
+        //logger.info("阿里大鱼短信秘钥 accessKeyId:" + staticConfig.getAccessKeyId());
+        //logger.info("阿里大鱼短信秘钥 accessKeySecret:"+ staticConfig.getAccessKeySecret());
         setAccessKeyId(staticConfig.getAccessKeyId());
         setAccessKeySecret(staticConfig.getAccessKeySecret());
         //update-end-author:taoyan date:20200811 for:配置类数据获取

+ 18 - 50
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/sqlInjection/parse/ConstAnalyzer.java

@@ -1,55 +1,6 @@
 package org.jeecg.common.util.sqlInjection.parse;
 
-import net.sf.jsqlparser.expression.AllValue;
-import net.sf.jsqlparser.expression.AnalyticExpression;
-import net.sf.jsqlparser.expression.AnyComparisonExpression;
-import net.sf.jsqlparser.expression.ArrayConstructor;
-import net.sf.jsqlparser.expression.ArrayExpression;
-import net.sf.jsqlparser.expression.BinaryExpression;
-import net.sf.jsqlparser.expression.CaseExpression;
-import net.sf.jsqlparser.expression.CastExpression;
-import net.sf.jsqlparser.expression.CollateExpression;
-import net.sf.jsqlparser.expression.ConnectByRootOperator;
-import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
-import net.sf.jsqlparser.expression.DateValue;
-import net.sf.jsqlparser.expression.DoubleValue;
-import net.sf.jsqlparser.expression.Expression;
-import net.sf.jsqlparser.expression.ExpressionVisitor;
-import net.sf.jsqlparser.expression.ExtractExpression;
-import net.sf.jsqlparser.expression.Function;
-import net.sf.jsqlparser.expression.HexValue;
-import net.sf.jsqlparser.expression.IntervalExpression;
-import net.sf.jsqlparser.expression.JdbcNamedParameter;
-import net.sf.jsqlparser.expression.JdbcParameter;
-import net.sf.jsqlparser.expression.JsonAggregateFunction;
-import net.sf.jsqlparser.expression.JsonExpression;
-import net.sf.jsqlparser.expression.JsonFunction;
-import net.sf.jsqlparser.expression.JsonFunctionExpression;
-import net.sf.jsqlparser.expression.KeepExpression;
-import net.sf.jsqlparser.expression.LongValue;
-import net.sf.jsqlparser.expression.MySQLGroupConcat;
-import net.sf.jsqlparser.expression.NextValExpression;
-import net.sf.jsqlparser.expression.NotExpression;
-import net.sf.jsqlparser.expression.NullValue;
-import net.sf.jsqlparser.expression.NumericBind;
-import net.sf.jsqlparser.expression.OracleHierarchicalExpression;
-import net.sf.jsqlparser.expression.OracleHint;
-import net.sf.jsqlparser.expression.OracleNamedFunctionParameter;
-import net.sf.jsqlparser.expression.Parenthesis;
-import net.sf.jsqlparser.expression.RowConstructor;
-import net.sf.jsqlparser.expression.RowGetExpression;
-import net.sf.jsqlparser.expression.SignedExpression;
-import net.sf.jsqlparser.expression.StringValue;
-import net.sf.jsqlparser.expression.TimeKeyExpression;
-import net.sf.jsqlparser.expression.TimeValue;
-import net.sf.jsqlparser.expression.TimestampValue;
-import net.sf.jsqlparser.expression.TimezoneExpression;
-import net.sf.jsqlparser.expression.TryCastExpression;
-import net.sf.jsqlparser.expression.UserVariable;
-import net.sf.jsqlparser.expression.ValueListExpression;
-import net.sf.jsqlparser.expression.VariableAssignment;
-import net.sf.jsqlparser.expression.WhenClause;
-import net.sf.jsqlparser.expression.XMLSerializeExpr;
+import net.sf.jsqlparser.expression.*;
 import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
 import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
 import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
@@ -215,6 +166,23 @@ public class ConstAnalyzer implements ExpressionVisitor, ItemsListVisitor {
         expr.getBetweenExpressionEnd().accept(this);
     }
 
+//    /**
+//     * 用于处理 OverlapsCondition 类型的表达式
+//     * @param overlapsCondition
+//     */
+//    @Override
+//    public void visit(OverlapsCondition overlapsCondition) {
+//        constFlag.set(false);
+//    }
+//    /**
+//     * 用于处理 SafeCastExpression 类型的表达式。
+//     * @param safeCastExpression
+//     */
+//    @Override
+//    public void visit(SafeCastExpression safeCastExpression) {
+//        constFlag.set(false);
+//    }
+
     @Override
     public void visit(EqualsTo expr) {
         visitBinaryExpression(expr);

+ 16 - 0
jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/IgnoreAuth.java

@@ -0,0 +1,16 @@
+package org.jeecg.config.shiro;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 免认证注解,认证系统结合spring MVC的@RequestMapping获取请求路径进行免登录配置
+ * @author eightmonth@qq.com
+ * @date 2024/2/28 9:58
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface IgnoreAuth {
+}

+ 108 - 6
jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java

@@ -1,5 +1,6 @@
 package org.jeecg.config.shiro;
 
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
@@ -17,19 +18,25 @@ import org.jeecg.config.shiro.filters.CustomShiroFilterFactoryBean;
 import org.jeecg.config.shiro.filters.JwtFilter;
 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.DependsOn;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.*;
+import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.core.env.Environment;
+import org.springframework.core.type.filter.AnnotationTypeFilter;
 import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
-import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.filter.DelegatingFilterProxy;
 import redis.clients.jedis.HostAndPort;
 import redis.clients.jedis.JedisCluster;
 
 import jakarta.annotation.Resource;
 import jakarta.servlet.Filter;
+import jakarta.servlet.DispatcherType;
+import java.lang.reflect.Method;
 import java.util.*;
 
 /**
@@ -40,6 +47,8 @@ import java.util.*;
 
 @Slf4j
 @Configuration
+// 免认证注解 @IgnoreAuth 注解生效范围配置
+@ComponentScan(basePackages = {"org.jeecg"})
 public class ShiroConfig {
 
     @Resource
@@ -50,7 +59,6 @@ public class ShiroConfig {
     private JeecgBaseConfig jeecgBaseConfig;
     @Autowired(required = false)
     private RedisProperties redisProperties;
-
     /**
      * Filter Chain定义说明
      *
@@ -165,6 +173,16 @@ public class ShiroConfig {
         // 企业微信证书排除
         filterChainDefinitionMap.put("/WW_verify*", "anon");
 
+
+        // 通过注解免登录url
+        List<String> ignoreAuthUrlList = collectIgnoreAuthUrl();
+        if (!CollectionUtils.isEmpty(ignoreAuthUrlList)) {
+            for (String url : ignoreAuthUrlList) {
+                filterChainDefinitionMap.put(url, "anon");
+            }
+        }
+
+
         // 添加自己的过滤器并且取名为jwt
         Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
         //如果cloudServer为空 则说明是单体 需要加载跨域配置【微服务跨域切换】
@@ -181,6 +199,20 @@ public class ShiroConfig {
         return shiroFilterFactoryBean;
     }
 
+    //update-begin---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
+    @Bean
+    public FilterRegistrationBean shiroFilterRegistration() {
+        FilterRegistrationBean registration = new FilterRegistrationBean();
+        registration.setFilter(new DelegatingFilterProxy("shiroFilterFactoryBean"));
+        registration.setEnabled(true);
+        registration.addUrlPatterns("/*");
+        //支持异步
+        registration.setAsyncSupported(true);
+        registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC);
+        return registration;
+    }
+    //update-end---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
+
     @Bean("securityManager")
     public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) {
         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
@@ -270,7 +302,7 @@ public class ShiroConfig {
 
             return sentinelManager;
         }
-
+        
         // redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com
         if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) {
             RedisManager redisManager = new RedisManager();
@@ -303,4 +335,74 @@ public class ShiroConfig {
         return manager;
     }
 
+
+    @SneakyThrows
+    public List<String> collectIgnoreAuthUrl() {
+        List<String> ignoreAuthUrls = new ArrayList<>();
+        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
+        provider.addIncludeFilter(new AnnotationTypeFilter(RestController.class));
+
+        // 获取当前类的扫描注解的配置
+        Set<BeanDefinition> components = new HashSet<>();
+        for (String basePackage : AnnotationUtils.getAnnotation(ShiroConfig.class, ComponentScan.class).basePackages()) {
+            components.addAll(provider.findCandidateComponents(basePackage));
+        }
+
+        // 逐个匹配获取免认证路径
+        for (BeanDefinition component : components) {
+            String beanClassName = component.getBeanClassName();
+            Class<?> clazz = Class.forName(beanClassName);
+            RequestMapping base = clazz.getAnnotation(RequestMapping.class);
+            String[] baseUrl = {};
+            if (Objects.nonNull(base)) {
+                baseUrl = base.value();
+            }
+            Method[] methods = clazz.getDeclaredMethods();
+
+            for (Method method : methods) {
+                if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(RequestMapping.class)) {
+                    RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
+                    String[] uri = requestMapping.value();
+                    ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
+                } else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(GetMapping.class)) {
+                    GetMapping requestMapping = method.getAnnotation(GetMapping.class);
+                    String[] uri = requestMapping.value();
+                    ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
+                } else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(PostMapping.class)) {
+                    PostMapping requestMapping = method.getAnnotation(PostMapping.class);
+                    String[] uri = requestMapping.value();
+                    ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
+                } else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(PutMapping.class)) {
+                    PutMapping requestMapping = method.getAnnotation(PutMapping.class);
+                    String[] uri = requestMapping.value();
+                    ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
+                } else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(DeleteMapping.class)) {
+                    DeleteMapping requestMapping = method.getAnnotation(DeleteMapping.class);
+                    String[] uri = requestMapping.value();
+                    ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
+                } else if (method.isAnnotationPresent(IgnoreAuth.class) && method.isAnnotationPresent(PatchMapping.class)) {
+                    PatchMapping requestMapping = method.getAnnotation(PatchMapping.class);
+                    String[] uri = requestMapping.value();
+                    ignoreAuthUrls.addAll(rebuildUrl(baseUrl, uri));
+                }
+            }
+        }
+
+        return ignoreAuthUrls;
+    }
+
+    private List<String> rebuildUrl(String[] bases, String[] uris) {
+        List<String> urls = new ArrayList<>();
+        for (String base : bases) {
+            for (String uri : uris) {
+                urls.add(prefix(base)+prefix(uri));
+            }
+        }
+        return urls;
+    }
+
+    private String prefix(String seg) {
+        return seg.startsWith("/") ? seg : "/"+seg;
+    }
+
 }

+ 3 - 1
jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java

@@ -62,9 +62,11 @@ public class ShiroRealm extends AuthorizingRealm {
     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
         log.debug("===============Shiro权限认证开始============ [ roles、permissions]==========");
         String username = null;
+        String userId = null;
         if (principals != null) {
             LoginUser sysUser = (LoginUser) principals.getPrimaryPrincipal();
             username = sysUser.getUsername();
+            userId = sysUser.getId();
         }
         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
 
@@ -74,7 +76,7 @@ public class ShiroRealm extends AuthorizingRealm {
         info.setRoles(roleSet);
 
         // 设置用户拥有的权限集合,比如“sys:role:add,sys:user:add”
-        Set<String> permissionSet = commonApi.queryUserAuths(username);
+        Set<String> permissionSet = commonApi.queryUserAuths(userId);
         info.addStringPermissions(permissionSet);
         //System.out.println(permissionSet);
         log.info("===============Shiro权限认证成功==============");

+ 10 - 2
jeecg-boot-base-core/src/main/java/org/jeecg/config/sign/util/HttpUtils.java

@@ -172,7 +172,11 @@ public class HttpUtils {
         String[] params = param.split("&");
         for (String s : params) {
             int index = s.indexOf("=");
-            result.put(s.substring(0, index), s.substring(index + 1));
+            //update-begin---author:chenrui ---date:20240222  for:[issues/5879]数据查询传ds=“”造成的异常------------
+            if (index != -1) {
+                result.put(s.substring(0, index), s.substring(index + 1));
+            }
+            //update-end---author:chenrui ---date:20240222  for:[issues/5879]数据查询传ds=“”造成的异常------------
         }
         return result;
     }
@@ -196,7 +200,11 @@ public class HttpUtils {
         String[] params = param.split("&");
         for (String s : params) {
             int index = s.indexOf("=");
-            result.put(s.substring(0, index), s.substring(index + 1));
+            //update-begin---author:chenrui ---date:20240222  for:[issues/5879]数据查询传ds=“”造成的异常------------
+            if (index != -1) {
+                result.put(s.substring(0, index), s.substring(index + 1));
+            }
+            //update-end---author:chenrui ---date:20240222  for:[issues/5879]数据查询传ds=“”造成的异常------------
         }
         return result;
     }

+ 7 - 1
jeecg-module-demo/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jeecg-boot-parent</artifactId>
         <groupId>org.jeecgframework.boot</groupId>
-        <version>3.6.2</version>
+        <version>3.6.3</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -16,6 +16,12 @@
             <groupId>org.jeecgframework.boot</groupId>
             <artifactId>jeecg-boot-base-core</artifactId>
         </dependency>
+
+        <!-- chatgpt -->
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-starter-chatgpt</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 34 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/cache/LocalCache.java

@@ -0,0 +1,34 @@
+package org.jeecg.modules.demo.gpt.cache;
+
+import cn.hutool.cache.CacheUtil;
+import cn.hutool.cache.impl.TimedCache;
+import cn.hutool.core.date.DateUnit;
+
+//update-begin---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
+
+/**
+ * 聊天记录本地缓存
+ * @author chenrui
+ * @date 2024/1/26 20:06
+ */
+public class LocalCache {
+    /**
+     * 缓存时长
+     */
+    public static final long TIMEOUT = 5 * DateUnit.MINUTE.getMillis();
+    /**
+     * 清理间隔
+     */
+    private static final long CLEAN_TIMEOUT = 5 * DateUnit.MINUTE.getMillis();
+    /**
+     * 缓存对象
+     */
+    public static final TimedCache<String, Object> CACHE = CacheUtil.newTimedCache(TIMEOUT);
+
+    static {
+        //启动定时任务
+        CACHE.schedulePrune(CLEAN_TIMEOUT);
+    }
+}
+
+//update-end---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------

+ 74 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/controller/ChatController.java

@@ -0,0 +1,74 @@
+package org.jeecg.modules.demo.gpt.controller;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.demo.gpt.service.ChatService;
+import org.jeecg.modules.demo.gpt.vo.ChatHistoryVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+//update-begin---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
+
+/**
+ * @Description: chatGpt-聊天接口
+ * @Author: chenrui
+ * @Date: 2024/1/9 16:30
+ */
+@Controller
+@RequestMapping("/ai/chat")
+public class ChatController {
+
+    @Autowired
+    ChatService chatService;
+
+    /**
+     * 创建sse连接
+     *
+     * @return
+     */
+    @GetMapping(value = "/send")
+    public SseEmitter createConnect(@RequestParam(name = "topicId", required = false) String topicId, @RequestParam(name = "message", required = true) String message) {
+        SseEmitter sse = chatService.createChat();
+        chatService.sendMessage(topicId, message);
+        return sse;
+    }
+
+    //update-begin---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+    /**
+     * 保存聊天记录
+     * @param chatHistoryVO
+     * @return
+     * @author chenrui
+     * @date 2024/2/22 13:54
+     */
+    @PostMapping(value = "/history/save")
+    @ResponseBody
+    public Result<?> saveHistory(@RequestBody ChatHistoryVO chatHistoryVO) {
+        return chatService.saveHistory(chatHistoryVO);
+    }
+
+    /**
+     * 查询聊天记录
+     * @return
+     * @author chenrui
+     * @date 2024/2/22 14:03
+     */
+    @GetMapping(value = "/history/get")
+    @ResponseBody
+    public Result<ChatHistoryVO> getHistoryByTopic() {
+        return chatService.getHistoryByTopic();
+    }
+    //update-end---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+
+    /**
+     * 关闭连接
+     */
+    @GetMapping(value = "/close")
+    public void closeConnect() {
+        chatService.closeChat();
+    }
+
+
+}
+//update-end---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------

+ 136 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/listeners/OpenAISSEEventSourceListener.java

@@ -0,0 +1,136 @@
+package org.jeecg.modules.demo.gpt.listeners;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
+import com.unfbx.chatgpt.entity.chat.Message;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import okhttp3.sse.EventSource;
+import okhttp3.sse.EventSourceListener;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import java.util.Objects;
+
+//update-begin---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
+/**
+ * OpenAI的SSE监听
+ * @author chenrui
+ * @date 2024/1/26 20:06
+ */
+@Slf4j
+public class OpenAISSEEventSourceListener extends EventSourceListener {
+
+    private long tokens;
+
+    private SseEmitter sseEmitter;
+
+    private String topicId;
+
+    public OpenAISSEEventSourceListener(SseEmitter sseEmitter) {
+        this.sseEmitter = sseEmitter;
+    }
+
+    public OpenAISSEEventSourceListener(String topicId,SseEmitter sseEmitter){
+        this.topicId = topicId;
+        this.sseEmitter = sseEmitter;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
+        log.info("OpenAI建立sse连接...");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @SneakyThrows
+    @Override
+    public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) {
+        log.debug("OpenAI返回数据:{}", data);
+        tokens += 1;
+        if (data.equals("[DONE]")) {
+            log.info("OpenAI返回数据结束了");
+            sseEmitter.send(SseEmitter.event()
+                    .id("[TOKENS]")
+                    .data("<br/><br/>tokens:" + tokens())
+                    .reconnectTime(3000));
+            sseEmitter.send(SseEmitter.event()
+                    .id("[DONE]")
+                    .data("[DONE]")
+                    .reconnectTime(3000));
+            // 传输完成后自动关闭sse
+            sseEmitter.complete();
+            return;
+        }
+        ObjectMapper mapper = new ObjectMapper();
+        ChatCompletionResponse completionResponse = mapper.readValue(data, ChatCompletionResponse.class); // 读取Json
+        try {
+            sseEmitter.send(SseEmitter.event()
+                    .id(this.topicId)
+                    .data(completionResponse.getChoices().get(0).getDelta())
+                    .reconnectTime(3000));
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+            eventSource.cancel();
+        }
+    }
+
+
+    @Override
+    public void onClosed(@NotNull EventSource eventSource) {
+        log.info("流式输出返回值总共{}tokens", tokens() - 2);
+        log.info("OpenAI关闭sse连接...");
+    }
+
+
+    @SneakyThrows
+    @Override
+    public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) {
+        String errMsg = "";
+        ResponseBody body = null == response ? null:response.body();
+        if (Objects.nonNull(body)) {
+            log.error("OpenAI  sse连接异常data:{},异常:{}", body.string(), t.getMessage());
+            errMsg = body.string();
+        } else {
+            log.error("OpenAI  sse连接异常data:{},异常:{}", response, t.getMessage());
+            errMsg = t.getMessage();
+        }
+        eventSource.cancel();
+        sseEmitter.send(SseEmitter.event()
+                .id("[ERR]")
+                .data(Message.builder().content(explainErr(errMsg)).build())
+                .reconnectTime(3000));
+        sseEmitter.send(SseEmitter.event()
+                .id("[DONE]")
+                .data("[DONE]")
+                .reconnectTime(3000));
+        sseEmitter.complete();
+    }
+
+    private String explainErr(String errMsg){
+        if(StringUtils.isEmpty(errMsg)){
+            return "";
+        }
+        if(errMsg.contains("Rate limit")){
+            return "请求频率太快了,请等待20秒再试.";
+        }
+        return errMsg;
+    }
+
+    /**
+     * tokens
+     * @return
+     */
+    public long tokens() {
+        return tokens;
+    }
+}
+
+//update-end---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------

+ 56 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/service/ChatService.java

@@ -0,0 +1,56 @@
+package org.jeecg.modules.demo.gpt.service;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.demo.gpt.vo.ChatHistoryVO;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+//update-begin---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
+
+/**
+ * AI助手聊天Service
+ * @author chenrui
+ * @date 2024/1/26 20:08
+ */
+public interface ChatService {
+    /**
+     * 创建SSE
+     * @return
+     */
+    SseEmitter createChat();
+
+    /**
+     * 关闭SSE
+     */
+    void closeChat();
+
+    /**
+     * 客户端发送消息到服务端
+     *
+     * @param topicId
+     * @param message
+     * @author chenrui
+     * @date 2024/1/26 20:01
+     */
+    void sendMessage(String topicId, String message);
+
+    //update-begin---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+    /**
+     * 保存聊天记录
+     * @param chatHistoryVO
+     * @return
+     * @author chenrui
+     * @date 2024/2/22 13:37
+     */
+    Result<?> saveHistory(ChatHistoryVO chatHistoryVO);
+
+    /**
+     * 查询聊天记录
+     * @return
+     * @author chenrui
+     * @date 2024/2/22 13:59
+     */
+    Result<ChatHistoryVO> getHistoryByTopic();
+    //update-end---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+}
+
+//update-end---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------

+ 199 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/service/impl/ChatServiceImpl.java

@@ -0,0 +1,199 @@
+package org.jeecg.modules.demo.gpt.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.unfbx.chatgpt.OpenAiStreamClient;
+import com.unfbx.chatgpt.entity.chat.ChatCompletion;
+import com.unfbx.chatgpt.entity.chat.Message;
+import com.unfbx.chatgpt.exception.BaseException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.common.util.UUIDGenerator;
+import org.jeecg.modules.demo.gpt.cache.LocalCache;
+import org.jeecg.modules.demo.gpt.listeners.OpenAISSEEventSourceListener;
+import org.jeecg.modules.demo.gpt.service.ChatService;
+import org.jeecg.modules.demo.gpt.vo.ChatHistoryVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+//update-begin---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------
+
+/**
+ * AI助手聊天Service
+ * @author chenrui
+ * @date 2024/1/26 20:07
+ */
+@Service
+@Slf4j
+public class ChatServiceImpl implements ChatService {
+
+    //update-begin---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+    private static final String CACHE_KEY_PREFIX = "ai:chart:";
+
+    /**
+     *
+     */
+    private static final String CACHE_KEY_MSG_CONTEXT = "msg_content";
+
+
+    /**
+     *
+     */
+    private static final String CACHE_KEY_MSG_HISTORY = "msg_history";
+
+    @Autowired
+    RedisTemplate redisTemplate;
+    //update-end---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+
+    private OpenAiStreamClient openAiStreamClient = null;
+
+    //update-begin---author:chenrui ---date:20240131  for:[QQYUN-8212]fix 没有配置启动报错------------
+    public ChatServiceImpl() {
+        try {
+            this.openAiStreamClient = SpringContextUtils.getBean(OpenAiStreamClient.class);
+        } catch (Exception ignored) {
+        }
+    }
+
+    /**
+     * 防止client不能成功注入
+     * @return
+     * @author chenrui
+     * @date 2024/2/3 23:08
+     */
+    private OpenAiStreamClient ensureClient(){
+        if(null == this.openAiStreamClient){
+            this.openAiStreamClient = SpringContextUtils.getBean(OpenAiStreamClient.class);
+        }
+        return this.openAiStreamClient;
+    }
+    //update-end---author:chenrui ---date:20240131  for:[QQYUN-8212]fix 没有配置启动报错------------
+
+    private String getUserId() {
+        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+        return sysUser.getId();
+    }
+
+    @Override
+    public SseEmitter createChat() {
+        String uid = getUserId();
+        //默认30秒超时,设置为0L则永不超时
+        SseEmitter sseEmitter = new SseEmitter(-0L);
+        //完成后回调
+        sseEmitter.onCompletion(() -> {
+            log.info("[{}]结束连接...................",uid);
+            LocalCache.CACHE.remove(uid);
+        });
+        //超时回调
+        sseEmitter.onTimeout(() -> {
+            log.info("[{}]连接超时...................", uid);
+        });
+        //异常回调
+        sseEmitter.onError(
+                throwable -> {
+                    try {
+                        log.info("[{}]连接异常,{}", uid, throwable.toString());
+                        sseEmitter.send(SseEmitter.event()
+                                .id(uid)
+                                .name("发生异常!")
+                                .data(Message.builder().content("发生异常请重试!").build())
+                                .reconnectTime(3000));
+                        LocalCache.CACHE.put(uid, sseEmitter);
+                    } catch (IOException e) {
+                        log.error(e.getMessage(),e);
+                    }
+                }
+        );
+        try {
+            sseEmitter.send(SseEmitter.event().reconnectTime(5000));
+        } catch (IOException e) {
+            log.error(e.getMessage(),e);
+        }
+        LocalCache.CACHE.put(uid, sseEmitter);
+        log.info("[{}]创建sse连接成功!", uid);
+        return sseEmitter;
+    }
+
+    @Override
+    public void closeChat() {
+        String uid = getUserId();
+        SseEmitter sse = (SseEmitter) LocalCache.CACHE.get(uid);
+        if (sse != null) {
+            sse.complete();
+            //移除
+            LocalCache.CACHE.remove(uid);
+        }
+    }
+
+    @Override
+    public void sendMessage(String topicId, String message) {
+        String uid = getUserId();
+        if (StrUtil.isBlank(message)) {
+            log.info("参数异常,message为null");
+            throw new BaseException("参数异常,message不能为空~");
+        }
+        if (StrUtil.isBlank(topicId)) {
+            topicId = UUIDGenerator.generate();
+        }
+        //update-begin---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+        log.info("话题id:{}", topicId);
+        String cacheKey = CACHE_KEY_PREFIX + uid + "_" + topicId;
+        String messageContext = (String) redisTemplate.opsForHash().get(cacheKey, CACHE_KEY_MSG_CONTEXT);
+        List<Message> msgHistory = new ArrayList<>();
+        if (StrUtil.isNotBlank(messageContext)) {
+            List<Message> messages = JSONArray.parseArray(messageContext, Message.class);
+            msgHistory = messages == null ? new ArrayList<>() : messages;
+        }
+        Message currentMessage = Message.builder().content(message).role(Message.Role.USER).build();
+        msgHistory.add(currentMessage);
+
+        SseEmitter sseEmitter = (SseEmitter) LocalCache.CACHE.get(uid);
+        if (sseEmitter == null) {
+            log.info("聊天消息推送失败uid:[{}],没有创建连接,请重试。", uid);
+            throw new JeecgBootException("聊天消息推送失败uid:[{}],没有创建连接,请重试。~");
+        }
+        OpenAISSEEventSourceListener openAIEventSourceListener = new OpenAISSEEventSourceListener(topicId, sseEmitter);
+        ChatCompletion completion = ChatCompletion
+                .builder()
+                .messages(msgHistory)
+                .model(ChatCompletion.Model.GPT_3_5_TURBO.getName())
+                .build();
+        ensureClient().streamChatCompletion(completion, openAIEventSourceListener);
+        redisTemplate.opsForHash().put(cacheKey, CACHE_KEY_MSG_CONTEXT, JSONUtil.toJsonStr(msgHistory));
+        //update-end---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+        Result.ok(completion.tokens());
+    }
+
+    //update-begin---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+    @Override
+    public Result<?> saveHistory(ChatHistoryVO chatHistoryVO) {
+        String uid = getUserId();
+        String cacheKey = CACHE_KEY_PREFIX + CACHE_KEY_MSG_HISTORY + ":" + uid;
+        redisTemplate.opsForValue().set(cacheKey, chatHistoryVO.getContent());
+        return Result.OK("保存成功");
+    }
+
+    @Override
+    public Result<ChatHistoryVO> getHistoryByTopic() {
+        String uid = getUserId();
+        String cacheKey = CACHE_KEY_PREFIX + CACHE_KEY_MSG_HISTORY + ":" + uid;
+        String historyContent = (String) redisTemplate.opsForValue().get(cacheKey);
+        ChatHistoryVO chatHistoryVO = new ChatHistoryVO();
+        chatHistoryVO.setContent(historyContent);
+        return Result.OK(chatHistoryVO);
+    }
+    //update-end---author:chenrui ---date:20240223  for:[QQYUN-8225]聊天记录保存------------
+}
+
+//update-end---author:chenrui ---date:20240126  for:【QQYUN-7932】AI助手------------

+ 25 - 0
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/vo/ChatHistoryVO.java

@@ -0,0 +1,25 @@
+package org.jeecg.modules.demo.gpt.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 聊天记录
+ * @Author: chenrui
+ * @Date: 2024/2/22 13:36
+ */
+@Data
+public class ChatHistoryVO implements Serializable {
+    private static final long serialVersionUID = 3238429500037511283L;
+
+    /**
+     * 话题id
+     */
+    String topicId;
+
+    /**
+     * 聊天记录内容
+     */
+    String content;
+}

+ 1 - 1
jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jeecg-system-api</artifactId>
         <groupId>org.jeecgframework.boot</groupId>
-        <version>3.6.2</version>
+        <version>3.6.3</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 7 - 21
jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java

@@ -108,7 +108,7 @@ public interface ISysBaseAPI extends CommonAPI {
      * @return 部门 parentIds
      */
     @GetMapping("/sys/api/getDepartParentIdsByDepIds")
-    Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set depIds);
+    Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set<String> depIds);
     
     /**
      * 9通过用户账号查询部门 name
@@ -213,7 +213,7 @@ public interface ISysBaseAPI extends CommonAPI {
      * @return
      */
     @GetMapping("/sys/api/queryAllUser")
-    public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize);
+    public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) Integer pageSize);
 
 
     /**
@@ -307,11 +307,11 @@ public interface ISysBaseAPI extends CommonAPI {
 
     /**
      * 31获取用户的权限集合
-     * @param username
+     * @param userId
      * @return
      */
     @GetMapping("/sys/api/getUserPermissionSet")
-    Set<String> getUserPermissionSet(@RequestParam("username") String username);
+    Set<String> getUserPermissionSet(@RequestParam("userId") String userId);
 
     /**
      * 32判断是否有online访问的权限
@@ -351,12 +351,12 @@ public interface ISysBaseAPI extends CommonAPI {
 
     /**
      * 36查询用户权限信息
-     * @param username
+     * @param userId
      * @return
      */
     @Override
     @GetMapping("/sys/api/queryUserAuths")
-    Set<String> queryUserAuths(@RequestParam("username")String username);
+    Set<String> queryUserAuths(@RequestParam("userId")String userId);
 
     /**
      * 37根据 id 查询数据库中存储的 DynamicDataSourceModel
@@ -611,20 +611,6 @@ public interface ISysBaseAPI extends CommonAPI {
     @PostMapping("/sys/api/saveDataLog")
     void saveDataLog(DataLogDTO dataLogDto);
 
-    /**
-     * 添加文件到知识库
-     * @param sysFilesModel
-     */
-    @PostMapping("/sys/api/addSysFiles")
-    void addSysFiles(SysFilesModel sysFilesModel);
-
-    /**
-     * 通过文件路径获取文件id
-     * @param fileId
-     */
-    @GetMapping("/sys/api/getFileUrl")
-    String getFileUrl(@RequestParam(name="fileId") String fileId);
-
     /**
      * 更新头像
      * @param loginUser
@@ -761,7 +747,7 @@ public interface ISysBaseAPI extends CommonAPI {
     @GetMapping("/sys/api/dictTableWhiteListCheckByDict")
     boolean dictTableWhiteListCheckByDict(
             @RequestParam("tableOrDictCode") String tableOrDictCode,
-            @RequestParam(value = "fields", required = false) String[] fields
+            @RequestParam(value = "fields", required = false) String... fields
     );
 
 }

+ 5 - 16
jeecg-module-system/jeecg-system-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java

@@ -71,7 +71,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
     }
 
     @Override
-    public Set<String> getDepartParentIdsByDepIds(Set depIds) {
+    public Set<String> getDepartParentIdsByDepIds(Set<String> depIds) {
         return null;
     }
 
@@ -133,7 +133,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
     }
 
     @Override
-    public JSONObject queryAllUser(String userIds, Integer pageNo, int pageSize) {
+    public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize) {
         return null;
     }
 
@@ -194,7 +194,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
     }
 
     @Override
-    public Set<String> getUserPermissionSet(String username) {
+    public Set<String> getUserPermissionSet(String userId) {
         return null;
     }
 
@@ -219,7 +219,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
     }
 
     @Override
-    public Set<String> queryUserAuths(String username) {
+    public Set<String> queryUserAuths(String userId) {
         return null;
     }
 
@@ -361,17 +361,6 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
         return null;
     }
 
-
-    @Override
-    public void addSysFiles(SysFilesModel sysFilesModel) {
-
-    }
-
-    @Override
-    public String getFileUrl(String fileId) {
-        return null;
-    }
-
     @Override
     public void updateAvatar(LoginUser loginUser) { }
 
@@ -446,7 +435,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
     }
 
     @Override
-    public boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String[] fields) {
+    public boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String... fields) {
         return false;
     }
 

+ 1 - 1
jeecg-module-system/jeecg-system-api/jeecg-system-local-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jeecg-system-api</artifactId>
         <groupId>org.jeecgframework.boot</groupId>
-        <version>3.6.2</version>
+        <version>3.6.3</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 3 - 16
jeecg-module-system/jeecg-system-api/jeecg-system-local-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java

@@ -101,7 +101,7 @@ public interface ISysBaseAPI extends CommonAPI {
      * @param depIds
      * @return 部门 parentIds
      */
-    Set<String> getDepartParentIdsByDepIds(Set depIds);
+    Set<String> getDepartParentIdsByDepIds(Set<String> depIds);
 
     /**
      * 9通过用户账号查询部门 name
@@ -302,10 +302,10 @@ public interface ISysBaseAPI extends CommonAPI {
 
     /**
      * 32获取用户的权限集合
-     * @param username
+     * @param userId
      * @return
      */
-    Set<String> getUserPermissionSet(String username);
+    Set<String> getUserPermissionSet(String userId);
 
     /**
      * 33判断是否有online访问的权限
@@ -445,19 +445,6 @@ public interface ISysBaseAPI extends CommonAPI {
      * @param dataLogDto
      */
     void saveDataLog(DataLogDTO dataLogDto);
-
-    /**
-     * 添加文件到知识库
-     * @param sysFilesModel
-     */
-    void addSysFiles(SysFilesModel sysFilesModel);
-
-    /**
-     * 通过文件路径获取文件id
-     * @param fileId
-     */
-    String getFileUrl(String fileId);
-
     /**
      * 更新头像
      * @param loginUser

+ 1 - 1
jeecg-module-system/jeecg-system-api/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jeecg-module-system</artifactId>
         <groupId>org.jeecgframework.boot</groupId>
-        <version>3.6.2</version>
+        <version>3.6.3</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
jeecg-module-system/jeecg-system-biz/pom.xml

@@ -4,7 +4,7 @@
 	<parent>
 		<groupId>org.jeecgframework.boot</groupId>
 		<artifactId>jeecg-module-system</artifactId>
-		<version>3.6.2</version>
+		<version>3.6.3</version>
 	</parent>
 	<modelVersion>4.0.0</modelVersion>
 

+ 17 - 25
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java

@@ -156,7 +156,7 @@ public class SystemApiController {
      * @return 部门 id
      */
     @GetMapping("/getDepartParentIdsByDepIds")
-    Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set depIds){
+    Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set<String> depIds){
         return sysBaseApi.getDepartParentIdsByDepIds(depIds);
     }
 
@@ -347,7 +347,7 @@ public class SystemApiController {
      * @return
      */
     @GetMapping("/queryAllUser")
-    public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize){
+    public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) Integer pageSize){
         return sysBaseApi.queryAllUser(userIds, pageNo, pageSize);
     }
 
@@ -386,12 +386,12 @@ public class SystemApiController {
 
     /**
      * 获取用户的权限集合
-     * @param username
+     * @param userId 用户表ID
      * @return
      */
     @GetMapping("/getUserPermissionSet")
-    public Set<String> getUserPermissionSet(@RequestParam("username") String username){
-        return sysBaseApi.getUserPermissionSet(username);
+    public Set<String> getUserPermissionSet(@RequestParam("userId") String userId){
+        return sysBaseApi.getUserPermissionSet(userId);
     }
 
     //-----
@@ -419,12 +419,12 @@ public class SystemApiController {
 
     /**
      * 查询用户权限信息
-     * @param username
+     * @param userId
      * @return
      */
     @GetMapping("/queryUserAuths")
-    public Set<String> queryUserAuths(@RequestParam("username") String username){
-        return sysUserService.getUserPermissionsSet(username);
+    public Set<String> queryUserAuths(@RequestParam("userId") String userId){
+        return sysUserService.getUserPermissionsSet(userId);
     }
 
     /**
@@ -578,7 +578,7 @@ public class SystemApiController {
      * @param tenantId      新的租户ID
      * @return Map<String, String>  Map<原字典编码, 新字典编码>
      */
-    @GetMapping("/sys/api/copyLowAppDict")
+    @GetMapping("/copyLowAppDict")
     Map<String, String> copyLowAppDict(@RequestParam("originalAppId") String originalAppId, @RequestParam("appId") String appId, @RequestParam("tenantId") String tenantId) {
         return sysBaseApi.copyLowAppDict(originalAppId, appId, tenantId);
     }
@@ -732,14 +732,6 @@ public class SystemApiController {
         this.sysBaseApi.saveDataLog(dataLogDto);
     }
 
-    @PostMapping("/addSysFiles")
-    public void addSysFiles(@RequestBody SysFilesModel sysFilesModel){this.sysBaseApi.addSysFiles(sysFilesModel);}
-
-    @GetMapping("/getFileUrl")
-    public String getFileUrl(@RequestParam(name="fileId") String fileId){
-        return this.sysBaseApi.getFileUrl(fileId);
-    }
-
     /**
      * 更新头像
      * @param loginUser
@@ -858,7 +850,7 @@ public class SystemApiController {
      * @param deptIds
      * @return
      */
-    @GetMapping("/sys/api/queryUserIdsByDeptIds")
+    @GetMapping("/queryUserIdsByDeptIds")
     public List<String> queryUserIdsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
         return sysBaseApi.queryUserIdsByDeptIds(deptIds);
     }
@@ -868,7 +860,7 @@ public class SystemApiController {
      * @param deptIds
      * @return
      */
-    @GetMapping("/sys/api/queryUserAccountsByDeptIds")
+    @GetMapping("/queryUserAccountsByDeptIds")
     public List<String> queryUserAccountsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
         return sysBaseApi.queryUserAccountsByDeptIds(deptIds);
     }
@@ -878,7 +870,7 @@ public class SystemApiController {
      * @param roleCodes
      * @return
      */
-    @GetMapping("/sys/api/queryUserIdsByRoleds")
+    @GetMapping("/queryUserIdsByRoleds")
     public List<String> queryUserIdsByRoleds(@RequestParam("roleCodes")  List<String> roleCodes){
         return sysBaseApi.queryUserIdsByRoleds(roleCodes);
     }
@@ -888,7 +880,7 @@ public class SystemApiController {
      * @param positionIds
      * @return
      */
-    @GetMapping("/sys/api/queryUserIdsByPositionIds")
+    @GetMapping("/queryUserIdsByPositionIds")
     public List<String> queryUserIdsByPositionIds(@RequestParam("positionIds") List<String> positionIds){
         return sysBaseApi.queryUserIdsByPositionIds(positionIds);
     }
@@ -900,7 +892,7 @@ public class SystemApiController {
      * @param orgCode 部门编码
      * @return
      */
-    @GetMapping("/sys/api/getUserAccountsByDepCode")
+    @GetMapping("/getUserAccountsByDepCode")
     public List<String> getUserAccountsByDepCode(String orgCode){
         return sysBaseApi.getUserAccountsByDepCode(orgCode);
     }
@@ -911,7 +903,7 @@ public class SystemApiController {
      * @param selectSql
      * @return
      */
-    @GetMapping("/sys/api/dictTableWhiteListCheckBySql")
+    @GetMapping("/dictTableWhiteListCheckBySql")
     public boolean dictTableWhiteListCheckBySql(@RequestParam("selectSql") String selectSql) {
         return sysBaseApi.dictTableWhiteListCheckBySql(selectSql);
     }
@@ -923,10 +915,10 @@ public class SystemApiController {
      * @param fields          如果传的是dictCode,则该参数必须传null
      * @return
      */
-    @GetMapping("/sys/api/dictTableWhiteListCheckByDict")
+    @GetMapping("/dictTableWhiteListCheckByDict")
     public boolean dictTableWhiteListCheckByDict(
             @RequestParam("tableOrDictCode") String tableOrDictCode,
-            @RequestParam(value = "fields", required = false) String[] fields
+            @RequestParam(value = "fields", required = false) String... fields
     ) {
         return sysBaseApi.dictTableWhiteListCheckByDict(tableOrDictCode, fields);
     }

+ 1 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/enums/RangeDateEnum.java

@@ -79,6 +79,7 @@ public enum RangeDateEnum {
             //本周
             calendar1.set(Calendar.DAY_OF_WEEK, 2);
 
+            calendar2.set(Calendar.DAY_OF_WEEK,2);
             calendar2.add(Calendar.WEEK_OF_MONTH,1);
             calendar2.add(Calendar.DAY_OF_WEEK,-1);
         } else if(SZ.key.equals(key)){

+ 25 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/constant/DefIndexConst.java

@@ -0,0 +1,25 @@
+package org.jeecg.modules.system.constant;
+
+/**
+ * 默认首页常量
+ */
+public interface DefIndexConst {
+
+    /**
+     * 默认首页的roleCode
+     */
+    String DEF_INDEX_ALL = "DEF_INDEX_ALL";
+
+    /**
+     * 默认首页的缓存key
+     */
+    String CACHE_KEY = "sys:cache:def_index";
+
+    /**
+     * 默认首页的初始值
+     */
+    String DEF_INDEX_NAME = "首页";
+    String DEF_INDEX_URL = "/dashboard/analysis";
+    String DEF_INDEX_COMPONENT = "dashboard/Analysis";
+
+}

+ 0 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java

@@ -9,8 +9,6 @@ import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.util.CommonUtils;
 import org.jeecg.common.util.filter.SsrfFileTypeFilter;
 import org.jeecg.common.util.oConvertUtils;
-import org.jeecg.modules.system.service.ISysFilesService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.util.AntPathMatcher;
 import org.springframework.util.FileCopyUtils;

+ 38 - 35
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/LoginController.java

@@ -72,32 +72,24 @@ public class LoginController {
 
 	@Operation(summary = "登录接口")
 	@RequestMapping(value = "/login", method = RequestMethod.POST)
-	public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){
+	public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request){
 		Result<JSONObject> result = new Result<JSONObject>();
 		String username = sysLoginModel.getUsername();
 		String password = sysLoginModel.getPassword();
-		//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
 		if(isLoginFailOvertimes(username)){
 			return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
 		}
-		//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
-		//update-begin--Author:scott  Date:20190805 for:暂时注释掉密码加密逻辑,有点问题
-		//前端密码加密,后端进行密码解密
-		//password = AesEncryptUtil.desEncrypt(sysLoginModel.getPassword().replaceAll("%2B", "\\+")).trim();//密码解密
-		//update-begin--Author:scott  Date:20190805 for:暂时注释掉密码加密逻辑,有点问题
 
-		//update-begin-author:taoyan date:20190828 for:校验验证码
+		// step.1 验证码check
         String captcha = sysLoginModel.getCaptcha();
         if(captcha==null){
             result.error500("验证码无效");
             return result;
         }
         String lowerCaseCaptcha = captcha.toLowerCase();
-        //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
 		// 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可
         String origin = lowerCaseCaptcha+sysLoginModel.getCheckKey()+jeecgBaseConfig.getSignatureSecret();
 		String realKey = Md5Util.md5Encode(origin, "utf-8");
-		//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
 		Object checkCode = redisUtil.get(realKey);
 		//当进入登录页时,有一定几率出现验证码错误 #1714
 		if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
@@ -107,40 +99,36 @@ public class LoginController {
 			result.setCode(HttpStatus.PRECONDITION_FAILED.value());
 			return result;
 		}
-		//update-end-author:taoyan date:20190828 for:校验验证码
 		
-		//1. 校验用户是否有效
-		//update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
+		// step.2 校验用户是否存在且有效
 		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
 		queryWrapper.eq(SysUser::getUsername,username);
 		SysUser sysUser = sysUserService.getOne(queryWrapper);
-		//update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
 		result = sysUserService.checkUserIsEffective(sysUser);
 		if(!result.isSuccess()) {
 			return result;
 		}
 
-		//2. 校验用户名或密码是否正确
+		// step.3 校验用户名或密码是否正确
 		String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
 		String syspassword = sysUser.getPassword();
 		if (!syspassword.equals(userpassword)) {
-			//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
 			addLoginFailOvertimes(username);
-			//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
 			result.error500("用户名或密码错误");
 			return result;
 		}
-				
-		//用户登录信息
-		userInfo(sysUser, result);
-		//update-begin--Author:liusq  Date:20210126  for:登录成功,删除redis中的验证码
+
+		// step.4  登录成功获取用户信息
+		userInfo(sysUser, result, request);
+
+		// step.5  登录成功删除验证码
 		redisUtil.del(realKey);
-		//update-begin--Author:liusq  Date:20210126  for:登录成功,删除redis中的验证码
 		redisUtil.del(CommonConstant.LOGIN_FAIL + username);
+
+		// step.6  记录用户登录日志
 		LoginUser loginUser = new LoginUser();
 		BeanUtils.copyProperties(sysUser, loginUser);
 		baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
-        //update-end--Author:wangshuai  Date:20200714  for:登录日志没有记录人员
 		return result;
 	}
 
@@ -150,18 +138,20 @@ public class LoginController {
 	 */
 	@GetMapping("/user/getUserInfo")
 	public Result<JSONObject> getUserInfo(HttpServletRequest request){
+		long start = System.currentTimeMillis();
 		Result<JSONObject> result = new Result<JSONObject>();
 		String  username = JwtUtil.getUserNameByToken(request);
 		if(oConvertUtils.isNotEmpty(username)) {
 			// 根据用户名查询用户信息
 			SysUser sysUser = sysUserService.getUserByName(username);
 			JSONObject obj=new JSONObject();
+			log.info("1 获取用户信息耗时(用户基础信息)" + (System.currentTimeMillis() - start) + "毫秒");
 
 			//update-begin---author:scott ---date:2022-06-20  for:vue3前端,支持自定义首页-----------
-			String version = request.getHeader(CommonConstant.VERSION);
+			String vue3Version = request.getHeader(CommonConstant.VERSION);
 			//update-begin---author:liusq ---date:2022-06-29  for:接口返回值修改,同步修改这里的判断逻辑-----------
-			SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, version);
-			if (oConvertUtils.isNotEmpty(version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
+			SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, vue3Version);
+			if (oConvertUtils.isNotEmpty(vue3Version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
 				String homePath = roleIndex.getUrl();
 				if (!homePath.startsWith(SymbolConstant.SINGLE_SLASH)) {
 					homePath = SymbolConstant.SINGLE_SLASH + homePath;
@@ -170,12 +160,16 @@ public class LoginController {
 			}
 			//update-begin---author:liusq ---date:2022-06-29  for:接口返回值修改,同步修改这里的判断逻辑-----------
 			//update-end---author:scott ---date::2022-06-20  for:vue3前端,支持自定义首页--------------
+			log.info("2 获取用户信息耗时 (首页面配置)" + (System.currentTimeMillis() - start) + "毫秒");
 			
 			obj.put("userInfo",sysUser);
 			obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
+			log.info("3 获取用户信息耗时 (字典数据)" + (System.currentTimeMillis() - start) + "毫秒");
+			
 			result.setResult(obj);
 			result.success("");
 		}
+		log.info("end 获取用户信息耗时 " + (System.currentTimeMillis() - start) + "毫秒");
 		return result;
 
 	}
@@ -397,7 +391,7 @@ public class LoginController {
 	 */
 	@Operation(summary ="手机号登录接口")
 	@PostMapping("/phoneLogin")
-	public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject) {
+	public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
 		Result<JSONObject> result = new Result<JSONObject>();
 		String phone = jsonObject.getString("mobile");
 		//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
@@ -423,11 +417,10 @@ public class LoginController {
 			//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
 			addLoginFailOvertimes(phone);
 			//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
-			result.setMessage("手机验证码错误");
-			return result;
+			return Result.error("手机验证码错误");
 		}
 		//用户信息
-		userInfo(sysUser, result);
+		userInfo(sysUser, result, request);
 		//添加日志
 		baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null);
 
@@ -442,7 +435,7 @@ public class LoginController {
 	 * @param result
 	 * @return
 	 */
-	private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result) {
+	private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result, HttpServletRequest request) {
 		String username = sysUser.getUsername();
 		String syspassword = sysUser.getPassword();
 		// 获取用户部门信息
@@ -482,7 +475,15 @@ public class LoginController {
 			// update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
 			obj.put("multi_depart", 2);
 		}
-		obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
+
+		//update-begin---author:scott ---date:2024-01-05  for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
+		// login接口,在vue3前端下不加载字典数据,vue2下加载字典
+		String vue3Version = request.getHeader(CommonConstant.VERSION);
+		if(oConvertUtils.isEmpty(vue3Version)){
+			obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
+		}
+		//end-begin---author:scott ---date:2024-01-05  for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
+		
 		result.setResult(obj);
 		result.success("登录成功");
 		return result;
@@ -543,7 +544,7 @@ public class LoginController {
 	@RequiresRoles({"admin"})
 	@GetMapping(value = "/switchVue3Menu")
 	public Result<String> switchVue3Menu(HttpServletResponse response) {
-		Result<String> res = new Result<String>();
+		Result<String> res = new Result<String>();	
 		sysPermissionService.switchVue3Menu();
 		return res;
 	}
@@ -588,10 +589,12 @@ public class LoginController {
 		String orgCode = sysUser.getOrgCode();
 		if(oConvertUtils.isEmpty(orgCode)) {
 			//如果当前用户无选择部门 查看部门关联信息
+			
 			List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
 			//update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
 			if (departs == null || departs.size() == 0) {
 				/*result.error500("用户暂未归属部门,不可登录!");
+				
 				return result;*/
 			}else{
 				orgCode = departs.get(0).getOrgCode();
@@ -727,8 +730,8 @@ public class LoginController {
 		if(failTime!=null){
 			val = Integer.parseInt(failTime.toString());
 		}
-		// 10分钟
-		redisUtil.set(key, ++val, 10);
+		// 10分钟,一分钟为60s
+		redisUtil.set(key, ++val, 600);
 	}
 
 }

+ 5 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java

@@ -333,6 +333,7 @@ public class SysAnnouncementController {
 	 */
 	@RequestMapping(value = "/listByUser", method = RequestMethod.GET)
 	public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) {
+		long start = System.currentTimeMillis();
 		Result<Map<String,Object>> result = new Result<Map<String,Object>>();
 		Map<String,Object> sysMsgMap = new HashMap(5);
 		LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
@@ -349,12 +350,16 @@ public class SysAnnouncementController {
 		anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1");
 		sysMsgMap.put("anntMsgList", anntMsgList.getRecords());
 		sysMsgMap.put("anntMsgTotal", anntMsgList.getTotal());
+
+		log.info("begin 获取用户系统公告 (通知)" + (System.currentTimeMillis() - start) + "毫秒");
 		
         //系统消息
 		Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize);
 		sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");
 		sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
 		sysMsgMap.put("sysMsgTotal", sysMsgList.getTotal());
+
+		log.info("end 获取用户系统公告 (系统消息)" + (System.currentTimeMillis() - start) + "毫秒");
 		
 		result.setSuccess(true);
 		result.setResult(sysMsgMap);

+ 3 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysDictController.java

@@ -600,9 +600,10 @@ public class SysDictController {
 	 * @return
 	 */
 	@RequestMapping(value = "/deleteList", method = RequestMethod.GET)
-	public Result<List<SysDict>> deleteList() {
+	public Result<List<SysDict>> deleteList(HttpServletRequest request) {
 		Result<List<SysDict>> result = new Result<List<SysDict>>();
-		List<SysDict> list = this.sysDictService.queryDeleteList();
+		String tenantId = TokenUtils.getTenantIdByRequest(request);
+		List<SysDict> list = this.sysDictService.queryDeleteList(tenantId);
 		result.setSuccess(true);
 		result.setResult(list);
 		return result;

+ 0 - 152
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysFilesController.java

@@ -1,152 +0,0 @@
-package org.jeecg.modules.system.controller;
-
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import lombok.extern.slf4j.Slf4j;
-import org.jeecg.common.api.vo.Result;
-import org.jeecg.common.aspect.annotation.AutoLog;
-import org.jeecg.common.system.base.controller.JeecgController;
-import org.jeecg.common.system.query.QueryGenerator;
-import org.jeecg.modules.system.entity.SysFiles;
-import org.jeecg.modules.system.service.ISysFilesService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.servlet.ModelAndView;
-
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import java.util.Arrays;
-
-/**
- * @Description: 知识库-文档管理
- * @Author: jeecg-boot
- * @Date: 2022-07-21
- * @Version: V1.0
- */
-@Slf4j
-@Tag(name = "知识库-文档管理")
-@RestController
-@RequestMapping("/sys/files")
-public class SysFilesController extends JeecgController<SysFiles, ISysFilesService> {
-    @Autowired
-    private ISysFilesService sysFilesService;
-
-    /**
-     * 分页列表查询
-     *
-     * @param sysFiles
-     * @param pageNo
-     * @param pageSize
-     * @param req
-     * @return
-     */
-    @AutoLog(value = "知识库-文档管理-分页列表查询")
-    @Operation(summary = "知识库-文档管理-分页列表查询")
-    @GetMapping(value = "/list")
-    public Result<?> queryPageList(SysFiles sysFiles,
-                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
-                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
-                                   HttpServletRequest req) {
-        QueryWrapper<SysFiles> queryWrapper = QueryGenerator.initQueryWrapper(sysFiles, req.getParameterMap());
-        Page<SysFiles> page = new Page<SysFiles>(pageNo, pageSize);
-        IPage<SysFiles> pageList = sysFilesService.page(page, queryWrapper);
-        return Result.OK(pageList);
-    }
-
-    /**
-     * 添加
-     *
-     * @param sysFiles
-     * @return
-     */
-    @AutoLog(value = "知识库-文档管理-添加")
-    @Operation(summary = "知识库-文档管理-添加")
-    @PostMapping(value = "/add")
-    public Result<?> add(@RequestBody SysFiles sysFiles) {
-        sysFilesService.save(sysFiles);
-        return Result.OK("添加成功!");
-    }
-
-    /**
-     * 编辑
-     *
-     * @param sysFiles
-     * @return
-     */
-    @AutoLog(value = "知识库-文档管理-编辑")
-    @Operation(summary = "知识库-文档管理-编辑")
-    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
-    public Result<?> edit(@RequestBody SysFiles sysFiles) {
-        sysFilesService.updateById(sysFiles);
-        return Result.OK("编辑成功!");
-    }
-
-    /**
-     * 通过id删除
-     *
-     * @param id
-     * @return
-     */
-    @AutoLog(value = "知识库-文档管理-通过id删除")
-    @Operation(summary = "知识库-文档管理-通过id删除")
-    @DeleteMapping(value = "/delete")
-    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
-        sysFilesService.removeById(id);
-        return Result.OK("删除成功!");
-    }
-
-    /**
-     * 批量删除
-     *
-     * @param ids
-     * @return
-     */
-    @AutoLog(value = "知识库-文档管理-批量删除")
-    @Operation(summary = "知识库-文档管理-批量删除")
-    @DeleteMapping(value = "/deleteBatch")
-    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
-        this.sysFilesService.removeByIds(Arrays.asList(ids.split(",")));
-        return Result.OK("批量删除成功!");
-    }
-
-    /**
-     * 通过id查询
-     *
-     * @param id
-     * @return
-     */
-    @AutoLog(value = "知识库-文档管理-通过id查询")
-    @Operation(summary = "知识库-文档管理-通过id查询")
-    @GetMapping(value = "/queryById")
-    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
-        SysFiles sysFiles = sysFilesService.getById(id);
-        return Result.OK(sysFiles);
-    }
-
-    /**
-     * 导出excel
-     *
-     * @param request
-     * @param sysFiles
-     */
-    @RequestMapping(value = "/exportXls")
-    public ModelAndView exportXls(HttpServletRequest request, SysFiles sysFiles) {
-        return super.exportXls(request, sysFiles, SysFiles.class, "知识库-文档管理");
-    }
-
-    /**
-     * 通过excel导入数据
-     *
-     * @param request
-     * @param response
-     * @return
-     */
-    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
-    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
-        return super.importExcel(request, response, SysFiles.class);
-    }
-
-}

+ 57 - 25
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java

@@ -1,15 +1,12 @@
 package org.jeecg.modules.system.controller;
 
-import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
-import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.constant.SymbolConstant;
@@ -19,6 +16,7 @@ import org.jeecg.common.util.Md5Util;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.config.JeecgBaseConfig;
 import org.jeecg.modules.base.service.BaseCommonService;
+import org.jeecg.modules.system.constant.DefIndexConst;
 import org.jeecg.modules.system.entity.*;
 import org.jeecg.modules.system.model.SysPermissionTree;
 import org.jeecg.modules.system.model.TreeModel;
@@ -246,38 +244,66 @@ public class SysPermissionController {
 			if (oConvertUtils.isEmpty(loginUser)) {
 				return Result.error("请登录系统!");
 			}
-			List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
+			List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getId());
 			//添加首页路由
 			//update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
-			if(!PermissionDataUtil.hasIndexPage(metaList)){
-				SysPermission indexMenu = sysPermissionService.list(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getName,"首页")).get(0);
-				metaList.add(0,indexMenu);
-			}
-			//update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
 
 			//update-begin--Author:zyf Date:20220425  for:自定义首页地址 LOWCOD-1578
 			String version = request.getHeader(CommonConstant.VERSION);
-			//update-begin---author:liusq ---date:2022-06-29  for:接口返回值修改,同步修改这里的判断逻辑-----------
-			SysRoleIndex roleIndex= sysUserService.getDynamicIndexByUserRole(loginUser.getUsername(),version);
-			//update-end---author:liusq ---date:2022-06-29  for:接口返回值修改,同步修改这里的判断逻辑-----------
+			SysRoleIndex defIndexCfg = sysUserService.getDynamicIndexByUserRole(loginUser.getUsername(), version);
+			if (defIndexCfg == null) {
+				defIndexCfg = sysRoleIndexService.initDefaultIndex();
+			}
 			//update-end--Author:zyf  Date:20220425  for:自定义首页地址 LOWCOD-1578
 
-			if(roleIndex!=null){
-				List<SysPermission> menus = metaList.stream().filter(sysPermission -> "首页".equals(sysPermission.getName())).collect(Collectors.toList());
-				//update-begin---author:liusq ---date:2022-06-29  for:设置自定义首页地址和组件----------
-				String component = roleIndex.getComponent();
-				String routeUrl = roleIndex.getUrl();
-				boolean route = roleIndex.isRoute();
-				if(oConvertUtils.isNotEmpty(routeUrl)){
+			// 如果没有授权角色首页,则自动添加首页路由
+			if (!PermissionDataUtil.hasIndexPage(metaList, defIndexCfg)) {
+				LambdaQueryWrapper<SysPermission> indexQueryWrapper = new LambdaQueryWrapper<>();
+				indexQueryWrapper.eq(SysPermission::getUrl, defIndexCfg.getUrl());
+				SysPermission indexMenu = sysPermissionService.getOne(indexQueryWrapper);
+				if (indexMenu == null) {
+					indexMenu = new SysPermission();
+					indexMenu.setUrl(defIndexCfg.getUrl());
+					indexMenu.setComponent(defIndexCfg.getComponent());
+					indexMenu.setRoute(defIndexCfg.isRoute());
+					indexMenu.setName(DefIndexConst.DEF_INDEX_NAME);
+					indexMenu.setMenuType(0);
+				}
+				// 如果没有授权一级菜单,则自身变为一级菜单
+				if (indexMenu.getParentId() != null && !PermissionDataUtil.hasMenuById(metaList, indexMenu.getParentId())) {
+					indexMenu.setMenuType(0);
+					indexMenu.setParentId(null);
+				}
+				if (oConvertUtils.isEmpty(indexMenu.getIcon())) {
+					indexMenu.setIcon("ant-design:home");
+				}
+				metaList.add(0, indexMenu);
+			}
+			//update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
+
+/* TODO 注: 这段代码的主要作用是:把首页菜单的组件替换成角色菜单的组件,由于现在的逻辑如果角色菜单不存在则自动插入一条,所以这段代码暂时不需要
+			List<SysPermission> menus = metaList.stream().filter(sysPermission -> {
+				if (defIndexCfg.getUrl().equals(sysPermission.getUrl())) {
+					return true;
+				}
+				return defIndexCfg.getUrl().equals(sysPermission.getUrl());
+			}).collect(Collectors.toList());
+			//update-begin---author:liusq ---date:2022-06-29  for:设置自定义首页地址和组件----------
+			if (menus.size() == 1) {
+				String component = defIndexCfg.getComponent();
+				String routeUrl = defIndexCfg.getUrl();
+				boolean route = defIndexCfg.isRoute();
+				if (oConvertUtils.isNotEmpty(routeUrl)) {
 					menus.get(0).setComponent(component);
 					menus.get(0).setRoute(route);
 					menus.get(0).setUrl(routeUrl);
-				}else{
+				} else {
 					menus.get(0).setComponent(component);
 				}
-				//update-end---author:liusq ---date:2022-06-29  for:设置自定义首页地址和组件-----------
 			}
-			
+			//update-end---author:liusq ---date:2022-06-29  for:设置自定义首页地址和组件-----------
+*/
+
 			JSONObject json = new JSONObject();
 			JSONArray menujsonArray = new JSONArray();
 			this.getPermissionJsonArray(menujsonArray, metaList, null);
@@ -287,7 +313,7 @@ public class SysPermissionController {
 			JSONArray authjsonArray = new JSONArray();
 			this.getAuthJsonArray(authjsonArray, metaList);
 			//查询所有的权限
-			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
+			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>().select( SysPermission::getName, SysPermission::getPermsType, SysPermission::getPerms, SysPermission::getStatus);
 			query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
 			query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
 			//query.eq(SysPermission::getStatus, "1");
@@ -298,6 +324,12 @@ public class SysPermissionController {
 			json.put("menu", menujsonArray);
 			//按钮权限(用户拥有的权限集合)
 			json.put("auth", authjsonArray);
+			// 按钮权限(用户拥有的权限集合)
+			List<String> codeList = metaList.stream()
+					.filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
+					.collect(ArrayList::new, (list, permission) -> list.add(permission.getPerms()), ArrayList::addAll);
+			// 所拥有的权限编码(vue3专用)
+			json.put("codeList", codeList);
 			//全部权限配置集合(按钮权限,访问权限)
 			json.put("allAuth", allauthjsonArray);
 			//数据源安全模式
@@ -325,7 +357,7 @@ public class SysPermissionController {
 				return Result.error("请登录系统!");
 			}
 			// 获取当前用户的权限集合
-			List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
+			List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getId());
             // 按钮权限(用户拥有的权限集合)
             List<String> codeList = metaList.stream()
                     .filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
@@ -334,7 +366,7 @@ public class SysPermissionController {
 			JSONArray authArray = new JSONArray();
 			this.getAuthJsonArray(authArray, metaList);
 			// 查询所有的权限
-			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
+			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>().select( SysPermission::getName, SysPermission::getPermsType, SysPermission::getPerms, SysPermission::getStatus);
 			query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
 			query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
 			List<SysPermission> allAuthList = sysPermissionService.list(query);

+ 10 - 7
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java

@@ -123,13 +123,8 @@ public class SysRoleController {
 												@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
 												HttpServletRequest req) {
 		Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
-
-		//update-begin---author:wangshuai---date:2023-11-20---for:【QQYUN-7089】低代码模式 选择组织角色没有数据 在租户角色中添加数据后,列表也无数据展示---
-		if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
-			//此接口必须通过租户来隔离查询
-			role.setTenantId(oConvertUtils.getInt(!"0".equals(TenantContext.getTenant()) ? TenantContext.getTenant() : "", -1));
-		}
-		//update-end---author:wangshuai---date:2023-11-20---for:【QQYUN-7089】低代码模式 选择组织角色没有数据 在租户角色中添加数据后,列表也无数据展示---
+		//此接口必须通过租户来隔离查询
+		role.setTenantId(oConvertUtils.getInt(!"0".equals(TenantContext.getTenant()) ? TenantContext.getTenant() : "", -1));
 		
 		QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
 		Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
@@ -220,6 +215,12 @@ public class SysRoleController {
 				return Result.error("删除角色失败,当前角色不在此租户中。");
 			}
 		}
+    	
+		//update-begin---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
+		//是否存在admin角色
+		sysRoleService.checkAdminRoleRejectDel(id);
+		//update-end---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
+    	
 		sysRoleService.deleteRole(id);
 		return Result.ok("删除角色成功");
 	}
@@ -252,6 +253,8 @@ public class SysRoleController {
 					}
 				}
 			}
+			//验证是否为admin角色
+			sysRoleService.checkAdminRoleRejectDel(ids);
 			sysRoleService.deleteBatchRole(ids.split(","));
 			result.success("删除角色成功!");
 		}

+ 28 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java

@@ -173,4 +173,32 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo
         SysRoleIndex sysRoleIndex = sysRoleIndexService.getOne(new LambdaQueryWrapper<SysRoleIndex>().eq(SysRoleIndex::getRoleCode, roleCode));
         return Result.OK(sysRoleIndex);
     }
+
+    /**
+     * 查询默认首页配置
+     */
+    @GetMapping("/queryDefIndex")
+    public Result<SysRoleIndex> queryDefIndex() {
+        SysRoleIndex defIndexCfg = sysRoleIndexService.queryDefaultIndex();
+        return Result.OK(defIndexCfg);
+    }
+
+    /**
+     * 更新默认首页配置
+     */
+    @RequiresPermissions("system:permission:setDefIndex")
+    @PutMapping("/updateDefIndex")
+    public Result<?> updateDefIndex(
+            @RequestParam("url") String url,
+            @RequestParam("component") String component,
+            @RequestParam("isRoute") Boolean isRoute
+    ) {
+        boolean success = sysRoleIndexService.updateDefaultIndex(url, component, isRoute);
+        if (success) {
+            return Result.OK("设置成功");
+        } else {
+            return Result.error("设置失败");
+        }
+    }
+
 }

+ 5 - 3
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserController.java

@@ -244,6 +244,7 @@ public class SysUserController {
 		Result<SysUser> result = new Result<SysUser>();
 		try {
 			String ids = jsonObject.getString("ids");
+			sysUserService.checkUserAdminRejectDel(ids);
 			String status = jsonObject.getString("status");
 			String[] arr = ids.split(",");
             for (String id : arr) {
@@ -1428,7 +1429,7 @@ public class SysUserController {
         //------------------------------------------------------------------------------------------------
         //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
         if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
-            String tenantId = TokenUtils.getTenantIdByRequest(request);
+            String tenantId = oConvertUtils.getString(TokenUtils.getTenantIdByRequest(request),"-1");
             //update-begin---author:wangshuai ---date:20221223  for:[QQYUN-3371]租户逻辑改造,改成关系表------------
             List<String> userIds = userTenantService.getUserIdsByTenantId(Integer.valueOf(tenantId));
             if (oConvertUtils.listIsNotEmpty(userIds)) {
@@ -1549,7 +1550,8 @@ public class SysUserController {
             @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
             @RequestParam(name = "departId", required = false) String departId,
             @RequestParam(name = "roleId", required = false) String roleId,
-            @RequestParam(name="keyword",required=false) String keyword) {
+            @RequestParam(name="keyword",required=false) String keyword,
+            @RequestParam(name="excludeUserIdList",required = false) String excludeUserIdList) {
         //------------------------------------------------------------------------------------------------
         Integer tenantId = null;
         //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
@@ -1560,7 +1562,7 @@ public class SysUserController {
             }
         }
         //------------------------------------------------------------------------------------------------
-        IPage<SysUser> pageList = sysUserDepartService.getUserInformation(tenantId, departId,roleId, keyword, pageSize, pageNo);
+        IPage<SysUser> pageList = sysUserDepartService.getUserInformation(tenantId, departId,roleId, keyword, pageSize, pageNo,excludeUserIdList);
         return Result.OK(pageList);
     }
 

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java

@@ -61,7 +61,7 @@ public class SysUserOnlineController {
                 online.setToken(token);
                 //TODO 改成一次性查询
                 LoginUser loginUser = sysBaseApi.getUserByName(JwtUtil.getUsername(token));
-                if (loginUser != null) {
+                if (loginUser != null && !"_reserve_user_external".equals(loginUser.getUsername())) {
                     //update-begin---author:wangshuai ---date:20220104  for:[JTC-382]在线用户查询无效------------
                     //验证用户名是否与传过来的用户名相同
                     boolean isMatchUsername=true;

+ 45 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java

@@ -14,6 +14,7 @@ import org.jeecg.common.constant.SymbolConstant;
 import org.jeecg.common.constant.enums.MessageTypeEnum;
 import org.jeecg.common.system.util.JwtUtil;
 import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.TokenUtils;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
 import org.jeecg.modules.system.entity.SysThirdAccount;
@@ -22,6 +23,8 @@ import org.jeecg.modules.system.service.ISysThirdAccountService;
 import org.jeecg.modules.system.service.ISysThirdAppConfigService;
 import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
 import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
+import org.jeecg.modules.system.vo.thirdapp.JwSysUserDepartVo;
+import org.jeecg.modules.system.vo.thirdapp.JwUserDepartVo;
 import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -518,4 +521,46 @@ public class ThirdAppController {
         return Result.ok("解绑成功");
     }
     //========================end 应用低代码账号设置第三方账号绑定 ================================
+
+    /**
+     * 获取企业微信绑定的用户信息
+     * @param request
+     * @return
+     */
+    @GetMapping("/getThirdUserByWechat")
+    public Result<JwSysUserDepartVo> getThirdUserByWechat(HttpServletRequest request){
+        //获取企业微信配置
+        Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request),0);
+        SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
+        if (null != config) {
+            JwSysUserDepartVo list = wechatEnterpriseService.getThirdUserByWechat(tenantId);
+            return Result.ok(list);
+        }
+        return Result.error("企业微信尚未配置,请配置企业微信"); 
+    }
+
+    /**
+     * 同步企业微信部门和用户到本地
+     * @param jwUserDepartJson
+     * @param request
+     * @return
+     */
+    @GetMapping("/sync/wechatEnterprise/departAndUser/toLocal")
+    public Result<SyncInfoVo> syncWechatEnterpriseDepartAndUserToLocal(@RequestParam(name = "jwUserDepartJson") String jwUserDepartJson,HttpServletRequest request){
+        int tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request), 0);
+        SyncInfoVo syncInfoVo = wechatEnterpriseService.syncWechatEnterpriseDepartAndUserToLocal(jwUserDepartJson,tenantId);
+        return Result.ok(syncInfoVo);
+    }
+
+    /**
+     * 查询被绑定的企业微信用户
+     * @param request
+     * @return
+     */
+    @GetMapping("/getThirdUserBindByWechat")
+    public Result<List<JwUserDepartVo>> getThirdUserBindByWechat(HttpServletRequest request){
+        int tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request), 0);
+        List<JwUserDepartVo> jwSysUserDepartVos = wechatEnterpriseService.getThirdUserBindByWechat(tenantId);
+        return Result.ok(jwSysUserDepartVos);
+    }
 }

+ 0 - 142
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysFiles.java

@@ -1,142 +0,0 @@
-package org.jeecg.modules.system.entity;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-import org.jeecg.common.aspect.annotation.Dict;
-import org.jeecgframework.poi.excel.annotation.Excel;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.util.Date;
-
-/**
- * @Description: 知识库-文档管理
- * @Author: jeecg-boot
- * @Date:   2022-07-21
- * @Version: V1.0
- */
-@Data
-@TableName("sys_files")
-@EqualsAndHashCode(callSuper = false)
-@Accessors(chain = true)
-@Schema(description="sys_files对象")
-public class SysFiles {
-    
-	/**主键id*/
-	@TableId(type = IdType.ASSIGN_ID)
-    @Schema(description = "主键id")
-	private String id;
-	/**文件名称*/
-	@Excel(name = "文件名称", width = 15)
-    @Schema(description = "文件名称")
-	private String fileName;
-	/**文件地址*/
-	@Excel(name = "文件地址", width = 15)
-    @Schema(description = "文件地址")
-	private String url;
-	/**创建人登录名称*/
-	@Excel(name = "创建人登录名称", width = 15)
-    @Dict(dicCode = "username",dicText = "realname",dictTable = "sys_user")
-    @Schema(description = "创建人登录名称")
-	private String createBy;
-	/**创建日期*/
-	@Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
-    @Schema(description = "创建日期")
-	private Date createTime;
-	/**更新人登录名称*/
-	@Excel(name = "更新人登录名称", width = 15)
-    @Schema(description = "更新人登录名称")
-	private String updateBy;
-	/**更新日期*/
-	@Excel(name = "更新日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
-	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
-    @Schema(description = "更新日期")
-	private Date updateTime;
-	/**文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片  archive:其他文档 video:视频)*/
-	@Excel(name = "文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片  archive:其他文档 video:视频)", width = 15)
-    @Schema(description = "文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片  archive:其他文档 video:视频)")
-	private String fileType;
-	/**文件上传类型(temp/本地上传(临时文件) manage/知识库 comment)*/
-	@Excel(name = "文件上传类型(temp/本地上传(临时文件) manage/知识库 common(通用上传))", width = 15)
-    @Schema(description = "文件上传类型(temp/本地上传(临时文件) manage/知识库)")
-	private String storeType;
-	/**父级id*/
-	@Excel(name = "父级id", width = 15)
-    @Schema(description = "父级id")
-	private String parentId;
-	/**租户id*/
-	@Excel(name = "租户id", width = 15)
-    @Schema(description = "租户id")
-	private String tenantId;
-	/**文件大小(kb)*/
-	@Excel(name = "文件大小(kb)", width = 15)
-    @Schema(description = "文件大小(kb)")
-	private Double fileSize;
-	/**是否文件夹(1:是  0:否)*/
-	@Excel(name = "是否文件夹(1:是  0:否)", width = 15)
-    @Schema(description = "是否文件夹(1:是  0:否)")
-	private String izFolder;
-	/**是否为1级文件夹,允许为空 (1:是 )*/
-	@Excel(name = "是否为1级文件夹,允许为空 (1:是 )", width = 15)
-    @Schema(description = "是否为1级文件夹,允许为空 (1:是 )")
-	private String izRootFolder;
-	/**是否标星(1:是  0:否)*/
-	@Excel(name = "是否标星(1:是  0:否)", width = 15)
-    @Schema(description = "是否标星(1:是  0:否)")
-	private String izStar;
-	/**下载次数*/
-	@Excel(name = "下载次数", width = 15)
-    @Schema(description = "下载次数")
-	private Integer downCount;
-	/**阅读次数*/
-	@Excel(name = "阅读次数", width = 15)
-    @Schema(description = "阅读次数")
-	private Integer readCount;
-	/**分享链接*/
-	@Excel(name = "分享链接", width = 15)
-    @Schema(description = "分享链接")
-	private String shareUrl;
-	/**分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)*/
-	@Excel(name = "分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)", width = 15)
-    @Schema(description = "分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)")
-	private String sharePerms;
-	/**是否允许下载(1:是  0:否)*/
-	@Excel(name = "是否允许下载(1:是  0:否)", width = 15)
-    @Schema(description = "是否允许下载(1:是  0:否)")
-	private String enableDown;
-	/**是否允许修改(1:是  0:否)*/
-	@Excel(name = "是否允许修改(1:是  0:否)", width = 15)
-    @Schema(description = "是否允许修改(1:是  0:否)")
-	private String enableUpdat;
-	/**删除状态(0-正常,1-删除至回收站)*/
-	@Excel(name = "删除状态(0-正常,1-删除至回收站)", width = 15)
-    @Schema(description = "删除状态(0-正常,1-删除至回收站)")
-	private String delFlag;
-
-    /**
-     * 文件表不存在的字段:用户数据集合
-     */
-	@TableField(exist=false)
-    private String userData;
-
-    /**
-     * 文件表不存在的字段:用户真实姓名
-     */
-    @TableField(exist=false)
-    private String realname;
-
-    /**
-     * 文件表不存在的字段:压缩名称
-     */
-    @TableField(exist=false)
-    private String zipName;
-}

+ 6 - 6
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/entity/SysPermission.java

@@ -9,7 +9,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 import org.jeecg.common.aspect.annotation.Dict;
-import org.jeecgframework.poi.excel.annotation.Excel;
+import org.jeecg.modules.system.constant.DefIndexConst;
 
 /**
  * <p>
@@ -166,11 +166,11 @@ public class SysPermission implements Serializable {
     }
     public SysPermission(boolean index) {
     	if(index) {
-    		this.id = "9502685863ab87f0ad1134142788a385";
-        	this.name="首页";
-        	this.component="dashboard/Analysis";
-        	this.componentName="dashboard-analysis";
-        	this.url="/dashboard/analysis";
+			this.id = "9502685863ab87f0ad1134142788a385";
+			this.name = DefIndexConst.DEF_INDEX_NAME;
+			this.component = DefIndexConst.DEF_INDEX_COMPONENT;
+			this.componentName = "dashboard-analysis";
+			this.url = DefIndexConst.DEF_INDEX_URL;
         	this.icon="home";
         	this.menuType=0;
         	this.sortNo=0.0;

+ 13 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java

@@ -82,6 +82,12 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
 	 */
 	List<DictModelMany> queryManyDictByKeys(@Param("dictCodeList") List<String> dictCodeList, @Param("keys") List<String> keys);
 
+	/**
+	 * 查询系统所有字典项
+	 * @return
+	 */
+	public List<DictModelMany> queryAllDictItems(List<Integer> tenantIdList);
+	
 	/**
 	 * 查询所有部门 作为字典信息 id -->value,departName -->text
 	 * @return
@@ -187,4 +193,11 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
 	 */
 	@InterceptorIgnore(tenantLine = "true")
     List<SysDict> getDictListByLowAppId(@Param("lowAppId") String lowAppId, @Param("tenantId") Integer tenantId);
+
+	/**
+	 * 查询被逻辑删除的数据(根据租户id)
+	 * @return
+	 */
+	@Select("select * from sys_dict where del_flag = 1 and tenant_id = #{tenantId}")
+	List<SysDict> queryDeleteListBtTenantId(@Param("tenantId") Integer tenantId);
 }

+ 0 - 14
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysFilesMapper.java

@@ -1,14 +0,0 @@
-package org.jeecg.modules.system.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import org.jeecg.modules.system.entity.SysFiles;
-
-/**
- * @Description: 知识库-文档管理
- * @Author: jeecg-boot
- * @Date: 2022-07-21
- * @Version: V1.0
- */
-public interface SysFilesMapper extends BaseMapper<SysFiles> {
-
-}

+ 2 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysPermissionMapper.java

@@ -29,10 +29,10 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
 	
 	/**
 	 * 根据用户查询用户权限
-     * @param username 用户账户名称
+     * @param userId 用户ID
      * @return List<SysPermission>
 	 */
-	public List<SysPermission> queryByUser(@Param("username") String username);
+	public List<SysPermission> queryByUser(@Param("userId") String userId);
 	
 	/**
 	 * 修改菜单状态字段: 是否子节点

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserDepartMapper.java

@@ -57,7 +57,7 @@ public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
 	 * @param keyword
 	 * @return
 	 */
-	IPage<SysUser> getProcessUserList(Page<SysUser> page,  @Param("orgCode") String orgCode,  @Param("keyword") String keyword,  @Param("tenantId") Integer tenantId);
+	IPage<SysUser> getProcessUserList(Page<SysUser> page,  @Param("orgCode") String orgCode,  @Param("keyword") String keyword,  @Param("tenantId") Integer tenantId, @Param("excludeUserIdList") List<String> excludeUserIdList);
 
 	/**
 	 * 获取租户下的部门通过前台传过来的部门id

+ 2 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/SysUserMapper.java

@@ -171,9 +171,10 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
 	 * @param page
 	 * @param roleId
 	 * @param keyword
+	 * @param userIdList
 	 * @return
 	 */
-	IPage<SysUser> selectUserListByRoleId(Page<SysUser> page,  @Param("roleId") String roleId,  @Param("keyword") String keyword,  @Param("tenantId") Integer tenantId);
+	IPage<SysUser> selectUserListByRoleId(Page<SysUser> page,  @Param("roleId") String roleId,  @Param("keyword") String keyword,  @Param("tenantId") Integer tenantId, @Param("excludeUserIdList") List<String> excludeUserIdList);
 
     /**
      * 更新刪除状态和离职状态

+ 22 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml

@@ -63,6 +63,28 @@
 			</foreach>
 		)
 	</select>
+	
+	<!-- 获取全部字典项 -->
+	<select id="queryAllDictItems" resultType="org.jeecg.common.system.vo.DictModelMany">
+		SELECT
+			dict.dict_code,
+			item.item_text AS "text",
+			item.item_value AS "value",
+			item.item_color AS "color"
+		FROM
+			sys_dict_item item
+		INNER JOIN sys_dict dict ON dict.id = item.dict_id
+		WHERE dict.del_flag = 0
+		<if test="tenantIdList!=null  and tenantIdList.size()>0">
+		AND  dict.tenant_id IN (
+			<foreach item="tenantId" collection="tenantIdList" separator=",">
+				#{tenantId}
+			</foreach>
+		)
+		</if>
+		AND item.status =1
+		order by dict.dict_code, item.sort_order
+	</select>
 
 	<!-- 查询部门信息 作为字典数据 -->
 	<select id="queryAllDepartBackDictModel" resultType="org.jeecg.common.system.vo.DictModel">

+ 88 - 30
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysPermissionMapper.xml

@@ -42,46 +42,104 @@
 	<!-- 获取登录用户拥有的权限 -->
 	<select id="queryByUser" parameterType="Object"  resultMap="SysPermission">
 		   SELECT * FROM (
-			   SELECT p.*
+				SELECT  p.id,
+						p.parent_id,
+						p.name,
+						p.url,
+						p.component,
+						p.is_route,
+						p.component_name,
+						p.redirect,
+						p.menu_type,
+						p.perms,
+						p.perms_type,
+						p.sort_no,
+						p.always_show,
+						p.icon,
+						p.is_leaf,
+						p.keep_alive,
+						p.hidden,
+						p.hide_tab,
+						p.rule_flag,
+						p.status,
+						p.internal_or_external
 			   FROM  sys_permission p
-			   WHERE (exists(
-						select a.id from sys_role_permission a
-						join sys_role b on a.role_id = b.id
-						join sys_user_role c on c.role_id = b.id
-						join sys_user d on d.id = c.user_id
-						where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
+			   WHERE p.del_flag = 0
+		       AND  ( p.id in (
+			   		SELECT DISTINCT a.permission_id
+					FROM sys_role_permission a
+					JOIN sys_role b ON a.role_id = b.id
+					JOIN sys_user_role c ON c.role_id = b.id AND c.user_id = #{userId,jdbcType=VARCHAR}
 					)
 					or (p.url like '%:code' and p.url like '/online%' and p.hidden = 1)
 					or (p.url like '%:id' and p.url like '/online%' and p.hidden = 1)
-					or p.url = '/online')
-			   and p.del_flag = 0
+					or p.url = '/online'
+		       )
 			<!--update begin Author:lvdandan  Date:20200213 for:加入部门权限 -->
 			   UNION
-			   SELECT p.*
-			   FROM  sys_permission p
-			   WHERE exists(
-					select a.id from sys_depart_role_permission a
-					join sys_depart_role b on a.role_id = b.id
-					join sys_depart_role_user c on c.drole_id = b.id
-					join sys_user d on d.id = c.user_id
-					where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
-			   )
+			   SELECT   p.id,
+						p.parent_id,
+						p.name,
+						p.url,
+						p.component,
+						p.is_route,
+						p.component_name,
+						p.redirect,
+						p.menu_type,
+						p.perms,
+						p.perms_type,
+						p.sort_no,
+						p.always_show,
+						p.icon,
+						p.is_leaf,
+						p.keep_alive,
+						p.hidden,
+						p.hide_tab,
+						p.rule_flag,
+						p.status,
+						p.internal_or_external
+			FROM  sys_permission p
+			WHERE p.id in(
+		        SELECT DISTINCT a.permission_id
+				FROM  sys_depart_role_permission a
+				INNER JOIN sys_depart_role b ON a.role_id = b.id
+				INNER JOIN sys_depart_role_user c ON c.drole_id = b.id AND c.user_id = #{userId,jdbcType=VARCHAR}
+				)
 			   and p.del_flag = 0
 			<!--update end Author:lvdandan  Date:20200213 for:加入部门权限 -->
 			
 			<!-- update begin Author: taoyan  Date:20200213 for:QQYUN-4303 【low app】 用户登录的时候 加载low app的套餐权限 加到用户信息 -->
-			    UNION 
-				SELECT p.* 
-				FROM  sys_permission p
-				WHERE exists(
-				select a.id from sys_tenant_pack_perms a
-				join sys_tenant_pack b on a.pack_id = b.id
-				join sys_tenant_pack_user c on c.pack_id = b.id
-				join sys_user d on d.id = c.user_id
-				where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
-				)
-				and p.del_flag = 0
-			<!-- update end Author: taoyan  Date:20200213 for:QQYUN-4303 【low app】 用户登录的时候 加载low app的套餐权限 加到用户信息 -->
+			UNION
+			SELECT  p.id,
+					p.parent_id,
+					p.name,
+					p.url,
+					p.component,
+					p.is_route,
+					p.component_name,
+					p.redirect,
+					p.menu_type,
+					p.perms,
+					p.perms_type,
+					p.sort_no,
+					p.always_show,
+					p.icon,
+					p.is_leaf,
+					p.keep_alive,
+					p.hidden,
+					p.hide_tab,
+					p.rule_flag,
+					p.status,
+					p.internal_or_external
+			FROM  sys_permission p
+			WHERE p.id in (
+				SELECT distinct a.permission_id
+				FROM sys_tenant_pack_perms a
+				INNER JOIN sys_tenant_pack b ON a.pack_id = b.id AND b.STATUS = '1'
+				INNER JOIN sys_tenant_pack_user c ON c.pack_id = b.id AND c.STATUS = '1' AND c.user_id = #{userId,jdbcType=VARCHAR}
+			)
+			and p.del_flag = 0
+		<!-- update end Author: taoyan  Date:20200213 for:QQYUN-4303 【low app】 用户登录的时候 加载low app的套餐权限 加到用户信息 -->
 			
 		   ) h order by h.sort_no ASC
 	</select>

+ 7 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserDepartMapper.xml

@@ -74,6 +74,13 @@
 				select user_id from sys_user_tenant where tenant_id = #{tenantId} and status = '1'
 			)
 		</if>
+		<!--【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页 需要将不符合的用户id排除--> 
+		<if test="excludeUserIdList!=null and excludeUserIdList.size()>0">
+			and a.id not in
+			<foreach collection="excludeUserIdList" item="userId" open="(" close=")" separator=",">
+				#{userId}
+			</foreach>
+		</if>
 	</select>
 	
 	<!--获取租户下的部门-通过前台传过来的部门id-->

+ 8 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserMapper.xml

@@ -219,6 +219,14 @@
 				select user_id from sys_user_tenant where tenant_id = #{tenantId} and status = '1'
 			)
 		</if>
+		  
+		<!--【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页 需要将不符合的用户id排除-->
+		<if test="excludeUserIdList!=null and excludeUserIdList.size()>0">
+			and a.id not in
+			<foreach collection="excludeUserIdList" item="userId" open="(" close=")" separator=",">
+				#{userId}
+			</foreach>
+		</if>
 	</select>
 
 	<!--获取租户下的用户离职列表信息-->

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysUserTenantMapper.xml

@@ -169,7 +169,7 @@
     <select id="getUserCount" resultType="java.lang.Long">
         SELECT count(1) FROM sys_user_tenant sut JOIN sys_user su on sut.user_id = su.id and su.del_flag = 0 and su.status = 1
         WHERE sut.status = #{tenantStatus} 
-        AND tenant_id = #{tenantId}
+        AND sut.tenant_id = #{tenantId}
     </select>
 
     <!--根据租户id和名称获取用户数据-->

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysDictService.java

@@ -238,7 +238,7 @@ public interface ISysDictService extends IService<SysDict> {
 	 * 查询被逻辑删除的数据
 	 * @return
 	 */
-	public List<SysDict> queryDeleteList();
+	public List<SysDict> queryDeleteList(String tenantId);
 
 	/**
 	 * 分页查询

+ 0 - 14
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysFilesService.java

@@ -1,14 +0,0 @@
-package org.jeecg.modules.system.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import org.jeecg.modules.system.entity.SysFiles;
-
-/**
- * @Description: 知识库-文档管理
- * @Author: jeecg-boot
- * @Date: 2022-07-21
- * @Version: V1.0
- */
-public interface ISysFilesService extends IService<SysFiles> {
-
-}

+ 31 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysRoleIndexService.java

@@ -1,14 +1,43 @@
 package org.jeecg.modules.system.service;
 
-import org.jeecg.modules.system.entity.SysRoleIndex;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.system.entity.SysRoleIndex;
 
 /**
  * @Description: 角色首页配置
  * @Author: jeecg-boot
- * @Date:   2022-03-25
+ * @Date: 2022-03-25
  * @Version: V1.0
  */
 public interface ISysRoleIndexService extends IService<SysRoleIndex> {
 
+    /**
+     * 查询默认首页
+     *
+     * @return
+     */
+    SysRoleIndex queryDefaultIndex();
+
+    /**
+     * 更新默认首页
+     *
+     * @param url
+     * @param component
+     * @param isRoute   是否是路由页面
+     * @return
+     */
+    boolean updateDefaultIndex(String url, String component, boolean isRoute);
+
+    /**
+     * 创建最原始的默认首页配置
+     *
+     * @return
+     */
+    SysRoleIndex initDefaultIndex();
+
+    /**
+     * 清理默认首页的redis缓存
+     */
+    void cleanDefaultIndexCache();
+
 }

+ 7 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysRoleService.java

@@ -67,4 +67,11 @@ public interface ISysRoleService extends IService<SysRole> {
      * @return
      */
     Long getRoleCountByTenantId(String id, Integer tenantId);
+
+    /**
+     * 验证是否为admin角色
+     * 
+     * @param ids
+     */
+    void checkAdminRoleRejectDel(String ids);
 }

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java

@@ -77,7 +77,7 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
 	 * @param pageNo
 	 * @return
 	 */
-	IPage<SysUser> getUserInformation(Integer tenantId,String departId,String roleId, String keyword, Integer pageSize, Integer pageNo);
+	IPage<SysUser> getUserInformation(Integer tenantId,String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList);
 
 	/**
 	 * 通过部门id和租户id获取多个用户

+ 8 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserService.java

@@ -190,10 +190,10 @@ public interface ISysUserService extends IService<SysUser> {
 	/**
 	 * 通过用户名获取用户权限集合
 	 *
-	 * @param username 用户名
+	 * @param userId 用户id
 	 * @return 权限集合
 	 */
-	Set<String> getUserPermissionsSet(String username);
+	Set<String> getUserPermissionsSet(String userId);
 	
 	/**
 	 * 根据用户名设置部门ID
@@ -411,4 +411,10 @@ public interface ISysUserService extends IService<SysUser> {
 	 * @return
 	 */
 	Result<?> importAppUser(HttpServletRequest request);
+
+	/**
+	 * 验证用户是否为管理员
+	 * @param ids
+	 */
+	void checkUserAdminRejectDel(String ids);
 }

+ 1 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysUserTenantService.java

@@ -35,7 +35,7 @@ public interface ISysUserTenantService extends IService<SysUserTenant> {
     List<SysUser> setUserTenantIds(List<SysUser> records);
 
     /**
-     * 获取用户id根据用户id
+     * 获取租户id获取用户ids
      * @param tenantId
      * @return
      */

+ 20 - 33
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java

@@ -22,7 +22,6 @@ import org.jeecg.common.api.dto.DataLogDTO;
 import org.jeecg.common.api.dto.OnlineAuthDTO;
 import org.jeecg.common.api.dto.message.*;
 import org.jeecg.common.aspect.UrlMatchEnum;
-import org.jeecg.common.config.TenantContext;
 import org.jeecg.common.constant.*;
 import org.jeecg.common.constant.enums.EmailTemplateEnum;
 import org.jeecg.common.constant.enums.MessageTypeEnum;
@@ -125,8 +124,6 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 	@Autowired
 	private ISysDataLogService sysDataLogService;
 	@Autowired
-	private ISysFilesService sysFilesService;
-	@Autowired
 	private ISysRoleService sysRoleService;
 	@Autowired
 	private ISysUserTenantService sysUserTenantService;
@@ -336,7 +333,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 	}
 
 	@Override
-	public Set<String> getDepartParentIdsByDepIds(Set depIds) {
+	public Set<String> getDepartParentIdsByDepIds(Set<String> depIds) {
 		LambdaQueryWrapper<SysDepart> departQuery = new LambdaQueryWrapper<SysDepart>().in(SysDepart::getId, depIds);
 		List<SysDepart> departList = departMapper.selectList(departQuery);
 
@@ -1098,13 +1095,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 
 	/**
 	 * 查询用户拥有的权限集合
-	 * @param username
+	 * @param userId
 	 * @return
 	 */
 	@Override
-	public Set<String> getUserPermissionSet(String username) {
+	public Set<String> getUserPermissionSet(String userId) {
 		Set<String> permissionSet = new HashSet<>();
-		List<SysPermission> permissionList = sysPermissionMapper.queryByUser(username);
+		List<SysPermission> permissionList = sysPermissionMapper.queryByUser(userId);
 		//================= begin 开启租户的时候 如果没有test角色,默认加入test角色================
 		if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
 			if (permissionList == null) {
@@ -1123,7 +1120,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 				permissionSet.add(po.getPerms());
 			}
 		}
-		log.info("-------通过数据库读取用户拥有的权限Perms------username: "+ username+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
+		log.info("-------通过数据库读取用户拥有的权限Perms------userId: "+ userId+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
 		return permissionSet;
 	}
 
@@ -1148,7 +1145,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 			sysPermission.setUrl(onlineFormUrl);
 			int count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
 			if(count<=0){
-				return false;
+				//update-begin---author:chenrui ---date:20240123  for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
+				sysPermission.setUrl(onlineAuthDTO.getOnlineWorkOrderUrl());
+				count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
+				if(count<=0) {
+					return false;
+				}
+				//update-end---author:chenrui ---date:20240123  for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
 			}
 		} else {
 			//找到菜单了
@@ -1174,12 +1177,12 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 
 	/**
 	 * 查询用户拥有的权限集合 common api 里面的接口实现
-	 * @param username
+	 * @param userId
 	 * @return
 	 */
 	@Override
-	public Set<String> queryUserAuths(String username) {
-		return getUserPermissionSet(username);
+	public Set<String> queryUserAuths(String userId) {
+		return getUserPermissionSet(userId);
 	}
 
 	/**
@@ -1591,30 +1594,14 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 		entity.setDataContent(dataLogDto.getContent());
 		entity.setType(dataLogDto.getType());
 		entity.setDataVersion("1");
-		entity.autoSetCreateName();
+		if (oConvertUtils.isNotEmpty(dataLogDto.getCreateName())) {
+			entity.setCreateBy(dataLogDto.getCreateName());
+		} else {
+			entity.autoSetCreateName();
+		}
 		sysDataLogService.save(entity);
 	}
 
-    @Override
-    public void addSysFiles(SysFilesModel sysFilesModel) {
-        SysFiles sysFiles = new SysFiles();
-        BeanUtils.copyProperties(sysFilesModel,sysFiles);
-        String defaultValue = "0";
-        sysFiles.setIzStar(defaultValue);
-        sysFiles.setIzFolder(defaultValue);
-        sysFiles.setIzRootFolder(defaultValue);
-        sysFiles.setDelFlag(defaultValue);
-		String tenantId = oConvertUtils.getString(TenantContext.getTenant());
-		sysFiles.setTenantId(tenantId);
-        sysFilesService.save(sysFiles);
-    }
-
-    @Override
-    public String getFileUrl(String fileId) {
-        SysFiles sysFiles = sysFilesService.getById(fileId);
-        return sysFiles.getUrl();
-    }
-
     @Override
     public void updateAvatar(LoginUser loginUser) {
         SysUser sysUser = new SysUser();

+ 17 - 22
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysCommentServiceImpl.java

@@ -12,14 +12,13 @@ import org.jeecg.common.constant.enums.FileTypeEnum;
 import org.jeecg.common.constant.enums.MessageTypeEnum;
 import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.common.system.vo.SysFilesModel;
 import org.jeecg.common.util.CommonUtils;
 import org.jeecg.common.util.RedisUtil;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.system.entity.SysComment;
-import org.jeecg.modules.system.entity.SysFiles;
 import org.jeecg.modules.system.entity.SysFormFile;
 import org.jeecg.modules.system.mapper.SysCommentMapper;
-import org.jeecg.modules.system.mapper.SysFilesMapper;
 import org.jeecg.modules.system.mapper.SysFormFileMapper;
 import org.jeecg.modules.system.service.ISysCommentService;
 import org.jeecg.modules.system.vo.SysCommentFileVo;
@@ -55,8 +54,8 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
     @Autowired
     private SysFormFileMapper sysFormFileMapper;
 
-    @Autowired
-    private SysFilesMapper sysFilesMapper;
+//    @Autowired
+//    private IEasyOaBaseApi easyOaBseApi;
 
     @Autowired
     private RedisUtil redisUtil;
@@ -158,7 +157,7 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
             FileTypeEnum fileType = FileTypeEnum.getByType(type);
 
             //保存至 SysFiles
-            SysFiles sysFiles = new SysFiles();
+            SysFilesModel sysFiles = new SysFilesModel();
             sysFiles.setFileName(orgName);
             sysFiles.setUrl(savePath);
             sysFiles.setFileType(fileType.getValue());
@@ -166,16 +165,13 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
             if (size > 0) {
                 sysFiles.setFileSize(Double.parseDouble(String.valueOf(size)));
             }
-            String defaultValue = "0";
-            sysFiles.setIzStar(defaultValue);
-            sysFiles.setIzFolder(defaultValue);
-            sysFiles.setIzRootFolder(defaultValue);
-            sysFiles.setDelFlag(defaultValue);
             String fileId = String.valueOf(IdWorker.getId());
             sysFiles.setId(fileId);
             String tenantId = oConvertUtils.getString(TenantContext.getTenant());
             sysFiles.setTenantId(tenantId);
-            sysFilesMapper.insert(sysFiles);
+//            //update-begin---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
+//            easyOaBseApi.addSysFiles(sysFiles);
+//            //update-end---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
 
             //保存至 SysFormFile
             String tableName = SYS_FORM_FILE_TABLE_NAME;
@@ -188,18 +184,20 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
             sysFormFileMapper.insert(sysFormFile);
 
         }else{
-            SysFiles sysFiles = sysFilesMapper.selectById(existFileId);
-            if(sysFiles!=null){
+//            //update-begin---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
+//            SysFilesModel sysFiles = easyOaBseApi.getFileById(existFileId);
+//            //update-end---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
+//            if(sysFiles!=null){
                 //保存至 SysFormFile
                 String tableName = SYS_FORM_FILE_TABLE_NAME;
                 String tableDataId = request.getParameter("commentId");
                 SysFormFile sysFormFile = new SysFormFile();
                 sysFormFile.setTableName(tableName);
-                sysFormFile.setFileType(sysFiles.getFileType());
+                sysFormFile.setFileType("");
                 sysFormFile.setTableDataId(tableDataId);
                 sysFormFile.setFileId(existFileId);
                 sysFormFileMapper.insert(sysFormFile);
-            }
+//            }
         }
         //update-end-author:taoyan date:2023-6-12 for: QQYUN-4310【文件】从文件库选择文件功能未做
     }
@@ -224,7 +222,7 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
         FileTypeEnum fileType = FileTypeEnum.getByType(type);
 
         //保存至 SysFiles
-        SysFiles sysFiles = new SysFiles();
+        SysFilesModel sysFiles = new SysFilesModel();
         sysFiles.setFileName(orgName);
         sysFiles.setUrl(savePath);
         sysFiles.setFileType(fileType.getValue());
@@ -233,16 +231,13 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
             sysFiles.setFileSize(Double.parseDouble(String.valueOf(size)));
         }
         String defaultValue = "0";
-        sysFiles.setIzStar(defaultValue);
-        sysFiles.setIzFolder(defaultValue);
-        sysFiles.setIzRootFolder(defaultValue);
-        sysFiles.setDelFlag(defaultValue);
         String fileId = String.valueOf(IdWorker.getId());
         sysFiles.setId(fileId);
         String tenantId = oConvertUtils.getString(TenantContext.getTenant());
         sysFiles.setTenantId(tenantId);
-        sysFilesMapper.insert(sysFiles);
-
+//        //update-begin---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
+//        easyOaBseApi.addSysFiles(sysFiles);
+//        //update-end---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
         //保存至 SysFormFile
         String tableName = SYS_FORM_FILE_TABLE_NAME;
         String tableDataId = request.getParameter("commentId");

+ 43 - 32
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java

@@ -152,37 +152,36 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 
 	@Override
 	public Map<String, List<DictModel>> queryAllDictItems() {
-		Map<String, List<DictModel>> res = new HashMap(5);
-		LambdaQueryWrapper<SysDict> sysDictQueryWrapper = new LambdaQueryWrapper<SysDict>();
+		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
+		long start = System.currentTimeMillis();
+		Map<String, List<DictModel>> sysAllDictItems = new HashMap(5);
+		List<Integer> tenantIds = null;
 		//------------------------------------------------------------------------------------------------
 		//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
-		if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
-			sysDictQueryWrapper.eq(SysDict::getTenantId, oConvertUtils.getInt(TenantContext.getTenant(), 0))
-					.or().eq(SysDict::getTenantId,0);
+		if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
+			tenantIds = new ArrayList<>();
+			tenantIds.add(0);
+			if (TenantContext.getTenant() != null) {
+				tenantIds.add(oConvertUtils.getInt(TenantContext.getTenant()));
+			}
 		}
 		//------------------------------------------------------------------------------------------------
-		
-		List<SysDict> ls = sysDictMapper.selectList(sysDictQueryWrapper);
-		LambdaQueryWrapper<SysDictItem> queryWrapper = new LambdaQueryWrapper<SysDictItem>();
-		queryWrapper.eq(SysDictItem::getStatus, 1);
-		queryWrapper.orderByAsc(SysDictItem::getSortOrder);
-		List<SysDictItem> sysDictItemList = sysDictItemMapper.selectList(queryWrapper);
-
-		for (SysDict d : ls) {
-			List<DictModel> dictModelList = sysDictItemList.stream().filter(s -> d.getId().equals(s.getDictId())).map(item -> {
-				DictModel dictModel = new DictModel();
-				dictModel.setText(item.getItemText());
-				dictModel.setValue(item.getItemValue());
-				return dictModel;
-			}).collect(Collectors.toList());
-			res.put(d.getDictCode(), dictModelList);
-		}
-		//update-begin-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
+		List<DictModelMany> sysDictItemList = sysDictMapper.queryAllDictItems(tenantIds);
+		// 使用groupingBy根据dictCode分组
+		sysAllDictItems = sysDictItemList.stream()
+				.collect(Collectors.groupingBy(DictModelMany::getDictCode,
+						Collectors.mapping(d -> new DictModel(d.getValue(), d.getText(), d.getColor()), Collectors.toList())));
+		log.info("      >>> 1 获取系统字典项耗时(SQL):" + (System.currentTimeMillis() - start) + "毫秒");
+
 		Map<String, List<DictModel>> enumRes = ResourceUtil.getEnumDictData();
-		res.putAll(enumRes);
-		//update-end-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
-		log.debug("-------登录加载系统字典-----" + res.toString());
-		return res;
+		sysAllDictItems.putAll(enumRes);
+		log.info("      >>> 2 获取系统字典项耗时(Enum):" + (System.currentTimeMillis() - start) + "毫秒");
+		
+		log.info("      >>> end 获取系统字典库总耗时:" + (System.currentTimeMillis() - start) + "毫秒");
+		log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
+
+		//log.info("-------登录加载系统字典-----" + sysAllDictItems.toString());
+		return sysAllDictItems;
 	}
 
 	/**
@@ -532,10 +531,12 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 		String filterSql = "";
 		String keywordSql = null;
 		String sqlWhere = "where ";
+		String sqlAnd = " and ";
 		
 		//【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
-        if (tableSql.toLowerCase().contains(sqlWhere)) {
-            sqlWhere = CommonUtils.getFilterSqlByTableSql(tableSql) + " and ";
+		boolean tableHasWhere = tableSql.toLowerCase().contains(sqlWhere);
+        if (tableHasWhere) {
+			sqlWhere = CommonUtils.getFilterSqlByTableSql(tableSql);
 		}
 
 		// 下拉搜索组件 支持传入排序信息 查询排序
@@ -566,11 +567,13 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 		
 		//下拉搜索组件 支持传入排序信息 查询排序
 		if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){
-			filterSql+= sqlWhere + condition + " and " + keywordSql;
+			filterSql += sqlWhere + sqlAnd + condition + sqlAnd + keywordSql;
 		}else if(oConvertUtils.isNotEmpty(condition)){
-			filterSql+= sqlWhere + condition;
+			filterSql += sqlWhere + sqlAnd + condition;
 		}else if(oConvertUtils.isNotEmpty(keywordSql)){
-			filterSql+= sqlWhere + keywordSql;
+			filterSql += sqlWhere + sqlAnd + keywordSql;
+		} else if (tableHasWhere){
+			filterSql += sqlWhere; 
 		}
 		
 		// 增加排序逻辑
@@ -653,7 +656,15 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 	}
 
 	@Override
-	public List<SysDict> queryDeleteList() {
+	public List<SysDict> queryDeleteList(String tenantId) {
+		//update-begin---author:wangshuai---date:2024-02-27---for:【QQYUN-8340】回收站查找软删除记录时,没有判断是否启用多租户,造成可以查找并回收其他租户的数据 #5907---
+		if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
+			if(oConvertUtils.isEmpty(tenantId)){
+				return new ArrayList<>();
+			}
+			return baseMapper.queryDeleteListBtTenantId(oConvertUtils.getInt(tenantId));
+		}
+		//update-end---author:wangshuai---date:2024-02-27---for:【QQYUN-8340】回收站查找软删除记录时,没有判断是否启用多租户,造成可以查找并回收其他租户的数据 #5907---
 		return baseMapper.queryDeleteList();
 	}
 

+ 0 - 19
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysFilesServiceImpl.java

@@ -1,19 +0,0 @@
-package org.jeecg.modules.system.service.impl;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.jeecg.modules.system.entity.SysFiles;
-import org.jeecg.modules.system.mapper.SysFilesMapper;
-import org.jeecg.modules.system.service.ISysFilesService;
-import org.springframework.stereotype.Service;
-
-
-/**
- * @Description: 知识库-文档管理
- * @Author: jeecg-boot
- * @Date: 2022-07-21
- * @Version: V1.0
- */
-@Service
-public class SysFilesServiceImpl extends ServiceImpl<SysFilesMapper, SysFiles> implements ISysFilesService {
-
-}

+ 21 - 9
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java

@@ -1,9 +1,8 @@
 package org.jeecg.modules.system.service.impl;
 
-import java.util.*;
-
-import jakarta.annotation.Resource;
-
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.jeecg.common.constant.CacheConstant;
 import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.exception.JeecgBootException;
@@ -11,6 +10,7 @@ import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
 import org.jeecg.modules.system.entity.SysPermission;
 import org.jeecg.modules.system.entity.SysPermissionDataRule;
+import org.jeecg.modules.system.entity.SysRoleIndex;
 import org.jeecg.modules.system.mapper.SysDepartPermissionMapper;
 import org.jeecg.modules.system.mapper.SysDepartRolePermissionMapper;
 import org.jeecg.modules.system.mapper.SysPermissionMapper;
@@ -18,14 +18,15 @@ import org.jeecg.modules.system.mapper.SysRolePermissionMapper;
 import org.jeecg.modules.system.model.TreeModel;
 import org.jeecg.modules.system.service.ISysPermissionDataRuleService;
 import org.jeecg.modules.system.service.ISysPermissionService;
+import org.jeecg.modules.system.service.ISysRoleIndexService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import jakarta.annotation.Resource;
+import java.util.*;
 
 /**
  * <p>
@@ -53,6 +54,9 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
 	@Resource
 	private SysDepartRolePermissionMapper sysDepartRolePermissionMapper;
 
+	@Autowired
+	private ISysRoleIndexService roleIndexService;
+
 	@Override
 	public void switchVue3Menu() {
 		sysPermissionMapper.backupVue2Menu();
@@ -217,13 +221,21 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
 				}
 				
 			}
+
+			// 同步更改默认菜单
+			SysRoleIndex defIndexCfg = this.roleIndexService.queryDefaultIndex();
+			boolean isDefIndex = defIndexCfg.getUrl().equals(p.getUrl());
+			if (isDefIndex) {
+				this.roleIndexService.updateDefaultIndex(sysPermission.getUrl(), sysPermission.getComponent(), sysPermission.isRoute());
+			}
+
 		}
 		
 	}
 
 	@Override
-	public List<SysPermission> queryByUser(String username) {
-		List<SysPermission> permissionList = this.sysPermissionMapper.queryByUser(username);
+	public List<SysPermission> queryByUser(String userId) {
+		List<SysPermission> permissionList = this.sysPermissionMapper.queryByUser(userId);
 		//================= begin 开启租户的时候 如果没有test角色,默认加入test角色================
 		if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
 			if (permissionList == null) {

+ 76 - 4
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysRoleIndexServiceImpl.java

@@ -1,19 +1,91 @@
 package org.jeecg.modules.system.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.util.RedisUtil;
+import org.jeecg.modules.system.constant.DefIndexConst;
 import org.jeecg.modules.system.entity.SysRoleIndex;
 import org.jeecg.modules.system.mapper.SysRoleIndexMapper;
 import org.jeecg.modules.system.service.ISysRoleIndexService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-
 /**
  * @Description: 角色首页配置
  * @Author: jeecg-boot
- * @Date:   2022-03-25
+ * @Date: 2022-03-25
  * @Version: V1.0
  */
-@Service
+@Service("sysRoleIndexServiceImpl")
 public class SysRoleIndexServiceImpl extends ServiceImpl<SysRoleIndexMapper, SysRoleIndex> implements ISysRoleIndexService {
 
+    @Autowired
+    private RedisUtil redisUtil;
+
+    @Override
+    @Cacheable(cacheNames = DefIndexConst.CACHE_KEY, key = "'" + DefIndexConst.DEF_INDEX_ALL + "'")
+    public SysRoleIndex queryDefaultIndex() {
+        LambdaQueryWrapper<SysRoleIndex> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SysRoleIndex::getRoleCode, DefIndexConst.DEF_INDEX_ALL);
+        SysRoleIndex entity = super.getOne(queryWrapper);
+        // 保证不为空
+        if (entity == null) {
+            entity = this.initDefaultIndex();
+        }
+        return entity;
+    }
+
+    @Override
+    public boolean updateDefaultIndex(String url, String component, boolean isRoute) {
+        // 1. 先查询出配置信息
+        LambdaQueryWrapper<SysRoleIndex> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SysRoleIndex::getRoleCode, DefIndexConst.DEF_INDEX_ALL);
+        SysRoleIndex entity = super.getOne(queryWrapper);
+        boolean success = false;
+        // 2. 如果不存在则新增
+        if (entity == null) {
+            entity = this.newDefIndexConfig(url, component, isRoute);
+            success = super.save(entity);
+        } else {
+            // 3. 如果存在则更新
+            entity.setUrl(url);
+            entity.setComponent(component);
+            entity.setRoute(isRoute);
+            success = super.updateById(entity);
+        }
+        // 4. 清理缓存
+        if (success) {
+            this.cleanDefaultIndexCache();
+        }
+        return success;
+    }
+
+    @Override
+    public SysRoleIndex initDefaultIndex() {
+        return this.newDefIndexConfig(DefIndexConst.DEF_INDEX_URL, DefIndexConst.DEF_INDEX_COMPONENT, true);
+    }
+
+    /**
+     * 创建默认首页配置
+     *
+     * @param indexComponent
+     * @return
+     */
+    private SysRoleIndex newDefIndexConfig(String indexUrl, String indexComponent, boolean isRoute) {
+        SysRoleIndex entity = new SysRoleIndex();
+        entity.setRoleCode(DefIndexConst.DEF_INDEX_ALL);
+        entity.setUrl(indexUrl);
+        entity.setComponent(indexComponent);
+        entity.setRoute(isRoute);
+        entity.setStatus(CommonConstant.STATUS_1);
+        return entity;
+    }
+
+    @Override
+    public void cleanDefaultIndexCache() {
+        redisUtil.del(DefIndexConst.CACHE_KEY + "::" + DefIndexConst.DEF_INDEX_ALL);
+    }
+
 }

+ 14 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysRoleServiceImpl.java

@@ -1,9 +1,12 @@
 package org.jeecg.modules.system.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.constant.SymbolConstant;
+import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.util.ImportExcelUtil;
 import org.jeecg.modules.system.entity.SysRole;
 import org.jeecg.modules.system.mapper.SysRoleMapper;
@@ -102,4 +105,15 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
     public Long getRoleCountByTenantId(String id, Integer tenantId) {
         return sysRoleMapper.getRoleCountByTenantId(id,tenantId);
     }
+
+    @Override
+    public void checkAdminRoleRejectDel(String ids) {
+        LambdaQueryWrapper<SysRole> query = new  LambdaQueryWrapper<>();
+        query.in(SysRole::getId,Arrays.asList(ids.split(SymbolConstant.COMMA)));
+        query.eq(SysRole::getRoleCode,"admin");
+        Long adminRoleCount = sysRoleMapper.selectCount(query);
+        if(adminRoleCount>0){
+            throw new JeecgBootException("admin角色,不允许删除!");
+        }
+    }
 }

+ 12 - 7
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java

@@ -128,11 +128,13 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
 
     @Override
     public void addDefaultTenantPack(Integer tenantId) {
+        ISysTenantPackService currentService = SpringContextUtils.getApplicationContext().getBean(ISysTenantPackService.class);
+        // 创建租户超级管理员
+        SysTenantPack superAdminPack = new SysTenantPack(tenantId, "超级管理员", TenantConstant.SUPER_ADMIN);
+        
+        //step.1 创建租户套餐包(超级管理员)
         LambdaQueryWrapper<SysTenantPack> query = new LambdaQueryWrapper<>();
         query.eq(SysTenantPack::getTenantId,tenantId);
-        // 创建超级管理员
-        SysTenantPack superAdminPack = new SysTenantPack(tenantId, "超级管理员", TenantConstant.SUPER_ADMIN);
-        ISysTenantPackService currentService = SpringContextUtils.getApplicationContext().getBean(ISysTenantPackService.class);
         query.eq(SysTenantPack::getPackCode, TenantConstant.SUPER_ADMIN);
         SysTenantPack sysTenantPackSuperAdmin = currentService.getOne(query);
         String packId = "";
@@ -141,13 +143,15 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
         }else{
             packId = sysTenantPackSuperAdmin.getId();
         }
+        //step.1.2 补充人员与套餐包的关系数据
         LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
         SysTenantPackUser packUser = new SysTenantPackUser(tenantId, packId, sysUser.getId());
         packUser.setRealname(sysUser.getRealname());
         packUser.setPackName(superAdminPack.getPackName());
-        //添加人员和管理员的关系数据
         currentService.savePackUser(packUser);
-
+        
+        //step.2 创建租户套餐包(组织账户管理员)和 添加人员关系数据
+        query.eq(SysTenantPack::getTenantId,tenantId);
         query.eq(SysTenantPack::getPackCode, TenantConstant.ACCOUNT_ADMIN);
         SysTenantPack sysTenantPackAccountAdmin = currentService.getOne(query);
         if(null == sysTenantPackAccountAdmin){
@@ -155,10 +159,11 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
             SysTenantPack accountAdminPack = new SysTenantPack(tenantId, "组织账户管理员", TenantConstant.ACCOUNT_ADMIN);
             currentService.saveOne(accountAdminPack);
         }
-        
+
+        //step.3 创建租户套餐包(组织应用管理员)
+        query.eq(SysTenantPack::getTenantId,tenantId);
         query.eq(SysTenantPack::getPackCode, TenantConstant.APP_ADMIN);
         SysTenantPack sysTenantPackAppAdmin = currentService.getOne(query);
-        
         if(null == sysTenantPackAppAdmin){
             // 创建超级管理员
             SysTenantPack appAdminPack = new SysTenantPack(tenantId, "组织应用管理员", TenantConstant.APP_ADMIN);

+ 19 - 8
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java

@@ -27,10 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -262,24 +259,38 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
     }
 
 	@Override
-	public IPage<SysUser> getUserInformation(Integer tenantId, String departId,String roleId, String keyword, Integer pageSize, Integer pageNo) {
+	public IPage<SysUser> getUserInformation(Integer tenantId, String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList) {
 		IPage<SysUser> pageList = null;
 		// 部门ID不存在 直接查询用户表即可
 		Page<SysUser> page = new Page<>(pageNo, pageSize);
 		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+		
+		List<String> userIdList = new ArrayList<>();
+		if(oConvertUtils.isNotEmpty(excludeUserIdList)){
+			userIdList = Arrays.asList(excludeUserIdList.split(SymbolConstant.COMMA));
+		}
 		if(oConvertUtils.isNotEmpty(departId)){
 			// 有部门ID 需要走自定义sql
 			SysDepart sysDepart = sysDepartService.getById(departId);
 			//update-begin-author:taoyan date:2023-1-3 for: 用户选择组件 加载用户需要根据租户ID过滤
-			pageList = this.baseMapper.getProcessUserList(page, sysDepart.getOrgCode(), keyword, tenantId);
+			//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
+			//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
+			pageList = this.baseMapper.getProcessUserList(page, sysDepart.getOrgCode(), keyword, tenantId, userIdList);
+			//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
 		} else if (oConvertUtils.isNotEmpty(roleId)) {
-			pageList = this.sysUserMapper.selectUserListByRoleId(page, roleId, keyword, tenantId);
+			//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
+			pageList = this.sysUserMapper.selectUserListByRoleId(page, roleId, keyword, tenantId,userIdList);
+			//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
 			//update-end-author:taoyan date:2023-1-3 for: 用户选择组件 加载用户需要根据租户ID过滤
 		} else{
 			LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
 			query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
 			query.ne(SysUser::getUsername,"_reserve_user_external");
-			
+			//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
+			if(oConvertUtils.isNotEmpty(excludeUserIdList)){
+				query.notIn(SysUser::getId,Arrays.asList(excludeUserIdList.split(SymbolConstant.COMMA)));
+			}
+			//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
 			// 支持租户隔离
 			if (tenantId != null) {
 				List<String> userIds = userTenantMapper.getUserIdsByTenantId(tenantId);

+ 14 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java

@@ -1,11 +1,13 @@
 package org.jeecg.modules.system.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.RandomUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -1384,7 +1386,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 	 * 保存用户职位
 	 *
 	 * @param userId
-	 * @param postIds
+	 * @param positionIds
 	 */
 	private void saveUserPosition(String userId, String positionIds) {
 		if (oConvertUtils.isNotEmpty(positionIds)) {
@@ -1802,5 +1804,15 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 		//update-end---author:wangshuai ---date:20230710  for:【QQYUN-5731】导入用户时,没有提醒------------
 	}
 	//======================================= end 用户与部门 用户列表导入 =========================================
-	
+	@Override
+	public void checkUserAdminRejectDel(String userIds) {
+		LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
+		query.in(SysUser::getId,Arrays.asList(userIds.split(SymbolConstant.COMMA)));
+		query.eq(SysUser::getUsername,"admin");
+		Long adminRoleCount = this.baseMapper.selectCount(query);
+		//大于0说明存在管理员用户,不允许删除
+		if(adminRoleCount>0){
+			throw new JeecgBootException("admin用户,不允许删除!");
+		}
+	}
 }

+ 33 - 6
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/util/PermissionDataUtil.java

@@ -1,11 +1,14 @@
 package org.jeecg.modules.system.util;
 
-import java.util.List;
-
 import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.constant.SymbolConstant;
+import org.jeecg.common.util.SpringContextUtils;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.system.entity.SysPermission;
+import org.jeecg.modules.system.entity.SysRoleIndex;
+import org.jeecg.modules.system.service.ISysRoleIndexService;
+
+import java.util.List;
 
 /**
  * @Author: scott
@@ -82,8 +85,9 @@ public class PermissionDataUtil {
 	 */
 	public static void addIndexPage(List<SysPermission> metaList) {
 		boolean hasIndexMenu = false;
+		SysRoleIndex defIndexCfg = PermissionDataUtil.getDefIndexConfig();
 		for (SysPermission sysPermission : metaList) {
-			if("首页".equals(sysPermission.getName())) {
+			if(defIndexCfg.getUrl().equals(sysPermission.getUrl())) {
 				hasIndexMenu = true;
 				break;
 			}
@@ -98,15 +102,38 @@ public class PermissionDataUtil {
 	 * @param metaList
 	 * @return
 	 */
-	public static boolean hasIndexPage(List<SysPermission> metaList){
+	public static boolean hasIndexPage(List<SysPermission> metaList, SysRoleIndex defIndexCfg){
 		boolean hasIndexMenu = false;
 		for (SysPermission sysPermission : metaList) {
-			if("首页".equals(sysPermission.getName())) {
+			if(defIndexCfg.getUrl().equals(sysPermission.getUrl())) {
 				hasIndexMenu = true;
 				break;
 			}
 		}
 		return hasIndexMenu;
 	}
-	
+
+	/**
+	 * 通过id判断是否授权某个页面
+	 *
+	 * @param metaList
+	 * @return
+	 */
+	public static boolean hasMenuById(List<SysPermission> metaList, String id) {
+		for (SysPermission sysPermission : metaList) {
+			if (id.equals(sysPermission.getId())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * 获取默认首页配置
+	 */
+	public static SysRoleIndex getDefIndexConfig() {
+		ISysRoleIndexService sysRoleIndexService = SpringContextUtils.getBean(ISysRoleIndexService.class);
+		return sysRoleIndexService.queryDefaultIndex();
+	}
+
 }

+ 0 - 57
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysFileLogVo.java

@@ -1,57 +0,0 @@
-package org.jeecg.modules.system.vo;
-
-import lombok.Data;
-
-/**
- * @Description:
- * @author: wangshuai
- * @date: 2022年09月27日 20:56
- */
-@Data
-public class SysFileLogVo {
-    /**
-     * 文件id
-     */
-    private String fileId;
-    /**
-     * 用户id
-     */
-    private String userId;
-    /**
-     * 日志内容
-     */
-    private String dataContent;
-    /**
-     * 真实姓名
-     */
-    private String realname;
-    /**
-     * 头像
-     */
-    private String avatar;
-
-    /**
-     * 日志创建时间
-     */
-    private String createTime;
-
-    /**
-     * 手机号
-     */
-    private String phone;
-
-    /**
-     * 文件名称
-     */
-    private String fileName;
-
-    /**
-     * 路径
-     */
-    private String url;
-
-    /**
-     * 是否为文件夹
-     */
-    private String izFolder;
-}

+ 0 - 142
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/vo/SysFilesVo.java

@@ -1,142 +0,0 @@
-package org.jeecg.modules.system.vo;
-
-import lombok.Data;
-
-/**
- * @Description:
- * @author: wangshuai
- * @date: 2022年09月21日 17:27
- */
-@Data
-public class SysFilesVo {
-    /**
-     * 需要复制的文件夹或者文件id
-     */
-    private String fileId;
-
-    /**
-     * 需要复制到哪个文件夹下的id
-     */
-    private String copyToFileId;
-
-    /**
-     * 用户id
-     */
-    private String userId;
-
-    /**
-     * 委托人的用户id
-     */
-    private String msgTo;
-
-    /**
-     * 权限
-     */
-    private String authority;
-
-    /**
-     * 文件名称
-     */
-    private String fileName;
-
-
-    /**
-     * 删除状态
-     */
-    private String delFlag;
-
-    /**
-     * 文件大小
-     */
-    private Double fileSize;
-
-    /**
-     * 文件路径
-     */
-    private String fileUrl;
-
-    /**
-     * 说明(添加到系统日志)
-     */
-    private String description;
-
-    /**
-     * 创建人
-     */
-    private String createBy;
-
-    /**
-     * 创建时间
-     */
-    private String createTime;
-
-    /**
-     * 更新时间
-     */
-    private String updateTime;
-
-    /**
-     * 下载数
-     */
-    private String downCount;
-
-    /**
-     * 阅读数
-     */
-    private String readCount;
-
-    /**
-     * 父id
-     */
-    private String parentId;
-
-    /**
-     * 分享地址
-     */
-    private String shareUrl;
-
-    /**
-     * 是否允许下载(1:是  0:否)
-     */
-    private String enableDown;
-
-    /**
-     * 分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)
-     */
-    private String sharePerms;
-
-    /**
-     * 是否允许修改(1:是  0:否)
-     */
-    private String enableUpdat;
-
-    /**
-     * 头像
-     */
-    private String avatar;
-
-    /**
-     * 真实姓名
-     */
-    private String realname;
-
-    /**
-     * 权限方式(enableDown:下载,enableUpdat:修改,sharePerms:分享权限,reduction:还原,rename:重命名,newFile:上传新版本)
-     */
-    private String type;
-
-    /**
-     * 最上级的id
-     */
-    private String rootId;
-
-    /**
-     * 是否为文件夹(0否 1是)
-     */
-    private String izFolder;
-
-    /**
-     * 是否为一级文件夹(0否 1是)
-     */
-    private String izRootFolder;
-}

+ 3 - 1
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl

@@ -20,7 +20,9 @@
       JSelectDept,
 </#if>
 <#if need_dept_user>
-      JSelectUserByDept,
+<#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+      JSelectUser,
+<#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
 </#if>
 <#if need_select_tree>
       JTreeSelect,

+ 6 - 2
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl

@@ -1,5 +1,7 @@
 <#include "/common/utils.ftl">
-<#if po.isShow =='Y' && po.fieldName != 'id' && isNotPidField(tableVo, po.fieldDbName)>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isShow =='Y' && po.fieldName != 'id' && po.fieldName !='delFlag' && isNotPidField(tableVo, po.fieldDbName)>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign form_field_dictCode="">
 	<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
 		<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
@@ -48,7 +50,9 @@
 	          <a-input-password v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
 			<#elseif po.classType =='sel_user'>
 	          <#assign need_dept_user = true>
-	          <j-select-user-by-dept v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
+			  <#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+			  <j-select-user v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
+			  <#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
 			<#elseif po.classType =='textarea'>
 	          <a-textarea v-model:value="formData.${autoStringSuffixForModel(po)}" :rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/>
 			<#elseif po.classType=='radio'>

+ 3 - 1
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl

@@ -20,7 +20,9 @@
   import JSelectDept from '/@/components/Form/src/jeecg/components/JSelectDept.vue';
 </#if>
 <#if need_dept_user>
-  import JSelectUserByDept from '/@/components/Form/src/jeecg/components/JSelectUserByDept.vue';
+<#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+  import JSelectUser from '/@/components/Form/src/jeecg/components/JSelectUser.vue';
+<#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
 </#if>
 <#if need_select_tree>
   import JTreeSelect from '/@/components/Form/src/jeecg/components/JTreeSelect.vue';

+ 6 - 2
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl

@@ -1,5 +1,7 @@
 <#include "/common/utils.ftl">
-<#if po.isQuery=='Y'>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign query_flag=true>
 	<#if query_field_no==2>
           <template v-if="toggleSearchStatus">
@@ -19,7 +21,9 @@
             <#if po.classType=='sel_search'>
               <#if query_field_no gt 1>  </#if><j-search-select placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dict="${po.dictTable},${po.dictText},${po.dictField}" />
             <#elseif po.classType=='sel_user'>
-              <#if query_field_no gt 1>  </#if><j-select-user-by-dept placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" @change="(value)=>handleFormJoinChange('${po.fieldName}',value)"/>
+              <#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+              <#if query_field_no gt 1>  </#if><j-select-user placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" @change="(value)=>handleFormJoinChange('${po.fieldName}',value)"/>
+              <#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
             <#elseif po.classType=='switch'>
               <#if query_field_no gt 1>  </#if><j-switch placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> query />
             <#elseif po.classType=='sel_depart'>

+ 12 - 4
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/common/utils.ftl

@@ -144,7 +144,9 @@
     <#assign extAttrs="">
     <#assign dictCode="">
     <#if po.dictTable?default('')?trim?length gt 1 && po.dictText?default('')?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
-        <#assign dictCode="dictTable: '${po.dictTable}', dictCode: '${po.dictField}', dictText: '${po.dictText}'">
+        <#-- update-begin---author:chenrui ---date:20231228  for:fix 带条件字典存在单引号导致js编译错误---------- -->
+        <#assign dictCode="dictTable: \"${po.dictTable}\", dictCode: '${po.dictField}', dictText: '${po.dictText}'">
+        <#-- update-begin---author:chenrui ---date:20231228  for:fix 带条件字典存在单引号导致js编译错误---------- -->
     <#elseif po.dictField?default("")?trim?length gt 1>
         <#assign dictCode="dictCode: '${po.dictField}'">
     </#if>
@@ -153,7 +155,9 @@
         <#assign extAttrs="${dictCode},">
     <#elseif po.classType=='cat_tree'>
     <#-- 分类字典树 -->
-        <#assign extAttrs="pcode: '${po.dictField}',">
+        <#-- update-begin---author:chenrui ---date:20240109  for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
+        <#assign extAttrs="pcode: '${po.dictField?default('')}',">
+        <#-- update-end---author:chenrui ---date:20240109  for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
     <#elseif po.classType=='sel_tree'>
     <#-- 自定义树 -->
         <#if po.dictText??>
@@ -166,10 +170,14 @@
                 <#assign extAttrs="hasChildField: '${po.dictText?split(',')[3]}'">
             </#if>
         </#if>
-        <#assign extAttrs="${extAttrs}, pidValue: '${po.dictField}',">
+        <#-- update-begin---author:chenrui ---date:20240109  for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
+        <#assign extAttrs="${extAttrs}, pidValue: '${po.dictField?default('')}',">
+        <#-- update-end---author:chenrui ---date:20240109  for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
     <#elseif po.classType=='popup'>
     <#-- popup -->
-        <#if po.dictText?default("")?trim?length gt 1 && po.dictText?index_of(',') gt 0>
+        <#-- update-begin---author:chenrui ---date:20240109  for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
+        <#if po.dictText?default("")?trim?length gt 1 && po.dictText?index_of(',') gt 0 && po.dictField?default("")?trim?length gt 1>
+        <#-- update-begin---author:chenrui ---date:20240109  for:[issue/5787]增加非空判断防止代码生成时空指针异常---------- -->
         <#-- 如果有多个回填字段,找到popup字段对应的来源字段 -->
             <#assign orgFieldIx=po.dictText?split(',')?seq_index_of(po.fieldDbName)>
             <#assign orgField=po.dictField?split(',')[orgFieldIx]>

jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/vue-app/${entityName}Form.vue_uniAppi → jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/uniapp/${entityName}Form.vue


jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/vue-app/${entityName}List.vue_uniAppi → jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/uniapp/${entityName}List.vue


jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql → jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql


+ 18 - 6
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi

@@ -6,7 +6,9 @@ import { render } from '/@/utils/common/renderUtils';
 //列表数据
 export const columns: BasicColumn[] = [
  <#list columns as po>
-   <#if po.isShowList =='Y' && po.fieldName !='id'>
+   <#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+   <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
+   <#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
    {
     title: '${po.filedComment}',
     align:"center",
@@ -70,7 +72,9 @@ export const searchFormSchema: FormSchema[] = [
 <#if po.fieldDbName=='bpm_status'>
   <#assign bpm_flag=true>
 </#if>
-<#if po.isQuery=='Y'>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign query_flag=true>
 	<#assign query_field_dictCode="">
 	<#if po.dictTable?default("")?trim?length gt 1>
@@ -88,7 +92,9 @@ export const searchFormSchema: FormSchema[] = [
          dict:"${po.dictTable},${po.dictText},${po.dictField}"
       },
 <#elseif po.classType=='sel_user'>
-      component: 'JSelectUserByDept',
+<#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+      component: 'JSelectUser',
+<#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
 <#elseif po.classType=='switch'>
       component: 'JSwitch',
       componentProps:{
@@ -186,7 +192,9 @@ export const formSchema: FormSchema[] = [
 <#if po.fieldDbName == 'id'>
 	<#assign id_exists = true>
 </#if>
-<#if po.isShow =='Y'>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isShow =='Y' && po.fieldName !='delFlag'>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign form_field_dictCode="">
 	<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
 		<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
@@ -236,7 +244,9 @@ export const formSchema: FormSchema[] = [
      <#elseif po.classType =='password'>
     component: 'InputPassword',
      <#elseif po.classType =='sel_user'>
-    component: 'JSelectUserByDept',
+    <#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+    component: 'JSelectUser',
+    <#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
     componentProps:{
         labelKey:'realname',
      },
@@ -387,7 +397,9 @@ export const formSchema: FormSchema[] = [
 // 高级查询数据
 export const superQuerySchema = {
   <#list columns as po>
-  <#if po.isShowList =='Y' && po.fieldName !='id'>
+  <#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+  <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
+  <#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
   ${superQueryFieldListForVue3(po,po_index)},
   </#if>
   </#list>

jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql → jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql


+ 18 - 6
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi

@@ -6,7 +6,9 @@ import { render } from '/@/utils/common/renderUtils';
 //列表数据
 export const columns: BasicColumn[] = [
  <#list columns as po>
-   <#if po.isShowList =='Y' && po.fieldName !='id'>
+   <#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+   <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
+   <#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
   {
     title: '${po.filedComment}',
     align: "center",
@@ -71,7 +73,9 @@ export const searchFormSchema: FormSchema[] = [
 <#if po.fieldDbName=='bpm_status'>
   <#assign bpm_flag=true>
 </#if>
-<#if po.isQuery=='Y'>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign query_flag=true>
 	<#assign query_field_dictCode="">
 	<#if po.dictTable?default("")?trim?length gt 1>
@@ -89,7 +93,9 @@ export const searchFormSchema: FormSchema[] = [
       dict: "${po.dictTable},${po.dictText},${po.dictField}"
     },
 <#elseif po.classType=='sel_user'>
-    component: 'JSelectUserByDept',
+<#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+    component: 'JSelectUser',
+<#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
 <#elseif po.classType=='switch'>
     component: 'JSwitch',
     componentProps:{
@@ -181,7 +187,9 @@ export const formSchema: FormSchema[] = [
 <#if po.fieldDbName == 'id'>
 	<#assign id_exists = true>
 </#if>
-<#if po.isShow =='Y'>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isShow =='Y' && po.fieldName !='delFlag'>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign form_field_dictCode="">
 	<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
 		<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
@@ -222,7 +230,9 @@ export const formSchema: FormSchema[] = [
      <#elseif po.classType =='password'>
     component: 'InputPassword',
      <#elseif po.classType =='sel_user'>
-    component: 'JSelectUserByDept',
+<#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+    component: 'JSelectUser',
+<#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
     componentProps:{
       labelKey: 'realname',
     },
@@ -373,7 +383,9 @@ export const formSchema: FormSchema[] = [
 // 高级查询数据
 export const superQuerySchema = {
   <#list columns as po>
-  <#if po.isShowList =='Y' && po.fieldName !='id'>
+  <#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+  <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
+  <#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
   ${superQueryFieldListForVue3(po,po_index)},
   </#if>
   </#list>

jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql → jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql


+ 8 - 2
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei

@@ -80,7 +80,7 @@
   const validatorRules = {
   <#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl">
   };
-  const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true });
+  const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: false });
 
   // 表单禁用
   const disabled = computed(()=>{
@@ -132,8 +132,14 @@
   function edit(record) {
     nextTick(() => {
       resetFields();
+      const tmpData = {};
+      Object.keys(formData).forEach((key) => {
+        if(record.hasOwnProperty(key)){
+          tmpData[key] = record[key]
+        }
+      })
       //赋值
-      Object.assign(formData, record);
+      Object.assign(formData, tmpData);
     });
   }
 

jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql → jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql


jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql → jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql


+ 18 - 6
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi

@@ -6,7 +6,9 @@ import { render } from '/@/utils/common/renderUtils';
 //列表数据
 export const columns: BasicColumn[] = [
  <#list columns as po>
-   <#if po.isShowList =='Y' && po.fieldName !='id'>
+   <#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+   <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
+   <#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
    {
     title: '${po.filedComment}',
     <#if po.fieldDbName == tableVo.extendParams.textField>
@@ -74,7 +76,9 @@ export const searchFormSchema: FormSchema[] = [
 <#if po.fieldDbName=='bpm_status'>
   <#assign bpm_flag=true>
 </#if>
-<#if po.isQuery=='Y'>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isQuery=='Y' && po.fieldName !='delFlag'>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign query_flag=true>
 	<#assign query_field_dictCode="">
 	<#if po.dictTable?default("")?trim?length gt 1>
@@ -92,7 +96,9 @@ export const searchFormSchema: FormSchema[] = [
          dict:"${po.dictTable},${po.dictText},${po.dictField}"
       },
 <#elseif po.classType=='sel_user'>
-      component: 'JSelectUserByDept',
+<#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+      component: 'JSelectUser',
+<#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
 <#elseif po.classType=='switch'>
       component: 'JSwitch',
       componentProps:{
@@ -204,7 +210,9 @@ export const formSchema: FormSchema[] = [
 <#if po.fieldDbName == 'id'>
 	<#assign id_exists = true>
 </#if>
-<#if po.isShow =='Y'>
+<#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+<#if po.isShow =='Y' && po.fieldName !='delFlag'>
+<#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
 <#assign form_field_dictCode="">
 	<#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1>
 		<#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}">
@@ -262,7 +270,9 @@ export const formSchema: FormSchema[] = [
      <#elseif po.classType =='password'>
     component: 'InputPassword',
      <#elseif po.classType =='sel_user'>
-    component: 'JSelectUserByDept',
+<#-- update-begin---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
+    component: 'JSelectUser',
+<#-- update-end---author:chenrui ---date:20240102  for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
     componentProps:{
         labelKey:'realname',
      },
@@ -416,7 +426,9 @@ export const formSchema: FormSchema[] = [
 // 高级查询数据
 export const superQuerySchema = {
   <#list columns as po>
-  <#if po.isShowList =='Y' && po.fieldName !='id'>
+  <#-- update-begin---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
+  <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'>
+  <#-- update-end---author:chenrui ---date:20240108  for:[issues/5755]vue代码不加入逻辑删除字段---------- -->
   ${superQueryFieldListForVue3(po,po_index)},
   </#if>
   </#list>

+ 0 - 0
jeecg-module-system/jeecg-system-biz/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql


Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott