1
13693261870
2024-08-16 29910029cee1c19509d26b79f861fb953f78fefc
1
已重命名158个文件
已添加47个文件
已修改15个文件
4815 ■■■■■ 文件已修改
pom.xml 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-api/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-auth/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/pom.xml 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/constant/CacheConstants.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/constant/GenConstants.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/constant/HttpStatus.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/constant/ScheduleConstants.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/constant/TokenConstants.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/context/SecurityContextHolder.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/DemoModeException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/InnerAuthException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/PreAuthorizeException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/UtilException.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/auth/NotLoginException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/base/BaseException.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/file/FileException.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/file/FileUploadException.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/job/TaskException.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/user/UserException.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/exception/user/UserPasswordNotMatchException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/text/CharsetKit.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/JwtUtils.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/bean/BeanValidators.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/file/MimeTypeUtils.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/poi/ExcelUtil.java 1538 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/reflect/ReflectUtils.java 410 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/sign/Base64.java 291 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/utils/sql/SqlUtil.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/xss/Xss.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-core/src/main/java/com/se/common/core/xss/XssValidator.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-datascope/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-datascope/src/main/java/com/se/common/datascope/aspect/DataScopeAspect.java 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-datasource/pom.xml 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-datasource/src/main/java/com/se/common/datasource/annotation/Master.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-log/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-log/src/main/java/com/se/common/log/annotation/Log.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-log/src/main/java/com/se/common/log/aspect/LogAspect.java 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-log/src/main/java/com/se/common/log/enums/BusinessStatus.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-log/src/main/java/com/se/common/log/enums/BusinessType.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-log/src/main/java/com/se/common/log/enums/OperatorType.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-log/src/main/java/com/se/common/log/service/AsyncLogService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-redis/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-seata/pom.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-security/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-security/src/main/java/com/se/common/security/annotation/InnerAuth.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-security/src/main/java/com/se/common/security/aspect/InnerAuthAspect.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-security/src/main/java/com/se/common/security/handler/GlobalExceptionHandler.java 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-security/src/main/java/com/se/common/security/utils/DictUtils.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-sensitive/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-sensitive/src/main/java/com/se/common/sensitive/config/SensitiveJsonSerializer.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-sensitive/src/main/java/com/se/common/sensitive/enums/DesensitizedType.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-sensitive/src/main/java/com/se/common/sensitive/utils/DesensitizedUtil.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-swagger/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-swagger/src/main/java/com/se/common/swagger/annotation/EnableCustomSwagger2.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-common/se-common-swagger/src/main/java/com/se/common/swagger/config/SwaggerBeanPostProcessor.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-gateway/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/pom.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/SeFileApplication.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/config/MinioConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/config/ResourcesConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/controller/SysFileController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/service/FastDfsSysFileServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/service/ISysFileService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/service/LocalSysFileServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/service/MinioSysFileServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/java/com/se/file/utils/FileUploadUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/resources/banner.txt 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/resources/bootstrap.yml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-file/src/main/resources/logback.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/SeGenApplication.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/config/GenConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/controller/GenController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/domain/GenTable.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/domain/GenTableColumn.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/mapper/GenTableColumnMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/mapper/GenTableMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/service/GenTableColumnServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/service/GenTableServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/service/IGenTableColumnService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/service/IGenTableService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/util/GenUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/util/VelocityInitializer.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/java/com/se/gen/util/VelocityUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/banner.txt 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/bootstrap.yml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/logback.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/mapper/generator/GenTableMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/java/controller.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/java/domain.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/java/mapper.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/java/service.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/java/serviceImpl.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/java/sub-domain.java.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/js/api.js.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/sql/sql.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/vue/index-tree.vue.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/vue/index.vue.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/vue/v3/index.vue.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-gen/src/main/resources/vm/xml/mapper.xml.vm 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/SeJobApplication.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/config/ScheduleConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/controller/SysJobController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/controller/SysJobLogController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/domain/SysJob.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/domain/SysJobLog.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/mapper/SysJobLogMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/mapper/SysJobMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/service/ISysJobLogService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/service/ISysJobService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/service/SysJobLogServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/service/SysJobServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/task/RyTask.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/util/AbstractQuartzJob.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/util/CronUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/util/JobInvokeUtil.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/util/QuartzDisallowConcurrentExecution.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/util/QuartzJobExecution.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/java/com/se/job/util/ScheduleUtils.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/resources/banner.txt 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/resources/bootstrap.yml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/resources/logback.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/resources/mapper/job/SysJobLogMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-job/src/main/resources/mapper/job/SysJobMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/RuoYiSystemApplication.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysConfigController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysDeptController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysDictDataController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysDictTypeController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysLogininforController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysMenuController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysNoticeController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysOperlogController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysPostController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysProfileController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysRoleController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysUserController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/controller/SysUserOnlineController.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysConfig.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysMenu.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysNotice.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysPost.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysRoleDept.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysRoleMenu.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysUserOnline.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysUserPost.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/SysUserRole.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/vo/MetaVo.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/vo/RouterVo.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/domain/vo/TreeSelect.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysConfigMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysDeptMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysDictDataMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysDictTypeMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysLogininforMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysMenuMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysNoticeMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysOperLogMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysPostMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysRoleDeptMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysRoleMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysRoleMenuMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysUserMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysUserPostMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/mapper/SysUserRoleMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysConfigService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysDeptService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysDictDataService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysDictTypeService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysLogininforService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysMenuService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysNoticeService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysOperLogService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysPermissionService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysPostService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysRoleService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysUserOnlineService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/ISysUserService.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysConfigServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysDeptServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysDictDataServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysDictTypeServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysLogininforServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysMenuServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysNoticeServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysOperLogServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysPermissionServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysPostServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysRoleServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysUserOnlineServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/java/com/se/system/service/impl/SysUserServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/banner.txt 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/bootstrap.yml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/logback.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysConfigMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysDeptMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysDictDataMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysDictTypeMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysLogininforMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysMenuMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysNoticeMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysOperLogMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysPostMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysRoleMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysUserMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysUserPostMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-modules/se-system/src/main/resources/mapper/system/SysUserRoleMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
se-visual/pom.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-visual/se-monitor/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
se-visual/se-monitor/src/main/java/com/se/modules/monitor/SeMonitorApplication.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -9,8 +9,7 @@
    <version>3.6.4</version>
    <name>ruoyi</name>
    <url>http://www.ruoyi.vip</url>
    <description>若依微服务系统</description>
    <description>微服务系统</description>
    <properties>
        <ruoyi.version>3.6.4</ruoyi.version>
@@ -227,12 +226,12 @@
    </dependencyManagement>
    <modules>
        <module>ruoyi-auth</module>
        <module>ruoyi-gateway</module>
        <module>ruoyi-visual</module>
        <module>ruoyi-modules</module>
        <module>ruoyi-api</module>
        <module>ruoyi-common</module>
        <module>se-auth</module>
        <module>se-gateway</module>
        <module>se-visual</module>
        <module>se-modules</module>
        <module>se-api</module>
        <module>se-common</module>
    </modules>
    <packaging>pom</packaging>
se-api/pom.xml
@@ -9,10 +9,10 @@
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>ruoyi-api-system</module>
        <module>se-api-system</module>
    </modules>
    <artifactId>ruoyi-api</artifactId>
    <artifactId>se-api</artifactId>
    <packaging>pom</packaging>
    <description>
se-auth/pom.xml
@@ -8,10 +8,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-auth</artifactId>
    <artifactId>se-auth</artifactId>
    
    <description>
        ruoyi-auth认证授权中心
        se-auth认证授权中心
    </description>
    
    <dependencies>
se-common/pom.xml
@@ -9,22 +9,22 @@
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>ruoyi-common-log</module>
        <module>ruoyi-common-core</module>
        <module>ruoyi-common-redis</module>
        <module>ruoyi-common-seata</module>
        <module>ruoyi-common-swagger</module>
        <module>ruoyi-common-security</module>
        <module>ruoyi-common-sensitive</module>
        <module>ruoyi-common-datascope</module>
        <module>ruoyi-common-datasource</module>
        <module>se-common-log</module>
        <module>se-common-core</module>
        <module>se-common-redis</module>
        <module>se-common-seata</module>
        <module>se-common-swagger</module>
        <module>se-common-security</module>
        <module>se-common-sensitive</module>
        <module>se-common-datascope</module>
        <module>se-common-datasource</module>
    </modules>
    <artifactId>ruoyi-common</artifactId>
    <artifactId>se-common</artifactId>
    <packaging>pom</packaging>
    <description>
        ruoyi-common通用模块
        se-common通用模块
    </description>
</project>
se-common/se-common-core/pom.xml
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-common-core</artifactId>
    <artifactId>se-common-core</artifactId>
    
    <description>
        ruoyi-common-core核心模块
        se-common-core核心模块
    </description>
    <dependencies>
se-common/se-common-core/src/main/java/com/se/common/core/constant/CacheConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.se.common.core.constant;
/**
 * ç¼“存常量信息
 *
 * @author admin
 */
public class CacheConstants
{
    /**
     * ç¼“存有效期,默认720(分钟)
     */
    public final static long EXPIRATION = 720;
    /**
     * ç¼“存刷新时间,默认120(分钟)
     */
    public final static long REFRESH_TIME = 120;
    /**
     * å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
     */
    public final static int PASSWORD_MAX_RETRY_COUNT = 5;
    /**
     * å¯†ç é”å®šæ—¶é—´ï¼Œé»˜è®¤10(分钟)
     */
    public final static long PASSWORD_LOCK_TIME = 10;
    /**
     * æƒé™ç¼“存前缀
     */
    public final static String LOGIN_TOKEN_KEY = "login_tokens:";
    /**
     * éªŒè¯ç  redis key
     */
    public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
    /**
     * å‚数管理 cache key
     */
    public static final String SYS_CONFIG_KEY = "sys_config:";
    /**
     * å­—典管理 cache key
     */
    public static final String SYS_DICT_KEY = "sys_dict:";
    /**
     * ç™»å½•账户密码错误次数 redis key
     */
    public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
    /**
     * ç™»å½•IP黑名单 cache key
     */
    public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList";
}
se-common/se-common-core/src/main/java/com/se/common/core/constant/GenConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
package com.se.common.core.constant;
/**
 * ä»£ç ç”Ÿæˆé€šç”¨å¸¸é‡
 *
 * @author admin
 */
public class GenConstants
{
    /** å•表(增删改查) */
    public static final String TPL_CRUD = "crud";
    /** æ ‘表(增删改查) */
    public static final String TPL_TREE = "tree";
    /** ä¸»å­è¡¨ï¼ˆå¢žåˆ æ”¹æŸ¥ï¼‰ */
    public static final String TPL_SUB = "sub";
    /** æ ‘编码字段 */
    public static final String TREE_CODE = "treeCode";
    /** æ ‘父编码字段 */
    public static final String TREE_PARENT_CODE = "treeParentCode";
    /** æ ‘名称字段 */
    public static final String TREE_NAME = "treeName";
    /** ä¸Šçº§èœå•ID字段 */
    public static final String PARENT_MENU_ID = "parentMenuId";
    /** ä¸Šçº§èœå•名称字段 */
    public static final String PARENT_MENU_NAME = "parentMenuName";
    /** æ•°æ®åº“字符串类型 */
    public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
    /** æ•°æ®åº“文本类型 */
    public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
    /** æ•°æ®åº“时间类型 */
    public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
    /** æ•°æ®åº“数字类型 */
    public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
            "bit", "bigint", "float", "double", "decimal" };
    /** é¡µé¢ä¸éœ€è¦ç¼–辑字段 */
    public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
    /** é¡µé¢ä¸éœ€è¦æ˜¾ç¤ºçš„列表字段 */
    public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
            "update_time" };
    /** é¡µé¢ä¸éœ€è¦æŸ¥è¯¢å­—段 */
    public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
            "update_time", "remark" };
    /** Entity基类字段 */
    public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
    /** Tree基类字段 */
    public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors" };
    /** æ–‡æœ¬æ¡† */
    public static final String HTML_INPUT = "input";
    /** æ–‡æœ¬åŸŸ */
    public static final String HTML_TEXTAREA = "textarea";
    /** ä¸‹æ‹‰æ¡† */
    public static final String HTML_SELECT = "select";
    /** å•选框 */
    public static final String HTML_RADIO = "radio";
    /** å¤é€‰æ¡† */
    public static final String HTML_CHECKBOX = "checkbox";
    /** æ—¥æœŸæŽ§ä»¶ */
    public static final String HTML_DATETIME = "datetime";
    /** å›¾ç‰‡ä¸Šä¼ æŽ§ä»¶ */
    public static final String HTML_IMAGE_UPLOAD = "imageUpload";
    /** æ–‡ä»¶ä¸Šä¼ æŽ§ä»¶ */
    public static final String HTML_FILE_UPLOAD = "fileUpload";
    /** å¯Œæ–‡æœ¬æŽ§ä»¶ */
    public static final String HTML_EDITOR = "editor";
    /** å­—符串类型 */
    public static final String TYPE_STRING = "String";
    /** æ•´åž‹ */
    public static final String TYPE_INTEGER = "Integer";
    /** é•¿æ•´åž‹ */
    public static final String TYPE_LONG = "Long";
    /** æµ®ç‚¹åž‹ */
    public static final String TYPE_DOUBLE = "Double";
    /** é«˜ç²¾åº¦è®¡ç®—类型 */
    public static final String TYPE_BIGDECIMAL = "BigDecimal";
    /** æ—¶é—´ç±»åž‹ */
    public static final String TYPE_DATE = "Date";
    /** æ¨¡ç³ŠæŸ¥è¯¢ */
    public static final String QUERY_LIKE = "LIKE";
    /** ç›¸ç­‰æŸ¥è¯¢ */
    public static final String QUERY_EQ = "EQ";
    /** éœ€è¦ */
    public static final String REQUIRE = "1";
}
se-common/se-common-core/src/main/java/com/se/common/core/constant/HttpStatus.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
package com.se.common.core.constant;
/**
 * è¿”回状态码
 *
 * @author admin
 */
public class HttpStatus
{
    /**
     * æ“ä½œæˆåŠŸ
     */
    public static final int SUCCESS = 200;
    /**
     * å¯¹è±¡åˆ›å»ºæˆåŠŸ
     */
    public static final int CREATED = 201;
    /**
     * è¯·æ±‚已经被接受
     */
    public static final int ACCEPTED = 202;
    /**
     * æ“ä½œå·²ç»æ‰§è¡ŒæˆåŠŸï¼Œä½†æ˜¯æ²¡æœ‰è¿”å›žæ•°æ®
     */
    public static final int NO_CONTENT = 204;
    /**
     * èµ„源已被移除
     */
    public static final int MOVED_PERM = 301;
    /**
     * é‡å®šå‘
     */
    public static final int SEE_OTHER = 303;
    /**
     * èµ„源没有被修改
     */
    public static final int NOT_MODIFIED = 304;
    /**
     * å‚数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;
    /**
     * æœªæŽˆæƒ
     */
    public static final int UNAUTHORIZED = 401;
    /**
     * è®¿é—®å—限,授权过期
     */
    public static final int FORBIDDEN = 403;
    /**
     * èµ„源,服务未找到
     */
    public static final int NOT_FOUND = 404;
    /**
     * ä¸å…è®¸çš„http方法
     */
    public static final int BAD_METHOD = 405;
    /**
     * èµ„源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;
    /**
     * ä¸æ”¯æŒçš„æ•°æ®ï¼Œåª’体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;
    /**
     * ç³»ç»Ÿå†…部错误
     */
    public static final int ERROR = 500;
    /**
     * æŽ¥å£æœªå®žçް
     */
    public static final int NOT_IMPLEMENTED = 501;
    /**
     * ç³»ç»Ÿè­¦å‘Šæ¶ˆæ¯
     */
    public static final int WARN = 601;
}
se-common/se-common-core/src/main/java/com/se/common/core/constant/ScheduleConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.se.common.core.constant;
/**
 * ä»»åŠ¡è°ƒåº¦é€šç”¨å¸¸é‡
 *
 * @author admin
 */
public class ScheduleConstants
{
    public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
    /** æ‰§è¡Œç›®æ ‡key */
    public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
    /** é»˜è®¤ */
    public static final String MISFIRE_DEFAULT = "0";
    /** ç«‹å³è§¦å‘执行 */
    public static final String MISFIRE_IGNORE_MISFIRES = "1";
    /** è§¦å‘一次执行 */
    public static final String MISFIRE_FIRE_AND_PROCEED = "2";
    /** ä¸è§¦å‘立即执行 */
    public static final String MISFIRE_DO_NOTHING = "3";
    public enum Status
    {
        /**
         * æ­£å¸¸
         */
        NORMAL("0"),
        /**
         * æš‚停
         */
        PAUSE("1");
        private String value;
        private Status(String value)
        {
            this.value = value;
        }
        public String getValue()
        {
            return value;
        }
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/constant/TokenConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.se.common.core.constant;
/**
 * Token的Key常量
 *
 * @author admin
 */
public class TokenConstants
{
    /**
     * ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
     */
    public static final String AUTHENTICATION = "Authorization";
    /**
     * ä»¤ç‰Œå‰ç¼€
     */
    public static final String PREFIX = "Bearer ";
    /**
     * ä»¤ç‰Œç§˜é’¥
     */
    public final static String SECRET = "abcdefghijklmnopqrstuvwxyz";
}
se-common/se-common-core/src/main/java/com/se/common/core/context/SecurityContextHolder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,98 @@
package com.se.common.core.context;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.se.common.core.constant.SecurityConstants;
import com.se.common.core.text.Convert;
import com.se.common.core.utils.StringUtils;
/**
 * èŽ·å–å½“å‰çº¿ç¨‹å˜é‡ä¸­çš„ ç”¨æˆ·id、用户名称、Token等信息
 * æ³¨æ„ï¼š å¿…须在网关通过请求头的方法传入,同时在HeaderInterceptor拦截器设置值。 å¦åˆ™è¿™é‡Œæ— æ³•获取
 *
 * @author admin
 */
public class SecurityContextHolder
{
    private static final TransmittableThreadLocal<Map<String, Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();
    public static void set(String key, Object value)
    {
        Map<String, Object> map = getLocalMap();
        map.put(key, value == null ? StringUtils.EMPTY : value);
    }
    public static String get(String key)
    {
        Map<String, Object> map = getLocalMap();
        return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY));
    }
    public static <T> T get(String key, Class<T> clazz)
    {
        Map<String, Object> map = getLocalMap();
        return StringUtils.cast(map.getOrDefault(key, null));
    }
    public static Map<String, Object> getLocalMap()
    {
        Map<String, Object> map = THREAD_LOCAL.get();
        if (map == null)
        {
            map = new ConcurrentHashMap<String, Object>();
            THREAD_LOCAL.set(map);
        }
        return map;
    }
    public static void setLocalMap(Map<String, Object> threadLocalMap)
    {
        THREAD_LOCAL.set(threadLocalMap);
    }
    public static Long getUserId()
    {
        return Convert.toLong(get(SecurityConstants.DETAILS_USER_ID), 0L);
    }
    public static void setUserId(String account)
    {
        set(SecurityConstants.DETAILS_USER_ID, account);
    }
    public static String getUserName()
    {
        return get(SecurityConstants.DETAILS_USERNAME);
    }
    public static void setUserName(String username)
    {
        set(SecurityConstants.DETAILS_USERNAME, username);
    }
    public static String getUserKey()
    {
        return get(SecurityConstants.USER_KEY);
    }
    public static void setUserKey(String userKey)
    {
        set(SecurityConstants.USER_KEY, userKey);
    }
    public static String getPermission()
    {
        return get(SecurityConstants.ROLE_PERMISSION);
    }
    public static void setPermission(String permissions)
    {
        set(SecurityConstants.ROLE_PERMISSION, permissions);
    }
    public static void remove()
    {
        THREAD_LOCAL.remove();
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/DemoModeException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.se.common.core.exception;
/**
 * æ¼”示模式异常
 *
 * @author admin
 */
public class DemoModeException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public DemoModeException()
    {
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/InnerAuthException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.se.common.core.exception;
/**
 * å†…部认证异常
 *
 * @author admin
 */
public class InnerAuthException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public InnerAuthException(String message)
    {
        super(message);
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/PreAuthorizeException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.se.common.core.exception;
/**
 * æƒé™å¼‚常
 *
 * @author admin
 */
public class PreAuthorizeException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public PreAuthorizeException()
    {
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/UtilException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.se.common.core.exception;
/**
 * å·¥å…·ç±»å¼‚常
 *
 * @author admin
 */
public class UtilException extends RuntimeException
{
    private static final long serialVersionUID = 8247610319171014183L;
    public UtilException(Throwable e)
    {
        super(e.getMessage(), e);
    }
    public UtilException(String message)
    {
        super(message);
    }
    public UtilException(String message, Throwable throwable)
    {
        super(message, throwable);
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/auth/NotLoginException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.se.common.core.exception.auth;
/**
 * æœªèƒ½é€šè¿‡çš„登录认证异常
 *
 * @author admin
 */
public class NotLoginException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public NotLoginException(String message)
    {
        super(message);
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/base/BaseException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
package com.se.common.core.exception.base;
/**
 * åŸºç¡€å¼‚常
 *
 * @author admin
 */
public class BaseException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    /**
     * æ‰€å±žæ¨¡å—
     */
    private String module;
    /**
     * é”™è¯¯ç 
     */
    private String code;
    /**
     * é”™è¯¯ç å¯¹åº”的参数
     */
    private Object[] args;
    /**
     * é”™è¯¯æ¶ˆæ¯
     */
    private String defaultMessage;
    public BaseException(String module, String code, Object[] args, String defaultMessage)
    {
        this.module = module;
        this.code = code;
        this.args = args;
        this.defaultMessage = defaultMessage;
    }
    public BaseException(String module, String code, Object[] args)
    {
        this(module, code, args, null);
    }
    public BaseException(String module, String defaultMessage)
    {
        this(module, null, null, defaultMessage);
    }
    public BaseException(String code, Object[] args)
    {
        this(null, code, args, null);
    }
    public BaseException(String defaultMessage)
    {
        this(null, null, null, defaultMessage);
    }
    public String getModule()
    {
        return module;
    }
    public String getCode()
    {
        return code;
    }
    public Object[] getArgs()
    {
        return args;
    }
    public String getDefaultMessage()
    {
        return defaultMessage;
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/file/FileException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.se.common.core.exception.file;
import com.se.common.core.exception.base.BaseException;
/**
 * æ–‡ä»¶ä¿¡æ¯å¼‚常类
 *
 * @author admin
 */
public class FileException extends BaseException
{
    private static final long serialVersionUID = 1L;
    public FileException(String code, Object[] args, String msg)
    {
        super("file", code, args, msg);
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/file/FileUploadException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
package com.se.common.core.exception.file;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
 * æ–‡ä»¶ä¸Šä¼ å¼‚常类
 *
 * @author admin
 */
public class FileUploadException extends Exception
{
    private static final long serialVersionUID = 1L;
    private final Throwable cause;
    public FileUploadException()
    {
        this(null, null);
    }
    public FileUploadException(final String msg)
    {
        this(msg, null);
    }
    public FileUploadException(String msg, Throwable cause)
    {
        super(msg);
        this.cause = cause;
    }
    @Override
    public void printStackTrace(PrintStream stream)
    {
        super.printStackTrace(stream);
        if (cause != null)
        {
            stream.println("Caused by:");
            cause.printStackTrace(stream);
        }
    }
    @Override
    public void printStackTrace(PrintWriter writer)
    {
        super.printStackTrace(writer);
        if (cause != null)
        {
            writer.println("Caused by:");
            cause.printStackTrace(writer);
        }
    }
    @Override
    public Throwable getCause()
    {
        return cause;
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/job/TaskException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.se.common.core.exception.job;
/**
 * è®¡åˆ’策略异常
 *
 * @author admin
 */
public class TaskException extends Exception
{
    private static final long serialVersionUID = 1L;
    private Code code;
    public TaskException(String msg, Code code)
    {
        this(msg, code, null);
    }
    public TaskException(String msg, Code code, Exception nestedEx)
    {
        super(msg, nestedEx);
        this.code = code;
    }
    public Code getCode()
    {
        return code;
    }
    public enum Code
    {
        TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/user/UserException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.se.common.core.exception.user;
import com.se.common.core.exception.base.BaseException;
/**
 * ç”¨æˆ·ä¿¡æ¯å¼‚常类
 *
 * @author admin
 */
public class UserException extends BaseException
{
    private static final long serialVersionUID = 1L;
    public UserException(String code, Object[] args)
    {
        super("user", code, args, null);
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/exception/user/UserPasswordNotMatchException.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.se.common.core.exception.user;
/**
 * ç”¨æˆ·å¯†ç ä¸æ­£ç¡®æˆ–不符合规范异常类
 *
 * @author admin
 */
public class UserPasswordNotMatchException extends UserException
{
    private static final long serialVersionUID = 1L;
    public UserPasswordNotMatchException()
    {
        super("user.password.not.match", null);
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/text/CharsetKit.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,86 @@
package com.se.common.core.text;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import com.se.common.core.utils.StringUtils;
/**
 * å­—符集工具类
 *
 * @author admin
 */
public class CharsetKit
{
    /** ISO-8859-1 */
    public static final String ISO_8859_1 = "ISO-8859-1";
    /** UTF-8 */
    public static final String UTF_8 = "UTF-8";
    /** GBK */
    public static final String GBK = "GBK";
    /** ISO-8859-1 */
    public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
    /** UTF-8 */
    public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
    /** GBK */
    public static final Charset CHARSET_GBK = Charset.forName(GBK);
    /**
     * è½¬æ¢ä¸ºCharset对象
     *
     * @param charset å­—符集,为空则返回默认字符集
     * @return Charset
     */
    public static Charset charset(String charset)
    {
        return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
    }
    /**
     * è½¬æ¢å­—符串的字符集编码
     *
     * @param source å­—符串
     * @param srcCharset æºå­—符集,默认ISO-8859-1
     * @param destCharset ç›®æ ‡å­—符集,默认UTF-8
     * @return è½¬æ¢åŽçš„字符集
     */
    public static String convert(String source, String srcCharset, String destCharset)
    {
        return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
    }
    /**
     * è½¬æ¢å­—符串的字符集编码
     *
     * @param source å­—符串
     * @param srcCharset æºå­—符集,默认ISO-8859-1
     * @param destCharset ç›®æ ‡å­—符集,默认UTF-8
     * @return è½¬æ¢åŽçš„字符集
     */
    public static String convert(String source, Charset srcCharset, Charset destCharset)
    {
        if (null == srcCharset)
        {
            srcCharset = StandardCharsets.ISO_8859_1;
        }
        if (null == destCharset)
        {
            destCharset = StandardCharsets.UTF_8;
        }
        if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
        {
            return source;
        }
        return new String(source.getBytes(srcCharset), destCharset);
    }
    /**
     * @return ç³»ç»Ÿå­—符集编码
     */
    public static String systemCharset()
    {
        return Charset.defaultCharset().name();
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/utils/JwtUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,123 @@
package com.se.common.core.utils;
import java.util.Map;
import com.se.common.core.constant.SecurityConstants;
import com.se.common.core.constant.TokenConstants;
import com.se.common.core.text.Convert;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
 * Jwt工具类
 *
 * @author admin
 */
public class JwtUtils
{
    public static String secret = TokenConstants.SECRET;
    /**
     * ä»Žæ•°æ®å£°æ˜Žç”Ÿæˆä»¤ç‰Œ
     *
     * @param claims æ•°æ®å£°æ˜Ž
     * @return ä»¤ç‰Œ
     */
    public static String createToken(Map<String, Object> claims)
    {
        String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }
    /**
     * ä»Žä»¤ç‰Œä¸­èŽ·å–æ•°æ®å£°æ˜Ž
     *
     * @param token ä»¤ç‰Œ
     * @return æ•°æ®å£°æ˜Ž
     */
    public static Claims parseToken(String token)
    {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }
    /**
     * æ ¹æ®ä»¤ç‰ŒèŽ·å–ç”¨æˆ·æ ‡è¯†
     *
     * @param token ä»¤ç‰Œ
     * @return ç”¨æˆ·ID
     */
    public static String getUserKey(String token)
    {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.USER_KEY);
    }
    /**
     * æ ¹æ®ä»¤ç‰ŒèŽ·å–ç”¨æˆ·æ ‡è¯†
     *
     * @param claims èº«ä»½ä¿¡æ¯
     * @return ç”¨æˆ·ID
     */
    public static String getUserKey(Claims claims)
    {
        return getValue(claims, SecurityConstants.USER_KEY);
    }
    /**
     * æ ¹æ®ä»¤ç‰ŒèŽ·å–ç”¨æˆ·ID
     *
     * @param token ä»¤ç‰Œ
     * @return ç”¨æˆ·ID
     */
    public static String getUserId(String token)
    {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.DETAILS_USER_ID);
    }
    /**
     * æ ¹æ®èº«ä»½ä¿¡æ¯èŽ·å–ç”¨æˆ·ID
     *
     * @param claims èº«ä»½ä¿¡æ¯
     * @return ç”¨æˆ·ID
     */
    public static String getUserId(Claims claims)
    {
        return getValue(claims, SecurityConstants.DETAILS_USER_ID);
    }
    /**
     * æ ¹æ®ä»¤ç‰ŒèŽ·å–ç”¨æˆ·å
     *
     * @param token ä»¤ç‰Œ
     * @return ç”¨æˆ·å
     */
    public static String getUserName(String token)
    {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.DETAILS_USERNAME);
    }
    /**
     * æ ¹æ®èº«ä»½ä¿¡æ¯èŽ·å–ç”¨æˆ·å
     *
     * @param claims èº«ä»½ä¿¡æ¯
     * @return ç”¨æˆ·å
     */
    public static String getUserName(Claims claims)
    {
        return getValue(claims, SecurityConstants.DETAILS_USERNAME);
    }
    /**
     * æ ¹æ®èº«ä»½ä¿¡æ¯èŽ·å–é”®å€¼
     *
     * @param claims èº«ä»½ä¿¡æ¯
     * @param key é”®
     * @return å€¼
     */
    public static String getValue(Claims claims, String key)
    {
        return Convert.toStr(claims.get(key), "");
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/utils/bean/BeanValidators.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.se.common.core.utils.bean;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
/**
 * bean对象属性验证
 *
 * @author admin
 */
public class BeanValidators
{
    public static void validateWithException(Validator validator, Object object, Class<?>... groups)
            throws ConstraintViolationException
    {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty())
        {
            throw new ConstraintViolationException(constraintViolations);
        }
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/utils/file/MimeTypeUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.se.common.core.utils.file;
/**
 * åª’体类型工具类
 *
 * @author admin
 */
public class MimeTypeUtils
{
    public static final String IMAGE_PNG = "image/png";
    public static final String IMAGE_JPG = "image/jpg";
    public static final String IMAGE_JPEG = "image/jpeg";
    public static final String IMAGE_BMP = "image/bmp";
    public static final String IMAGE_GIF = "image/gif";
    public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };
    public static final String[] FLASH_EXTENSION = { "swf", "flv" };
    public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
            "asf", "rm", "rmvb" };
    public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };
    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
            // å›¾ç‰‡
            "bmp", "gif", "jpg", "jpeg", "png",
            // word excel powerpoint
            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
            // åŽ‹ç¼©æ–‡ä»¶
            "rar", "zip", "gz", "bz2",
            // è§†é¢‘格式
            "mp4", "avi", "rmvb",
            // pdf
            "pdf" };
    public static String getExtension(String prefix)
    {
        switch (prefix)
        {
            case IMAGE_PNG:
                return "png";
            case IMAGE_JPG:
                return "jpg";
            case IMAGE_JPEG:
                return "jpeg";
            case IMAGE_BMP:
                return "bmp";
            case IMAGE_GIF:
                return "gif";
            default:
                return "";
        }
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/utils/poi/ExcelUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1538 @@
package com.se.common.core.utils.poi;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import com.se.common.core.annotation.Excel;
import com.se.common.core.annotation.Excels;
import com.se.common.core.exception.UtilException;
import com.se.common.core.text.Convert;
import com.se.common.core.utils.file.FileTypeUtils;
import com.se.common.core.utils.file.ImageUtils;
import com.se.common.core.utils.reflect.ReflectUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.se.common.core.utils.DateUtils;
import com.se.common.core.utils.StringUtils;
/**
 * Excel相关处理
 *
 * @author admin
 */
public class ExcelUtil<T>
{
    private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
    public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
    public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
    /**
     * Excel sheet最大行数,默认65536
     */
    public static final int sheetSize = 65536;
    /**
     * å·¥ä½œè¡¨åç§°
     */
    private String sheetName;
    /**
     * å¯¼å‡ºç±»åž‹ï¼ˆEXPORT:导出数据;IMPORT:导入模板)
     */
    private Excel.Type type;
    /**
     * å·¥ä½œè–„对象
     */
    private Workbook wb;
    /**
     * å·¥ä½œè¡¨å¯¹è±¡
     */
    private Sheet sheet;
    /**
     * æ ·å¼åˆ—表
     */
    private Map<String, CellStyle> styles;
    /**
     * å¯¼å…¥å¯¼å‡ºæ•°æ®åˆ—表
     */
    private List<T> list;
    /**
     * æ³¨è§£åˆ—表
     */
    private List<Object[]> fields;
    /**
     * å½“前行号
     */
    private int rownum;
    /**
     * æ ‡é¢˜
     */
    private String title;
    /**
     * æœ€å¤§é«˜åº¦
     */
    private short maxHeight;
    /**
     * åˆå¹¶åŽæœ€åŽè¡Œæ•°
     */
    private int subMergedLastRowNum = 0;
    /**
     * åˆå¹¶åŽå¼€å§‹è¡Œæ•°
     */
    private int subMergedFirstRowNum = 1;
    /**
     * å¯¹è±¡çš„子列表方法
     */
    private Method subMethod;
    /**
     * å¯¹è±¡çš„子列表属性
     */
    private List<Field> subFields;
    /**
     * ç»Ÿè®¡åˆ—表
     */
    private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
    /**
     * æ•°å­—格式
     */
    private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
    /**
     * å®žä½“对象
     */
    public Class<T> clazz;
    /**
     * éœ€è¦æŽ’除列属性
     */
    public String[] excludeFields;
    public ExcelUtil(Class<T> clazz)
    {
        this.clazz = clazz;
    }
    /**
     * éšè—Excel中列属性
     *
     * @param fields åˆ—属性名 ç¤ºä¾‹[单个"name"/多个"id","name"]
     * @throws Exception
     */
    public void hideColumn(String... fields)
    {
        this.excludeFields = fields;
    }
    public void init(List<T> list, String sheetName, String title, Excel.Type type)
    {
        if (list == null)
        {
            list = new ArrayList<T>();
        }
        this.list = list;
        this.sheetName = sheetName;
        this.type = type;
        this.title = title;
        createExcelField();
        createWorkbook();
        createTitle();
        createSubHead();
    }
    /**
     * åˆ›å»ºexcel第一行标题
     */
    public void createTitle()
    {
        if (StringUtils.isNotEmpty(title))
        {
            subMergedFirstRowNum++;
            subMergedLastRowNum++;
            int titleLastCol = this.fields.size() - 1;
            if (isSubList())
            {
                titleLastCol = titleLastCol + subFields.size() - 1;
            }
            Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
            titleRow.setHeightInPoints(30);
            Cell titleCell = titleRow.createCell(0);
            titleCell.setCellStyle(styles.get("title"));
            titleCell.setCellValue(title);
            sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol));
        }
    }
    /**
     * åˆ›å»ºå¯¹è±¡çš„子列表名称
     */
    public void createSubHead()
    {
        if (isSubList())
        {
            subMergedFirstRowNum++;
            subMergedLastRowNum++;
            Row subRow = sheet.createRow(rownum);
            int excelNum = 0;
            for (Object[] objects : fields)
            {
                Excel attr = (Excel) objects[1];
                Cell headCell1 = subRow.createCell(excelNum);
                headCell1.setCellValue(attr.name());
                headCell1.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
                excelNum++;
            }
            int headFirstRow = excelNum - 1;
            int headLastRow = headFirstRow + subFields.size() - 1;
            if (headLastRow > headFirstRow)
            {
                sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow));
            }
            rownum++;
        }
    }
    /**
     * å¯¹excel表单默认第一个索引名转换成list
     *
     * @param is è¾“入流
     * @return è½¬æ¢åŽé›†åˆ
     */
    public List<T> importExcel(InputStream is)
    {
        List<T> list = null;
        try
        {
            list = importExcel(is, 0);
        }
        catch (Exception e)
        {
            log.error("导入Excel异常{}", e.getMessage());
            throw new UtilException(e.getMessage());
        }
        finally
        {
            IOUtils.closeQuietly(is);
        }
        return list;
    }
    /**
     * å¯¹excel表单默认第一个索引名转换成list
     *
     * @param is è¾“入流
     * @param titleNum æ ‡é¢˜å ç”¨è¡Œæ•°
     * @return è½¬æ¢åŽé›†åˆ
     */
    public List<T> importExcel(InputStream is, int titleNum) throws Exception
    {
        return importExcel(StringUtils.EMPTY, is, titleNum);
    }
    /**
     * å¯¹excel表单指定表格索引名转换成list
     *
     * @param sheetName è¡¨æ ¼ç´¢å¼•名
     * @param titleNum æ ‡é¢˜å ç”¨è¡Œæ•°
     * @param is è¾“入流
     * @return è½¬æ¢åŽé›†åˆ
     */
    public List<T> importExcel(String sheetName, InputStream is, int titleNum) throws Exception
    {
        this.type = Excel.Type.IMPORT;
        this.wb = WorkbookFactory.create(is);
        List<T> list = new ArrayList<T>();
        // å¦‚果指定sheet名,则取指定sheet中的内容 å¦åˆ™é»˜è®¤æŒ‡å‘第1个sheet
        Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0);
        if (sheet == null)
        {
            throw new IOException("文件sheet不存在");
        }
        // èŽ·å–æœ€åŽä¸€ä¸ªéžç©ºè¡Œçš„è¡Œä¸‹æ ‡ï¼Œæ¯”å¦‚æ€»è¡Œæ•°ä¸ºn,则返回的为n-1
        int rows = sheet.getLastRowNum();
        if (rows > 0)
        {
            // å®šä¹‰ä¸€ä¸ªmap用于存放excel列的序号和field.
            Map<String, Integer> cellMap = new HashMap<String, Integer>();
            // èŽ·å–è¡¨å¤´
            Row heard = sheet.getRow(titleNum);
            for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
            {
                Cell cell = heard.getCell(i);
                if (StringUtils.isNotNull(cell))
                {
                    String value = this.getCellValue(heard, i).toString();
                    cellMap.put(value, i);
                }
                else
                {
                    cellMap.put(null, i);
                }
            }
            // æœ‰æ•°æ®æ—¶æ‰å¤„理 å¾—到类的所有field.
            List<Object[]> fields = this.getFields();
            Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>();
            for (Object[] objects : fields)
            {
                Excel attr = (Excel) objects[1];
                Integer column = cellMap.get(attr.name());
                if (column != null)
                {
                    fieldsMap.put(column, objects);
                }
            }
            for (int i = titleNum + 1; i <= rows; i++)
            {
                // ä»Žç¬¬2行开始取数据,默认第一行是表头.
                Row row = sheet.getRow(i);
                // åˆ¤æ–­å½“前行是否是空行
                if (isRowEmpty(row))
                {
                    continue;
                }
                T entity = null;
                for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet())
                {
                    Object val = this.getCellValue(row, entry.getKey());
                    // å¦‚果不存在实例则新建.
                    entity = (entity == null ? clazz.newInstance() : entity);
                    // ä»Žmap中得到对应列的field.
                    Field field = (Field) entry.getValue()[0];
                    Excel attr = (Excel) entry.getValue()[1];
                    // å–得类型,并根据对象类型设置值.
                    Class<?> fieldType = field.getType();
                    if (String.class == fieldType)
                    {
                        String s = Convert.toStr(val);
                        if (StringUtils.endsWith(s, ".0"))
                        {
                            val = StringUtils.substringBefore(s, ".0");
                        }
                        else
                        {
                            String dateFormat = field.getAnnotation(Excel.class).dateFormat();
                            if (StringUtils.isNotEmpty(dateFormat))
                            {
                                val = parseDateToStr(dateFormat, val);
                            }
                            else
                            {
                                val = Convert.toStr(val);
                            }
                        }
                    }
                    else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
                    {
                        val = Convert.toInt(val);
                    }
                    else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val)))
                    {
                        val = Convert.toLong(val);
                    }
                    else if (Double.TYPE == fieldType || Double.class == fieldType)
                    {
                        val = Convert.toDouble(val);
                    }
                    else if (Float.TYPE == fieldType || Float.class == fieldType)
                    {
                        val = Convert.toFloat(val);
                    }
                    else if (BigDecimal.class == fieldType)
                    {
                        val = Convert.toBigDecimal(val);
                    }
                    else if (Date.class == fieldType)
                    {
                        if (val instanceof String)
                        {
                            val = DateUtils.parseDate(val);
                        }
                        else if (val instanceof Double)
                        {
                            val = DateUtil.getJavaDate((Double) val);
                        }
                    }
                    else if (Boolean.TYPE == fieldType || Boolean.class == fieldType)
                    {
                        val = Convert.toBool(val, false);
                    }
                    if (StringUtils.isNotNull(fieldType))
                    {
                        String propertyName = field.getName();
                        if (StringUtils.isNotEmpty(attr.targetAttr()))
                        {
                            propertyName = field.getName() + "." + attr.targetAttr();
                        }
                        if (StringUtils.isNotEmpty(attr.readConverterExp()))
                        {
                            val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
                        }
                        else if (!attr.handler().equals(ExcelHandlerAdapter.class))
                        {
                            val = dataFormatHandlerAdapter(val, attr, null);
                        }
                        ReflectUtils.invokeSetter(entity, propertyName, val);
                    }
                }
                list.add(entity);
            }
        }
        return list;
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @param response è¿”回数据
     * @param list å¯¼å‡ºæ•°æ®é›†åˆ
     * @param sheetName å·¥ä½œè¡¨çš„名称
     * @return ç»“æžœ
     */
    public void exportExcel(HttpServletResponse response, List<T> list, String sheetName)
    {
        exportExcel(response, list, sheetName, StringUtils.EMPTY);
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @param response è¿”回数据
     * @param list å¯¼å‡ºæ•°æ®é›†åˆ
     * @param sheetName å·¥ä½œè¡¨çš„名称
     * @param title æ ‡é¢˜
     * @return ç»“æžœ
     */
    public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title)
    {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        this.init(list, sheetName, title, Excel.Type.EXPORT);
        exportExcel(response);
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @param sheetName å·¥ä½œè¡¨çš„名称
     * @return ç»“æžœ
     */
    public void importTemplateExcel(HttpServletResponse response, String sheetName)
    {
        importTemplateExcel(response, sheetName, StringUtils.EMPTY);
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @param sheetName å·¥ä½œè¡¨çš„名称
     * @param title æ ‡é¢˜
     * @return ç»“æžœ
     */
    public void importTemplateExcel(HttpServletResponse response, String sheetName, String title)
    {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        this.init(null, sheetName, title, Excel.Type.IMPORT);
        exportExcel(response);
    }
    /**
     * å¯¹list数据源将其里面的数据导入到excel表单
     *
     * @return ç»“æžœ
     */
    public void exportExcel(HttpServletResponse response)
    {
        try
        {
            writeSheet();
            wb.write(response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("导出Excel异常{}", e.getMessage());
        }
        finally
        {
            IOUtils.closeQuietly(wb);
        }
    }
    /**
     * åˆ›å»ºå†™å…¥æ•°æ®åˆ°Sheet
     */
    public void writeSheet()
    {
        // å–出一共有多少个sheet.
        int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize));
        for (int index = 0; index < sheetNo; index++)
        {
            createSheet(sheetNo, index);
            // äº§ç”Ÿä¸€è¡Œ
            Row row = sheet.createRow(rownum);
            int column = 0;
            // å†™å…¥å„个字段的列头名称
            for (Object[] os : fields)
            {
                Field field = (Field) os[0];
                Excel excel = (Excel) os[1];
                if (Collection.class.isAssignableFrom(field.getType()))
                {
                    for (Field subField : subFields)
                    {
                        Excel subExcel = subField.getAnnotation(Excel.class);
                        this.createHeadCell(subExcel, row, column++);
                    }
                }
                else
                {
                    this.createHeadCell(excel, row, column++);
                }
            }
            if (Excel.Type.EXPORT.equals(type))
            {
                fillExcelData(index, row);
                addStatisticsRow();
            }
        }
    }
    /**
     * å¡«å……excel数据
     *
     * @param index åºå·
     * @param row å•元格行
     */
    @SuppressWarnings("unchecked")
    public void fillExcelData(int index, Row row)
    {
        int startNo = index * sheetSize;
        int endNo = Math.min(startNo + sheetSize, list.size());
        int rowNo = (1 + rownum) - startNo;
        for (int i = startNo; i < endNo; i++)
        {
            rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo;
            row = sheet.createRow(rowNo);
            // å¾—到导出对象.
            T vo = (T) list.get(i);
            Collection<?> subList = null;
            if (isSubList())
            {
                if (isSubListValue(vo))
                {
                    subList = getListCellValue(vo);
                    subMergedLastRowNum = subMergedLastRowNum + subList.size();
                }
                else
                {
                    subMergedFirstRowNum++;
                    subMergedLastRowNum++;
                }
            }
            int column = 0;
            for (Object[] os : fields)
            {
                Field field = (Field) os[0];
                Excel excel = (Excel) os[1];
                if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList))
                {
                    boolean subFirst = false;
                    for (Object obj : subList)
                    {
                        if (subFirst)
                        {
                            rowNo++;
                            row = sheet.createRow(rowNo);
                        }
                        List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class);
                        int subIndex = 0;
                        for (Field subField : subFields)
                        {
                            if (subField.isAnnotationPresent(Excel.class))
                            {
                                subField.setAccessible(true);
                                Excel attr = subField.getAnnotation(Excel.class);
                                this.addCell(attr, row, (T) obj, subField, column + subIndex);
                            }
                            subIndex++;
                        }
                        subFirst = true;
                    }
                    this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size();
                }
                else
                {
                    this.addCell(excel, row, vo, field, column++);
                }
            }
        }
    }
    /**
     * åˆ›å»ºè¡¨æ ¼æ ·å¼
     *
     * @param wb å·¥ä½œè–„对象
     * @return æ ·å¼åˆ—表
     */
    private Map<String, CellStyle> createStyles(Workbook wb)
    {
        // å†™å…¥å„条记录,每条记录对应excel表中的一行
        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
        CellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        Font titleFont = wb.createFont();
        titleFont.setFontName("Arial");
        titleFont.setFontHeightInPoints((short) 16);
        titleFont.setBold(true);
        style.setFont(titleFont);
        DataFormat dataFormat = wb.createDataFormat();
        style.setDataFormat(dataFormat.getFormat("@"));
        styles.put("title", style);
        style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setBorderRight(BorderStyle.THIN);
        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderLeft(BorderStyle.THIN);
        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderTop(BorderStyle.THIN);
        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setBorderBottom(BorderStyle.THIN);
        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
        Font dataFont = wb.createFont();
        dataFont.setFontName("Arial");
        dataFont.setFontHeightInPoints((short) 10);
        style.setFont(dataFont);
        styles.put("data", style);
        style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        Font totalFont = wb.createFont();
        totalFont.setFontName("Arial");
        totalFont.setFontHeightInPoints((short) 10);
        style.setFont(totalFont);
        styles.put("total", style);
        styles.putAll(annotationHeaderStyles(wb, styles));
        styles.putAll(annotationDataStyles(wb));
        return styles;
    }
    /**
     * æ ¹æ®Excel注解创建表格头样式
     *
     * @param wb å·¥ä½œè–„对象
     * @return è‡ªå®šä¹‰æ ·å¼åˆ—表
     */
    private Map<String, CellStyle> annotationHeaderStyles(Workbook wb, Map<String, CellStyle> styles)
    {
        Map<String, CellStyle> headerStyles = new HashMap<String, CellStyle>();
        for (Object[] os : fields)
        {
            Excel excel = (Excel) os[1];
            String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor());
            if (!headerStyles.containsKey(key))
            {
                CellStyle style = wb.createCellStyle();
                style.cloneStyleFrom(styles.get("data"));
                style.setAlignment(HorizontalAlignment.CENTER);
                style.setVerticalAlignment(VerticalAlignment.CENTER);
                style.setFillForegroundColor(excel.headerBackgroundColor().index);
                style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                Font headerFont = wb.createFont();
                headerFont.setFontName("Arial");
                headerFont.setFontHeightInPoints((short) 10);
                headerFont.setBold(true);
                headerFont.setColor(excel.headerColor().index);
                style.setFont(headerFont);
                // è®¾ç½®è¡¨æ ¼å¤´å•元格文本形式
                DataFormat dataFormat = wb.createDataFormat();
                style.setDataFormat(dataFormat.getFormat("@"));
                headerStyles.put(key, style);
            }
        }
        return headerStyles;
    }
    /**
     * æ ¹æ®Excel注解创建表格列样式
     *
     * @param wb å·¥ä½œè–„对象
     * @return è‡ªå®šä¹‰æ ·å¼åˆ—表
     */
    private Map<String, CellStyle> annotationDataStyles(Workbook wb)
    {
        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
        for (Object[] os : fields)
        {
            Field field = (Field) os[0];
            Excel excel = (Excel) os[1];
            if (Collection.class.isAssignableFrom(field.getType()))
            {
                ParameterizedType pt = (ParameterizedType) field.getGenericType();
                Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
                List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
                for (Field subField : subFields)
                {
                    Excel subExcel = subField.getAnnotation(Excel.class);
                    annotationDataStyles(styles, subField, subExcel);
                }
            }
            else
            {
                annotationDataStyles(styles, field, excel);
            }
        }
        return styles;
    }
    /**
     * æ ¹æ®Excel注解创建表格列样式
     *
     * @param styles è‡ªå®šä¹‰æ ·å¼åˆ—表
     * @param field  å±žæ€§åˆ—信息
     * @param excel  æ³¨è§£ä¿¡æ¯
     */
    public void annotationDataStyles(Map<String, CellStyle> styles, Field field, Excel excel)
    {
        String key = StringUtils.format("data_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType());
        if (!styles.containsKey(key))
        {
            CellStyle style = wb.createCellStyle();
            style.setAlignment(excel.align());
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            style.setBorderRight(BorderStyle.THIN);
            style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderLeft(BorderStyle.THIN);
            style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderTop(BorderStyle.THIN);
            style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderBottom(BorderStyle.THIN);
            style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            style.setFillForegroundColor(excel.backgroundColor().getIndex());
            Font dataFont = wb.createFont();
            dataFont.setFontName("Arial");
            dataFont.setFontHeightInPoints((short) 10);
            dataFont.setColor(excel.color().index);
            style.setFont(dataFont);
            if (Excel.ColumnType.TEXT == excel.cellType())
            {
                DataFormat dataFormat = wb.createDataFormat();
                style.setDataFormat(dataFormat.getFormat("@"));
            }
            styles.put(key, style);
        }
    }
    /**
     * åˆ›å»ºå•元格
     */
    public Cell createHeadCell(Excel attr, Row row, int column)
    {
        // åˆ›å»ºåˆ—
        Cell cell = row.createCell(column);
        // å†™å…¥åˆ—信息
        cell.setCellValue(attr.name());
        setDataValidation(attr, row, column);
        cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
        if (isSubList())
        {
            // å¡«å……默认样式,防止合并单元格样式失效
            sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType())));
            if (attr.needMerge())
            {
                sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));
            }
        }
        return cell;
    }
    /**
     * è®¾ç½®å•元格信息
     *
     * @param value å•元格值
     * @param attr æ³¨è§£ç›¸å…³
     * @param cell å•元格信息
     */
    public void setCellVo(Object value, Excel attr, Cell cell)
    {
        if (Excel.ColumnType.STRING == attr.cellType() || Excel.ColumnType.TEXT == attr.cellType())
        {
            String cellValue = Convert.toStr(value);
            // å¯¹äºŽä»»ä½•以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。
            if (StringUtils.startsWithAny(cellValue, FORMULA_STR))
            {
                cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");
            }
            if (value instanceof Collection && StringUtils.equals("[]", cellValue))
            {
                cellValue = StringUtils.EMPTY;
            }
            cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
        }
        else if (Excel.ColumnType.NUMERIC == attr.cellType())
        {
            if (StringUtils.isNotNull(value))
            {
                cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
            }
        }
        else if (Excel.ColumnType.IMAGE == attr.cellType())
        {
            ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
            String imagePath = Convert.toStr(value);
            if (StringUtils.isNotEmpty(imagePath))
            {
                byte[] data = ImageUtils.getImage(imagePath);
                getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
                        cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
            }
        }
    }
    /**
     * èŽ·å–ç”»å¸ƒ
     */
    public static Drawing<?> getDrawingPatriarch(Sheet sheet)
    {
        if (sheet.getDrawingPatriarch() == null)
        {
            sheet.createDrawingPatriarch();
        }
        return sheet.getDrawingPatriarch();
    }
    /**
     * èŽ·å–å›¾ç‰‡ç±»åž‹,设置图片插入类型
     */
    public int getImageType(byte[] value)
    {
        String type = FileTypeUtils.getFileExtendName(value);
        if ("JPG".equalsIgnoreCase(type))
        {
            return Workbook.PICTURE_TYPE_JPEG;
        }
        else if ("PNG".equalsIgnoreCase(type))
        {
            return Workbook.PICTURE_TYPE_PNG;
        }
        return Workbook.PICTURE_TYPE_JPEG;
    }
    /**
     * åˆ›å»ºè¡¨æ ¼æ ·å¼
     */
    public void setDataValidation(Excel attr, Row row, int column)
    {
        if (attr.name().indexOf("注:") >= 0)
        {
            sheet.setColumnWidth(column, 6000);
        }
        else
        {
            // è®¾ç½®åˆ—宽
            sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
        }
        if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)
        {
            if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255)
            {
                // å¦‚果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到
                setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
            }
            else
            {
                // æç¤ºä¿¡æ¯æˆ–只能选择不能输入的列内容.
                setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
            }
        }
    }
    /**
     * æ·»åŠ å•å…ƒæ ¼
     */
    public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
    {
        Cell cell = null;
        try
        {
            // è®¾ç½®è¡Œé«˜
            row.setHeight(maxHeight);
            // æ ¹æ®Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
            if (attr.isExport())
            {
                // åˆ›å»ºcell
                cell = row.createCell(column);
                if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())
                {
                    CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column);
                    sheet.addMergedRegion(cellAddress);
                }
                cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType())));
                // ç”¨äºŽè¯»å–对象中的属性
                Object value = getTargetValue(vo, field, attr);
                String dateFormat = attr.dateFormat();
                String readConverterExp = attr.readConverterExp();
                String separator = attr.separator();
                if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(parseDateToStr(dateFormat, value));
                }
                else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value))
                {
                    cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator));
                }
                else if (value instanceof BigDecimal && -1 != attr.scale())
                {
                    cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue());
                }
                else if (!attr.handler().equals(ExcelHandlerAdapter.class))
                {
                    cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell));
                }
                else
                {
                    // è®¾ç½®åˆ—类型
                    setCellVo(value, attr, cell);
                }
                addStatisticsData(column, Convert.toStr(value), attr);
            }
        }
        catch (Exception e)
        {
            log.error("导出Excel失败{}", e);
        }
        return cell;
    }
    /**
     * è®¾ç½® POI XSSFSheet å•元格提示或选择框
     *
     * @param sheet è¡¨å•
     * @param textlist ä¸‹æ‹‰æ¡†æ˜¾ç¤ºçš„内容
     * @param promptContent æç¤ºå†…容
     * @param firstRow å¼€å§‹è¡Œ
     * @param endRow ç»“束行
     * @param firstCol å¼€å§‹åˆ—
     * @param endCol ç»“束列
     */
    public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow,
            int firstCol, int endCol)
    {
        DataValidationHelper helper = sheet.getDataValidationHelper();
        DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1");
        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
        DataValidation dataValidation = helper.createValidation(constraint, regions);
        if (StringUtils.isNotEmpty(promptContent))
        {
            // å¦‚果设置了提示信息则鼠标放上去提示
            dataValidation.createPromptBox("", promptContent);
            dataValidation.setShowPromptBox(true);
        }
        // å¤„理Excel兼容性问题
        if (dataValidation instanceof XSSFDataValidation)
        {
            dataValidation.setSuppressDropDownArrow(true);
            dataValidation.setShowErrorBox(true);
        }
        else
        {
            dataValidation.setSuppressDropDownArrow(false);
        }
        sheet.addValidationData(dataValidation);
    }
    /**
     * è®¾ç½®æŸäº›åˆ—的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框).
     *
     * @param sheet è¦è®¾ç½®çš„sheet.
     * @param textlist ä¸‹æ‹‰æ¡†æ˜¾ç¤ºçš„内容
     * @param promptContent æç¤ºå†…容
     * @param firstRow å¼€å§‹è¡Œ
     * @param endRow ç»“束行
     * @param firstCol å¼€å§‹åˆ—
     * @param endCol ç»“束列
     */
    public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
    {
        String hideSheetName = "combo_" + firstCol + "_" + endCol;
        Sheet hideSheet = wb.createSheet(hideSheetName); // ç”¨äºŽå­˜å‚¨ ä¸‹æ‹‰èœå•数据
        for (int i = 0; i < textlist.length; i++)
        {
            hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
        }
        // åˆ›å»ºåç§°ï¼Œå¯è¢«å…¶ä»–单元格引用
        Name name = wb.createName();
        name.setNameName(hideSheetName + "_data");
        name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
        DataValidationHelper helper = sheet.getDataValidationHelper();
        // åŠ è½½ä¸‹æ‹‰åˆ—è¡¨å†…å®¹
        DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data");
        // è®¾ç½®æ•°æ®æœ‰æ•ˆæ€§åŠ è½½åœ¨å“ªä¸ªå•å…ƒæ ¼ä¸Š,四个参数分别是:起始行、终止行、起始列、终止列
        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
        // æ•°æ®æœ‰æ•ˆæ€§å¯¹è±¡
        DataValidation dataValidation = helper.createValidation(constraint, regions);
        if (StringUtils.isNotEmpty(promptContent))
        {
            // å¦‚果设置了提示信息则鼠标放上去提示
            dataValidation.createPromptBox("", promptContent);
            dataValidation.setShowPromptBox(true);
        }
        // å¤„理Excel兼容性问题
        if (dataValidation instanceof XSSFDataValidation)
        {
            dataValidation.setSuppressDropDownArrow(true);
            dataValidation.setShowErrorBox(true);
        }
        else
        {
            dataValidation.setSuppressDropDownArrow(false);
        }
        sheet.addValidationData(dataValidation);
        // è®¾ç½®hiddenSheet隐藏
        wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);
    }
    /**
     * è§£æžå¯¼å‡ºå€¼ 0=男,1=女,2=未知
     *
     * @param propertyValue å‚数值
     * @param converterExp ç¿»è¯‘注解
     * @param separator åˆ†éš”符
     * @return è§£æžåŽå€¼
     */
    public static String convertByExp(String propertyValue, String converterExp, String separator)
    {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource)
        {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(propertyValue, separator))
            {
                for (String value : propertyValue.split(separator))
                {
                    if (itemArray[0].equals(value))
                    {
                        propertyString.append(itemArray[1] + separator);
                        break;
                    }
                }
            }
            else
            {
                if (itemArray[0].equals(propertyValue))
                {
                    return itemArray[1];
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }
    /**
     * åå‘解析值 ç”·=0,女=1,未知=2
     *
     * @param propertyValue å‚数值
     * @param converterExp ç¿»è¯‘注解
     * @param separator åˆ†éš”符
     * @return è§£æžåŽå€¼
     */
    public static String reverseByExp(String propertyValue, String converterExp, String separator)
    {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(",");
        for (String item : convertSource)
        {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(propertyValue, separator))
            {
                for (String value : propertyValue.split(separator))
                {
                    if (itemArray[1].equals(value))
                    {
                        propertyString.append(itemArray[0] + separator);
                        break;
                    }
                }
            }
            else
            {
                if (itemArray[1].equals(propertyValue))
                {
                    return itemArray[0];
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }
    /**
     * æ•°æ®å¤„理器
     *
     * @param value æ•°æ®å€¼
     * @param excel æ•°æ®æ³¨è§£
     * @return
     */
    public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell)
    {
        try
        {
            Object instance = excel.handler().newInstance();
            Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class });
            value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb);
        }
        catch (Exception e)
        {
            log.error("不能格式化数据 " + excel.handler(), e.getMessage());
        }
        return Convert.toStr(value);
    }
    /**
     * åˆè®¡ç»Ÿè®¡ä¿¡æ¯
     */
    private void addStatisticsData(Integer index, String text, Excel entity)
    {
        if (entity != null && entity.isStatistics())
        {
            Double temp = 0D;
            if (!statistics.containsKey(index))
            {
                statistics.put(index, temp);
            }
            try
            {
                temp = Double.valueOf(text);
            }
            catch (NumberFormatException e)
            {
            }
            statistics.put(index, statistics.get(index) + temp);
        }
    }
    /**
     * åˆ›å»ºç»Ÿè®¡è¡Œ
     */
    public void addStatisticsRow()
    {
        if (statistics.size() > 0)
        {
            Row row = sheet.createRow(sheet.getLastRowNum() + 1);
            Set<Integer> keys = statistics.keySet();
            Cell cell = row.createCell(0);
            cell.setCellStyle(styles.get("total"));
            cell.setCellValue("合计");
            for (Integer key : keys)
            {
                cell = row.createCell(key);
                cell.setCellStyle(styles.get("total"));
                cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key)));
            }
            statistics.clear();
        }
    }
    /**
     * èŽ·å–bean中的属性值
     *
     * @param vo å®žä½“对象
     * @param field å­—段
     * @param excel æ³¨è§£
     * @return æœ€ç»ˆçš„属性值
     * @throws Exception
     */
    private Object getTargetValue(T vo, Field field, Excel excel) throws Exception
    {
        Object o = field.get(vo);
        if (StringUtils.isNotEmpty(excel.targetAttr()))
        {
            String target = excel.targetAttr();
            if (target.contains("."))
            {
                String[] targets = target.split("[.]");
                for (String name : targets)
                {
                    o = getValue(o, name);
                }
            }
            else
            {
                o = getValue(o, target);
            }
        }
        return o;
    }
    /**
     * ä»¥ç±»çš„属性的get方法方法形式获取值
     *
     * @param o
     * @param name
     * @return value
     * @throws Exception
     */
    private Object getValue(Object o, String name) throws Exception
    {
        if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name))
        {
            Class<?> clazz = o.getClass();
            Field field = clazz.getDeclaredField(name);
            field.setAccessible(true);
            o = field.get(o);
        }
        return o;
    }
    /**
     * å¾—到所有定义字段
     */
    private void createExcelField()
    {
        this.fields = getFields();
        this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
        this.maxHeight = getRowHeight();
    }
    /**
     * èŽ·å–å­—æ®µæ³¨è§£ä¿¡æ¯
     */
    public List<Object[]> getFields()
    {
        List<Object[]> fields = new ArrayList<Object[]>();
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        for (Field field : tempFields)
        {
            if (!ArrayUtils.contains(this.excludeFields, field.getName()))
            {
                // å•注解
                if (field.isAnnotationPresent(Excel.class))
                {
                    Excel attr = field.getAnnotation(Excel.class);
                    if (attr != null && (attr.type() == Excel.Type.ALL || attr.type() == type))
                    {
                        field.setAccessible(true);
                        fields.add(new Object[] { field, attr });
                    }
                    if (Collection.class.isAssignableFrom(field.getType()))
                    {
                        subMethod = getSubMethod(field.getName(), clazz);
                        ParameterizedType pt = (ParameterizedType) field.getGenericType();
                        Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
                        this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
                    }
                }
                // å¤šæ³¨è§£
                if (field.isAnnotationPresent(Excels.class))
                {
                    Excels attrs = field.getAnnotation(Excels.class);
                    Excel[] excels = attrs.value();
                    for (Excel attr : excels)
                    {
                        if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr())
                                && (attr != null && (attr.type() == Excel.Type.ALL || attr.type() == type)))
                        {
                            field.setAccessible(true);
                            fields.add(new Object[] { field, attr });
                        }
                    }
                }
            }
        }
        return fields;
    }
    /**
     * æ ¹æ®æ³¨è§£èŽ·å–æœ€å¤§è¡Œé«˜
     */
    public short getRowHeight()
    {
        double maxHeight = 0;
        for (Object[] os : this.fields)
        {
            Excel excel = (Excel) os[1];
            maxHeight = Math.max(maxHeight, excel.height());
        }
        return (short) (maxHeight * 20);
    }
    /**
     * åˆ›å»ºä¸€ä¸ªå·¥ä½œç°¿
     */
    public void createWorkbook()
    {
        this.wb = new SXSSFWorkbook(500);
        this.sheet = wb.createSheet();
        wb.setSheetName(0, sheetName);
        this.styles = createStyles(wb);
    }
    /**
     * åˆ›å»ºå·¥ä½œè¡¨
     *
     * @param sheetNo sheet数量
     * @param index åºå·
     */
    public void createSheet(int sheetNo, int index)
    {
        // è®¾ç½®å·¥ä½œè¡¨çš„名称.
        if (sheetNo > 1 && index > 0)
        {
            this.sheet = wb.createSheet();
            this.createTitle();
            wb.setSheetName(index, sheetName + index);
        }
    }
    /**
     * èŽ·å–å•å…ƒæ ¼å€¼
     *
     * @param row èŽ·å–çš„è¡Œ
     * @param column èŽ·å–å•å…ƒæ ¼åˆ—å·
     * @return å•元格值
     */
    public Object getCellValue(Row row, int column)
    {
        if (row == null)
        {
            return row;
        }
        Object val = "";
        try
        {
            Cell cell = row.getCell(column);
            if (StringUtils.isNotNull(cell))
            {
                if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA)
                {
                    val = cell.getNumericCellValue();
                    if (DateUtil.isCellDateFormatted(cell))
                    {
                        val = DateUtil.getJavaDate((Double) val); // POI Excel æ—¥æœŸæ ¼å¼è½¬æ¢
                    }
                    else
                    {
                        if ((Double) val % 1 != 0)
                        {
                            val = new BigDecimal(val.toString());
                        }
                        else
                        {
                            val = new DecimalFormat("0").format(val);
                        }
                    }
                }
                else if (cell.getCellType() == CellType.STRING)
                {
                    val = cell.getStringCellValue();
                }
                else if (cell.getCellType() == CellType.BOOLEAN)
                {
                    val = cell.getBooleanCellValue();
                }
                else if (cell.getCellType() == CellType.ERROR)
                {
                    val = cell.getErrorCellValue();
                }
            }
        }
        catch (Exception e)
        {
            return val;
        }
        return val;
    }
    /**
     * åˆ¤æ–­æ˜¯å¦æ˜¯ç©ºè¡Œ
     *
     * @param row åˆ¤æ–­çš„行
     * @return
     */
    private boolean isRowEmpty(Row row)
    {
        if (row == null)
        {
            return true;
        }
        for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++)
        {
            Cell cell = row.getCell(i);
            if (cell != null && cell.getCellType() != CellType.BLANK)
            {
                return false;
            }
        }
        return true;
    }
    /**
     * æ ¼å¼åŒ–不同类型的日期对象
     *
     * @param dateFormat æ—¥æœŸæ ¼å¼
     * @param val è¢«æ ¼å¼åŒ–的日期对象
     * @return æ ¼å¼åŒ–后的日期字符
     */
    public String parseDateToStr(String dateFormat, Object val)
    {
        if (val == null)
        {
            return "";
        }
        String str;
        if (val instanceof Date)
        {
            str = DateUtils.parseDateToStr(dateFormat, (Date) val);
        }
        else if (val instanceof LocalDateTime)
        {
            str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val));
        }
        else if (val instanceof LocalDate)
        {
            str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val));
        }
        else
        {
            str = val.toString();
        }
        return str;
    }
    /**
     * æ˜¯å¦æœ‰å¯¹è±¡çš„子列表
     */
    public boolean isSubList()
    {
        return StringUtils.isNotNull(subFields) && subFields.size() > 0;
    }
    /**
     * æ˜¯å¦æœ‰å¯¹è±¡çš„子列表,集合不为空
     */
    public boolean isSubListValue(T vo)
    {
        return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0;
    }
    /**
     * èŽ·å–é›†åˆçš„å€¼
     */
    public Collection<?> getListCellValue(Object obj)
    {
        Object value;
        try
        {
            value = subMethod.invoke(obj, new Object[] {});
        }
        catch (Exception e)
        {
            return new ArrayList<Object>();
        }
        return (Collection<?>) value;
    }
    /**
     * èŽ·å–å¯¹è±¡çš„å­åˆ—è¡¨æ–¹æ³•
     *
     * @param name åç§°
     * @param pojoClass ç±»å¯¹è±¡
     * @return å­åˆ—表方法
     */
    public Method getSubMethod(String name, Class<?> pojoClass)
    {
        StringBuffer getMethodName = new StringBuffer("get");
        getMethodName.append(name.substring(0, 1).toUpperCase());
        getMethodName.append(name.substring(1));
        Method method = null;
        try
        {
            method = pojoClass.getMethod(getMethodName.toString(), new Class[] {});
        }
        catch (Exception e)
        {
            log.error("获取对象异常{}", e.getMessage());
        }
        return method;
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/utils/reflect/ReflectUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,410 @@
package com.se.common.core.utils.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.poi.ss.usermodel.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.se.common.core.text.Convert;
import com.se.common.core.utils.DateUtils;
/**
 * åå°„工具类. æä¾›è°ƒç”¨getter/setter方法, è®¿é—®ç§æœ‰å˜é‡, è°ƒç”¨ç§æœ‰æ–¹æ³•, èŽ·å–æ³›åž‹ç±»åž‹Class, è¢«AOP过的真实类等工具函数.
 *
 * @author admin
 */
@SuppressWarnings("rawtypes")
public class ReflectUtils
{
    private static final String SETTER_PREFIX = "set";
    private static final String GETTER_PREFIX = "get";
    private static final String CGLIB_CLASS_SEPARATOR = "$$";
    private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class);
    /**
     * è°ƒç”¨Getter方法.
     * æ”¯æŒå¤šçº§ï¼Œå¦‚:对象名.对象名.方法
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeGetter(Object obj, String propertyName)
    {
        Object object = obj;
        for (String name : StringUtils.split(propertyName, "."))
        {
            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
            object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
        }
        return (E) object;
    }
    /**
     * è°ƒç”¨Setter方法, ä»…匹配方法名。
     * æ”¯æŒå¤šçº§ï¼Œå¦‚:对象名.对象名.方法
     */
    public static <E> void invokeSetter(Object obj, String propertyName, E value)
    {
        Object object = obj;
        String[] names = StringUtils.split(propertyName, ".");
        for (int i = 0; i < names.length; i++)
        {
            if (i < names.length - 1)
            {
                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
                object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
            }
            else
            {
                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
                invokeMethodByName(object, setterMethodName, new Object[] { value });
            }
        }
    }
    /**
     * ç›´æŽ¥è¯»å–对象属性值, æ— è§†private/protected修饰符, ä¸ç»è¿‡getter函数.
     */
    @SuppressWarnings("unchecked")
    public static <E> E getFieldValue(final Object obj, final String fieldName)
    {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null)
        {
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + fieldName + "] å­—段 ");
            return null;
        }
        E result = null;
        try
        {
            result = (E) field.get(obj);
        }
        catch (IllegalAccessException e)
        {
            logger.error("不可能抛出的异常{}", e.getMessage());
        }
        return result;
    }
    /**
     * ç›´æŽ¥è®¾ç½®å¯¹è±¡å±žæ€§å€¼, æ— è§†private/protected修饰符, ä¸ç»è¿‡setter函数.
     */
    public static <E> void setFieldValue(final Object obj, final String fieldName, final E value)
    {
        Field field = getAccessibleField(obj, fieldName);
        if (field == null)
        {
            // throw new IllegalArgumentException("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + fieldName + "] å­—段 ");
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + fieldName + "] å­—段 ");
            return;
        }
        try
        {
            field.set(obj, value);
        }
        catch (IllegalAccessException e)
        {
            logger.error("不可能抛出的异常: {}", e.getMessage());
        }
    }
    /**
     * ç›´æŽ¥è°ƒç”¨å¯¹è±¡æ–¹æ³•, æ— è§†private/protected修饰符.
     * ç”¨äºŽä¸€æ¬¡æ€§è°ƒç”¨çš„æƒ…况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
     * åŒæ—¶åŒ¹é…æ–¹æ³•名+参数类型,
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
            final Object[] args)
    {
        if (obj == null || methodName == null)
        {
            return null;
        }
        Method method = getAccessibleMethod(obj, methodName, parameterTypes);
        if (method == null)
        {
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + methodName + "] æ–¹æ³• ");
            return null;
        }
        try
        {
            return (E) method.invoke(obj, args);
        }
        catch (Exception e)
        {
            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }
    /**
     * ç›´æŽ¥è°ƒç”¨å¯¹è±¡æ–¹æ³•, æ— è§†private/protected修饰符,
     * ç”¨äºŽä¸€æ¬¡æ€§è°ƒç”¨çš„æƒ…况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
     * åªåŒ¹é…å‡½æ•°åï¼Œå¦‚果有多个同名函数调用第一个。
     */
    @SuppressWarnings("unchecked")
    public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args)
    {
        Method method = getAccessibleMethodByName(obj, methodName, args.length);
        if (method == null)
        {
            // å¦‚果为空不报错,直接返回空。
            logger.debug("在 [" + obj.getClass() + "] ä¸­ï¼Œæ²¡æœ‰æ‰¾åˆ° [" + methodName + "] æ–¹æ³• ");
            return null;
        }
        try
        {
            // ç±»åž‹è½¬æ¢ï¼ˆå°†å‚数数据类型转换为目标方法参数类型)
            Class<?>[] cs = method.getParameterTypes();
            for (int i = 0; i < cs.length; i++)
            {
                if (args[i] != null && !args[i].getClass().equals(cs[i]))
                {
                    if (cs[i] == String.class)
                    {
                        args[i] = Convert.toStr(args[i]);
                        if (StringUtils.endsWith((String) args[i], ".0"))
                        {
                            args[i] = StringUtils.substringBefore((String) args[i], ".0");
                        }
                    }
                    else if (cs[i] == Integer.class)
                    {
                        args[i] = Convert.toInt(args[i]);
                    }
                    else if (cs[i] == Long.class)
                    {
                        args[i] = Convert.toLong(args[i]);
                    }
                    else if (cs[i] == Double.class)
                    {
                        args[i] = Convert.toDouble(args[i]);
                    }
                    else if (cs[i] == Float.class)
                    {
                        args[i] = Convert.toFloat(args[i]);
                    }
                    else if (cs[i] == Date.class)
                    {
                        if (args[i] instanceof String)
                        {
                            args[i] = DateUtils.parseDate(args[i]);
                        }
                        else
                        {
                            args[i] = DateUtil.getJavaDate((Double) args[i]);
                        }
                    }
                    else if (cs[i] == boolean.class || cs[i] == Boolean.class)
                    {
                        args[i] = Convert.toBool(args[i]);
                    }
                }
            }
            return (E) method.invoke(obj, args);
        }
        catch (Exception e)
        {
            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
            throw convertReflectionExceptionToUnchecked(msg, e);
        }
    }
    /**
     * å¾ªçŽ¯å‘ä¸Šè½¬åž‹, èŽ·å–å¯¹è±¡çš„DeclaredField, å¹¶å¼ºåˆ¶è®¾ç½®ä¸ºå¯è®¿é—®.
     * å¦‚向上转型到Object仍无法找到, è¿”回null.
     */
    public static Field getAccessibleField(final Object obj, final String fieldName)
    {
        // ä¸ºç©ºä¸æŠ¥é”™ã€‚直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(fieldName, "fieldName can't be blank");
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())
        {
            try
            {
                Field field = superClass.getDeclaredField(fieldName);
                makeAccessible(field);
                return field;
            }
            catch (NoSuchFieldException e)
            {
                continue;
            }
        }
        return null;
    }
    /**
     * å¾ªçŽ¯å‘ä¸Šè½¬åž‹, èŽ·å–å¯¹è±¡çš„DeclaredMethod,并强制设置为可访问.
     * å¦‚向上转型到Object仍无法找到, è¿”回null.
     * åŒ¹é…å‡½æ•°å+参数类型。
     * ç”¨äºŽæ–¹æ³•需要被多次调用的情况. å…ˆä½¿ç”¨æœ¬å‡½æ•°å…ˆå–å¾—Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethod(final Object obj, final String methodName,
            final Class<?>... parameterTypes)
    {
        // ä¸ºç©ºä¸æŠ¥é”™ã€‚直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
        {
            try
            {
                Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
                makeAccessible(method);
                return method;
            }
            catch (NoSuchMethodException e)
            {
                continue;
            }
        }
        return null;
    }
    /**
     * å¾ªçŽ¯å‘ä¸Šè½¬åž‹, èŽ·å–å¯¹è±¡çš„DeclaredMethod,并强制设置为可访问.
     * å¦‚向上转型到Object仍无法找到, è¿”回null.
     * åªåŒ¹é…å‡½æ•°åã€‚
     * ç”¨äºŽæ–¹æ³•需要被多次调用的情况. å…ˆä½¿ç”¨æœ¬å‡½æ•°å…ˆå–å¾—Method,然后调用Method.invoke(Object obj, Object... args)
     */
    public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum)
    {
        // ä¸ºç©ºä¸æŠ¥é”™ã€‚直接返回 null
        if (obj == null)
        {
            return null;
        }
        Validate.notBlank(methodName, "methodName can't be blank");
        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
        {
            Method[] methods = searchType.getDeclaredMethods();
            for (Method method : methods)
            {
                if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum)
                {
                    makeAccessible(method);
                    return method;
                }
            }
        }
        return null;
    }
    /**
     * æ”¹å˜private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Method method)
    {
        if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
                && !method.isAccessible())
        {
            method.setAccessible(true);
        }
    }
    /**
     * æ”¹å˜private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
     */
    public static void makeAccessible(Field field)
    {
        if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
                || Modifier.isFinal(field.getModifiers())) && !field.isAccessible())
        {
            field.setAccessible(true);
        }
    }
    /**
     * é€šè¿‡åå°„, èŽ·å¾—Class定义中声明的泛型参数的类型, æ³¨æ„æ³›åž‹å¿…须定义在父类处
     * å¦‚无法找到, è¿”回Object.class.
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> getClassGenricType(final Class clazz)
    {
        return getClassGenricType(clazz, 0);
    }
    /**
     * é€šè¿‡åå°„, èŽ·å¾—Class定义中声明的父类的泛型参数的类型.
     * å¦‚无法找到, è¿”回Object.class.
     */
    public static Class getClassGenricType(final Class clazz, final int index)
    {
        Type genType = clazz.getGenericSuperclass();
        if (!(genType instanceof ParameterizedType))
        {
            logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
            return Object.class;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0)
        {
            logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
                    + params.length);
            return Object.class;
        }
        if (!(params[index] instanceof Class))
        {
            logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
            return Object.class;
        }
        return (Class) params[index];
    }
    public static Class<?> getUserClass(Object instance)
    {
        if (instance == null)
        {
            throw new RuntimeException("Instance must not be null");
        }
        Class clazz = instance.getClass();
        if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR))
        {
            Class<?> superClass = clazz.getSuperclass();
            if (superClass != null && !Object.class.equals(superClass))
            {
                return superClass;
            }
        }
        return clazz;
    }
    /**
     * å°†åå°„æ—¶çš„checked exception转换为unchecked exception.
     */
    public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e)
    {
        if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
                || e instanceof NoSuchMethodException)
        {
            return new IllegalArgumentException(msg, e);
        }
        else if (e instanceof InvocationTargetException)
        {
            return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException());
        }
        return new RuntimeException(msg, e);
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/utils/sign/Base64.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,291 @@
package com.se.common.core.utils.sign;
/**
 * Base64工具类
 *
 * @author admin
 */
public final class Base64
{
    static private final int     BASELENGTH           = 128;
    static private final int     LOOKUPLENGTH         = 64;
    static private final int     TWENTYFOURBITGROUP   = 24;
    static private final int     EIGHTBIT             = 8;
    static private final int     SIXTEENBIT           = 16;
    static private final int     FOURBYTE             = 4;
    static private final int     SIGN                 = -128;
    static private final char    PAD                  = '=';
    static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
    static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];
    static
    {
        for (int i = 0; i < BASELENGTH; ++i)
        {
            base64Alphabet[i] = -1;
        }
        for (int i = 'Z'; i >= 'A'; i--)
        {
            base64Alphabet[i] = (byte) (i - 'A');
        }
        for (int i = 'z'; i >= 'a'; i--)
        {
            base64Alphabet[i] = (byte) (i - 'a' + 26);
        }
        for (int i = '9'; i >= '0'; i--)
        {
            base64Alphabet[i] = (byte) (i - '0' + 52);
        }
        base64Alphabet['+'] = 62;
        base64Alphabet['/'] = 63;
        for (int i = 0; i <= 25; i++)
        {
            lookUpBase64Alphabet[i] = (char) ('A' + i);
        }
        for (int i = 26, j = 0; i <= 51; i++, j++)
        {
            lookUpBase64Alphabet[i] = (char) ('a' + j);
        }
        for (int i = 52, j = 0; i <= 61; i++, j++)
        {
            lookUpBase64Alphabet[i] = (char) ('0' + j);
        }
        lookUpBase64Alphabet[62] = (char) '+';
        lookUpBase64Alphabet[63] = (char) '/';
    }
    private static boolean isWhiteSpace(char octect)
    {
        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
    }
    private static boolean isPad(char octect)
    {
        return (octect == PAD);
    }
    private static boolean isData(char octect)
    {
        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
    }
    /**
     * Encodes hex octects into Base64
     *
     * @param binaryData Array containing binaryData
     * @return Encoded Base64 array
     */
    public static String encode(byte[] binaryData)
    {
        if (binaryData == null)
        {
            return null;
        }
        int lengthDataBits = binaryData.length * EIGHTBIT;
        if (lengthDataBits == 0)
        {
            return "";
        }
        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
        char encodedData[] = null;
        encodedData = new char[numberQuartet * 4];
        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        for (int i = 0; i < numberTriplets; i++)
        {
            b1 = binaryData[dataIndex++];
            b2 = binaryData[dataIndex++];
            b3 = binaryData[dataIndex++];
            l = (byte) (b2 & 0x0f);
            k = (byte) (b1 & 0x03);
            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
        }
        // form integral number of 6-bit groups
        if (fewerThan24bits == EIGHTBIT)
        {
            b1 = binaryData[dataIndex];
            k = (byte) (b1 & 0x03);
            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
            encodedData[encodedIndex++] = PAD;
            encodedData[encodedIndex++] = PAD;
        }
        else if (fewerThan24bits == SIXTEENBIT)
        {
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex + 1];
            l = (byte) (b2 & 0x0f);
            k = (byte) (b1 & 0x03);
            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
            encodedData[encodedIndex++] = PAD;
        }
        return new String(encodedData);
    }
    /**
     * Decodes Base64 data into octects
     *
     * @param encoded string containing Base64 data
     * @return Array containind decoded data.
     */
    public static byte[] decode(String encoded)
    {
        if (encoded == null)
        {
            return null;
        }
        char[] base64Data = encoded.toCharArray();
        // remove white spaces
        int len = removeWhiteSpace(base64Data);
        if (len % FOURBYTE != 0)
        {
            return null;// should be divisible by four
        }
        int numberQuadruple = (len / FOURBYTE);
        if (numberQuadruple == 0)
        {
            return new byte[0];
        }
        byte decodedData[] = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
        int i = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        decodedData = new byte[(numberQuadruple) * 3];
        for (; i < numberQuadruple - 1; i++)
        {
            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
                    || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++])))
            {
                return null;
            } // if found "no data" just return null
            b1 = base64Alphabet[d1];
            b2 = base64Alphabet[d2];
            b3 = base64Alphabet[d3];
            b4 = base64Alphabet[d4];
            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
        }
        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])))
        {
            return null;// if found "no data" just return null
        }
        b1 = base64Alphabet[d1];
        b2 = base64Alphabet[d2];
        d3 = base64Data[dataIndex++];
        d4 = base64Data[dataIndex++];
        if (!isData((d3)) || !isData((d4)))
        {// Check if they are PAD characters
            if (isPad(d3) && isPad(d4))
            {
                if ((b2 & 0xf) != 0)// last 4 bits should be zero
                {
                    return null;
                }
                byte[] tmp = new byte[i * 3 + 1];
                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                return tmp;
            }
            else if (!isPad(d3) && isPad(d4))
            {
                b3 = base64Alphabet[d3];
                if ((b3 & 0x3) != 0)// last 2 bits should be zero
                {
                    return null;
                }
                byte[] tmp = new byte[i * 3 + 2];
                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
                return tmp;
            }
            else
            {
                return null;
            }
        }
        else
        { // No PAD e.g 3cQl
            b3 = base64Alphabet[d3];
            b4 = base64Alphabet[d4];
            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
        }
        return decodedData;
    }
    /**
     * remove WhiteSpace from MIME containing encoded Base64 data.
     *
     * @param data the byte array of base64 data (with WS)
     * @return the new length
     */
    private static int removeWhiteSpace(char[] data)
    {
        if (data == null)
        {
            return 0;
        }
        // count characters that's not whitespace
        int newSize = 0;
        int len = data.length;
        for (int i = 0; i < len; i++)
        {
            if (!isWhiteSpace(data[i]))
            {
                data[newSize++] = data[i];
            }
        }
        return newSize;
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/utils/sql/SqlUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package com.se.common.core.utils.sql;
import com.se.common.core.exception.UtilException;
import com.se.common.core.utils.StringUtils;
/**
 * sql操作工具类
 *
 * @author admin
 */
public class SqlUtil
{
    /**
     * å®šä¹‰å¸¸ç”¨çš„ sql关键字
     */
    public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()";
    /**
     * ä»…支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
     */
    public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
    /**
     * é™åˆ¶orderBy最大长度
     */
    private static final int ORDER_BY_MAX_LENGTH = 500;
    /**
     * æ£€æŸ¥å­—符,防止注入绕过
     */
    public static String escapeOrderBySql(String value)
    {
        if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
        {
            throw new UtilException("参数不符合规范,不能进行查询");
        }
        if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
        {
            throw new UtilException("参数已超过最大限制,不能进行查询");
        }
        return value;
    }
    /**
     * éªŒè¯ order by è¯­æ³•是否符合规范
     */
    public static boolean isValidOrderBySql(String value)
    {
        return value.matches(SQL_PATTERN);
    }
    /**
     * SQL关键字检查
     */
    public static void filterKeyword(String value)
    {
        if (StringUtils.isEmpty(value))
        {
            return;
        }
        String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
        for (String sqlKeyword : sqlKeywords)
        {
            if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
            {
                throw new UtilException("参数存在SQL注入风险");
            }
        }
    }
}
se-common/se-common-core/src/main/java/com/se/common/core/xss/Xss.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.se.common.core.xss;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * è‡ªå®šä¹‰xss校验注解
 *
 * @author admin
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Constraint(validatedBy = { XssValidator.class })
public @interface Xss
{
    String message()
    default "不允许任何脚本运行";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
se-common/se-common-core/src/main/java/com/se/common/core/xss/XssValidator.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.se.common.core.xss;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.se.common.core.utils.StringUtils;
/**
 * è‡ªå®šä¹‰xss校验注解实现
 *
 * @author admin
 */
public class XssValidator implements ConstraintValidator<Xss, String>
{
    private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";
    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext)
    {
        if (StringUtils.isBlank(value))
        {
            return true;
        }
        return !containsHtml(value);
    }
    public static boolean containsHtml(String value)
    {
        StringBuilder sHtml = new StringBuilder();
        Pattern pattern = Pattern.compile(HTML_PATTERN);
        Matcher matcher = pattern.matcher(value);
        while (matcher.find())
        {
            sHtml.append(matcher.group());
        }
        return pattern.matcher(sHtml).matches();
    }
}
se-common/se-common-datascope/pom.xml
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-common-datascope</artifactId>
    <artifactId>se-common-datascope</artifactId>
    
    <description>
        ruoyi-common-datascope权限范围
        se-common-datascope权限范围
    </description>
    <dependencies>
se-common/se-common-datascope/src/main/java/com/se/common/datascope/aspect/DataScopeAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,185 @@
package com.se.common.datascope.aspect;
import java.util.ArrayList;
import java.util.List;
import com.se.common.datascope.annotation.DataScope;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import com.se.common.core.context.SecurityContextHolder;
import com.se.common.core.text.Convert;
import com.se.common.core.utils.StringUtils;
import com.se.common.core.web.domain.BaseEntity;
import com.se.common.security.utils.SecurityUtils;
import com.se.system.api.domain.SysRole;
import com.se.system.api.domain.SysUser;
import com.se.system.api.model.LoginUser;
/**
 * æ•°æ®è¿‡æ»¤å¤„理
 *
 * @author admin
 */
@Aspect
@Component
public class DataScopeAspect
{
    /**
     * å…¨éƒ¨æ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_ALL = "1";
    /**
     * è‡ªå®šæ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_CUSTOM = "2";
    /**
     * éƒ¨é—¨æ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_DEPT = "3";
    /**
     * éƒ¨é—¨åŠä»¥ä¸‹æ•°æ®æƒé™
     */
    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
    /**
     * ä»…本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";
    /**
     * æ•°æ®æƒé™è¿‡æ»¤å…³é”®å­—
     */
    public static final String DATA_SCOPE = "dataScope";
    @Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
    {
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }
    protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope)
    {
        // èŽ·å–å½“å‰çš„ç”¨æˆ·
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNotNull(loginUser))
        {
            SysUser currentUser = loginUser.getSysUser();
            // å¦‚果是超级管理员,则不过滤数据
            if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
            {
                String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), SecurityContextHolder.getPermission());
                dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
                        controllerDataScope.userAlias(), permission);
            }
        }
    }
    /**
     * æ•°æ®èŒƒå›´è¿‡æ»¤
     *
     * @param joinPoint åˆ‡ç‚¹
     * @param user ç”¨æˆ·
     * @param deptAlias éƒ¨é—¨åˆ«å
     * @param userAlias ç”¨æˆ·åˆ«å
     * @param permission æƒé™å­—符
     */
    public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission)
    {
        StringBuilder sqlString = new StringBuilder();
        List<String> conditions = new ArrayList<String>();
        List<String> scopeCustomIds = new ArrayList<String>();
        user.getRoles().forEach(role -> {
            if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
            {
                scopeCustomIds.add(Convert.toStr(role.getRoleId()));
            }
        });
        for (SysRole role : user.getRoles())
        {
            String dataScope = role.getDataScope();
            if (conditions.contains(dataScope))
            {
                continue;
            }
            if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
            {
                continue;
            }
            if (DATA_SCOPE_ALL.equals(dataScope))
            {
                sqlString = new StringBuilder();
                conditions.add(dataScope);
                break;
            }
            else if (DATA_SCOPE_CUSTOM.equals(dataScope))
            {
                if (scopeCustomIds.size() > 1)
                {
                    // å¤šä¸ªè‡ªå®šæ•°æ®æƒé™ä½¿ç”¨in查询,避免多次拼接。
                    sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds)));
                }
                else
                {
                    sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
                }
            }
            else if (DATA_SCOPE_DEPT.equals(dataScope))
            {
                sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
            }
            else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
            {
                sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId()));
            }
            else if (DATA_SCOPE_SELF.equals(dataScope))
            {
                if (StringUtils.isNotBlank(userAlias))
                {
                    sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
                }
                else
                {
                    // æ•°æ®æƒé™ä¸ºä»…本人且没有userAlias别名不查询任何数据
                    sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
                }
            }
            conditions.add(dataScope);
        }
        // è§’色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据
        if (StringUtils.isEmpty(conditions))
        {
            sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
        }
        if (StringUtils.isNotBlank(sqlString.toString()))
        {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
            {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
            }
        }
    }
    /**
     * æ‹¼æŽ¥æƒé™sql前先清空params.dataScope参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint)
    {
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
        {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, "");
        }
    }
}
se-common/se-common-datasource/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-common</artifactId>
        <version>3.6.4</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>se-common-datasource</artifactId>
    <description>
        se-common-datasource多数据源
    </description>
    <dependencies>
        <!-- Druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- Dynamic DataSource -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>${dynamic-ds.version}</version>
        </dependency>
    </dependencies>
</project>
se-common/se-common-datasource/src/main/java/com/se/common/datasource/annotation/Master.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.se.common.datasource.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.baomidou.dynamic.datasource.annotation.DS;
/**
 * ä¸»åº“数据源
 *
 * @author admin
 */
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("master")
public @interface Master
{
}
se-common/se-common-log/pom.xml
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-common-log</artifactId>
    <artifactId>se-common-log</artifactId>
    
    <description>
        ruoyi-common-log日志记录
        se-common-log日志记录
    </description>
    <dependencies>
se-common/se-common-log/src/main/java/com/se/common/log/annotation/Log.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.se.common.log.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.se.common.log.enums.BusinessType;
import com.se.common.log.enums.OperatorType;
/**
 * è‡ªå®šä¹‰æ“ä½œæ—¥å¿—记录注解
 *
 * @author admin
 *
 */
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
    /**
     * æ¨¡å—
     */
    public String title() default "";
    /**
     * åŠŸèƒ½
     */
    public BusinessType businessType() default BusinessType.OTHER;
    /**
     * æ“ä½œäººç±»åˆ«
     */
    public OperatorType operatorType() default OperatorType.MANAGE;
    /**
     * æ˜¯å¦ä¿å­˜è¯·æ±‚的参数
     */
    public boolean isSaveRequestData() default true;
    /**
     * æ˜¯å¦ä¿å­˜å“åº”的参数
     */
    public boolean isSaveResponseData() default true;
    /**
     * æŽ’除指定的请求参数
     */
    public String[] excludeParamNames() default {};
}
se-common/se-common-log/src/main/java/com/se/common/log/aspect/LogAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,250 @@
package com.se.common.log.aspect;
import java.util.Collection;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.se.common.log.enums.BusinessStatus;
import com.se.common.log.filter.PropertyPreExcludeFilter;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NamedThreadLocal;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson2.JSON;
import com.se.common.core.utils.ServletUtils;
import com.se.common.core.utils.StringUtils;
import com.se.common.core.utils.ip.IpUtils;
import com.se.common.log.annotation.Log;
import com.se.common.log.service.AsyncLogService;
import com.se.common.security.utils.SecurityUtils;
import com.se.system.api.domain.SysOperLog;
/**
 * æ“ä½œæ—¥å¿—记录处理
 *
 * @author admin
 */
@Aspect
@Component
public class LogAspect
{
    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
    /** æŽ’除敏感属性字段 */
    public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
    /** è®¡ç®—操作消耗时间 */
    private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
    @Autowired
    private AsyncLogService asyncLogService;
    /**
     * å¤„理请求前执行
     */
    @Before(value = "@annotation(controllerLog)")
    public void boBefore(JoinPoint joinPoint, Log controllerLog)
    {
        TIME_THREADLOCAL.set(System.currentTimeMillis());
    }
    /**
     * å¤„理完请求后执行
     *
     * @param joinPoint åˆ‡ç‚¹
     */
    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
    {
        handleLog(joinPoint, controllerLog, null, jsonResult);
    }
    /**
     * æ‹¦æˆªå¼‚常操作
     *
     * @param joinPoint åˆ‡ç‚¹
     * @param e å¼‚常
     */
    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
    {
        handleLog(joinPoint, controllerLog, e, null);
    }
    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult)
    {
        try
        {
            // *========数据库日志=========*//
            SysOperLog operLog = new SysOperLog();
            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
            // è¯·æ±‚的地址
            String ip = IpUtils.getIpAddr();
            operLog.setOperIp(ip);
            operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
            String username = SecurityUtils.getUsername();
            if (StringUtils.isNotBlank(username))
            {
                operLog.setOperName(username);
            }
            if (e != null)
            {
                operLog.setStatus(BusinessStatus.FAIL.ordinal());
                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
            }
            // è®¾ç½®æ–¹æ³•名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            operLog.setMethod(className + "." + methodName + "()");
            // è®¾ç½®è¯·æ±‚方式
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
            // å¤„理设置注解上的参数
            getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
            // è®¾ç½®æ¶ˆè€—æ—¶é—´
            operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
            // ä¿å­˜æ•°æ®åº“
            asyncLogService.saveSysLog(operLog);
        }
        catch (Exception exp)
        {
            // è®°å½•本地异常日志
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
        finally
        {
            TIME_THREADLOCAL.remove();
        }
    }
    /**
     * èŽ·å–æ³¨è§£ä¸­å¯¹æ–¹æ³•çš„æè¿°ä¿¡æ¯ ç”¨äºŽController层注解
     *
     * @param log æ—¥å¿—
     * @param operLog æ“ä½œæ—¥å¿—
     * @throws Exception
     */
    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception
    {
        // è®¾ç½®action动作
        operLog.setBusinessType(log.businessType().ordinal());
        // è®¾ç½®æ ‡é¢˜
        operLog.setTitle(log.title());
        // è®¾ç½®æ“ä½œäººç±»åˆ«
        operLog.setOperatorType(log.operatorType().ordinal());
        // æ˜¯å¦éœ€è¦ä¿å­˜request,参数和值
        if (log.isSaveRequestData())
        {
            // èŽ·å–å‚æ•°çš„ä¿¡æ¯ï¼Œä¼ å…¥åˆ°æ•°æ®åº“ä¸­ã€‚
            setRequestValue(joinPoint, operLog, log.excludeParamNames());
        }
        // æ˜¯å¦éœ€è¦ä¿å­˜response,参数和值
        if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult))
        {
            operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));
        }
    }
    /**
     * èŽ·å–è¯·æ±‚çš„å‚æ•°ï¼Œæ”¾åˆ°log中
     *
     * @param operLog æ“ä½œæ—¥å¿—
     * @throws Exception å¼‚常
     */
    private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
    {
        String requestMethod = operLog.getRequestMethod();
        Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
        if (StringUtils.isEmpty(paramsMap)
                && (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)))
        {
            String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
        }
        else
        {
            operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
        }
    }
    /**
     * å‚数拼装
     */
    private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
    {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0)
        {
            for (Object o : paramsArray)
            {
                if (StringUtils.isNotNull(o) && !isFilterObject(o))
                {
                    try
                    {
                        String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
                        params += jsonObj.toString() + " ";
                    }
                    catch (Exception e)
                    {
                    }
                }
            }
        }
        return params.trim();
    }
    /**
     * å¿½ç•¥æ•æ„Ÿå±žæ€§
     */
    public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames)
    {
        return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
    }
    /**
     * åˆ¤æ–­æ˜¯å¦éœ€è¦è¿‡æ»¤çš„对象。
     *
     * @param o å¯¹è±¡ä¿¡æ¯ã€‚
     * @return å¦‚果是需要过滤的对象,则返回true;否则返回false。
     */
    @SuppressWarnings("rawtypes")
    public boolean isFilterObject(final Object o)
    {
        Class<?> clazz = o.getClass();
        if (clazz.isArray())
        {
            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
        }
        else if (Collection.class.isAssignableFrom(clazz))
        {
            Collection collection = (Collection) o;
            for (Object value : collection)
            {
                return value instanceof MultipartFile;
            }
        }
        else if (Map.class.isAssignableFrom(clazz))
        {
            Map map = (Map) o;
            for (Object value : map.entrySet())
            {
                Map.Entry entry = (Map.Entry) value;
                return entry.getValue() instanceof MultipartFile;
            }
        }
        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
                || o instanceof BindingResult;
    }
}
se-common/se-common-log/src/main/java/com/se/common/log/enums/BusinessStatus.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.se.common.log.enums;
/**
 * æ“ä½œçŠ¶æ€
 *
 * @author admin
 *
 */
public enum BusinessStatus
{
    /**
     * æˆåŠŸ
     */
    SUCCESS,
    /**
     * å¤±è´¥
     */
    FAIL,
}
se-common/se-common-log/src/main/java/com/se/common/log/enums/BusinessType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.se.common.log.enums;
/**
 * ä¸šåŠ¡æ“ä½œç±»åž‹
 *
 * @author admin
 */
public enum BusinessType
{
    /**
     * å…¶å®ƒ
     */
    OTHER,
    /**
     * æ–°å¢ž
     */
    INSERT,
    /**
     * ä¿®æ”¹
     */
    UPDATE,
    /**
     * åˆ é™¤
     */
    DELETE,
    /**
     * æŽˆæƒ
     */
    GRANT,
    /**
     * å¯¼å‡º
     */
    EXPORT,
    /**
     * å¯¼å…¥
     */
    IMPORT,
    /**
     * å¼ºé€€
     */
    FORCE,
    /**
     * ç”Ÿæˆä»£ç 
     */
    GENCODE,
    /**
     * æ¸…空数据
     */
    CLEAN,
}
se-common/se-common-log/src/main/java/com/se/common/log/enums/OperatorType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.se.common.log.enums;
/**
 * æ“ä½œäººç±»åˆ«
 *
 * @author admin
 */
public enum OperatorType
{
    /**
     * å…¶å®ƒ
     */
    OTHER,
    /**
     * åŽå°ç”¨æˆ·
     */
    MANAGE,
    /**
     * æ‰‹æœºç«¯ç”¨æˆ·
     */
    MOBILE
}
se-common/se-common-log/src/main/java/com/se/common/log/service/AsyncLogService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.se.common.log.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.se.common.core.constant.SecurityConstants;
import com.se.system.api.RemoteLogService;
import com.se.system.api.domain.SysOperLog;
/**
 * å¼‚步调用日志服务
 *
 * @author admin
 */
@Service
public class AsyncLogService
{
    @Autowired
    private RemoteLogService remoteLogService;
    /**
     * ä¿å­˜ç³»ç»Ÿæ—¥å¿—记录
     */
    @Async
    public void saveSysLog(SysOperLog sysOperLog) throws Exception
    {
        remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER);
    }
}
se-common/se-common-redis/pom.xml
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-common-redis</artifactId>
    <artifactId>se-common-redis</artifactId>
    
    <description>
        ruoyi-common-redis缓存服务
        se-common-redis缓存服务
    </description>
    <dependencies>
se-common/se-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
com.se.common.redis.configure.RedisConfig
com.se.common.redis.service.RedisService
se-common/se-common-seata/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.ruoyi</groupId>
        <artifactId>ruoyi-common</artifactId>
        <version>3.6.4</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>se-common-seata</artifactId>
    <description>
        se-common-seata分布式事务
    </description>
    <dependencies>
        <!-- SpringBoot Seata -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>
    </dependencies>
</project>
se-common/se-common-security/pom.xml
@@ -8,10 +8,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-common-security</artifactId>
    <artifactId>se-common-security</artifactId>
    <description>
        ruoyi-common-security安全模块
        se-common-security安全模块
    </description>
    <dependencies>
se-common/se-common-security/src/main/java/com/se/common/security/annotation/InnerAuth.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.se.common.security.annotation;
import java.lang.annotation.*;
/**
 * å†…部认证注解
 *
 * @author admin
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InnerAuth
{
    /**
     * æ˜¯å¦æ ¡éªŒç”¨æˆ·ä¿¡æ¯
     */
    boolean isUser() default false;
}
se-common/se-common-security/src/main/java/com/se/common/security/aspect/InnerAuthAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.se.common.security.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import com.se.common.core.constant.SecurityConstants;
import com.se.common.core.exception.InnerAuthException;
import com.se.common.core.utils.ServletUtils;
import com.se.common.core.utils.StringUtils;
import com.se.common.security.annotation.InnerAuth;
/**
 * å†…部服务调用验证处理
 *
 * @author admin
 */
@Aspect
@Component
public class InnerAuthAspect implements Ordered
{
    @Around("@annotation(innerAuth)")
    public Object innerAround(ProceedingJoinPoint point, InnerAuth innerAuth) throws Throwable
    {
        String source = ServletUtils.getRequest().getHeader(SecurityConstants.FROM_SOURCE);
        // å†…部请求验证
        if (!StringUtils.equals(SecurityConstants.INNER, source))
        {
            throw new InnerAuthException("没有内部访问权限,不允许访问");
        }
        String userid = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USER_ID);
        String username = ServletUtils.getRequest().getHeader(SecurityConstants.DETAILS_USERNAME);
        // ç”¨æˆ·ä¿¡æ¯éªŒè¯
        if (innerAuth.isUser() && (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)))
        {
            throw new InnerAuthException("没有设置用户信息,不允许访问 ");
        }
        return point.proceed();
    }
    /**
     * ç¡®ä¿åœ¨æƒé™è®¤è¯aop执行前执行
     */
    @Override
    public int getOrder()
    {
        return Ordered.HIGHEST_PRECEDENCE + 1;
    }
}
se-common/se-common-security/src/main/java/com/se/common/security/handler/GlobalExceptionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,166 @@
package com.se.common.security.handler;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import com.se.common.core.constant.HttpStatus;
import com.se.common.core.exception.DemoModeException;
import com.se.common.core.exception.InnerAuthException;
import com.se.common.core.exception.ServiceException;
import com.se.common.core.exception.auth.NotPermissionException;
import com.se.common.core.exception.auth.NotRoleException;
import com.se.common.core.text.Convert;
import com.se.common.core.utils.StringUtils;
import com.se.common.core.utils.html.EscapeUtil;
import com.se.common.core.web.domain.AjaxResult;
/**
 * å…¨å±€å¼‚常处理器
 *
 * @author admin
 */
@RestControllerAdvice
public class GlobalExceptionHandler
{
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    /**
     * æƒé™ç å¼‚常
     */
    @ExceptionHandler(NotPermissionException.class)
    public AjaxResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
    }
    /**
     * è§’色权限异常
     */
    @ExceptionHandler(NotRoleException.class)
    public AjaxResult handleNotRoleException(NotRoleException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',角色权限校验失败'{}'", requestURI, e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有访问权限,请联系管理员授权");
    }
    /**
     * è¯·æ±‚方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return AjaxResult.error(e.getMessage());
    }
    /**
     * ä¸šåС异叏
     */
    @ExceptionHandler(ServiceException.class)
    public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
    {
        log.error(e.getMessage(), e);
        Integer code = e.getCode();
        return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
    }
    /**
     * è¯·æ±‚路径中缺少必需的路径变量
     */
    @ExceptionHandler(MissingPathVariableException.class)
    public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
        return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
    }
    /**
     * è¯·æ±‚参数类型不匹配
     */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        String value = Convert.toStr(e.getValue());
        if (StringUtils.isNotEmpty(value))
        {
            value = EscapeUtil.clean(value);
        }
        log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
        return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));
    }
    /**
     * æ‹¦æˆªæœªçŸ¥çš„运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常.", requestURI, e);
        return AjaxResult.error(e.getMessage());
    }
    /**
     * ç³»ç»Ÿå¼‚常
     */
    @ExceptionHandler(Exception.class)
    public AjaxResult handleException(Exception e, HttpServletRequest request)
    {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURI, e);
        return AjaxResult.error(e.getMessage());
    }
    /**
     * è‡ªå®šä¹‰éªŒè¯å¼‚常
     */
    @ExceptionHandler(BindException.class)
    public AjaxResult handleBindException(BindException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return AjaxResult.error(message);
    }
    /**
     * è‡ªå®šä¹‰éªŒè¯å¼‚常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return AjaxResult.error(message);
    }
    /**
     * å†…部认证异常
     */
    @ExceptionHandler(InnerAuthException.class)
    public AjaxResult handleInnerAuthException(InnerAuthException e)
    {
        return AjaxResult.error(e.getMessage());
    }
    /**
     * æ¼”示模式异常
     */
    @ExceptionHandler(DemoModeException.class)
    public AjaxResult handleDemoModeException(DemoModeException e)
    {
        return AjaxResult.error("演示模式,不允许操作");
    }
}
se-common/se-common-security/src/main/java/com/se/common/security/utils/DictUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
package com.se.common.security.utils;
import java.util.Collection;
import java.util.List;
import com.alibaba.fastjson2.JSONArray;
import com.se.common.core.constant.CacheConstants;
import com.se.common.core.utils.SpringUtils;
import com.se.common.core.utils.StringUtils;
import com.se.common.redis.service.RedisService;
import com.se.system.api.domain.SysDictData;
/**
 * å­—典工具类
 *
 * @author admin
 */
public class DictUtils
{
    /**
     * è®¾ç½®å­—典缓存
     *
     * @param key å‚æ•°é”®
     * @param dictDatas å­—典数据列表
     */
    public static void setDictCache(String key, List<SysDictData> dictDatas)
    {
        SpringUtils.getBean(RedisService.class).setCacheObject(getCacheKey(key), dictDatas);
    }
    /**
     * èŽ·å–å­—å…¸ç¼“å­˜
     *
     * @param key å‚æ•°é”®
     * @return dictDatas å­—典数据列表
     */
    public static List<SysDictData> getDictCache(String key)
    {
        JSONArray arrayCache = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key));
        if (StringUtils.isNotNull(arrayCache))
        {
            return arrayCache.toList(SysDictData.class);
        }
        return null;
    }
    /**
     * åˆ é™¤æŒ‡å®šå­—典缓存
     *
     * @param key å­—典键
     */
    public static void removeDictCache(String key)
    {
        SpringUtils.getBean(RedisService.class).deleteObject(getCacheKey(key));
    }
    /**
     * æ¸…空字典缓存
     */
    public static void clearDictCache()
    {
        Collection<String> keys = SpringUtils.getBean(RedisService.class).keys(CacheConstants.SYS_DICT_KEY + "*");
        SpringUtils.getBean(RedisService.class).deleteObject(keys);
    }
    /**
     * è®¾ç½®cache key
     *
     * @param configKey å‚æ•°é”®
     * @return ç¼“存键key
     */
    public static String getCacheKey(String configKey)
    {
        return CacheConstants.SYS_DICT_KEY + configKey;
    }
}
se-common/se-common-sensitive/pom.xml
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-common-sensitive</artifactId>
    <artifactId>se-common-sensitive</artifactId>
    <description>
        ruoyi-common-sensitive数据脱敏
        se-common-sensitive数据脱敏
    </description>
    <dependencies>
se-common/se-common-sensitive/src/main/java/com/se/common/sensitive/config/SensitiveJsonSerializer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.se.common.sensitive.config;
import java.io.IOException;
import java.util.Objects;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.se.common.security.utils.SecurityUtils;
import com.se.common.sensitive.annotation.Sensitive;
import com.se.common.sensitive.enums.DesensitizedType;
import com.se.system.api.model.LoginUser;
/**
 * æ•°æ®è„±æ•åºåˆ—化过滤
 *
 * @author admin
 */
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer
{
    private DesensitizedType desensitizedType;
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException
    {
        if (desensitization())
        {
            gen.writeString(desensitizedType.desensitizer().apply(value));
        }
        else
        {
            gen.writeString(value);
        }
    }
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
            throws JsonMappingException
    {
        Sensitive annotation = property.getAnnotation(Sensitive.class);
        if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass()))
        {
            this.desensitizedType = annotation.desensitizedType();
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
    /**
     * æ˜¯å¦éœ€è¦è„±æ•å¤„理
     */
    private boolean desensitization()
    {
        try
        {
            LoginUser securityUser = SecurityUtils.getLoginUser();
            // ç®¡ç†å‘˜ä¸è„±æ•
            return !securityUser.getSysUser().isAdmin();
        }
        catch (Exception e)
        {
            return true;
        }
    }
}
se-common/se-common-sensitive/src/main/java/com/se/common/sensitive/enums/DesensitizedType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.se.common.sensitive.enums;
import java.util.function.Function;
import com.se.common.sensitive.utils.DesensitizedUtil;
/**
 * è„±æ•ç±»åž‹
 *
 * @author admin
 */
public enum DesensitizedType
{
    /**
     * å§“名,第2位星号替换
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
    /**
     * å¯†ç ï¼Œå…¨éƒ¨å­—符都用*代替
     */
    PASSWORD(DesensitizedUtil::password),
    /**
     * èº«ä»½è¯ï¼Œä¸­é—´10位星号替换
     */
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")),
    /**
     * æ‰‹æœºå·ï¼Œä¸­é—´4位星号替换
     */
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
    /**
     * ç”µå­é‚®ç®±ï¼Œä»…显示第一个字母和@后面的地址显示,其他星号替换
     */
    EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")),
    /**
     * é“¶è¡Œå¡å·ï¼Œä¿ç•™æœ€åŽ4位,其他星号替换
     */
    BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")),
    /**
     * è½¦ç‰Œå·ç ï¼ŒåŒ…含普通车辆、新能源车辆
     */
    CAR_LICENSE(DesensitizedUtil::carLicense);
    private final Function<String, String> desensitizer;
    DesensitizedType(Function<String, String> desensitizer)
    {
        this.desensitizer = desensitizer;
    }
    public Function<String, String> desensitizer()
    {
        return desensitizer;
    }
}
se-common/se-common-sensitive/src/main/java/com/se/common/sensitive/utils/DesensitizedUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.se.common.sensitive.utils;
import com.se.common.core.utils.StringUtils;
/**
 * è„±æ•å·¥å…·ç±»
 *
 * @author admin
 */
public class DesensitizedUtil
{
    /**
     * å¯†ç çš„全部字符都用*代替,比如:******
     *
     * @param password å¯†ç 
     * @return è„±æ•åŽçš„密码
     */
    public static String password(String password)
    {
        if (StringUtils.isBlank(password))
        {
            return StringUtils.EMPTY;
        }
        return StringUtils.repeat('*', password.length());
    }
    /**
     * è½¦ç‰Œä¸­é—´ç”¨*代替,如果是错误的车牌,不处理
     *
     * @param carLicense å®Œæ•´çš„车牌号
     * @return è„±æ•åŽçš„车牌
     */
    public static String carLicense(String carLicense)
    {
        if (StringUtils.isBlank(carLicense))
        {
            return StringUtils.EMPTY;
        }
        // æ™®é€šè½¦ç‰Œ
        if (carLicense.length() == 7)
        {
            carLicense = StringUtils.hide(carLicense, 3, 6);
        }
        else if (carLicense.length() == 8)
        {
            // æ–°èƒ½æºè½¦ç‰Œ
            carLicense = StringUtils.hide(carLicense, 3, 7);
        }
        return carLicense;
    }
}
se-common/se-common-swagger/pom.xml
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-common-swagger</artifactId>
    <artifactId>se-common-swagger</artifactId>
    
    <description>
        ruoyi-common-swagger系统接口
        se-common-swagger系统接口
    </description>
    <dependencies>
se-common/se-common-swagger/src/main/java/com/se/common/swagger/annotation/EnableCustomSwagger2.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.se.common.swagger.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
import com.se.common.swagger.config.SwaggerAutoConfiguration;
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({ SwaggerAutoConfiguration.class })
public @interface EnableCustomSwagger2
{
}
se-common/se-common-swagger/src/main/java/com/se/common/swagger/config/SwaggerBeanPostProcessor.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.se.common.swagger.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;
/**
 * swagger åœ¨ springboot 2.6.x ä¸å…¼å®¹é—®é¢˜çš„处理
 *
 * @author admin
 */
public class SwaggerBeanPostProcessor implements BeanPostProcessor
{
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
    {
        if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider)
        {
            customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
        }
        return bean;
    }
    private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings)
    {
        List<T> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null)
                .collect(Collectors.toList());
        mappings.clear();
        mappings.addAll(copy);
    }
    @SuppressWarnings("unchecked")
    private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean)
    {
        try
        {
            Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
            field.setAccessible(true);
            return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
        }
        catch (IllegalArgumentException | IllegalAccessException e)
        {
            throw new IllegalStateException(e);
        }
    }
}
se-gateway/pom.xml
@@ -8,10 +8,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-gateway</artifactId>
    <artifactId>se-gateway</artifactId>
    <description>
        ruoyi-gateway网关模块
        se-gateway网关模块
    </description>
    <dependencies>
se-modules/pom.xml
ÎļþÃû´Ó ruoyi-modules/pom.xml ÐÞ¸Ä
@@ -9,17 +9,17 @@
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>ruoyi-system</module>
        <module>ruoyi-gen</module>
        <module>ruoyi-job</module>
        <module>ruoyi-file</module>
        <module>se-system</module>
        <module>se-gen</module>
        <module>se-job</module>
        <module>se-file</module>
    </modules>
    <artifactId>ruoyi-modules</artifactId>
    <artifactId>se-modules</artifactId>
    <packaging>pom</packaging>
    <description>
        ruoyi-modules业务模块
        se-modules业务模块
    </description>
</project>
se-modules/se-file/pom.xml
ÎļþÃû´Ó ruoyi-modules/se-file/pom.xml ÐÞ¸Ä
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-modules-file</artifactId>
    <artifactId>se-modules-file</artifactId>
    <description>
        ruoyi-modules-file文件服务
        se-modules-file文件服务
    </description>
    <dependencies>
se-modules/se-file/src/main/java/com/se/file/SeFileApplication.java
se-modules/se-file/src/main/java/com/se/file/config/MinioConfig.java
se-modules/se-file/src/main/java/com/se/file/config/ResourcesConfig.java
se-modules/se-file/src/main/java/com/se/file/controller/SysFileController.java
se-modules/se-file/src/main/java/com/se/file/service/FastDfsSysFileServiceImpl.java
se-modules/se-file/src/main/java/com/se/file/service/ISysFileService.java
se-modules/se-file/src/main/java/com/se/file/service/LocalSysFileServiceImpl.java
se-modules/se-file/src/main/java/com/se/file/service/MinioSysFileServiceImpl.java
se-modules/se-file/src/main/java/com/se/file/utils/FileUploadUtils.java
se-modules/se-file/src/main/resources/banner.txt
se-modules/se-file/src/main/resources/bootstrap.yml
se-modules/se-file/src/main/resources/logback.xml
se-modules/se-gen/pom.xml
ÎļþÃû´Ó ruoyi-modules/se-gen/pom.xml ÐÞ¸Ä
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-modules-gen</artifactId>
    <artifactId>se-modules-gen</artifactId>
    <description>
        ruoyi-modules-gen代码生成
        se-modules-gen代码生成
    </description>
    <dependencies>
se-modules/se-gen/src/main/java/com/se/gen/SeGenApplication.java
se-modules/se-gen/src/main/java/com/se/gen/config/GenConfig.java
se-modules/se-gen/src/main/java/com/se/gen/controller/GenController.java
se-modules/se-gen/src/main/java/com/se/gen/domain/GenTable.java
se-modules/se-gen/src/main/java/com/se/gen/domain/GenTableColumn.java
se-modules/se-gen/src/main/java/com/se/gen/mapper/GenTableColumnMapper.java
se-modules/se-gen/src/main/java/com/se/gen/mapper/GenTableMapper.java
se-modules/se-gen/src/main/java/com/se/gen/service/GenTableColumnServiceImpl.java
se-modules/se-gen/src/main/java/com/se/gen/service/GenTableServiceImpl.java
se-modules/se-gen/src/main/java/com/se/gen/service/IGenTableColumnService.java
se-modules/se-gen/src/main/java/com/se/gen/service/IGenTableService.java
se-modules/se-gen/src/main/java/com/se/gen/util/GenUtils.java
se-modules/se-gen/src/main/java/com/se/gen/util/VelocityInitializer.java
se-modules/se-gen/src/main/java/com/se/gen/util/VelocityUtils.java
se-modules/se-gen/src/main/resources/banner.txt
se-modules/se-gen/src/main/resources/bootstrap.yml
se-modules/se-gen/src/main/resources/logback.xml
se-modules/se-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml
se-modules/se-gen/src/main/resources/mapper/generator/GenTableMapper.xml
se-modules/se-gen/src/main/resources/vm/java/controller.java.vm
se-modules/se-gen/src/main/resources/vm/java/domain.java.vm
se-modules/se-gen/src/main/resources/vm/java/mapper.java.vm
se-modules/se-gen/src/main/resources/vm/java/service.java.vm
se-modules/se-gen/src/main/resources/vm/java/serviceImpl.java.vm
se-modules/se-gen/src/main/resources/vm/java/sub-domain.java.vm
se-modules/se-gen/src/main/resources/vm/js/api.js.vm
se-modules/se-gen/src/main/resources/vm/sql/sql.vm
se-modules/se-gen/src/main/resources/vm/vue/index-tree.vue.vm
se-modules/se-gen/src/main/resources/vm/vue/index.vue.vm
se-modules/se-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm
se-modules/se-gen/src/main/resources/vm/vue/v3/index.vue.vm
se-modules/se-gen/src/main/resources/vm/xml/mapper.xml.vm
se-modules/se-job/pom.xml
ÎļþÃû´Ó ruoyi-modules/se-job/pom.xml ÐÞ¸Ä
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ruoyi-modules-job</artifactId>
    <artifactId>se-modules-job</artifactId>
    <description>
        ruoyi-modules-job定时任务
        se-modules-job定时任务
    </description>
    <dependencies>
se-modules/se-job/src/main/java/com/se/job/SeJobApplication.java
se-modules/se-job/src/main/java/com/se/job/config/ScheduleConfig.java
se-modules/se-job/src/main/java/com/se/job/controller/SysJobController.java
se-modules/se-job/src/main/java/com/se/job/controller/SysJobLogController.java
se-modules/se-job/src/main/java/com/se/job/domain/SysJob.java
se-modules/se-job/src/main/java/com/se/job/domain/SysJobLog.java
se-modules/se-job/src/main/java/com/se/job/mapper/SysJobLogMapper.java
se-modules/se-job/src/main/java/com/se/job/mapper/SysJobMapper.java
se-modules/se-job/src/main/java/com/se/job/service/ISysJobLogService.java
se-modules/se-job/src/main/java/com/se/job/service/ISysJobService.java
se-modules/se-job/src/main/java/com/se/job/service/SysJobLogServiceImpl.java
se-modules/se-job/src/main/java/com/se/job/service/SysJobServiceImpl.java
se-modules/se-job/src/main/java/com/se/job/task/RyTask.java
se-modules/se-job/src/main/java/com/se/job/util/AbstractQuartzJob.java
se-modules/se-job/src/main/java/com/se/job/util/CronUtils.java
se-modules/se-job/src/main/java/com/se/job/util/JobInvokeUtil.java
se-modules/se-job/src/main/java/com/se/job/util/QuartzDisallowConcurrentExecution.java
se-modules/se-job/src/main/java/com/se/job/util/QuartzJobExecution.java
se-modules/se-job/src/main/java/com/se/job/util/ScheduleUtils.java
se-modules/se-job/src/main/resources/banner.txt
se-modules/se-job/src/main/resources/bootstrap.yml
se-modules/se-job/src/main/resources/logback.xml
se-modules/se-job/src/main/resources/mapper/job/SysJobLogMapper.xml
se-modules/se-job/src/main/resources/mapper/job/SysJobMapper.xml
se-modules/se-system/pom.xml
ÎļþÃû´Ó ruoyi-modules/se-system/pom.xml ÐÞ¸Ä
@@ -9,10 +9,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-modules-system</artifactId>
    <artifactId>se-modules-system</artifactId>
    <description>
        ruoyi-modules-system系统模块
        se-modules-system系统模块
    </description>
    
    <dependencies>
se-modules/se-system/src/main/java/com/se/system/RuoYiSystemApplication.java
se-modules/se-system/src/main/java/com/se/system/controller/SysConfigController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysDeptController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysDictDataController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysDictTypeController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysLogininforController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysMenuController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysNoticeController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysOperlogController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysPostController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysProfileController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysRoleController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysUserController.java
se-modules/se-system/src/main/java/com/se/system/controller/SysUserOnlineController.java
se-modules/se-system/src/main/java/com/se/system/domain/SysConfig.java
se-modules/se-system/src/main/java/com/se/system/domain/SysMenu.java
se-modules/se-system/src/main/java/com/se/system/domain/SysNotice.java
se-modules/se-system/src/main/java/com/se/system/domain/SysPost.java
se-modules/se-system/src/main/java/com/se/system/domain/SysRoleDept.java
se-modules/se-system/src/main/java/com/se/system/domain/SysRoleMenu.java
se-modules/se-system/src/main/java/com/se/system/domain/SysUserOnline.java
se-modules/se-system/src/main/java/com/se/system/domain/SysUserPost.java
se-modules/se-system/src/main/java/com/se/system/domain/SysUserRole.java
se-modules/se-system/src/main/java/com/se/system/domain/vo/MetaVo.java
se-modules/se-system/src/main/java/com/se/system/domain/vo/RouterVo.java
se-modules/se-system/src/main/java/com/se/system/domain/vo/TreeSelect.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysConfigMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysDeptMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysDictDataMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysDictTypeMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysLogininforMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysMenuMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysNoticeMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysOperLogMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysPostMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysRoleDeptMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysRoleMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysRoleMenuMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysUserMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysUserPostMapper.java
se-modules/se-system/src/main/java/com/se/system/mapper/SysUserRoleMapper.java
se-modules/se-system/src/main/java/com/se/system/service/ISysConfigService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysDeptService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysDictDataService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysDictTypeService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysLogininforService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysMenuService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysNoticeService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysOperLogService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysPermissionService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysPostService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysRoleService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysUserOnlineService.java
se-modules/se-system/src/main/java/com/se/system/service/ISysUserService.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysConfigServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysDeptServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysDictDataServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysDictTypeServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysLogininforServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysMenuServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysNoticeServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysOperLogServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysPermissionServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysPostServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysRoleServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysUserOnlineServiceImpl.java
se-modules/se-system/src/main/java/com/se/system/service/impl/SysUserServiceImpl.java
se-modules/se-system/src/main/resources/banner.txt
se-modules/se-system/src/main/resources/bootstrap.yml
se-modules/se-system/src/main/resources/logback.xml
se-modules/se-system/src/main/resources/mapper/system/SysConfigMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysDeptMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysDictDataMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysDictTypeMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysLogininforMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysMenuMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysNoticeMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysOperLogMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysPostMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysRoleMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysUserMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysUserPostMapper.xml
se-modules/se-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
se-visual/pom.xml
@@ -9,14 +9,14 @@
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>ruoyi-monitor</module>
        <module>se-monitor</module>
    </modules>
    <artifactId>ruoyi-visual</artifactId>
    <artifactId>se-visual</artifactId>
    <packaging>pom</packaging>
    <description>
        ruoyi-visual图形化管理模块
        se-visual图形化管理模块
    </description>
</project>
se-visual/se-monitor/pom.xml
@@ -8,10 +8,10 @@
    </parent>
    <modelVersion>4.0.0</modelVersion>
    
    <artifactId>ruoyi-visual-monitor</artifactId>
    <artifactId>se-visual-monitor</artifactId>
    <description>
        ruoyi-visual-monitor监控中心
        se-visual-monitor监控中心
    </description>
    <dependencies>
se-visual/se-monitor/src/main/java/com/se/modules/monitor/SeMonitorApplication.java
@@ -16,15 +16,6 @@
    public static void main(String[] args)
    {
        SpringApplication.run(SeMonitorApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  ç›‘控中心启动成功   áƒš(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
        System.out.println("    ç›‘控中心启动成功    ");
    }
}