From ebbb265e1f73e0077a3c86cd1faa995882564acd Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Mon, 5 May 2025 09:07:44 +0800 Subject: [PATCH 1/4] =?UTF-8?q?:bricks:=20feat:=20=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E6=9B=B4=E6=8D=A2=E6=96=87=E4=BB=B6=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/configuration/ConfigurationController.java | 2 +- .../controller/configuration/EmailTemplateController.java | 2 +- .../services/controller/configuration/EmailUsersController.java | 2 +- .../bunny/services/controller/configuration/I18nController.java | 2 +- .../services/controller/configuration/I18nTypeController.java | 2 +- .../services/controller/configuration/MenuIconController.java | 2 +- .../services/controller/log/ScheduleExecuteLogController.java | 2 +- .../bunny/services/controller/log/UserLoginLogController.java | 2 +- .../cn/bunny/services/controller/message/MessageController.java | 2 +- .../services/controller/message/MessageReceivedController.java | 2 +- .../services/controller/message/MessageTypeController.java | 2 +- .../services/controller/schedule/SchedulersController.java | 2 +- .../services/controller/schedule/SchedulersGroupController.java | 2 +- .../cn/bunny/services/controller/system/DeptController.java | 2 +- .../cn/bunny/services/controller/system/FilesController.java | 2 +- .../bunny/services/controller/system/PermissionController.java | 2 +- .../cn/bunny/services/controller/system/RoleController.java | 2 +- .../cn/bunny/services/controller/system/RouterController.java | 2 +- .../cn/bunny/services/controller/system/UserController.java | 2 +- .../bunny/services/controller/system/UserLoginController.java | 2 +- .../common/{model/vo/result => enums}/ResultCodeEnum.java | 2 +- .../cn/bunny/services/domain/common/model/vo/result/Result.java | 1 + .../java/cn/bunny/services/exception/AuthCustomerException.java | 2 +- .../cn/bunny/services/exception/GlobalExceptionHandler.java | 2 +- .../src/main/java/cn/bunny/services/minio/MinioService.java | 2 +- .../src/main/java/cn/bunny/services/utils/JwtTokenUtil.java | 2 +- .../bunny/services/aop/scanner/AbstractAnnotationScanner.java | 2 +- .../main/java/cn/bunny/services/excel/RoleExcelListener.java | 2 +- .../cn/bunny/services/security/config/MethodSecurityConfig.java | 2 +- .../security/exception/CustomAuthenticationException.java | 2 +- .../services/security/handelr/SecurityAccessDeniedHandler.java | 2 +- .../security/handelr/SecurityAuthenticationEntryPoint.java | 2 +- .../security/service/CustomAuthorizationManagerServiceImpl.java | 2 +- .../bunny/services/security/service/TokenValidationService.java | 2 +- .../configuration/helper/email/AbstractSenderEmailTemplate.java | 2 +- .../service/configuration/impl/ConfigurationServiceImpl.java | 2 +- .../service/configuration/impl/EmailTemplateServiceImpl.java | 2 +- .../service/configuration/impl/EmailUsersServiceImpl.java | 2 +- .../services/service/configuration/impl/I18nServiceImpl.java | 2 +- .../service/configuration/impl/I18nTypeServiceImpl.java | 2 +- .../service/configuration/impl/MenuIconServiceImpl.java | 2 +- .../service/message/impl/MessageReceivedServiceImpl.java | 2 +- .../bunny/services/service/message/impl/MessageServiceImpl.java | 2 +- .../services/service/schedule/impl/SchedulersServiceImpl.java | 2 +- .../service/system/helper/login/EmailLoginStrategy.java | 2 +- .../cn/bunny/services/service/system/impl/DeptServiceImpl.java | 2 +- .../cn/bunny/services/service/system/impl/FilesServiceImpl.java | 2 +- .../services/service/system/impl/PermissionServiceImpl.java | 2 +- .../cn/bunny/services/service/system/impl/RoleServiceImpl.java | 2 +- .../services/service/system/impl/RouterRoleServiceImpl.java | 2 +- .../bunny/services/service/system/impl/RouterServiceImpl.java | 2 +- .../services/service/system/impl/UserLoginServiceImpl.java | 2 +- .../bunny/services/service/system/impl/UserRoleServiceImpl.java | 2 +- .../cn/bunny/services/service/system/impl/UserServiceImpl.java | 2 +- 54 files changed, 54 insertions(+), 53 deletions(-) rename auth-core/src/main/java/cn/bunny/services/domain/common/{model/vo/result => enums}/ResultCodeEnum.java (98%) diff --git a/auh-api/src/main/java/cn/bunny/services/controller/configuration/ConfigurationController.java b/auh-api/src/main/java/cn/bunny/services/controller/configuration/ConfigurationController.java index 204aa4c..b5abb4f 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/configuration/ConfigurationController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/configuration/ConfigurationController.java @@ -3,7 +3,7 @@ package cn.bunny.services.controller.configuration; import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto; import cn.bunny.services.domain.system.configuration.entity.WebConfiguration; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.configuration.ConfigurationService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java b/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java index f16512e..72e0c5e 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.domain.system.email.vo.EmailTemplateVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.configuration.EmailTemplateService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailUsersController.java b/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailUsersController.java index 23666de..2f3d338 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailUsersController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailUsersController.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.email.entity.EmailUsers; import cn.bunny.services.domain.system.email.vo.EmailUsersVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.configuration.EmailUsersService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nController.java b/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nController.java index 35ec6c5..767e4db 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nController.java @@ -8,7 +8,7 @@ import cn.bunny.services.domain.system.i18n.entity.I18n; import cn.bunny.services.domain.system.i18n.vo.I18nVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.configuration.I18nService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nTypeController.java b/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nTypeController.java index abbdf28..a422b0d 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nTypeController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/configuration/I18nTypeController.java @@ -5,7 +5,7 @@ import cn.bunny.services.domain.system.i18n.dto.I18nTypeDto; import cn.bunny.services.domain.system.i18n.dto.I18nTypeUpdateDto; import cn.bunny.services.domain.system.i18n.vo.I18nTypeVo; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.configuration.I18nTypeService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/configuration/MenuIconController.java b/auh-api/src/main/java/cn/bunny/services/controller/configuration/MenuIconController.java index a2ca7a6..d3468d4 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/configuration/MenuIconController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/configuration/MenuIconController.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.menuIcon.entity.MenuIcon; import cn.bunny.services.domain.system.menuIcon.vo.MenuIconVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.configuration.MenuIconService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/log/ScheduleExecuteLogController.java b/auh-api/src/main/java/cn/bunny/services/controller/log/ScheduleExecuteLogController.java index 48be47b..67937e8 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/log/ScheduleExecuteLogController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/log/ScheduleExecuteLogController.java @@ -5,7 +5,7 @@ import cn.bunny.services.domain.system.log.entity.ScheduleExecuteLog; import cn.bunny.services.domain.system.log.vo.ScheduleExecuteLogVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.log.ScheduleExecuteLogService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/log/UserLoginLogController.java b/auh-api/src/main/java/cn/bunny/services/controller/log/UserLoginLogController.java index d3bca6f..2b3a8ab 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/log/UserLoginLogController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/log/UserLoginLogController.java @@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.log.vo.UserLoginLogLocalVo; import cn.bunny.services.domain.system.log.vo.UserLoginLogVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.log.UserLoginLogService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/message/MessageController.java b/auh-api/src/main/java/cn/bunny/services/controller/message/MessageController.java index 483d6a0..a24b431 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/message/MessageController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/message/MessageController.java @@ -9,7 +9,7 @@ import cn.bunny.services.domain.system.message.vo.MessageReceivedWithUserVo; import cn.bunny.services.domain.system.message.vo.MessageVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.message.MessageService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/message/MessageReceivedController.java b/auh-api/src/main/java/cn/bunny/services/controller/message/MessageReceivedController.java index 1bd33db..1e95714 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/message/MessageReceivedController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/message/MessageReceivedController.java @@ -8,7 +8,7 @@ import cn.bunny.services.domain.system.message.vo.MessageReceivedWithMessageVo; import cn.bunny.services.domain.system.message.vo.MessageUserVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.message.MessageReceivedService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/message/MessageTypeController.java b/auh-api/src/main/java/cn/bunny/services/controller/message/MessageTypeController.java index 8e3777d..f4c93c5 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/message/MessageTypeController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/message/MessageTypeController.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.message.entity.MessageType; import cn.bunny.services.domain.system.message.vo.MessageTypeVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.message.MessageTypeService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java b/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java index f661380..060faa0 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersController.java @@ -3,7 +3,7 @@ package cn.bunny.services.controller.schedule; import cn.bunny.services.aop.scanner.QuartzSchedulersScanner; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.quartz.dto.SchedulersAddDto; import cn.bunny.services.domain.system.quartz.dto.SchedulersDto; import cn.bunny.services.domain.system.quartz.dto.SchedulersUpdateDto; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersGroupController.java b/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersGroupController.java index 6b5b772..f76ac88 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersGroupController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/schedule/SchedulersGroupController.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.quartz.entity.SchedulersGroup; import cn.bunny.services.domain.system.quartz.vo.SchedulersGroupVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.schedule.SchedulersGroupService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/DeptController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/DeptController.java index 1dbf324..7ed5acf 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/DeptController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/DeptController.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.system.entity.Dept; import cn.bunny.services.domain.system.system.vo.DeptVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.system.DeptService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/FilesController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/FilesController.java index 2d5c137..0a8beb4 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/FilesController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/FilesController.java @@ -10,7 +10,7 @@ import cn.bunny.services.domain.system.files.vo.FileInfoVo; import cn.bunny.services.domain.system.files.vo.FilesVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.system.FilesService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/PermissionController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/PermissionController.java index d738395..1fa1efe 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/PermissionController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/PermissionController.java @@ -4,7 +4,7 @@ import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner; import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.power.PermissionAddDto; import cn.bunny.services.domain.system.system.dto.power.PermissionDto; import cn.bunny.services.domain.system.system.dto.power.PermissionUpdateBatchByParentIdDto; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/RoleController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/RoleController.java index 6f398e5..6e51d76 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/RoleController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/RoleController.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.system.entity.Role; import cn.bunny.services.domain.system.system.vo.RoleVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.system.RoleService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/RouterController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/RouterController.java index 2bb8b66..ce7afcc 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/RouterController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/RouterController.java @@ -5,7 +5,7 @@ import cn.bunny.services.domain.system.system.dto.router.RouterUpdateDto; import cn.bunny.services.domain.system.system.vo.router.RouterManageVo; import cn.bunny.services.domain.system.system.vo.router.WebUserRouterVo; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.system.RouterService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java index a0436d7..45e8c0a 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java @@ -3,7 +3,7 @@ package cn.bunny.services.controller.system; import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.AdminUserAddDto; import cn.bunny.services.domain.system.system.dto.user.AdminUserDto; import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateDto; diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/UserLoginController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/UserLoginController.java index d3f0d74..0013dbc 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/UserLoginController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/UserLoginController.java @@ -3,7 +3,7 @@ package cn.bunny.services.controller.system; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateByLocalUserDto; import cn.bunny.services.domain.system.system.dto.user.LoginDto; import cn.bunny.services.domain.system.system.dto.user.RefreshTokenDto; diff --git a/auth-core/src/main/java/cn/bunny/services/domain/common/model/vo/result/ResultCodeEnum.java b/auth-core/src/main/java/cn/bunny/services/domain/common/enums/ResultCodeEnum.java similarity index 98% rename from auth-core/src/main/java/cn/bunny/services/domain/common/model/vo/result/ResultCodeEnum.java rename to auth-core/src/main/java/cn/bunny/services/domain/common/enums/ResultCodeEnum.java index c2ec9a3..042e339 100644 --- a/auth-core/src/main/java/cn/bunny/services/domain/common/model/vo/result/ResultCodeEnum.java +++ b/auth-core/src/main/java/cn/bunny/services/domain/common/enums/ResultCodeEnum.java @@ -1,4 +1,4 @@ -package cn.bunny.services.domain.common.model.vo.result; +package cn.bunny.services.domain.common.enums; import lombok.Getter; diff --git a/auth-core/src/main/java/cn/bunny/services/domain/common/model/vo/result/Result.java b/auth-core/src/main/java/cn/bunny/services/domain/common/model/vo/result/Result.java index b1d7bc3..f9fc571 100644 --- a/auth-core/src/main/java/cn/bunny/services/domain/common/model/vo/result/Result.java +++ b/auth-core/src/main/java/cn/bunny/services/domain/common/model/vo/result/Result.java @@ -1,5 +1,6 @@ package cn.bunny.services.domain.common.model.vo.result; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/auth-core/src/main/java/cn/bunny/services/exception/AuthCustomerException.java b/auth-core/src/main/java/cn/bunny/services/exception/AuthCustomerException.java index a13d738..941c59a 100644 --- a/auth-core/src/main/java/cn/bunny/services/exception/AuthCustomerException.java +++ b/auth-core/src/main/java/cn/bunny/services/exception/AuthCustomerException.java @@ -1,6 +1,6 @@ package cn.bunny.services.exception; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; diff --git a/auth-core/src/main/java/cn/bunny/services/exception/GlobalExceptionHandler.java b/auth-core/src/main/java/cn/bunny/services/exception/GlobalExceptionHandler.java index 4c19899..87a4670 100644 --- a/auth-core/src/main/java/cn/bunny/services/exception/GlobalExceptionHandler.java +++ b/auth-core/src/main/java/cn/bunny/services/exception/GlobalExceptionHandler.java @@ -2,7 +2,7 @@ package cn.bunny.services.exception; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.context.BaseContext; import lombok.extern.slf4j.Slf4j; import org.mybatis.spring.MyBatisSystemException; diff --git a/auth-core/src/main/java/cn/bunny/services/minio/MinioService.java b/auth-core/src/main/java/cn/bunny/services/minio/MinioService.java index 892ab09..b9fbb56 100644 --- a/auth-core/src/main/java/cn/bunny/services/minio/MinioService.java +++ b/auth-core/src/main/java/cn/bunny/services/minio/MinioService.java @@ -2,7 +2,7 @@ package cn.bunny.services.minio; import cn.bunny.services.domain.common.constant.MinioConstant; import cn.bunny.services.domain.common.model.dto.minio.MinioUploadFileInfo; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import io.minio.*; import io.minio.messages.DeleteError; diff --git a/auth-core/src/main/java/cn/bunny/services/utils/JwtTokenUtil.java b/auth-core/src/main/java/cn/bunny/services/utils/JwtTokenUtil.java index d052a09..5f0d2ea 100644 --- a/auth-core/src/main/java/cn/bunny/services/utils/JwtTokenUtil.java +++ b/auth-core/src/main/java/cn/bunny/services/utils/JwtTokenUtil.java @@ -1,6 +1,6 @@ package cn.bunny.services.utils; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; diff --git a/service/src/main/java/cn/bunny/services/aop/scanner/AbstractAnnotationScanner.java b/service/src/main/java/cn/bunny/services/aop/scanner/AbstractAnnotationScanner.java index affb415..94cdf47 100644 --- a/service/src/main/java/cn/bunny/services/aop/scanner/AbstractAnnotationScanner.java +++ b/service/src/main/java/cn/bunny/services/aop/scanner/AbstractAnnotationScanner.java @@ -1,6 +1,6 @@ package cn.bunny.services.aop.scanner; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; diff --git a/service/src/main/java/cn/bunny/services/excel/RoleExcelListener.java b/service/src/main/java/cn/bunny/services/excel/RoleExcelListener.java index 984a1f0..9ebbe95 100644 --- a/service/src/main/java/cn/bunny/services/excel/RoleExcelListener.java +++ b/service/src/main/java/cn/bunny/services/excel/RoleExcelListener.java @@ -1,7 +1,7 @@ package cn.bunny.services.excel; import cn.bunny.services.domain.common.model.dto.excel.RoleExcel; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.entity.Role; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.service.system.RoleService; diff --git a/service/src/main/java/cn/bunny/services/security/config/MethodSecurityConfig.java b/service/src/main/java/cn/bunny/services/security/config/MethodSecurityConfig.java index be361ab..355e494 100644 --- a/service/src/main/java/cn/bunny/services/security/config/MethodSecurityConfig.java +++ b/service/src/main/java/cn/bunny/services/security/config/MethodSecurityConfig.java @@ -1,6 +1,6 @@ package cn.bunny.services.security.config; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.mapper.system.UserMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; diff --git a/service/src/main/java/cn/bunny/services/security/exception/CustomAuthenticationException.java b/service/src/main/java/cn/bunny/services/security/exception/CustomAuthenticationException.java index 8ec2828..05130a4 100644 --- a/service/src/main/java/cn/bunny/services/security/exception/CustomAuthenticationException.java +++ b/service/src/main/java/cn/bunny/services/security/exception/CustomAuthenticationException.java @@ -1,6 +1,6 @@ package cn.bunny.services.security.exception; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import lombok.Getter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; diff --git a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java index b4482ca..e9a9ed7 100644 --- a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java +++ b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAccessDeniedHandler.java @@ -1,7 +1,7 @@ package cn.bunny.services.security.handelr; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import com.alibaba.fastjson2.JSON; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationEntryPoint.java b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationEntryPoint.java index 166c665..b2a64b8 100644 --- a/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationEntryPoint.java +++ b/service/src/main/java/cn/bunny/services/security/handelr/SecurityAuthenticationEntryPoint.java @@ -1,7 +1,7 @@ package cn.bunny.services.security.handelr; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.security.exception.CustomAuthenticationException; import cn.bunny.services.utils.ResponseUtil; import jakarta.servlet.http.HttpServletRequest; diff --git a/service/src/main/java/cn/bunny/services/security/service/CustomAuthorizationManagerServiceImpl.java b/service/src/main/java/cn/bunny/services/security/service/CustomAuthorizationManagerServiceImpl.java index d0b2549..c08b633 100644 --- a/service/src/main/java/cn/bunny/services/security/service/CustomAuthorizationManagerServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/security/service/CustomAuthorizationManagerServiceImpl.java @@ -3,7 +3,7 @@ package cn.bunny.services.security.service; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.model.dto.security.TokenInfo; import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.security.exception.CustomAuthenticationException; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; diff --git a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java index 4a321e4..f6586d0 100644 --- a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java +++ b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java @@ -3,7 +3,7 @@ package cn.bunny.services.security.service; import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.model.dto.security.TokenInfo; import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.security.exception.CustomAuthenticationException; import cn.bunny.services.utils.JwtTokenUtil; import com.alibaba.fastjson2.JSON; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/helper/email/AbstractSenderEmailTemplate.java b/service/src/main/java/cn/bunny/services/service/configuration/helper/email/AbstractSenderEmailTemplate.java index be85b5e..1665ad0 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/helper/email/AbstractSenderEmailTemplate.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/helper/email/AbstractSenderEmailTemplate.java @@ -3,7 +3,7 @@ package cn.bunny.services.service.configuration.helper.email; import cn.bunny.services.config.mail.MailSenderConfiguration; import cn.bunny.services.domain.common.model.dto.email.EmailSend; import cn.bunny.services.domain.common.model.dto.email.EmailSendInit; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.domain.system.email.entity.EmailUsers; import cn.bunny.services.exception.AuthCustomerException; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/ConfigurationServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/ConfigurationServiceImpl.java index f017a08..5f34b98 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/ConfigurationServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/ConfigurationServiceImpl.java @@ -3,7 +3,7 @@ package cn.bunny.services.service.configuration.impl; import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto; import cn.bunny.services.domain.system.configuration.entity.WebConfiguration; import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.service.configuration.ConfigurationService; import com.alibaba.fastjson2.JSON; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailTemplateServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailTemplateServiceImpl.java index b8eca77..2cfab02 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailTemplateServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailTemplateServiceImpl.java @@ -7,7 +7,7 @@ import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.domain.system.email.vo.EmailTemplateVo; import cn.bunny.services.domain.common.enums.EmailTemplateEnums; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.EmailTemplateMapper; import cn.bunny.services.service.configuration.EmailTemplateService; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailUsersServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailUsersServiceImpl.java index 78b3dd1..9684761 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailUsersServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/EmailUsersServiceImpl.java @@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.email.dto.EmailUsersUpdateDto; import cn.bunny.services.domain.system.email.entity.EmailUsers; import cn.bunny.services.domain.system.email.vo.EmailUsersVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.EmailUsersMapper; import cn.bunny.services.service.configuration.EmailUsersService; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java index 7eeb35e..313658e 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java @@ -4,7 +4,7 @@ import cn.bunny.services.domain.common.constant.FileType; import cn.bunny.services.domain.common.model.dto.excel.I18nExcel; import cn.bunny.services.domain.common.model.entity.BaseEntity; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.i18n.dto.I18nAddDto; import cn.bunny.services.domain.system.i18n.dto.I18nDto; import cn.bunny.services.domain.system.i18n.dto.I18nUpdateByFileDto; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java index 1baf30a..93de871 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java @@ -5,7 +5,7 @@ import cn.bunny.services.domain.system.i18n.dto.I18nTypeDto; import cn.bunny.services.domain.system.i18n.dto.I18nTypeUpdateDto; import cn.bunny.services.domain.system.i18n.entity.I18nType; import cn.bunny.services.domain.system.i18n.vo.I18nTypeVo; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.I18nTypeMapper; import cn.bunny.services.service.configuration.I18nTypeService; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/MenuIconServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/MenuIconServiceImpl.java index e0d408d..ebbe334 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/MenuIconServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/MenuIconServiceImpl.java @@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.menuIcon.dto.MenuIconUpdateDto; import cn.bunny.services.domain.system.menuIcon.entity.MenuIcon; import cn.bunny.services.domain.system.menuIcon.vo.MenuIconVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.MenuIconMapper; import cn.bunny.services.service.configuration.MenuIconService; diff --git a/service/src/main/java/cn/bunny/services/service/message/impl/MessageReceivedServiceImpl.java b/service/src/main/java/cn/bunny/services/service/message/impl/MessageReceivedServiceImpl.java index 323a89f..5b3a03f 100644 --- a/service/src/main/java/cn/bunny/services/service/message/impl/MessageReceivedServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/message/impl/MessageReceivedServiceImpl.java @@ -2,7 +2,7 @@ package cn.bunny.services.service.message.impl; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.message.dto.MessageReceivedDto; import cn.bunny.services.domain.system.message.dto.MessageReceivedUpdateDto; import cn.bunny.services.domain.system.message.dto.MessageUserDto; diff --git a/service/src/main/java/cn/bunny/services/service/message/impl/MessageServiceImpl.java b/service/src/main/java/cn/bunny/services/service/message/impl/MessageServiceImpl.java index f9405e9..1aa6baf 100644 --- a/service/src/main/java/cn/bunny/services/service/message/impl/MessageServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/message/impl/MessageServiceImpl.java @@ -3,7 +3,7 @@ package cn.bunny.services.service.message.impl; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.model.entity.BaseEntity; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.message.dto.MessageAddDto; import cn.bunny.services.domain.system.message.dto.MessageDto; import cn.bunny.services.domain.system.message.dto.MessageUpdateDto; diff --git a/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java b/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java index 1aa16f5..ebbfc76 100644 --- a/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/schedule/impl/SchedulersServiceImpl.java @@ -1,7 +1,7 @@ package cn.bunny.services.service.schedule.impl; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.quartz.dto.SchedulersAddDto; import cn.bunny.services.domain.system.quartz.dto.SchedulersDto; import cn.bunny.services.domain.system.quartz.dto.SchedulersUpdateDto; diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java b/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java index 1c7d3b8..9659316 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java +++ b/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java @@ -1,7 +1,7 @@ package cn.bunny.services.service.system.helper.login; import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.LoginDto; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.mapper.system.UserMapper; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java index f41bb22..6b2e078 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java @@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.system.dto.dept.DeptUpdateDto; import cn.bunny.services.domain.system.system.entity.Dept; import cn.bunny.services.domain.system.system.vo.DeptVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.system.DeptMapper; import cn.bunny.services.mapper.system.UserDeptMapper; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/FilesServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/FilesServiceImpl.java index 05787ea..b171d90 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/FilesServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/FilesServiceImpl.java @@ -3,7 +3,7 @@ package cn.bunny.services.service.system.impl; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.model.dto.minio.MinioUploadFileInfo; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.files.dto.FileUploadDto; import cn.bunny.services.domain.system.files.dto.FilesAddDto; import cn.bunny.services.domain.system.files.dto.FilesDto; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java index 38b363c..4e095f6 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java @@ -3,7 +3,7 @@ package cn.bunny.services.service.system.impl; import cn.bunny.services.domain.common.constant.FileType; import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.power.PermissionAddDto; import cn.bunny.services.domain.system.system.dto.power.PermissionDto; import cn.bunny.services.domain.system.system.dto.power.PermissionUpdateBatchByParentIdDto; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java index 236c7a4..158d2c2 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java @@ -2,7 +2,7 @@ package cn.bunny.services.service.system.impl; import cn.bunny.services.domain.common.model.dto.excel.RoleExcel; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.role.RoleAddDto; import cn.bunny.services.domain.system.system.dto.role.RoleDto; import cn.bunny.services.domain.system.system.dto.role.RoleUpdateDto; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RouterRoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RouterRoleServiceImpl.java index d8940f6..733e548 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RouterRoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RouterRoleServiceImpl.java @@ -1,7 +1,7 @@ package cn.bunny.services.service.system.impl; import cn.bunny.services.domain.system.system.entity.RouterRole; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.system.RouterRoleMapper; import cn.bunny.services.service.system.RouterRoleService; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java index 96d74e5..a176923 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java @@ -1,6 +1,6 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.router.RouterAddDto; import cn.bunny.services.domain.system.system.dto.router.RouterUpdateDto; import cn.bunny.services.domain.system.system.entity.router.Router; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java index e1d3ed5..4e816de 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java @@ -6,7 +6,7 @@ import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.enums.EmailTemplateEnums; import cn.bunny.services.domain.common.enums.LoginEnums; import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateByLocalUserDto; import cn.bunny.services.domain.system.system.dto.user.LoginDto; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java index 05fe733..c6cc21a 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java @@ -3,7 +3,7 @@ package cn.bunny.services.service.system.impl; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.AssignRolesToUsersDto; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.domain.system.system.entity.UserRole; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java index 464b850..6a3ca71 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java @@ -5,7 +5,7 @@ import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.ResultCodeEnum; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.files.dto.FileUploadDto; import cn.bunny.services.domain.system.files.vo.FileInfoVo; import cn.bunny.services.domain.system.log.entity.UserLoginLog; From 35e08940e027710b152a5281473c73b6f079dfde Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Mon, 5 May 2025 21:57:43 +0800 Subject: [PATCH 2/4] =?UTF-8?q?:passport=5Fcontrol:=20feat:=20=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E6=9E=9A=E4=B8=BE=E6=9B=B4=E6=8D=A2=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/system/UserController.java | 7 +- .../java/AbstractPermissionCheckHandler.java | 10 - .../cn/bunny/services/config/WebConfig.java | 27 --- .../bunny/services/controller/LoginTest.java | 37 --- .../controller/TestControllerTest.java | 56 ----- .../ConfigurationControllerTest.java | 163 ------------- .../EmailTemplateControllerTest.java | 215 ------------------ .../log/UserLoginLogControllerTest.java | 179 --------------- .../controller/system/UserControllerTest.java | 58 ----- .../bunny/services/utils/TokenUtilsTest.java | 25 -- .../test/java/impl/I18nServiceImplTest.java | 55 ----- .../src/test/java/system/UserServiceTest.java | 33 --- auth-core/pom.xml | 6 + .../services/config/RedisConfiguration.java | 8 +- .../common/constant/RedisUserConstant.java | 54 ++++- .../domain/common/enums/ResultCodeEnum.java | 4 +- .../mapper/system/RolePermissionMapper.java | 14 +- .../mapper/system/UserRoleMapper.java | 8 + .../mapper/system/PermissionMapper.xml | 14 +- .../resources/mapper/system/RoleMapper.xml | 10 +- .../mapper/system/RolePermissionMapper.xml | 15 +- .../mapper/system/UserRoleMapper.xml | 8 + pom.xml | 2 +- service/pom.xml | 5 - .../services/cache/EmailCacheService.java | 58 +++++ .../bunny/services/cache}/RedisService.java | 4 +- .../cache/UserAuthorizationCacheService.java | 121 ++++++++++ .../UserCacheService.java} | 163 +++++++------ .../service/PermissionCheckService.java | 19 +- .../service/TokenValidationService.java | 15 +- .../configuration/impl/I18nServiceImpl.java | 13 +- .../impl/I18nTypeServiceImpl.java | 23 +- .../service/system/UserLoginService.java | 5 +- .../services/service/system/UserService.java | 3 +- ...RoleHelper.java => RoleServiceHelper.java} | 61 +---- .../service/system/helper/RouterHelper.java | 3 +- .../system/helper/UserServiceHelper.java | 103 +++++++++ .../helper/login/EmailLoginStrategy.java | 19 +- .../system/helper/login/LoginStrategy.java | 2 +- .../system/helper/role/RoleUpdateHandler.java | 59 ----- .../system/helper/role/RoleUpdatedEvent.java | 17 -- .../service/system/impl/DeptServiceImpl.java | 13 +- .../system/impl/PermissionServiceImpl.java | 58 +++-- .../impl/RolePermissionServiceImpl.java | 15 +- .../service/system/impl/RoleServiceImpl.java | 81 ++++--- .../system/impl/RouterServiceImpl.java | 9 +- .../system/impl/UserLoginServiceImpl.java | 93 +++++--- .../system/impl/UserRoleServiceImpl.java | 23 +- .../service/system/impl/UserServiceImpl.java | 98 ++++---- 49 files changed, 768 insertions(+), 1323 deletions(-) delete mode 100644 auh-api/src/test/java/AbstractPermissionCheckHandler.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/config/WebConfig.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/controller/LoginTest.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/controller/TestControllerTest.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/controller/configuration/ConfigurationControllerTest.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/controller/configuration/EmailTemplateControllerTest.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/controller/log/UserLoginLogControllerTest.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/controller/system/UserControllerTest.java delete mode 100644 auh-api/src/test/java/cn/bunny/services/utils/TokenUtilsTest.java delete mode 100644 auh-api/src/test/java/impl/I18nServiceImplTest.java delete mode 100644 auh-api/src/test/java/system/UserServiceTest.java create mode 100644 service/src/main/java/cn/bunny/services/cache/EmailCacheService.java rename {auth-core/src/main/java/cn/bunny/services/redis => service/src/main/java/cn/bunny/services/cache}/RedisService.java (93%) create mode 100644 service/src/main/java/cn/bunny/services/cache/UserAuthorizationCacheService.java rename service/src/main/java/cn/bunny/services/{service/system/helper/UserLoginHelper.java => cache/UserCacheService.java} (57%) rename service/src/main/java/cn/bunny/services/service/system/helper/{role/RoleHelper.java => RoleServiceHelper.java} (51%) create mode 100644 service/src/main/java/cn/bunny/services/service/system/helper/UserServiceHelper.java delete mode 100644 service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdateHandler.java delete mode 100644 service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdatedEvent.java diff --git a/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java b/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java index 45e8c0a..d673096 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/system/UserController.java @@ -1,9 +1,8 @@ package cn.bunny.services.controller.system; -import cn.bunny.services.domain.common.model.vo.LoginVo; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.AdminUserAddDto; import cn.bunny.services.domain.system.system.dto.user.AdminUserDto; import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateDto; @@ -91,13 +90,13 @@ public class UserController { @Operation(summary = "已登录用户", description = "查询缓存中已登录用户", tags = "user::query") @GetMapping("getCacheUserPage/{page}/{limit}") - public Result> getCacheUserPage( + public Result> getCacheUserPage( @Parameter(name = "page", description = "当前页", required = true) @PathVariable("page") Integer page, @Parameter(name = "limit", description = "每页记录数", required = true) @PathVariable("limit") Integer limit) { Page pageParams = new Page<>(page, limit); - PageResult pageResult = userService.getCacheUserPage(pageParams); + PageResult pageResult = userService.getCacheUserPage(pageParams); return Result.success(pageResult); } diff --git a/auh-api/src/test/java/AbstractPermissionCheckHandler.java b/auh-api/src/test/java/AbstractPermissionCheckHandler.java deleted file mode 100644 index dbc3fa1..0000000 --- a/auh-api/src/test/java/AbstractPermissionCheckHandler.java +++ /dev/null @@ -1,10 +0,0 @@ -public abstract class AbstractPermissionCheckHandler { - - private AbstractPermissionCheckHandler abstractPermissionCheckHandler; - - public AbstractPermissionCheckHandler(AbstractPermissionCheckHandler abstractPermissionCheckHandler) { - this.abstractPermissionCheckHandler = abstractPermissionCheckHandler; - } - - abstract protected void checkPermission(String requestUrl); -} diff --git a/auh-api/src/test/java/cn/bunny/services/config/WebConfig.java b/auh-api/src/test/java/cn/bunny/services/config/WebConfig.java deleted file mode 100644 index 63dc5d6..0000000 --- a/auh-api/src/test/java/cn/bunny/services/config/WebConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.bunny.services.config; - -import cn.bunny.services.utils.TokenUtilsTest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.web.client.RestTemplate; - -// @TestConfiguration -// public class WebConfig { -// @Value("${server.port}") -// private String port; -// -// @Autowired -// private TokenUtilsTest tokenUtils; -// -// @Bean -// public RestTemplate restTemplate(RestTemplateBuilder builder) { -// String token = tokenUtils.getToken(); -// return builder.rootUri("http://localhost:" + port) -// .defaultHeader("token", token) -// .defaultHeader("Content-Type", "application/json") -// .build(); -// } -// } diff --git a/auh-api/src/test/java/cn/bunny/services/controller/LoginTest.java b/auh-api/src/test/java/cn/bunny/services/controller/LoginTest.java deleted file mode 100644 index ed8ea5e..0000000 --- a/auh-api/src/test/java/cn/bunny/services/controller/LoginTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.bunny.services.controller; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.openqa.selenium.chrome.ChromeDriver; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; - -import java.time.Duration; -import java.util.concurrent.TimeUnit; - -@SpringBootTest -@AutoConfigureMockMvc -public class LoginTest { - private ChromeDriver chromeDriver; - - @BeforeEach - void setUpMockMvc() { - chromeDriver = new ChromeDriver(); - } - - @AfterEach - void tearDown() { - chromeDriver.quit(); - } - - // 测试登录页面 - @Test - // @WithMockUser(username = "Administrator", password = "admin123", roles = "admin") - // @WithUserDetails("Administrator") - void testLogin() throws InterruptedException { - chromeDriver.get("http://localhost:7000/"); - TimeUnit.MINUTES.sleep(100); - chromeDriver.manage().timeouts().implicitlyWait(Duration.of(1000L, TimeUnit.SECONDS.toChronoUnit())); - } -} diff --git a/auh-api/src/test/java/cn/bunny/services/controller/TestControllerTest.java b/auh-api/src/test/java/cn/bunny/services/controller/TestControllerTest.java deleted file mode 100644 index fbc4af4..0000000 --- a/auh-api/src/test/java/cn/bunny/services/controller/TestControllerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package cn.bunny.services.controller; - -import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner; -import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo; -import cn.bunny.services.domain.system.system.entity.Permission; -import cn.bunny.services.service.system.PermissionService; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.util.List; - -@SpringBootTest -class TestControllerTest { - - @Autowired - private PermissionService permissionService; - - @Test - void test1() { - List list = ControllerApiPermissionScanner.getSystemApiInfoList(); - list.forEach(parent -> { - String parentPath = parent.getPath(); - String powerCode = parentPath.replace("/api/", "").replace("/**", ""); - powerCode = "user::" + powerCode; - - Permission permission = new Permission(); - permission.setParentId(0L); - permission.setPowerCode(powerCode); - permission.setPowerName(parent.getSummary()); - permission.setRequestUrl(parentPath); - permissionService.saveOrUpdate(permission); - // System.out.println(permission); - - List permissionList = parent.getChildren().stream() - .map(children -> { - Permission childrenPermission = new Permission(); - childrenPermission.setParentId(permission.getId()); - childrenPermission.setPowerName(children.getSummary()); - if (!children.getPowerCodes().isEmpty()) { - String ChildrenPowerCode = children.getPowerCodes().get(0); - childrenPermission.setPowerCode(ChildrenPowerCode); - } - - String childrenPath = children.getPath(); - childrenPermission.setRequestUrl(childrenPath); - childrenPermission.setRequestMethod(children.getHttpMethod()); - - return childrenPermission; - }) - .toList(); - // System.out.println(JSON.toJSONString(permissionList)); - permissionService.saveOrUpdateBatch(permissionList); - }); - } -} \ No newline at end of file diff --git a/auh-api/src/test/java/cn/bunny/services/controller/configuration/ConfigurationControllerTest.java b/auh-api/src/test/java/cn/bunny/services/controller/configuration/ConfigurationControllerTest.java deleted file mode 100644 index 5c9f0bb..0000000 --- a/auh-api/src/test/java/cn/bunny/services/controller/configuration/ConfigurationControllerTest.java +++ /dev/null @@ -1,163 +0,0 @@ -package cn.bunny.services.controller.configuration; - -import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto; -import cn.bunny.services.domain.system.configuration.entity.WebConfiguration; -import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.utils.TokenUtilsTest; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.TypeReference; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -import java.util.concurrent.atomic.AtomicReference; - -@SpringBootTest -@WebAppConfiguration -class ConfigurationControllerTest { - private static final String prefix = "/api/config"; - - @Autowired - private WebApplicationContext webApplicationContext; - - @Autowired - private TokenUtilsTest tokenUtils; - - private MockMvc mockMvc; - - private String token; - - @BeforeEach - void setUpMockMvc() { - token = tokenUtils.getToken(); - mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build(); - } - - @Test - void webConfig() throws Exception { - mockMvc.perform(MockMvcRequestBuilders - .get(prefix + "/noAuth/webConfig") - .header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - MockHttpServletResponse response = result.getResponse(); - String contentAsString = response.getContentAsString(); - - WebConfiguration webConfiguration = JSON.parseObject(contentAsString, WebConfiguration.class); - - if (!webConfiguration.getTitle().equals("BunnyAdmin")) { - throw new Exception(); - } - - System.out.println(webConfiguration); - }); - } - - @Test - void getWebConfig() throws Exception { - mockMvc.perform(MockMvcRequestBuilders - .request(HttpMethod.GET, prefix + "/getWebConfig") - .header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - MockHttpServletResponse response = result.getResponse(); - String contentAsString = response.getContentAsString(); - - Result webConfigurationResult = JSON.parseObject(contentAsString, new TypeReference<>() { - }); - - if (!webConfigurationResult.getCode().equals(200)) { - throw new Exception(); - } - - if (!webConfigurationResult.getData().getShowModel().equals("smart")) { - throw new Exception(); - } - System.out.println(contentAsString); - }); - } - - @Test - void updateWebConfiguration() throws Exception { - AtomicReference webConfigurationDto = new AtomicReference<>(); - String testTitle = "修改的之"; - - // 获取原本的配置信息 - mockMvc.perform(MockMvcRequestBuilders - .request(HttpMethod.GET, prefix + "/getWebConfig") - .header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - MockHttpServletResponse response = result.getResponse(); - String contentAsString = response.getContentAsString(); - - System.out.println(contentAsString); - - Result webConfigurationResult = JSON.parseObject(contentAsString, new TypeReference<>() { - }); - - WebConfigurationDto dto = new WebConfigurationDto(); - BeanUtils.copyProperties(webConfigurationResult.getData(), dto); - - webConfigurationDto.set(dto); - }); - - // 修改原本的测试内容 - webConfigurationDto.get().setTitle(testTitle); - - // 测试修改方法 - mockMvc.perform(MockMvcRequestBuilders.put(prefix + "/updateWebConfiguration") - .contentType(MediaType.APPLICATION_JSON) - .content(JSON.toJSONString(webConfigurationDto.get())) - .header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - String contentAsString = result.getResponse().getContentAsString(); - - System.out.println(contentAsString); - - Result stringResult = JSON.parseObject(contentAsString, new TypeReference<>() { - }); - - if (!stringResult.getCode().equals(200)) { - throw new Exception(); - } - }); - - // 验证是否修改成功 - mockMvc.perform(MockMvcRequestBuilders - .request(HttpMethod.GET, prefix + "/getWebConfig") - .header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - MockHttpServletResponse response = result.getResponse(); - String contentAsString = response.getContentAsString(); - - Result webConfigurationResult = JSON.parseObject(contentAsString, new TypeReference<>() { - }); - - if (!webConfigurationResult.getCode().equals(200)) { - throw new Exception(); - } - - if (!webConfigurationResult.getData().getTitle().equals(testTitle)) { - throw new Exception(); - } - System.out.println(contentAsString); - }); - } -} \ No newline at end of file diff --git a/auh-api/src/test/java/cn/bunny/services/controller/configuration/EmailTemplateControllerTest.java b/auh-api/src/test/java/cn/bunny/services/controller/configuration/EmailTemplateControllerTest.java deleted file mode 100644 index e853091..0000000 --- a/auh-api/src/test/java/cn/bunny/services/controller/configuration/EmailTemplateControllerTest.java +++ /dev/null @@ -1,215 +0,0 @@ -package cn.bunny.services.controller.configuration; - -import cn.bunny.services.domain.system.email.dto.EmailTemplateAddDto; -import cn.bunny.services.domain.system.email.dto.EmailTemplateUpdateDto; -import cn.bunny.services.domain.system.email.vo.EmailTemplateVo; -import cn.bunny.services.domain.common.enums.EmailTemplateEnums; -import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.utils.TokenUtilsTest; -import cn.hutool.crypto.digest.MD5; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; -import com.alibaba.fastjson2.TypeReference; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.util.UriComponentsBuilder; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -@SpringBootTest -@WebAppConfiguration -class EmailTemplateControllerTest { - private static final String prefix = "/api/emailTemplate"; - - private String token; - - private MockMvc mockMvc; - - @Autowired - private WebApplicationContext webApplicationContext; - - @Autowired - private TokenUtilsTest tokenUtilsTest; - - @Autowired - private RestTemplate restTemplate; - - @BeforeEach - void setUp() { - token = tokenUtilsTest.getToken(); - mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build(); - } - - @AfterEach - void tearDown() { - - } - - @Test - void getEmailTemplatePage() throws Exception { - String api = prefix + "/getEmailTemplateList/1/10"; - - mockMvc.perform(MockMvcRequestBuilders - .get(api) - .header("token", token) - .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE) - .param("type", "code")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - String contentAsString = result.getResponse().getContentAsString(); - JSONObject jsonObject = JSONObject.parseObject(contentAsString); - - if (jsonObject == null) { - throw new Exception(contentAsString); - } - System.out.println(jsonObject); - }); - } - - @Test - void getEmailTypeList() throws Exception { - String api = prefix + "/getEmailTypes"; - - mockMvc.perform(MockMvcRequestBuilders.get(api).header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - String contentAsString = result.getResponse().getContentAsString(); - JSONObject jsonObject = JSONObject.parseObject(contentAsString); - - if (jsonObject == null) { - throw new Exception(contentAsString); - } - - System.out.println(jsonObject); - }); - } - - @Test - void addEmailTemplate() throws Exception { - String api = prefix + "/addEmailTemplate"; - - EmailTemplateAddDto dto = EmailTemplateAddDto.builder() - .emailUser(2L) - .body("哈哈哈") - .templateName("测试") - .subject("test") - .type(EmailTemplateEnums.NOTIFICATION.getType()) - .isDefault(false) - .build(); - - mockMvc.perform(MockMvcRequestBuilders - .post(api) - .header("token", token) - .content(JSONObject.toJSONString(dto)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - String contentAsString = result.getResponse().getContentAsString(); - JSONObject jsonObject = JSONObject.parseObject(contentAsString); - - System.out.println(jsonObject); - }); - - getEmailTemplatePage(); - } - - @Test - void updateEmailTemplate() throws Exception { - String api = prefix + "/updateEmailTemplate"; - String restTemplateApi = prefix + "/getEmailTemplateList/1/10"; - - String url = UriComponentsBuilder.fromUriString(restTemplateApi) - .queryParam("subject", "test") - .build() - .toUriString(); - - Result> result = restTemplate.exchange( - url, - HttpMethod.GET, - new HttpEntity<>(null), - new ParameterizedTypeReference>>() { - } - ).getBody(); - - if (result == null) throw new Exception(); - if (!result.getCode().equals(200)) throw new Exception(result.getMessage()); - if (result.getData().getList().isEmpty()) throw new Exception("没有测试数据"); - - EmailTemplateVo emailTemplateVo = result.getData().getList().get(0); - EmailTemplateUpdateDto emailTemplateUpdateDto = new EmailTemplateUpdateDto(); - BeanUtils.copyProperties(emailTemplateVo, emailTemplateUpdateDto); - - System.out.println(emailTemplateUpdateDto); - - emailTemplateUpdateDto.setBody(MD5.create().digestHex16(LocalDateTime.now().toString())); - mockMvc.perform(MockMvcRequestBuilders.put(api) - .header("token", token) - .content(JSON.toJSONString(emailTemplateUpdateDto)) - .contentType(MediaType.APPLICATION_JSON) - ) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result1 -> { - String contentAsString = result1.getResponse().getContentAsString(); - var pageResultResult = JSONObject.parseObject(contentAsString, new TypeReference>>() { - }); - if (pageResultResult == null) throw new Exception(contentAsString); - if (!pageResultResult.getCode().equals(200)) throw new Exception(pageResultResult.getMessage()); - - System.out.println(pageResultResult); - }); - - result = restTemplate.exchange( - url, - HttpMethod.GET, - new HttpEntity<>(null), - new ParameterizedTypeReference>>() { - } - ).getBody(); - - if (result == null) throw new Exception(); - if (!result.getCode().equals(200)) throw new Exception(result.getMessage()); - emailTemplateVo = result.getData().getList().get(0); - if (!emailTemplateVo.getBody().equals(emailTemplateUpdateDto.getBody())) { - throw new Exception(emailTemplateUpdateDto.getBody()); - } - } - - @Test - void deleteEmailTemplate() throws Exception { - String api = prefix + "/deleteEmailTemplate"; - List ids = new ArrayList<>(); - ids.add(1905180657917157378L); - mockMvc.perform(MockMvcRequestBuilders - .delete(api) - .header("token", token) - .contentType(MediaType.APPLICATION_JSON) - .content(JSON.toJSONString(ids))) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - String contentAsString = result.getResponse().getContentAsString(); - JSONObject jsonObject = JSONObject.parseObject(contentAsString); - System.out.println(jsonObject); - }); - } -} \ No newline at end of file diff --git a/auh-api/src/test/java/cn/bunny/services/controller/log/UserLoginLogControllerTest.java b/auh-api/src/test/java/cn/bunny/services/controller/log/UserLoginLogControllerTest.java deleted file mode 100644 index 7ade491..0000000 --- a/auh-api/src/test/java/cn/bunny/services/controller/log/UserLoginLogControllerTest.java +++ /dev/null @@ -1,179 +0,0 @@ -package cn.bunny.services.controller.log; - -import cn.bunny.services.domain.system.log.dto.UserLoginLogDto; -import cn.bunny.services.domain.system.log.entity.UserLoginLog; -import cn.bunny.services.domain.system.log.vo.UserLoginLogLocalVo; -import cn.bunny.services.domain.system.log.vo.UserLoginLogVo; -import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.service.log.UserLoginLogService; -import cn.bunny.services.utils.TokenUtilsTest; -import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.TypeReference; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.context.WebApplicationContext; - -import java.util.List; -import java.util.Map; - -@Slf4j -@SpringBootTest -@WebAppConfiguration -class UserLoginLogControllerTest { - private static final String prefix = "/api/userLoginLog"; - - private WebTestClient testClient; - - @Autowired - private WebApplicationContext webApplicationContext; - - @Autowired - private UserLoginLogService userLoginLogService; - - @Autowired - private TokenUtilsTest tokenUtils; - - private MockMvc mockMvc; - - private String token; - - @Autowired - private RestTemplate restTemplate; - - @BeforeEach - void setUp() { - token = tokenUtils.getToken(); - mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) - .apply(SecurityMockMvcConfigurers.springSecurity()) - .build(); - - testClient = WebTestClient.bindToController(new UserLoginLogController()).build(); - } - - @AfterEach - void tearDown() { - } - - @Test - void getUserLoginLogPage() throws Exception { - UserLoginLogDto dto = UserLoginLogDto.builder() - .username("bunny") - .build(); - - mockMvc.perform(MockMvcRequestBuilders.get(prefix + "/getUserLoginLogList/1/10") - .contentType(MediaType.APPLICATION_JSON) - .content(JSON.toJSONString(dto)) - .header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - MockHttpServletResponse response = result.getResponse(); - String contentAsString = response.getContentAsString(); - - System.out.println(contentAsString); - }); - } - - @Test - void getUserLoginLogPage2() { - UserLoginLogDto dto = UserLoginLogDto.builder() - .username("bunny") - .build(); - Map params = JSON.parseObject(JSON.toJSONString(dto), new TypeReference<>() { - }); - - // 发送请求 - ResponseEntity>> response = restTemplate.exchange( - prefix + "/getUserLoginLogList/1/10", - HttpMethod.GET, - new HttpEntity<>(params), - new ParameterizedTypeReference<>() { - } - ); - - Result> body = response.getBody(); - System.out.println(JSON.toJSONString(body)); - } - - @Test - void getUserLoginLogPageByUser() throws Exception { - String api = prefix + "/noManage/getUserLoginLogListByLocalUser/1/10"; - - mockMvc.perform(MockMvcRequestBuilders.get(api) - .header("token", token)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - MockHttpServletResponse response = result.getResponse(); - String contentAsString = response.getContentAsString(); - - System.out.println(contentAsString); - }); - } - - @Test - void getUserLoginLogPageByUser2() { - String api = prefix + "/noManage/getUserLoginLogListByLocalUser/1/10"; - - testClient.get() - .uri(api) - .header("token", token) - .accept(MediaType.APPLICATION_JSON) - .exchange() - .expectStatus().isOk() - .expectBody(new ParameterizedTypeReference>>() { - }) - .consumeWith(result -> { - Result> responseBody = result.getResponseBody(); - System.out.println(JSON.toJSONString(responseBody)); - }); - } - - @Test - void deleteUserLoginLog() throws Exception { - String api = prefix + "/deleteUserLoginLog"; - - Page page = new Page<>(1, 10); - List deleteBeforeList = userLoginLogService.list(page); - List ids = deleteBeforeList.stream().map(UserLoginLog::getId).limit(4).toList(); - List deleteBeforeIds = deleteBeforeList.stream().map(UserLoginLog::getId).toList(); - - log.info("要删除的ids: {}", ids); - log.info("删除前ids数据:{}", deleteBeforeIds); - - mockMvc.perform(MockMvcRequestBuilders - .delete(api) - .header("token", token) - .contentType(MediaType.APPLICATION_JSON) - .content(JSON.toJSONString(ids))) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(result -> { - MockHttpServletResponse response = result.getResponse(); - String contentAsString = response.getContentAsString(); - System.out.println(contentAsString); - }); - - deleteBeforeList = userLoginLogService.list(page); - deleteBeforeIds = deleteBeforeList.stream().map(UserLoginLog::getId).toList(); - log.info("要删除的ids: {}", ids); - log.info("删除前ids数据:{}", deleteBeforeIds); - } -} \ No newline at end of file diff --git a/auh-api/src/test/java/cn/bunny/services/controller/system/UserControllerTest.java b/auh-api/src/test/java/cn/bunny/services/controller/system/UserControllerTest.java deleted file mode 100644 index c5470a9..0000000 --- a/auh-api/src/test/java/cn/bunny/services/controller/system/UserControllerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package cn.bunny.services.controller.system; - -import cn.bunny.services.domain.common.constant.RedisUserConstant; -import com.alibaba.fastjson2.JSONObject; -import jakarta.annotation.Resource; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.redis.core.Cursor; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ScanOptions; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -class UserControllerTest { - @Resource - private RedisTemplate redisTemplate; - - @Test - void test() { - // Set keys = redisTemplate.keys("admin::login_info::*"); - // for (String key : keys) { - // System.out.println(key); - // } - - Map adminLoginInfoWithScan = getAdminLoginInfoWithScan(); - JSONObject adminLoginInfo = new JSONObject(adminLoginInfoWithScan); - System.out.println(adminLoginInfo); - } - - public Map getAdminLoginInfoWithScan() { - String pattern = "admin::login_info::*"; - Map result = new HashMap<>(); - - // 使用scan命令迭代查找 - ScanOptions options = ScanOptions.scanOptions().match(pattern).count(100).build(); - Cursor cursor = redisTemplate.scan(options); - - while (cursor.hasNext()) { - String key = cursor.next(); - Object value = redisTemplate.opsForValue().get(key); - result.put(key, value); - } - - try { - cursor.close(); - } catch (Exception e) { - // 处理异常 - } - - return result; - } -} \ No newline at end of file diff --git a/auh-api/src/test/java/cn/bunny/services/utils/TokenUtilsTest.java b/auh-api/src/test/java/cn/bunny/services/utils/TokenUtilsTest.java deleted file mode 100644 index 587d563..0000000 --- a/auh-api/src/test/java/cn/bunny/services/utils/TokenUtilsTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.bunny.services.utils; - -import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.system.system.entity.AdminUser; -import cn.bunny.services.mapper.system.UserMapper; -import cn.bunny.services.service.system.helper.UserLoginHelper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class TokenUtilsTest { - @Autowired - private UserLoginHelper userUtil; - - @Autowired - private UserMapper userMapper; - - public String getToken() { - AdminUser adminUser = userMapper.selectOne(Wrappers.lambdaQuery().eq(AdminUser::getUsername, "Administrator")); - adminUser.setPassword("admin123"); - LoginVo loginVo = userUtil.buildLoginUserVo(adminUser, 7); - return loginVo.getToken(); - } -} diff --git a/auh-api/src/test/java/impl/I18nServiceImplTest.java b/auh-api/src/test/java/impl/I18nServiceImplTest.java deleted file mode 100644 index 64e1974..0000000 --- a/auh-api/src/test/java/impl/I18nServiceImplTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package impl; - -import cn.bunny.services.domain.common.model.dto.excel.I18nExcel; -import cn.bunny.services.domain.system.i18n.entity.I18n; -import cn.bunny.services.mapper.configuration.I18nMapper; -import com.alibaba.excel.EasyExcel; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -public class I18nServiceImplTest extends ServiceImpl { - - @Test - void downloadI18nByExcel() { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) { - // 查找默认语言内容 - List i18nList = list(); - Map> hashMap = i18nList.stream() - .collect(Collectors.groupingBy( - I18n::getTypeName, - Collectors.mapping((I18n i18n) -> { - String keyName = i18n.getKeyName(); - String translation = i18n.getTranslation(); - return I18nExcel.builder().keyName(keyName).translation(translation).build(); - }, Collectors.toList()) - )); - - - hashMap.forEach((key, value) -> { - // EasyExcel.write(key + ".xlsx", I18nExcel.class).sheet(key).doWrite(value); - - try { - ZipEntry zipEntry = new ZipEntry(key + ".xlsx"); - zipOutputStream.putNextEntry(zipEntry); - - // 直接写入到ZipOutputStream - EasyExcel.write(zipOutputStream, I18nExcel.class).sheet(key).doWrite(value); - zipOutputStream.closeEntry(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} \ No newline at end of file diff --git a/auh-api/src/test/java/system/UserServiceTest.java b/auh-api/src/test/java/system/UserServiceTest.java deleted file mode 100644 index 53f61b9..0000000 --- a/auh-api/src/test/java/system/UserServiceTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package system; - -import cn.bunny.services.controller.system.UserController; -import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.service.system.impl.UserServiceImpl; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.redis.core.RedisConnectionUtils; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.test.context.web.WebAppConfiguration; - -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest(classes = UserServiceImpl.class) -class UserServiceTest { - - @Resource - private RedisTemplate redisTemplate; - - @Test - void test() { - String prefix = RedisUserConstant.getAdminUserEmailCodePrefix(""); - Set keys = redisTemplate.keys(prefix); - for (String key : keys) { - System.out.println(key); - } - } -} \ No newline at end of file diff --git a/auth-core/pom.xml b/auth-core/pom.xml index ce655e8..3fe8099 100644 --- a/auth-core/pom.xml +++ b/auth-core/pom.xml @@ -127,5 +127,11 @@ ip2region 2.6.5 + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + diff --git a/auth-core/src/main/java/cn/bunny/services/config/RedisConfiguration.java b/auth-core/src/main/java/cn/bunny/services/config/RedisConfiguration.java index e79ff68..90782da 100644 --- a/auth-core/src/main/java/cn/bunny/services/config/RedisConfiguration.java +++ b/auth-core/src/main/java/cn/bunny/services/config/RedisConfiguration.java @@ -18,7 +18,6 @@ import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; @@ -42,13 +41,14 @@ public class RedisConfiguration { public RedisTemplate redisTemplate(LettuceConnectionFactory connectionFactory) { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); + // 设置key序列化为string redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // 设置value序列化为JSON,使用GenericJackson2JsonRedisSerializer替换默认序列化 - redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); - redisTemplate.setHashKeySerializer(new StringRedisSerializer()); - redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); + redisTemplate.setValueSerializer(jsonRedisSerializer()); + redisTemplate.setHashValueSerializer(jsonRedisSerializer()); // 开启Redis事务 redisTemplate.setEnableTransactionSupport(true); diff --git a/auth-core/src/main/java/cn/bunny/services/domain/common/constant/RedisUserConstant.java b/auth-core/src/main/java/cn/bunny/services/domain/common/constant/RedisUserConstant.java index acef486..b07bc24 100644 --- a/auth-core/src/main/java/cn/bunny/services/domain/common/constant/RedisUserConstant.java +++ b/auth-core/src/main/java/cn/bunny/services/domain/common/constant/RedisUserConstant.java @@ -12,15 +12,57 @@ public class RedisUserConstant { public static final Integer Cookie_EXPIRATION_TIME = 5 * 60 * 60;// cookies 过期时间 5 分钟 public static final String WEB_CONFIG_KEY = "webConfig::platformConfig";// web配置 - private static final String ADMIN_LOGIN_INFO_PREFIX = "admin::login_info::"; - private static final String ADMIN_EMAIL_CODE_PREFIX = "admin::email_code::"; + /* 用户登录前缀 */ + private static final String USER_LOGIN_INFO_PREFIX = "user::login_info::"; + + /* 用户邮箱验证码前缀 */ + private static final String USER_EMAIL_CODE_PREFIX = "user::email_code::"; + + /* 用户角色前缀 */ + private static final String USER_ROLES_CODE_PREFIX = "user::roles::"; + + /* 用户权限前缀 */ + private static final String USER_PERMISSION_CODE_PREFIX = "user::permission::"; + + /** + * 用户登录前缀 + * + * @param user 用户名信息 + * @return 格式化后缓存前缀 + */ + public static String getUserLoginInfoPrefix(String user) { + return USER_LOGIN_INFO_PREFIX + user; - public static String getAdminLoginInfoPrefix(String adminUser) { - return ADMIN_LOGIN_INFO_PREFIX + adminUser; } - public static String getAdminUserEmailCodePrefix(String adminUser) { - return ADMIN_EMAIL_CODE_PREFIX + adminUser; + /** + * 用户邮箱前缀 + * + * @param user 用户信息 + * @return 邮箱验证码前缀 + */ + public static String getUserEmailCodePrefix(String user) { + return USER_EMAIL_CODE_PREFIX + user; + } + + /** + * 用户角色前缀 + * + * @param user 用户信息 + * @return 格式化后用户角色前缀 + */ + public static String getUserRolesCodePrefix(String user) { + return USER_ROLES_CODE_PREFIX + user; + } + + /** + * 用户权限前缀 + * + * @param user 用户信息 + * @return 格式化后用户权限前缀 + */ + public static String getUserPermissionCodePrefix(String user) { + return USER_PERMISSION_CODE_PREFIX + user; } } diff --git a/auth-core/src/main/java/cn/bunny/services/domain/common/enums/ResultCodeEnum.java b/auth-core/src/main/java/cn/bunny/services/domain/common/enums/ResultCodeEnum.java index 042e339..a055478 100644 --- a/auth-core/src/main/java/cn/bunny/services/domain/common/enums/ResultCodeEnum.java +++ b/auth-core/src/main/java/cn/bunny/services/domain/common/enums/ResultCodeEnum.java @@ -53,7 +53,8 @@ public enum ResultCodeEnum { LOGIN_AUTH(208, "请先登陆"), AUTHENTICATION_EXPIRED(208, "身份验证过期"), SESSION_EXPIRATION(208, "会话过期"), - + FAIL_NO_ACCESS_DENIED_USER_LOCKED(208, "该账户已封禁"), + // 209 THE_SAME_USER_HAS_LOGGED_IN(209, "相同用户已登录"), @@ -71,7 +72,6 @@ public enum ResultCodeEnum { FAIL_NO_ACCESS_DENIED(403, "无权访问"), FAIL_NO_ACCESS_DENIED_USER_OFFLINE(403, "用户强制下线"), TOKEN_PARSING_FAILED(403, "token解析失败"), - FAIL_NO_ACCESS_DENIED_USER_LOCKED(403, "该账户已封禁"), // 系统错误 500 UNKNOWN_EXCEPTION(500, "服务异常"), diff --git a/dao/src/main/java/cn/bunny/services/mapper/system/RolePermissionMapper.java b/dao/src/main/java/cn/bunny/services/mapper/system/RolePermissionMapper.java index 7bae207..73f6411 100644 --- a/dao/src/main/java/cn/bunny/services/mapper/system/RolePermissionMapper.java +++ b/dao/src/main/java/cn/bunny/services/mapper/system/RolePermissionMapper.java @@ -21,9 +21,9 @@ public interface RolePermissionMapper extends BaseMapper { /** * * 根据权限id列表删除角色权限相关 * - * @param powerIds 权限id列表 + * @param permissionIds 权限id列表 */ - void deleteBatchPowerIds(List powerIds); + void deleteBatchPowerIds(List permissionIds); /** * * 根据角色id删除角色权限 @@ -38,7 +38,7 @@ public interface RolePermissionMapper extends BaseMapper { * @param roleId 角色id * @return 已选择的权限列表 */ - List selectPowerListByRoleId(Long roleId); + List selectRolePermissionListByRoleId(Long roleId); /** * 查看所有角色关联的权限 @@ -46,4 +46,12 @@ public interface RolePermissionMapper extends BaseMapper { * @return 角色权限关系视图 */ List viewRolePowerWithAll(); + + /** + * 根据权限id列表查询角色和权限 + * + * @param permissionIds 权限id列表 + * @return List + */ + List selectRolePermissionListByPermissionIds(List permissionIds); } diff --git a/dao/src/main/java/cn/bunny/services/mapper/system/UserRoleMapper.java b/dao/src/main/java/cn/bunny/services/mapper/system/UserRoleMapper.java index fc01be5..08c87f6 100644 --- a/dao/src/main/java/cn/bunny/services/mapper/system/UserRoleMapper.java +++ b/dao/src/main/java/cn/bunny/services/mapper/system/UserRoleMapper.java @@ -31,4 +31,12 @@ public interface UserRoleMapper extends BaseMapper { */ void deleteBatchIdsByRoleIds(List roleIds); + /** + * 根据角色id列表查询 + * + * @param ids 角色id列表 + * @return {@link List} + */ + List selectListByRoleIds(List ids); + } diff --git a/dao/src/main/resources/mapper/system/PermissionMapper.xml b/dao/src/main/resources/mapper/system/PermissionMapper.xml index e7387bc..d53a638 100644 --- a/dao/src/main/resources/mapper/system/PermissionMapper.xml +++ b/dao/src/main/resources/mapper/system/PermissionMapper.xml @@ -53,15 +53,11 @@ diff --git a/dao/src/main/resources/mapper/system/RoleMapper.xml b/dao/src/main/resources/mapper/system/RoleMapper.xml index dd01ece..edff789 100644 --- a/dao/src/main/resources/mapper/system/RoleMapper.xml +++ b/dao/src/main/resources/mapper/system/RoleMapper.xml @@ -43,12 +43,10 @@ diff --git a/dao/src/main/resources/mapper/system/RolePermissionMapper.xml b/dao/src/main/resources/mapper/system/RolePermissionMapper.xml index 095f16d..f4930a3 100644 --- a/dao/src/main/resources/mapper/system/RolePermissionMapper.xml +++ b/dao/src/main/resources/mapper/system/RolePermissionMapper.xml @@ -24,7 +24,7 @@ delete from sys_role_permission where power_id in - + #{id} @@ -40,7 +40,8 @@ - select * from sys_role_permission where role_id = #{roleId} @@ -61,4 +62,14 @@ LEFT JOIN sys_permission permission ON rp.power_id = permission.id + + + diff --git a/dao/src/main/resources/mapper/system/UserRoleMapper.xml b/dao/src/main/resources/mapper/system/UserRoleMapper.xml index 7983fd6..9b0fddd 100644 --- a/dao/src/main/resources/mapper/system/UserRoleMapper.xml +++ b/dao/src/main/resources/mapper/system/UserRoleMapper.xml @@ -39,4 +39,12 @@ + + + diff --git a/pom.xml b/pom.xml index 91b2263..3e6c0d6 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ 3.1 6.2.1 4.3.1 - 2.12.3 + 2.19.0 2.3.2 diff --git a/service/pom.xml b/service/pom.xml index b40a69d..669a101 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -91,10 +91,5 @@ com.mysql mysql-connector-j - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - diff --git a/service/src/main/java/cn/bunny/services/cache/EmailCacheService.java b/service/src/main/java/cn/bunny/services/cache/EmailCacheService.java new file mode 100644 index 0000000..2476ba4 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/cache/EmailCacheService.java @@ -0,0 +1,58 @@ +package cn.bunny.services.cache; + +import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; +import jakarta.annotation.Resource; +import org.jetbrains.annotations.NotNull; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.concurrent.TimeUnit; + +@Service +public class EmailCacheService { + + @Resource + private RedisTemplate redisTemplate; + + /** + * 存储邮箱验证码 + * + * @param email 邮箱 + * @param emailCode 邮箱验证码 + */ + public void buildEmailCodeCache(@NotNull String email, String emailCode) { + // 在Redis中存储验证码 + String emailCodePrefix = RedisUserConstant.getUserEmailCodePrefix(email); + redisTemplate.opsForValue().set(emailCodePrefix, emailCode, RedisUserConstant.REDIS_EXPIRATION_TIME, TimeUnit.MINUTES); + } + + /** + * 获取邮箱验证码 + * + * @param email 邮箱 + * @return 邮箱验证码 + */ + public String getEmailCode(@NotNull String email) { + String userEmailCodePrefix = RedisUserConstant.getUserEmailCodePrefix(email); + Object emailCode = redisTemplate.opsForValue().get(userEmailCodePrefix); + + if (emailCode == null) { + throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_EMPTY.getMessage()); + } + + return emailCode.toString(); + } + + /** + * 清除邮箱验证码 + * + * @param email 邮箱 + */ + public void deleteEmailCodeCache(String email) { + String emailCodePrefix = RedisUserConstant.getUserEmailCodePrefix(email); + redisTemplate.delete(emailCodePrefix); + } + +} diff --git a/auth-core/src/main/java/cn/bunny/services/redis/RedisService.java b/service/src/main/java/cn/bunny/services/cache/RedisService.java similarity index 93% rename from auth-core/src/main/java/cn/bunny/services/redis/RedisService.java rename to service/src/main/java/cn/bunny/services/cache/RedisService.java index b9fdb3a..4d6e17f 100644 --- a/auth-core/src/main/java/cn/bunny/services/redis/RedisService.java +++ b/service/src/main/java/cn/bunny/services/cache/RedisService.java @@ -1,4 +1,4 @@ -package cn.bunny.services.redis; +package cn.bunny.services.cache; import cn.bunny.services.domain.common.constant.RedisUserConstant; import jakarta.annotation.Resource; @@ -26,7 +26,7 @@ public class RedisService { */ @NotNull public List scannerRedisKeyByPage(long pageNum, long pageSize) { - String prefix = RedisUserConstant.getAdminLoginInfoPrefix("*"); + String prefix = RedisUserConstant.getUserLoginInfoPrefix("*"); List keys = new ArrayList<>(); ScanOptions scanOptions = ScanOptions.scanOptions() diff --git a/service/src/main/java/cn/bunny/services/cache/UserAuthorizationCacheService.java b/service/src/main/java/cn/bunny/services/cache/UserAuthorizationCacheService.java new file mode 100644 index 0000000..4ebb9bf --- /dev/null +++ b/service/src/main/java/cn/bunny/services/cache/UserAuthorizationCacheService.java @@ -0,0 +1,121 @@ +package cn.bunny.services.cache; + +import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.domain.system.system.entity.Permission; +import cn.bunny.services.domain.system.system.entity.Role; +import cn.bunny.services.mapper.system.PermissionMapper; +import cn.bunny.services.mapper.system.RoleMapper; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.TypeReference; +import jakarta.annotation.Resource; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +@Service +public class UserAuthorizationCacheService { + + @Resource + private PermissionMapper permissionMapper; + + @Resource + private RoleMapper roleMapper; + + @Resource + private RedisTemplate redisTemplate; + + /** + * 根据用户ID和用户名获取角色列表(缓存优先) + * + *

执行逻辑

+ *
    + *
  1. 尝试从Redis缓存获取用户角色(使用用户名作为缓存key)
  2. + *
  3. 若缓存未命中,则从数据库查询并写入缓存(有效期1天)
  4. + *
  5. 若缓存命中,反序列化缓存数据返回
  6. + *
+ * + * @param userId 用户ID(数据库查询用) + * @param username 用户名(缓存key生成用) + * @return 用户角色列表 + */ + public List getRolesByUser(Long userId, String username) { + // 角色列表 + List roleList; + + // 尝试从缓存中获取当前用户角色 + String userRolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(username); + Object object = redisTemplate.opsForValue().get(userRolesCodePrefix); + + // 为空查询数据库,并将信息存入Redis + if (Objects.isNull(object)) { + roleList = roleMapper.selectListByUserId(userId); + redisTemplate.opsForValue().set(userRolesCodePrefix, roleList, 1, TimeUnit.DAYS); + } + // 从缓存中得到当前用户的角色列表 + else { + String jsonString = JSON.toJSONString(object); + TypeReference> reference = new TypeReference<>() { + }; + List list = JSON.parseObject(jsonString, reference); + // 防止 list 为空报错 + roleList = list != null ? list : new ArrayList<>(); + } + + return roleList; + } + + /** + * 根据用户ID和用户名获取权限列表(缓存优先) + * + *

执行逻辑

+ *
    + *
  1. 尝试从Redis缓存获取用户权限(使用用户名作为缓存key)
  2. + *
  3. 若缓存未命中,则从数据库查询并写入缓存(有效期1天)
  4. + *
  5. 若缓存命中,反序列化缓存数据返回
  6. + *
+ * + * @param userId 用户ID(数据库查询用) + * @param username 用户名(缓存key生成用) + * @return 用户权限列表 + */ + public List getPermissionsByUser(Long userId, String username) { + // 权限列表 + List permissionList; + + // 获取缓存中的用户权限 + String userPermissionCodePrefix = RedisUserConstant.getUserPermissionCodePrefix(username); + Object object = redisTemplate.opsForValue().get(userPermissionCodePrefix); + + // 为空查询数据库,并将用户权限放在Redis中 + if (Objects.isNull(object)) { + permissionList = permissionMapper.selectListByUserId(userId); + redisTemplate.opsForValue().set(userPermissionCodePrefix, permissionList, 1, TimeUnit.DAYS); + } + // 从缓存中得到当前用户权限 + else { + String jsonString = JSON.toJSONString(object); + TypeReference> reference = new TypeReference<>() { + }; + List list = JSON.parseObject(jsonString, reference); + // 防止 list 为空报错 + permissionList = list != null ? list : new ArrayList<>(); + } + + return permissionList; + } + + /** + * 清除缓存 + * 如有需要清除当前服务缓存 + */ + public void deleteRoleAndPermissionCache(String key) { + String permissionCodePrefix = RedisUserConstant.getUserPermissionCodePrefix(key); + String rolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(key); + redisTemplate.delete(permissionCodePrefix); + redisTemplate.delete(rolesCodePrefix); + } +} diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/UserLoginHelper.java b/service/src/main/java/cn/bunny/services/cache/UserCacheService.java similarity index 57% rename from service/src/main/java/cn/bunny/services/service/system/helper/UserLoginHelper.java rename to service/src/main/java/cn/bunny/services/cache/UserCacheService.java index b1b2e42..1c23781 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/UserLoginHelper.java +++ b/service/src/main/java/cn/bunny/services/cache/UserCacheService.java @@ -1,30 +1,22 @@ -package cn.bunny.services.service.system.helper; +package cn.bunny.services.cache; import cn.bunny.services.domain.common.constant.LocalDateTimeConstant; import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.system.log.entity.UserLoginLog; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.domain.system.system.entity.Permission; import cn.bunny.services.domain.system.system.entity.Role; -import cn.bunny.services.mapper.log.UserLoginLogMapper; import cn.bunny.services.mapper.system.PermissionMapper; import cn.bunny.services.mapper.system.RoleMapper; import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.minio.MinioHelper; -import cn.bunny.services.service.system.helper.role.RoleHelper; -import cn.bunny.services.utils.IpUtil; +import cn.bunny.services.service.system.helper.RoleServiceHelper; import cn.bunny.services.utils.JwtTokenUtil; +import com.alibaba.fastjson2.JSON; import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletRequest; -import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -32,26 +24,40 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -@Slf4j -@Component -@Transactional -public class UserLoginHelper { +@Service +public class UserCacheService { @Resource private RedisTemplate redisTemplate; - @Resource - private UserMapper userMapper; - @Resource - private UserLoginLogMapper userLoginLogMapper; - @Resource - private RoleMapper roleMapper; - @Resource - private PermissionMapper permissionMapper; + @Resource private MinioHelper minioHelper; + @Resource + private UserMapper userMapper; + + @Resource + private RoleMapper roleMapper; + + @Resource + private PermissionMapper permissionMapper; + + @Resource + private UserAuthorizationCacheService userAuthorizationCacheService; + /** - * 构建用户登录返回对象(LoginVo) + * 根据用户名获取缓存中内容 + * + * @param username 用户名 + * @return LoginVo + */ + public LoginVo getLoginVoByUsername(String username) { + Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(username)); + return JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); + } + + /** + * 构建用户登录返回对象(LoginVo) 更新用户相关就用这个包括登录 * *

主要处理流程:

*
    @@ -94,24 +100,18 @@ public class UserLoginHelper { // 判断是否是 admin 如果是admin 赋予所有权限 List permissions = new ArrayList<>(); - boolean isAdmin = RoleHelper.checkAdmin(roles, permissions, user); + boolean isAdmin = RoleServiceHelper.checkAdmin(roles, permissions, user); if (!isAdmin) { permissions = permissionMapper.selectListByUserId(userId).stream() .map(Permission::getPowerCode) .toList(); } - // 为这两个去重 + + // 为这两个去重,在判断 checkAdmin 会重新赋值 permissions = permissions.stream().distinct().toList(); roles = roles.stream().distinct().toList(); - // 获取IP地址并更新用户登录信息, - String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr(); - String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion(); - // 设置用户IP地址,并更新用户信息 - user.setIpAddress(ipAddr); - user.setIpRegion(ipRegion); - userMapper.updateById(user); - + // 设置用户返回对象 LoginVo loginVo = new LoginVo(); BeanUtils.copyProperties(user, loginVo); loginVo.setPersonDescription(user.getSummary()); @@ -135,55 +135,68 @@ public class UserLoginHelper { String userAvatar = minioHelper.getUserAvatar(user.getAvatar()); loginVo.setAvatar(userAvatar); - // 将用户登录保存在用户登录日志表中 - setUserLoginLog(user, token, UserConstant.LOGIN); - - // 将信息保存在Redis中,一定要确保用户名是唯一的 - String loginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(username); + String loginInfoPrefix = RedisUserConstant.getUserLoginInfoPrefix(username); redisTemplate.opsForValue().set(loginInfoPrefix, loginVo, readMeDay, TimeUnit.DAYS); - return loginVo; } /** - * 设置用户登录日志内容 - *

    - * 该方法用于将管理员用户信息复制到用户登录日志对象中,同时处理特殊字段映射关系。 - *

    - * 实现说明: - * 1. 使用BeanUtils.copyProperties()复制属性时,会自动将AdminUser.id复制到UserLoginLog.id - * 2. 由于UserLoginLog实际需要的是userId字段而非id字段,需要特殊处理: - * - 先进行属性复制 - * - 然后将UserLoginLog.userId设置为AdminUser.id - * - 最后将UserLoginLog.id显式设为null(避免自动生成的id被覆盖) + * 批量更新Redis中用户权限信息,设计用户和角色就用这个 * - * @param user 管理员用户实体对象,包含用户基本信息 - * @param token 本次登录/退出的认证令牌 - * @param type 操作类型(LOGIN-登录/LOGOUT-退出) + *

    使用场景:当用户角色或权限变更时,同步更新Redis中的用户权限数据

    + * + *

    实现策略

    + *
      + *
    1. 主动更新(当前实现):重新构建用户权限信息并更新Redis缓存
    2. + *
    3. 强制下线:删除用户登录态,强制重新认证获取最新权限
    4. + *
    + * + *

    技术实现

    + *
      + *
    • 采用Spring事件驱动机制触发更新
    • + *
    • 使用并行流(parallelStream)提高批量处理效率
    • + *
    • 仅更新Redis中存在登录态的用户
    • + *
    + * + * @param userIds 需要更新的用户ID集合 + * (仅处理集合中存在的有效用户) + * @see RedisUserConstant Redis键前缀常量 */ - public void setUserLoginLog(AdminUser user, String token, String type) { - UserLoginLog userLoginLog = new UserLoginLog(); - BeanUtils.copyProperties(user, userLoginLog); - userLoginLog.setUserId(user.getId()); - userLoginLog.setId(null); - userLoginLog.setToken(token); - userLoginLog.setType(type); + public void updateUserRedisInfo(List userIds) { + if (userIds.isEmpty()) return; - // 当前请求request - ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (requestAttributes != null) { - HttpServletRequest request = requestAttributes.getRequest(); + // 批量查询用户 + List adminUsers = userMapper.selectBatchIds(userIds); + // 并行处理用户更新 + adminUsers.stream() + .filter(user -> redisTemplate.hasKey(RedisUserConstant.getUserLoginInfoPrefix(user.getUsername()))) + .forEach(user -> { + // 更新时清除缓存中的角色和权限 + String username = user.getUsername(); + userAuthorizationCacheService.deleteRoleAndPermissionCache(username); - // 获取User-Agent - String userAgent = request.getHeader("User-Agent"); - userLoginLog.setUserAgent(userAgent); - - // 获取X-Requested-With - String xRequestedWith = request.getHeader("X-Requested-With"); - userLoginLog.setXRequestedWith(xRequestedWith); - } - - userLoginLogMapper.insert(userLoginLog); + // 更新用户权限信息 + buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); + }); } + /** + * 清除用户登录时的缓存 + * + * @param username 用户名 + */ + public void deleteLoginUserCache(String username) { + String userRolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(username); + redisTemplate.delete(userRolesCodePrefix); + } + + /** + * 清除用户登录时的缓存 + * + * @param username 用户名 + */ + public void deleteUserCache(String username) { + userAuthorizationCacheService.deleteRoleAndPermissionCache(username); + deleteLoginUserCache(username); + } } diff --git a/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java b/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java index 2e397f8..2aa2713 100644 --- a/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java +++ b/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java @@ -1,12 +1,11 @@ package cn.bunny.services.security.service; +import cn.bunny.services.cache.UserAuthorizationCacheService; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.system.system.entity.Permission; import cn.bunny.services.domain.system.system.entity.Role; -import cn.bunny.services.mapper.system.PermissionMapper; -import cn.bunny.services.mapper.system.RoleMapper; import cn.bunny.services.security.config.WebSecurityConfig; -import cn.bunny.services.service.system.helper.role.RoleHelper; +import cn.bunny.services.service.system.helper.RoleServiceHelper; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @@ -23,10 +22,7 @@ import java.util.Objects; public class PermissionCheckService { @Resource - private PermissionMapper permissionMapper; - - @Resource - private RoleMapper roleMapper; + private UserAuthorizationCacheService authorizationCacheService; /** * 查询用户所属的角色信息 @@ -38,13 +34,15 @@ public class PermissionCheckService { // 根据用户ID查询角色数据 Long userId = BaseContext.getUserId(); - List roleList = roleMapper.selectListByUserId(userId); + String username = BaseContext.getUsername(); + // List roleList = roleMapper.selectListByUserId(userId); + List roleList = authorizationCacheService.getRolesByUser(userId, username); // 角色代码 List roleCodeList = roleList.stream().map(Role::getRoleCode).toList(); // 判断是否是管理员用户 - boolean checkedAdmin = RoleHelper.checkAdmin(roleCodeList); + boolean checkedAdmin = RoleServiceHelper.checkAdmin(roleCodeList); if (checkedAdmin) return true; // 判断请求地址是否是登录之后才需要访问的,已经登录了不需要验证的 @@ -54,7 +52,8 @@ public class PermissionCheckService { } // 根据角色列表查询权限信息 - List permissionList = permissionMapper.selectListByUserId(userId); + // List permissionList = permissionMapper.selectListByUserId(userId); + List permissionList = authorizationCacheService.getPermissionsByUser(userId, username); // 判断是否与请求路径匹配 return permissionList.stream() diff --git a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java index f6586d0..61fa2e2 100644 --- a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java +++ b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java @@ -1,25 +1,23 @@ package cn.bunny.services.security.service; -import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.cache.UserCacheService; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.security.TokenInfo; import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.security.exception.CustomAuthenticationException; import cn.bunny.services.utils.JwtTokenUtil; -import com.alibaba.fastjson2.JSON; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; /** * 处理Token相关逻辑 */ -@Component +@Service public class TokenValidationService { @Resource - private RedisTemplate redisTemplate; + private UserCacheService userCacheService; public TokenInfo validateToken(HttpServletRequest request) { // 判断是否有 token @@ -39,8 +37,7 @@ public class TokenValidationService { Long userId = JwtTokenUtil.getUserId(token); // 查找 Redis - Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getAdminLoginInfoPrefix(username)); - LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); + LoginVo loginVo = userCacheService.getLoginVoByUsername(username); return TokenInfo.builder().userId(userId).username(username).token(token).loginVo(loginVo).build(); } diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java index 313658e..c3d6993 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java @@ -1,10 +1,10 @@ package cn.bunny.services.service.configuration.impl; import cn.bunny.services.domain.common.constant.FileType; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.I18nExcel; import cn.bunny.services.domain.common.model.entity.BaseEntity; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.i18n.dto.I18nAddDto; import cn.bunny.services.domain.system.i18n.dto.I18nDto; import cn.bunny.services.domain.system.i18n.dto.I18nUpdateByFileDto; @@ -60,6 +60,7 @@ import java.util.zip.ZipOutputStream; @Service @Transactional public class I18nServiceImpl extends ServiceImpl implements I18nService { + private static final String CACHE_NAMES = "i18n"; @Resource private I18nTypeMapper i18nTypeMapper; @@ -70,7 +71,7 @@ public class I18nServiceImpl extends ServiceImpl implements I1 * @return 多语言返回内容 */ @Override - @Cacheable(cacheNames = "i18n", key = "'i18n'", cacheManager = "cacheManagerWithMouth") + @Cacheable(cacheNames = CACHE_NAMES, key = "'i18nMap'", cacheManager = "cacheManagerWithMouth") public HashMap getI18nMap() { // 查找默认语言内容 I18nType i18nType = i18nTypeMapper.selectOne(Wrappers.lambdaQuery().eq(I18nType::getIsDefault, true)); @@ -105,7 +106,7 @@ public class I18nServiceImpl extends ServiceImpl implements I1 * @param dto 添加表单 */ @Override - @CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true) + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true) public void addI18n(@Valid I18nAddDto dto) { String keyName = dto.getKeyName(); String typeName = dto.getTypeName(); @@ -126,7 +127,7 @@ public class I18nServiceImpl extends ServiceImpl implements I1 * @param dto 更新表单 */ @Override - @CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true) + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true) public void updateI18n(@Valid I18nUpdateDto dto) { Long id = dto.getId(); @@ -146,7 +147,7 @@ public class I18nServiceImpl extends ServiceImpl implements I1 * @param ids 删除id列表 */ @Override - @CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true) + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true) public void deleteI18n(List ids) { // 判断数据请求是否为空 if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); @@ -193,7 +194,7 @@ public class I18nServiceImpl extends ServiceImpl implements I1 * @param dto 文件更新对象 */ @Override - @CacheEvict(cacheNames = "i18n", key = "'i18n'", beforeInvocation = true) + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true) public void uploadI18nFile(I18nUpdateByFileDto dto) { String type = dto.getType(); MultipartFile file = dto.getFile(); diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java index 93de871..6eb12f3 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nTypeServiceImpl.java @@ -1,17 +1,20 @@ package cn.bunny.services.service.configuration.impl; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.i18n.dto.I18nTypeAddDto; import cn.bunny.services.domain.system.i18n.dto.I18nTypeDto; import cn.bunny.services.domain.system.i18n.dto.I18nTypeUpdateDto; import cn.bunny.services.domain.system.i18n.entity.I18nType; import cn.bunny.services.domain.system.i18n.vo.I18nTypeVo; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.I18nTypeMapper; import cn.bunny.services.service.configuration.I18nTypeService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.BeanUtils; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,6 +31,7 @@ import java.util.List; @Service @Transactional public class I18nTypeServiceImpl extends ServiceImpl implements I18nTypeService { + private static final String CACHE_NAMES = "i18n"; /** * 获取多语言类型 @@ -35,6 +39,7 @@ public class I18nTypeServiceImpl extends ServiceImpl i * @return 多语言类型列表 */ @Override + @Cacheable(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", cacheManager = "cacheManagerWithMouth") public List getI18nTypeList(I18nTypeDto dto) { List i18nTypeList = baseMapper.selectListByPage(dto); return i18nTypeList.stream().map(i18nType -> { @@ -50,6 +55,10 @@ public class I18nTypeServiceImpl extends ServiceImpl i * @param dto 多语言类型添加 */ @Override + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true), + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", beforeInvocation = true), + }) public void addI18nType(I18nTypeAddDto dto) { String typeName = dto.getTypeName(); Boolean isDefault = dto.getIsDefault(); @@ -77,14 +86,18 @@ public class I18nTypeServiceImpl extends ServiceImpl i * @param dto 多语言类型更新 */ @Override + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true), + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", beforeInvocation = true), + }) public void updateI18nType(I18nTypeUpdateDto dto) { Long id = dto.getId(); Boolean isDefault = dto.getIsDefault(); I18nType i18nType = new I18nType(); // 查询更新的内容是否存在 - List i18nTypeList = list(Wrappers.lambdaQuery().eq(I18nType::getId, id)); - if (i18nTypeList.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.DATA_NOT_EXIST); + I18nType dbI18nType = getOne(Wrappers.lambdaQuery().eq(I18nType::getId, id)); + if (dbI18nType == null) throw new AuthCustomerException(ResultCodeEnum.DATA_NOT_EXIST); // 如果是默认,将其它内容设为false if (isDefault) { @@ -104,6 +117,10 @@ public class I18nTypeServiceImpl extends ServiceImpl i * @param ids 删除id列表 */ @Override + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nMap'", beforeInvocation = true), + @CacheEvict(cacheNames = CACHE_NAMES, key = "'i18nTypeList'", beforeInvocation = true), + }) public void deleteI18nType(List ids) { // 判断数据请求是否为空 if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); diff --git a/service/src/main/java/cn/bunny/services/service/system/UserLoginService.java b/service/src/main/java/cn/bunny/services/service/system/UserLoginService.java index 73a874d..bea6a47 100644 --- a/service/src/main/java/cn/bunny/services/service/system/UserLoginService.java +++ b/service/src/main/java/cn/bunny/services/service/system/UserLoginService.java @@ -7,7 +7,6 @@ import cn.bunny.services.domain.system.system.dto.user.RefreshTokenDto; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.domain.system.system.vo.user.RefreshTokenVo; import com.baomidou.mybatisplus.extension.service.IService; -import jakarta.validation.Valid; import org.jetbrains.annotations.NotNull; public interface UserLoginService extends IService { @@ -53,6 +52,6 @@ public interface UserLoginService extends IService { * * @param password 更新本地用户密码 */ - void updateUserPasswordByLocalUser(@Valid String password); - + void updateUserPasswordByLocalUser(String password); + } diff --git a/service/src/main/java/cn/bunny/services/service/system/UserService.java b/service/src/main/java/cn/bunny/services/service/system/UserService.java index 51f9557..00dad0d 100644 --- a/service/src/main/java/cn/bunny/services/service/system/UserService.java +++ b/service/src/main/java/cn/bunny/services/service/system/UserService.java @@ -1,6 +1,5 @@ package cn.bunny.services.service.system; -import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.system.system.dto.user.AdminUserAddDto; import cn.bunny.services.domain.system.system.dto.user.AdminUserDto; @@ -81,5 +80,5 @@ public interface UserService extends IService { * @param pageParams 分页查询 * @return 分页查询结果 */ - PageResult getCacheUserPage(Page pageParams); + PageResult getCacheUserPage(Page pageParams); } diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleHelper.java b/service/src/main/java/cn/bunny/services/service/system/helper/RoleServiceHelper.java similarity index 51% rename from service/src/main/java/cn/bunny/services/service/system/helper/role/RoleHelper.java rename to service/src/main/java/cn/bunny/services/service/system/helper/RoleServiceHelper.java index 719d974..54c189d 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleHelper.java +++ b/service/src/main/java/cn/bunny/services/service/system/helper/RoleServiceHelper.java @@ -1,28 +1,12 @@ -package cn.bunny.services.service.system.helper.role; +package cn.bunny.services.service.system.helper; import cn.bunny.services.context.BaseContext; -import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.constant.SecurityConfigConstant; import cn.bunny.services.domain.system.system.entity.AdminUser; -import cn.bunny.services.mapper.system.UserMapper; -import cn.bunny.services.service.system.helper.UserLoginHelper; -import jakarta.annotation.Resource; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Component; import java.util.List; -@Component -public class RoleHelper { - - @Resource - private RedisTemplate redisTemplate; - - @Resource - private UserMapper userMapper; - - @Resource - private UserLoginHelper userloginHelper; +public class RoleServiceHelper { /** * 判断用户是否具有管理员权限 @@ -80,45 +64,4 @@ public class RoleHelper { // 判断是否是 admin return roleList.stream().anyMatch(permissionList::contains); } - - /** - * 批量更新Redis中用户权限信息 - * - *

    使用场景:当用户角色或权限变更时,同步更新Redis中的用户权限数据

    - * - *

    实现策略

    - *
      - *
    1. 主动更新(当前实现):重新构建用户权限信息并更新Redis缓存
    2. - *
    3. 强制下线:删除用户登录态,强制重新认证获取最新权限
    4. - *
    - * - *

    技术实现

    - *
      - *
    • 采用Spring事件驱动机制触发更新
    • - *
    • 使用并行流(parallelStream)提高批量处理效率
    • - *
    • 仅更新Redis中存在登录态的用户
    • - *
    - * - * @param userIds 需要更新的用户ID集合 - * (仅处理集合中存在的有效用户) - * @see RedisUserConstant Redis键前缀常量 - * @see UserLoginHelper#buildLoginUserVo 用户登录信息构建方法 - */ - public void updateUserRedisInfo(List userIds) { - if (userIds.isEmpty()) return; - - // 批量查询用户 - List adminUsers = userMapper.selectBatchIds(userIds); - - // 并行处理用户更新 - adminUsers.parallelStream() - .filter(user -> redisTemplate.hasKey(RedisUserConstant.getAdminLoginInfoPrefix(user.getUsername()))) - .forEach(user -> { - // 策略1: 更新用户权限信息 - userloginHelper.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); - - // 或者策略2: 强制用户下线 - // redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(user.getUsername())); - }); - } } diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/RouterHelper.java b/service/src/main/java/cn/bunny/services/service/system/helper/RouterHelper.java index 60e2bf1..b29fb8a 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/RouterHelper.java +++ b/service/src/main/java/cn/bunny/services/service/system/helper/RouterHelper.java @@ -8,7 +8,6 @@ import cn.bunny.services.domain.system.system.views.ViewRolePermission; import cn.bunny.services.domain.system.system.views.ViewRouterRole; import cn.bunny.services.domain.system.system.vo.router.WebUserRouterVo; import cn.bunny.services.service.system.RouterRoleService; -import cn.bunny.services.service.system.helper.role.RoleHelper; import com.alibaba.fastjson2.JSON; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -90,7 +89,7 @@ public class RouterHelper { public List getWebUserRouterVos(List routerList, Map> routerRoleList, Map> rolePermissionList) { // 检查当前是否是 admin 用户 List roles = BaseContext.getLoginVo().getRoles(); - List allAuths = !RoleHelper.checkAdmin(roles) ? new ArrayList<>() : List.of("*:*:*", "*:*", "*", "admin"); + List allAuths = !RoleServiceHelper.checkAdmin(roles) ? new ArrayList<>() : List.of("*:*:*", "*:*", "*", "admin"); // 查询路由所有数据,整理前端需要的路和、角色、权限 return routerList.stream().map(view -> { diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/UserServiceHelper.java b/service/src/main/java/cn/bunny/services/service/system/helper/UserServiceHelper.java new file mode 100644 index 0000000..83b1a3e --- /dev/null +++ b/service/src/main/java/cn/bunny/services/service/system/helper/UserServiceHelper.java @@ -0,0 +1,103 @@ +package cn.bunny.services.service.system.helper; + +import cn.bunny.services.cache.UserCacheService; +import cn.bunny.services.domain.system.log.entity.UserLoginLog; +import cn.bunny.services.domain.system.system.entity.AdminUser; +import cn.bunny.services.domain.system.system.entity.RolePermission; +import cn.bunny.services.domain.system.system.entity.UserRole; +import cn.bunny.services.mapper.log.UserLoginLogMapper; +import cn.bunny.services.mapper.system.RolePermissionMapper; +import cn.bunny.services.mapper.system.UserRoleMapper; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.BeanUtils; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.List; + +@Service +public class UserServiceHelper { + + @Resource + private UserRoleMapper userRoleMapper; + + @Resource + private UserCacheService userCacheService; + + @Resource + private UserLoginLogMapper userLoginLogMapper; + + @Resource + private RolePermissionMapper rolePermissionMapper; + + /** + * 设置用户登录日志内容 + *

    + * 该方法用于将管理员用户信息复制到用户登录日志对象中,同时处理特殊字段映射关系。 + *

    + * 实现说明: + * 1. 使用BeanUtils.copyProperties()复制属性时,会自动将AdminUser.id复制到UserLoginLog.id + * 2. 由于UserLoginLog实际需要的是userId字段而非id字段,需要特殊处理: + * - 先进行属性复制 + * - 然后将UserLoginLog.userId设置为AdminUser.id + * - 最后将UserLoginLog.id显式设为null(避免自动生成的id被覆盖) + * + * @param user 管理员用户实体对象,包含用户基本信息 + * @param token 本次登录/退出的认证令牌 + * @param type 操作类型(LOGIN-登录/LOGOUT-退出) + */ + public void setUserLoginLog(AdminUser user, String token, String type) { + UserLoginLog userLoginLog = new UserLoginLog(); + BeanUtils.copyProperties(user, userLoginLog); + userLoginLog.setUserId(user.getId()); + userLoginLog.setId(null); + userLoginLog.setToken(token); + userLoginLog.setType(type); + + // 当前请求request + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (requestAttributes != null) { + HttpServletRequest request = requestAttributes.getRequest(); + + // 获取User-Agent + String userAgent = request.getHeader("User-Agent"); + userLoginLog.setUserAgent(userAgent); + + // 获取X-Requested-With + String xRequestedWith = request.getHeader("X-Requested-With"); + userLoginLog.setXRequestedWith(xRequestedWith); + } + + userLoginLogMapper.insert(userLoginLog); + } + + /** + * 处理角色更新事件 + * + * @param roleIds 角色ID + */ + @Async + public void updateBatchUserRedisInfoByRoleId(List roleIds) { + // 批量查询关联用户ID + List userRoles = userRoleMapper.selectListByRoleIds(roleIds); + List userIds = userRoles.stream().map(UserRole::getUserId).toList(); + userCacheService.updateUserRedisInfo(userIds); + } + + /** + * 处理权限更新事件 + * + * @param permissionIds 权限ID + */ + @Async + public void updateBatchUserRedisInfoByPermissionId(List permissionIds) { + // 批量查询关联用户ID + List rolePermissions = rolePermissionMapper.selectRolePermissionListByPermissionIds(permissionIds); + List roleIds = rolePermissions.stream().map(RolePermission::getRoleId).toList(); + updateBatchUserRedisInfoByRoleId(roleIds); + } + +} diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java b/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java index 9659316..c1c7cad 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java +++ b/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java @@ -1,23 +1,22 @@ package cn.bunny.services.service.system.helper.login; -import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.cache.EmailCacheService; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.LoginDto; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.mapper.system.UserMapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.core.userdetails.UsernameNotFoundException; /** * 邮箱登录策略 */ public class EmailLoginStrategy implements LoginStrategy { - private final RedisTemplate redisTemplate; + private final EmailCacheService emailCacheService; private final UserMapper userMapper; - public EmailLoginStrategy(RedisTemplate redisTemplate, UserMapper userMapper) { - this.redisTemplate = redisTemplate; + public EmailLoginStrategy(EmailCacheService emailCacheService, UserMapper userMapper) { + this.emailCacheService = emailCacheService; this.userMapper = userMapper; } @@ -38,13 +37,10 @@ public class EmailLoginStrategy implements LoginStrategy { String emailCode = loginDto.getEmailCode().toLowerCase(); // 查找Redis中的验证码 - Object redisEmailCode = redisTemplate.opsForValue().get(RedisUserConstant.getAdminUserEmailCodePrefix(username)); - if (redisEmailCode == null) { - throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_EMPTY.getMessage()); - } + String redisEmailCode = emailCacheService.getEmailCode(username); // 判断用户邮箱验证码是否和Redis中发送的验证码 - if (!emailCode.equals(redisEmailCode.toString().toLowerCase())) { + if (!emailCode.equals(redisEmailCode.toLowerCase())) { throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING.getMessage()); } @@ -63,8 +59,7 @@ public class EmailLoginStrategy implements LoginStrategy { @Override public void authenticateAfter(LoginDto loginDto, AdminUser adminUser) { // 将Redis中验证码删除 - String emailCodePrefix = RedisUserConstant.getAdminUserEmailCodePrefix(loginDto.getUsername()); - redisTemplate.delete(emailCodePrefix); + emailCacheService.deleteEmailCodeCache(loginDto.getUsername()); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginStrategy.java b/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginStrategy.java index 29d832f..3e2fb67 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginStrategy.java +++ b/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginStrategy.java @@ -21,7 +21,7 @@ public interface LoginStrategy { * 登录完成后的内容 * * @param loginDto 登录参数 - * @param adminUser + * @param adminUser {@link AdminUser} */ void authenticateAfter(LoginDto loginDto, AdminUser adminUser); } diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdateHandler.java b/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdateHandler.java deleted file mode 100644 index 753e134..0000000 --- a/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdateHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -package cn.bunny.services.service.system.helper.role; - -import cn.bunny.services.domain.system.system.entity.UserRole; -import cn.bunny.services.mapper.system.UserRoleMapper; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import jakarta.annotation.Resource; -import org.springframework.context.event.EventListener; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Component; - -import java.util.List; - -/** - * 角色更新事件处理器 - * - *

    职责说明:监听并处理角色变更事件,同步更新关联用户的权限信息

    - * - *

    处理流程

    - *
      - *
    1. 监听{@code RoleUpdatedEvent}事件
    2. - *
    3. 查询关联该角色的所有用户ID
    4. - *
    5. 通过{@code RoleHelper}批量更新用户Redis缓存
    6. - *
    - * - *

    注意事项

    - *
      - *
    • 使用异步处理(@{@link Async})避免阻塞主线程
    • - *
    • 仅处理直接关联的用户,不包含通过用户组等间接关联的情况
    • - *
    • 更新操作采用批量处理提高效率
    • - *
    - */ -@Component -public class RoleUpdateHandler { - @Resource - private UserRoleMapper userRoleMapper; - - @Resource - private RoleHelper roleHelper; - - /** - * 处理角色更新事件 - * - * @param event 角色更新事件,包含变更的角色ID - * @see RoleUpdatedEvent 角色更新事件定义 - * @see RoleHelper#updateUserRedisInfo 用户缓存更新方法 - */ - @Async - @EventListener - public void handleRoleUpdatedEvent(RoleUpdatedEvent event) { - // 查询当前用户角色中角色id - LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery().eq(UserRole::getRoleId, event.getRoleId()); - - // 批量查询关联用户ID - List userRoles = userRoleMapper.selectList(lambdaQueryWrapper); - List userIds = userRoles.stream().map(UserRole::getUserId).toList(); - roleHelper.updateUserRedisInfo(userIds); - } -} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdatedEvent.java b/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdatedEvent.java deleted file mode 100644 index bfbfe13..0000000 --- a/service/src/main/java/cn/bunny/services/service/system/helper/role/RoleUpdatedEvent.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.bunny.services.service.system.helper.role; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.context.ApplicationEvent; - -// 角色更新事件 -@Getter -@Setter -public class RoleUpdatedEvent extends ApplicationEvent { - private final Long roleId; - - public RoleUpdatedEvent(Object source, Long roleId) { - super(source); - this.roleId = roleId; - } -} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java index 6b2e078..1b5993b 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/DeptServiceImpl.java @@ -1,12 +1,12 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; +import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.system.system.dto.dept.DeptAddDto; import cn.bunny.services.domain.system.system.dto.dept.DeptDto; import cn.bunny.services.domain.system.system.dto.dept.DeptUpdateDto; import cn.bunny.services.domain.system.system.entity.Dept; import cn.bunny.services.domain.system.system.vo.DeptVo; -import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.system.DeptMapper; import cn.bunny.services.mapper.system.UserDeptMapper; @@ -35,6 +35,7 @@ import java.util.stream.Collectors; @Service @Transactional public class DeptServiceImpl extends ServiceImpl implements DeptService { + private static final String CACHE_NAMES = "dept"; @Resource private UserDeptMapper userDeptMapper; @@ -64,7 +65,7 @@ public class DeptServiceImpl extends ServiceImpl implements De * @return 所有部门列表 */ @Override - @Cacheable(cacheNames = "dept", key = "'deptList'", cacheManager = "cacheManagerWithMouth") + @Cacheable(cacheNames = CACHE_NAMES, key = "'deptList'", cacheManager = "cacheManagerWithMouth") public List getDeptPage() { return list().stream().map(dept -> { DeptVo deptVo = new DeptVo(); @@ -79,7 +80,7 @@ public class DeptServiceImpl extends ServiceImpl implements De * @param dto 部门添加 */ @Override - @CacheEvict(cacheNames = "dept", key = "'deptList'", beforeInvocation = true) + @CacheEvict(cacheNames = CACHE_NAMES, key = "'deptList'", beforeInvocation = true) public void addDept(DeptAddDto dto) { // 整理管理者人员 String mangerList = dto.getManager().stream().map(String::trim).collect(Collectors.joining(",")); @@ -98,7 +99,7 @@ public class DeptServiceImpl extends ServiceImpl implements De * @param dto 部门更新 */ @Override - @CacheEvict(cacheNames = "dept", key = "'deptList'", beforeInvocation = true) + @CacheEvict(cacheNames = CACHE_NAMES, key = "'deptList'", beforeInvocation = true) public void updateDept(DeptUpdateDto dto) { if (dto.getId().equals(dto.getParentId())) throw new AuthCustomerException(ResultCodeEnum.ILLEGAL_DATA_REQUEST); @@ -119,7 +120,7 @@ public class DeptServiceImpl extends ServiceImpl implements De * @param ids 删除id列表 */ @Override - @CacheEvict(cacheNames = "dept", key = "'deptList'", beforeInvocation = true) + @CacheEvict(cacheNames = CACHE_NAMES, key = "'deptList'", beforeInvocation = true) public void deleteDept(List ids) { // 判断数据请求是否为空 if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java index 4e095f6..a3dd484 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java @@ -1,9 +1,10 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.cache.UserAuthorizationCacheService; import cn.bunny.services.domain.common.constant.FileType; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.power.PermissionAddDto; import cn.bunny.services.domain.system.system.dto.power.PermissionDto; import cn.bunny.services.domain.system.system.dto.power.PermissionUpdateBatchByParentIdDto; @@ -13,9 +14,9 @@ import cn.bunny.services.domain.system.system.vo.PermissionVo; import cn.bunny.services.excel.PermissionExcelListener; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.system.PermissionMapper; -import cn.bunny.services.mapper.system.RolePermissionMapper; import cn.bunny.services.service.system.PermissionService; import cn.bunny.services.service.system.helper.PermissionHelper; +import cn.bunny.services.service.system.helper.UserServiceHelper; import cn.bunny.services.utils.FileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.fastjson2.JSON; @@ -29,6 +30,7 @@ import jakarta.validation.Valid; import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; +import org.springframework.cache.annotation.Caching; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -56,9 +58,13 @@ import java.util.zip.ZipOutputStream; @Service @Transactional public class PermissionServiceImpl extends ServiceImpl implements PermissionService { + private static final String CACHE_NAMES = "permission"; @Resource - private RolePermissionMapper rolePermissionMapper; + private UserAuthorizationCacheService userAuthorizationCacheService; + + @Resource + private UserServiceHelper userServiceHelper; /** * * 权限 服务实现类 @@ -80,12 +86,12 @@ public class PermissionServiceImpl extends ServiceImpl getPermissionList() { List permissionList = list(); return permissionList.stream().map(power -> { @@ -101,7 +107,9 @@ public class PermissionServiceImpl extends ServiceImpl permissionList = list(Wrappers.lambdaQuery().eq(Permission::getId, id)); @@ -125,33 +135,40 @@ public class PermissionServiceImpl extends ServiceImpl ids) { // 判断数据请求是否为空 if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); + // 删除缓存中所有这个权限关联的用户,角色和权限信息 + userServiceHelper.updateBatchUserRedisInfoByPermissionId(ids); + // 删除权限 removeByIds(ids); - - // 删除角色部门相关 - rolePermissionMapper.deleteBatchPowerIds(ids); } /** - * * 批量修改权限父级 + * 批量修改权限父级 * * @param dto 批量修改权限表单 */ @Override - @CacheEvict(cacheNames = "permission", key = "'permissionList'", beforeInvocation = true) + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'permissionList'", beforeInvocation = true), + }) public void updatePermissionListByParentId(PermissionUpdateBatchByParentIdDto dto) { List permissionList = dto.getIds().stream().map(id -> { Permission permission = new Permission(); @@ -160,6 +177,9 @@ public class PermissionServiceImpl extends ServiceImpl permissionExcelList = list().stream().map(permission -> { PermissionExcel permissionExcel = new PermissionExcel(); BeanUtils.copyProperties(permission, permissionExcel); @@ -213,12 +232,15 @@ public class PermissionServiceImpl extends ServiceImpl ids = list.stream().map(PermissionUpdateDto::getId).toList(); + userServiceHelper.updateBatchUserRedisInfoByPermissionId(ids); } + } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java index 59f3ebe..e26aaf0 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java @@ -8,7 +8,7 @@ import cn.bunny.services.mapper.system.RolePermissionMapper; import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.mapper.system.UserRoleMapper; import cn.bunny.services.service.system.RolePermissionService; -import cn.bunny.services.service.system.helper.role.RoleHelper; +import cn.bunny.services.service.system.helper.UserServiceHelper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; @@ -33,10 +33,10 @@ public class RolePermissionServiceImpl extends ServiceImpl getPermissionListByRoleId(Long id) { - List rolePermissionList = baseMapper.selectPowerListByRoleId(id); + List rolePermissionList = baseMapper.selectRolePermissionListByRoleId(id); return rolePermissionList.stream() .map(rolePermission -> rolePermission.getPowerId().toString()) .toList(); } /** - * * 为角色分配权限 + * 为角色分配权限 * * @param dto 为角色分配权限表单 */ @@ -84,8 +84,7 @@ public class RolePermissionServiceImpl extends ServiceImpl userIds = adminUsers.stream().map(AdminUser::getId).toList(); - roleHelper.updateUserRedisInfo(userIds); + // 更新角色绑定的用户 + userServiceHelper.updateBatchUserRedisInfoByRoleId(List.of(roleId)); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java index 158d2c2..eca8e3b 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java @@ -1,13 +1,12 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.RoleExcel; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.role.RoleAddDto; import cn.bunny.services.domain.system.system.dto.role.RoleDto; import cn.bunny.services.domain.system.system.dto.role.RoleUpdateDto; import cn.bunny.services.domain.system.system.entity.Role; -import cn.bunny.services.domain.system.system.entity.UserRole; import cn.bunny.services.domain.system.system.vo.RoleVo; import cn.bunny.services.excel.RoleExcelListener; import cn.bunny.services.exception.AuthCustomerException; @@ -16,7 +15,7 @@ import cn.bunny.services.mapper.system.RolePermissionMapper; import cn.bunny.services.mapper.system.RouterRoleMapper; import cn.bunny.services.mapper.system.UserRoleMapper; import cn.bunny.services.service.system.RoleService; -import cn.bunny.services.service.system.helper.role.RoleUpdatedEvent; +import cn.bunny.services.service.system.helper.UserServiceHelper; import cn.bunny.services.utils.FileUtil; import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -28,7 +27,7 @@ import jakarta.validation.Valid; import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; -import org.springframework.context.ApplicationEventPublisher; +import org.springframework.cache.annotation.Caching; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -57,6 +56,7 @@ import java.util.zip.ZipOutputStream; @Service @Transactional public class RoleServiceImpl extends ServiceImpl implements RoleService { + private static final String CACHE_NAMES = "role"; @Resource private UserRoleMapper userRoleMapper; @@ -68,10 +68,10 @@ public class RoleServiceImpl extends ServiceImpl implements Ro private RouterRoleMapper routerRoleMapper; @Resource - private ApplicationEventPublisher eventPublisher; + private UserServiceHelper userServiceHelper; /** - * * 角色 服务实现类 + * 角色 服务实现类 * * @param pageParams 角色分页查询page对象 * @param dto 角色分页查询对象 @@ -95,7 +95,7 @@ public class RoleServiceImpl extends ServiceImpl implements Ro * @return 所有角色列表 */ @Override - @Cacheable(cacheNames = "role", key = "'roleList'", cacheManager = "cacheManagerWithMouth") + @Cacheable(cacheNames = CACHE_NAMES, key = "'roleList'", cacheManager = "cacheManagerWithMouth") public List roleList() { return list().stream().map(role -> { RoleVo roleVo = new RoleVo(); @@ -152,11 +152,14 @@ public class RoleServiceImpl extends ServiceImpl implements Ro /** * 使用Excel更新角色列表 + * 不做任何操作有需要让用户重新登录 * * @param file Excel文件 */ @Override - @CacheEvict(cacheNames = "role", key = "'roleList'", beforeInvocation = true) + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'roleList'", beforeInvocation = true), + }) public void updateRoleByFile(MultipartFile file) { if (file == null) { throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); @@ -166,6 +169,7 @@ public class RoleServiceImpl extends ServiceImpl implements Ro try { fileInputStream = file.getInputStream(); EasyExcel.read(fileInputStream, RoleExcel.class, new RoleExcelListener(this)).sheet().doRead(); + } catch (IOException e) { throw new AuthCustomerException(ResultCodeEnum.UPLOAD_ERROR); } @@ -177,7 +181,9 @@ public class RoleServiceImpl extends ServiceImpl implements Ro * @param dto 角色添加 */ @Override - @CacheEvict(cacheNames = "role", key = "'roleList'", beforeInvocation = true) + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'roleList'", beforeInvocation = true), + }) public void addRole(@Valid RoleAddDto dto) { Role role = new Role(); BeanUtils.copyProperties(dto, role); @@ -185,15 +191,39 @@ public class RoleServiceImpl extends ServiceImpl implements Ro } /** - * 更新角色 + * 更新角色信息及关联用户缓存 * - * @param dto 角色更新 + *

    功能说明

    + *
      + *
    1. 更新角色基础信息
    2. + *
    3. 触发关联用户权限信息更新(通过事件机制异步处理)
    4. + *
    5. 清理相关缓存数据
    6. + *
    + * + *

    处理流程

    + *
      + *
    1. 校验角色是否存在
    2. + *
    3. 更新角色实体信息
    4. + *
    5. 清理角色列表和用户角色列表缓存
    6. + *
    + * + *

    注意事项

    + *
      + *
    • 使用 {@code @CacheEvict} 在方法执行前清理缓存,保证数据一致性
    • + *
    • 通过事件机制解耦用户权限更新操作,提高响应速度
    • + *
    + * + * @param dto 角色更新数据传输对象,包含角色ID和更新字段 + * @throws AuthCustomerException 当指定角色不存在时抛出(错误码:DATA_NOT_EXIST) */ @Override - @CacheEvict(cacheNames = "role", key = "'roleList'", beforeInvocation = true) + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'roleList'", beforeInvocation = true), + }) public void updateRole(@Valid RoleUpdateDto dto) { // 查询更新的角色是否存在 - List roleList = list(Wrappers.lambdaQuery().eq(Role::getId, dto.getId())); + Long roleId = dto.getId(); + List roleList = list(Wrappers.lambdaQuery().eq(Role::getId, roleId)); if (roleList.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.DATA_NOT_EXIST); // 更新内容 @@ -201,37 +231,28 @@ public class RoleServiceImpl extends ServiceImpl implements Ro BeanUtils.copyProperties(dto, role); updateById(role); - // 找到所有和当前更新角色相同的用户,并更新Redis中用户信息 - List userIds = userRoleMapper.selectList(Wrappers.lambdaQuery().eq(UserRole::getRoleId, dto.getId())) - .stream().map(UserRole::getUserId).toList(); - // TODO 1 - // roleUtil.updateUserRedisInfo(userIds); // 发布角色更新事件 - eventPublisher.publishEvent(new RoleUpdatedEvent(this, dto.getId())); + userServiceHelper.updateBatchUserRedisInfoByRoleId(List.of(roleId)); } - /** * 删除|批量删除角色 + * 做的物理删除,已经将角色路由、角色权限做了外键 * * @param ids 删除id列表 */ @Override - @CacheEvict(cacheNames = "role", key = "'roleList'", beforeInvocation = true) + @Caching(evict = { + @CacheEvict(cacheNames = CACHE_NAMES, key = "'roleList'", beforeInvocation = true), + }) public void deleteRole(List ids) { // 判断数据请求是否为空 if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); + // 重新构建角色和用户缓存 + userServiceHelper.updateBatchUserRedisInfoByRoleId(ids); + // 删除角色 removeByIds(ids); - - // 删除角色权限相关 - rolePermissionMapper.deleteBatchRoleIds(ids); - - // 删除角色和用户相关 - userRoleMapper.deleteBatchIdsByRoleIds(ids); - - // 删除角色和路由相关 - routerRoleMapper.deleteBatchIdsByRoleIds(ids); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java index a176923..1149886 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java @@ -22,6 +22,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; import org.springframework.beans.BeanUtils; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; @@ -43,6 +45,7 @@ import java.util.stream.Collectors; @Service @Transactional public class RouterServiceImpl extends ServiceImpl implements RouterService { + private static final String CACHE_NAMES = "router"; @Resource private RouterRoleMapper routerRoleMapper; @@ -95,6 +98,7 @@ public class RouterServiceImpl extends ServiceImpl impleme * @return 系统菜单表 */ @Override + @Cacheable(cacheNames = CACHE_NAMES, key = "'routerList'", cacheManager = "cacheManagerWithMouth") public List routerList() { // 查询菜单路由 List routerList = baseMapper.selectRouterList(); @@ -124,11 +128,12 @@ public class RouterServiceImpl extends ServiceImpl impleme } /** - * * 添加路由菜单 + * 添加路由菜单 * * @param dto 添加菜单表单 */ @Override + @CacheEvict(cacheNames = CACHE_NAMES, key = "'routerList'", beforeInvocation = true) public void addRouter(RouterAddDto dto) { // 添加路由 Router router = new Router(); @@ -154,6 +159,7 @@ public class RouterServiceImpl extends ServiceImpl impleme * @param dto 更新表单 */ @Override + @CacheEvict(cacheNames = CACHE_NAMES, key = "'routerList'", beforeInvocation = true) public void updateRouter(RouterUpdateDto dto) { // 更新路由 Router router = new Router(); @@ -181,6 +187,7 @@ public class RouterServiceImpl extends ServiceImpl impleme * @param ids 删除id列表 */ @Override + @CacheEvict(cacheNames = CACHE_NAMES, key = "'routerList'", beforeInvocation = true) public void deletedRouterByIds(List ids) { // 判断数据请求是否为空 if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java index 4e816de..4a6501e 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java @@ -1,12 +1,14 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.cache.EmailCacheService; +import cn.bunny.services.cache.UserCacheService; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.enums.EmailTemplateEnums; import cn.bunny.services.domain.common.enums.LoginEnums; -import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.common.enums.ResultCodeEnum; +import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateByLocalUserDto; import cn.bunny.services.domain.system.system.dto.user.LoginDto; @@ -19,7 +21,7 @@ import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.minio.MinioHelper; import cn.bunny.services.service.configuration.helper.email.ConcreteSenderEmailTemplate; import cn.bunny.services.service.system.UserLoginService; -import cn.bunny.services.service.system.helper.UserLoginHelper; +import cn.bunny.services.service.system.helper.UserServiceHelper; import cn.bunny.services.service.system.helper.login.DefaultLoginStrategy; import cn.bunny.services.service.system.helper.login.EmailLoginStrategy; import cn.bunny.services.service.system.helper.login.LoginContext; @@ -32,34 +34,41 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; -import jakarta.validation.Valid; import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeanUtils; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import java.util.HashMap; -import java.util.concurrent.TimeUnit; @Service public class UserLoginServiceImpl extends ServiceImpl implements UserLoginService { + @Resource - private UserLoginHelper userloginHelper; - @Resource - private RedisTemplate redisTemplate; + private UserServiceHelper userServiceHelper; + @Resource private PasswordEncoder passwordEncoder; + @Resource private UserMapper userMapper; + @Resource private EmailTemplateMapper emailTemplateMapper; + @Resource private ConcreteSenderEmailTemplate concreteSenderEmailTemplate; + @Resource private MinioHelper minioHelper; + @Resource + private UserCacheService userCacheService; + + @Resource + private EmailCacheService emailCacheService; + /** * 前台用户登录接口 * 这里不用判断用户是否为空,因为在登录时已经校验过了 @@ -78,7 +87,7 @@ public class UserLoginServiceImpl extends ServiceImpl imp // 默认的登录方式 loginStrategyHashMap.put(LoginEnums.default_STRATEGY.getValue(), new DefaultLoginStrategy(userMapper)); // 注册邮箱 - loginStrategyHashMap.put(LoginEnums.EMAIL_STRATEGY.getValue(), new EmailLoginStrategy(redisTemplate, userMapper)); + loginStrategyHashMap.put(LoginEnums.EMAIL_STRATEGY.getValue(), new EmailLoginStrategy(emailCacheService, userMapper)); // 使用登录上下文调用登录策略 LoginContext loginContext = new LoginContext(loginStrategyHashMap); @@ -102,9 +111,26 @@ public class UserLoginServiceImpl extends ServiceImpl imp // 登录结束后的操作 loginContext.loginAfter(loginDto, user); - user.setUpdateUser(user.getId()); + // 获取IP地址并更新用户登录信息, + String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr(); + String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion(); + // 设置用户IP地址,并更新用户信息 + user.setIpAddress(ipAddr); + user.setIpRegion(ipRegion); + + // 设置用户创建用户id 和 更新用户id user.setCreateUser(user.getId()); - return userloginHelper.buildLoginUserVo(user, loginDto.getReadMeDay()); + user.setUpdateUser(user.getId()); + updateById(user); + + // 构建用户返回对象 + Long readMeDay = loginDto.getReadMeDay(); + LoginVo loginVo = userCacheService.buildLoginUserVo(user, readMeDay); + + // 将用户登录保存在用户登录日志表中 + userServiceHelper.setUserLoginLog(user, loginVo.getToken(), UserConstant.LOGIN); + + return loginVo; } /** @@ -150,12 +176,10 @@ public class UserLoginServiceImpl extends ServiceImpl imp // 发送邮件 concreteSenderEmailTemplate.sendEmailTemplate(email, emailTemplate, hashMap); - - // 在Redis中存储验证码 - String emailCodePrefix = RedisUserConstant.getAdminUserEmailCodePrefix(email); - redisTemplate.opsForValue().set(emailCodePrefix, emailCode, RedisUserConstant.REDIS_EXPIRATION_TIME, TimeUnit.MINUTES); + emailCacheService.buildEmailCodeCache(email, emailCode); } + /** * 刷新用户token * @@ -172,9 +196,10 @@ public class UserLoginServiceImpl extends ServiceImpl imp if (adminUser == null) throw new AuthCustomerException(ResultCodeEnum.USER_IS_EMPTY); if (adminUser.getStatus()) throw new AuthCustomerException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED); - LoginVo buildUserVo = userloginHelper.buildLoginUserVo(adminUser, dto.getReadMeDay()); + // 构建 LoginVo 对象 + LoginVo loginVo = userCacheService.buildLoginUserVo(adminUser, dto.getReadMeDay()); RefreshTokenVo refreshTokenVo = new RefreshTokenVo(); - BeanUtils.copyProperties(buildUserVo, refreshTokenVo); + BeanUtils.copyProperties(loginVo, refreshTokenVo); return refreshTokenVo; } @@ -197,16 +222,17 @@ public class UserLoginServiceImpl extends ServiceImpl imp AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); adminUser.setIpAddress(ipAddr); adminUser.setIpRegion(ipRegion); - userloginHelper.setUserLoginLog(adminUser, token, UserConstant.LOGOUT); + userServiceHelper.setUserLoginLog(adminUser, token, UserConstant.LOGOUT); // 删除Redis中用户信息 - String loginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername()); - redisTemplate.delete(loginInfoPrefix); + String username = adminUser.getUsername(); + + userCacheService.deleteUserCache(username); } /** - * * 更新本地用户信息 + * 更新本地用户信息 * * @param dto 用户信息 */ @@ -223,23 +249,20 @@ public class UserLoginServiceImpl extends ServiceImpl imp dto.setAvatar(userAvatar); // 更新用户 - AdminUser adminUser = new AdminUser(); - adminUser.setId(userId); - BeanUtils.copyProperties(dto, adminUser); - updateById(adminUser); + BeanUtils.copyProperties(dto, user); + updateById(user); // 重新生成用户信息到Redis中 - BeanUtils.copyProperties(dto, user); - userloginHelper.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); + userCacheService.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); } /** - * * 更新本地用户密码 + * 更新本地用户密码 * * @param password 更新本地用户密码 */ @Override - public void updateUserPasswordByLocalUser(@Valid String password) { + public void updateUserPasswordByLocalUser(String password) { // 根据当前用户查询用户信息 Long userId = BaseContext.getUserId(); AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); @@ -249,18 +272,20 @@ public class UserLoginServiceImpl extends ServiceImpl imp // 数据库中的密码 String dbPassword = adminUser.getPassword(); - password = passwordEncoder.encode(password); // 判断数据库中密码是否和更新用户密码相同 - if (dbPassword.equals(password)) throw new AuthCustomerException(ResultCodeEnum.NEW_PASSWORD_SAME_OLD_PASSWORD); + if (passwordEncoder.matches(password, dbPassword)) { + throw new AuthCustomerException(ResultCodeEnum.NEW_PASSWORD_SAME_OLD_PASSWORD); + } // 更新用户密码 + String encodePassword = passwordEncoder.encode(password); adminUser = new AdminUser(); adminUser.setId(userId); - adminUser.setPassword(password); + adminUser.setPassword(encodePassword); updateById(adminUser); - // 删除Redis中登录用户信息 - redisTemplate.delete(RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername())); + // 删除Redis中登录用户信息、角色、权限信息 + userCacheService.deleteUserCache(adminUser.getUsername()); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java index c6cc21a..d269dd5 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java @@ -1,8 +1,6 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.context.BaseContext; -import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.domain.common.model.vo.LoginVo; +import cn.bunny.services.cache.UserCacheService; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.AssignRolesToUsersDto; import cn.bunny.services.domain.system.system.entity.AdminUser; @@ -11,16 +9,13 @@ import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.mapper.system.UserRoleMapper; import cn.bunny.services.service.system.UserRoleService; -import cn.bunny.services.service.system.helper.UserLoginHelper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.concurrent.TimeUnit; /** *

    @@ -34,14 +29,14 @@ import java.util.concurrent.TimeUnit; @Transactional public class UserRoleServiceImpl extends ServiceImpl implements UserRoleService { - @Resource - private UserLoginHelper userloginHelper; @Resource private UserRoleMapper userRoleMapper; + @Resource private UserMapper userMapper; + @Resource - private RedisTemplate redisTemplate; + private UserCacheService userCacheService; /** * * 根据用户id获取角色列表 @@ -58,7 +53,7 @@ public class UserRoleServiceImpl extends ServiceImpl i } /** - * * 为用户分配角色 + * 为用户分配角色 * * @param dto 用户分配角色 */ @@ -85,13 +80,7 @@ public class UserRoleServiceImpl extends ServiceImpl i }).toList(); saveBatch(roleList); - // 获取记住我时间 - LoginVo loginVo = BaseContext.getLoginVo(); - Long readMeDay = loginVo != null ? loginVo.getReadMeDay() : RedisUserConstant.REDIS_EXPIRATION_TIME; - // 重新设置Redis中的用户存储信息vo对象 - String username = adminUser.getUsername(); - loginVo = userloginHelper.buildLoginUserVo(adminUser, readMeDay); - redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(username), loginVo, readMeDay, TimeUnit.DAYS); + userCacheService.updateUserRedisInfo(List.of(userId)); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java index 6a3ca71..739aacf 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java @@ -1,11 +1,12 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.cache.RedisService; +import cn.bunny.services.cache.UserCacheService; import cn.bunny.services.domain.common.constant.MinioConstant; -import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.constant.UserConstant; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.files.dto.FileUploadDto; import cn.bunny.services.domain.system.files.vo.FileInfoVo; import cn.bunny.services.domain.system.log.entity.UserLoginLog; @@ -25,12 +26,8 @@ import cn.bunny.services.mapper.system.UserDeptMapper; import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.mapper.system.UserRoleMapper; import cn.bunny.services.minio.MinioHelper; -import cn.bunny.services.redis.RedisService; import cn.bunny.services.service.system.FilesService; import cn.bunny.services.service.system.UserService; -import cn.bunny.services.service.system.helper.UserLoginHelper; -import cn.bunny.services.utils.IpUtil; -import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -39,8 +36,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; import jakarta.validation.Valid; import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -60,29 +55,36 @@ import java.util.List; @Transactional public class UserServiceImpl extends ServiceImpl implements UserService { - @Resource - private UserLoginHelper userloginHelper; @Resource private PasswordEncoder passwordEncoder; - @Resource - private RedisTemplate redisTemplate; + @Resource private FilesService filesService; + @Resource private UserDeptMapper userDeptMapper; + @Resource private UserRoleMapper userRoleMapper; + @Resource private UserLoginLogMapper userLoginLogMapper; + @Resource private RoleMapper roleMapper; + @Resource private MinioHelper minioHelper; - @Autowired + + @Resource private RedisService redisService; + @Resource + private UserCacheService userCacheService; + + /** - * * 获取用户信息 + * 获取用户信息 * * @param id 用户id * @return 用户信息 @@ -119,15 +121,7 @@ public class UserServiceImpl extends ServiceImpl implemen *

  1. 清除登录状态:删除Redis中的用户登录信息
  2. *
* - *

注意事项

- *
    - *
  • 会中断用户当前会话,无需用户确认
  • - *
  • 操作会记录到用户登录日志,用于审计追踪
  • - *
  • Redis键使用用户名作为唯一标识
  • - *
- * * @param id 用户ID(不可为空) - * @see RedisUserConstant#getAdminLoginInfoPrefix Redis键生成规则 * @see UserConstant#FORCE_LOGOUT 强制下线类型常量 */ @Override @@ -136,7 +130,6 @@ public class UserServiceImpl extends ServiceImpl implemen // 根据id查询用户登录前缀 AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, id)); - String adminLoginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername()); // 将用户登录保存在用户登录日志表中 UserLoginLog userLoginLog = new UserLoginLog(); @@ -147,18 +140,19 @@ public class UserServiceImpl extends ServiceImpl implemen userLoginLogMapper.insert(userLoginLog); // 删除Redis中用户信息 - redisTemplate.delete(adminLoginInfoPrefix); + String username = adminUser.getUsername(); + userCacheService.deleteUserCache(username); } /** - * * 查询用户 + * 查询用户 * * @param keyword 查询用户信息关键字 * @return 用户信息列表 */ @Override public List getUserListByKeyword(String keyword) { - // 如果没有输入 + // 如果没有输入,返回前20条用户信息 if (!StringUtils.hasText(keyword)) { Page page = Page.of(1, 20); LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery().eq(AdminUser::getStatus, false); @@ -186,25 +180,20 @@ public class UserServiceImpl extends ServiceImpl implemen * @return 分页查询结果 */ @Override - public PageResult getCacheUserPage(Page pageParams) { + public PageResult getCacheUserPage(Page pageParams) { long pageNum = pageParams.getCurrent(); long pageSize = pageParams.getSize(); List keys = redisService.scannerRedisKeyByPage(pageNum, pageSize); - List list = keys.stream().map(key -> { - Object object = redisTemplate.opsForValue().get(key); - LoginVo loginVo = JSON.parseObject(JSON.toJSONString(object), LoginVo.class); + List list = keys.stream().map(key -> { + LoginVo loginVo = userCacheService.getLoginVoByUsername(key); - // 隐藏IP地址 - String ip = IpUtil.replaceIp(loginVo.getIpAddress()); - loginVo.setIpAddress(ip); - - loginVo.setPassword("********"); - - return loginVo; + UserVo userVo = new UserVo(); + BeanUtils.copyProperties(loginVo, userVo); + return userVo; }).toList(); - return PageResult.builder() + return PageResult.builder() .pageNo(pageNum).pageSize(pageSize) .list(list).total((long) keys.size()) .build(); @@ -212,7 +201,7 @@ public class UserServiceImpl extends ServiceImpl implemen /** - * * 用户信息 服务实现类 + * 用户信息 服务实现类 * * @param pageParams 用户信息分页查询page对象 * @param dto 用户信息分页查询对象 @@ -244,7 +233,7 @@ public class UserServiceImpl extends ServiceImpl implemen } /** - * * 添加用户信息 + * 添加用户信息 * 需要确认用户名-username是唯一的 * 需要确认邮箱-email是唯一的 * @@ -253,12 +242,12 @@ public class UserServiceImpl extends ServiceImpl implemen @Override public void addUserByAdmin(@Valid AdminUserAddDto dto) { // 对密码加密 - String encode = passwordEncoder.encode(dto.getPassword()); + String encodePassword = passwordEncoder.encode(dto.getPassword()); // 保存数据 AdminUser adminUser = new AdminUser(); BeanUtils.copyProperties(dto, adminUser); - adminUser.setPassword(encode); + adminUser.setPassword(encodePassword); save(adminUser); // 插入用户部门关系表 @@ -287,7 +276,7 @@ public class UserServiceImpl extends ServiceImpl implemen if (adminUser == null) throw new AuthCustomerException(ResultCodeEnum.DATA_NOT_EXIST); // 更新用户 - adminUser = new AdminUser(); + // AdminUser user = new AdminUser(); BeanUtils.copyProperties(dto, adminUser); // 部门Id @@ -306,16 +295,14 @@ public class UserServiceImpl extends ServiceImpl implemen // 更新头像 uploadAvatarByAdmin(dto, adminUser); - // 构建用户返回信息,同步到redis - userloginHelper.buildLoginUserVo(adminUser, RedisUserConstant.REDIS_EXPIRATION_TIME); - // 更新密码,放在最后,如果更新密码就将密码删除 updateUserPasswordByAdmin(adminUser); + // 更新用户信息 updateById(adminUser); - // 删除Redis中用户信息 - String loginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(adminUser.getUsername()); - redisTemplate.delete(loginInfoPrefix); + + // 同步到 Redis + userCacheService.updateUserRedisInfo(List.of(adminUser.getId())); } /** @@ -333,18 +320,25 @@ public class UserServiceImpl extends ServiceImpl implemen List roleList = list.stream().filter(role -> role.getRoleCode().equals("admin") || ids.contains(1L)).toList(); if (!roleList.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.ADMIN_ROLE_CAN_NOT_DELETED); - // 逻辑删除 - removeByIds(ids); + // 清除Redis中数据 + List adminUserList = list(Wrappers.lambdaQuery().eq(AdminUser::getId, ids)); + adminUserList.parallelStream().forEach(adminUser -> { + String username = adminUser.getUsername(); + userCacheService.deleteLoginUserCache(username); + }); // 删除部门相关 userDeptMapper.deleteBatchIdsByUserIds(ids); // 删除用户角色相关 userRoleMapper.deleteBatchIdsByUserIds(ids); + + // 逻辑删除 + removeByIds(ids); } /** - * * 管理员修改管理员用户密码 + * 管理员修改管理员用户密码 * * @param adminUser 管理员用户修改密码 */ From 382f0e4e929d64ebf07f08756a11b5070f260fc0 Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Tue, 6 May 2025 10:55:41 +0800 Subject: [PATCH 3/4] =?UTF-8?q?:art:=20feat:=20=E6=94=B9=E8=BF=9B=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E5=AF=BC=E5=87=BAzip=E6=96=B9=E6=A1=88;=E5=92=8C?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/impl/PermissionServiceImplTest.java | 38 ++++ .../services/processor/TreeProcessor.java | 18 ++ auth-core/src/test/java/MinioTest.java | 14 -- .../src/test/java/cn/bunny/JDBCTest.java | 99 --------- .../src/test/java/cn/bunny/SqlParserTest.java | 105 --------- .../test/java/cn/bunny/StringFormatTest.java | 43 ---- .../src/test/java/cn/bunny/TimeTest.java | 14 -- .../service/impl/VmsServiceImplTest.java | 50 ----- .../cn/bunny/utils/DatabaseInfoCoreTest.java | 75 ------- .../services/cache/UserCacheService.java | 202 ------------------ .../{ => core}/cache/EmailCacheService.java | 2 +- .../{ => core}/cache/RedisService.java | 2 +- .../cache/UserAuthorizationCacheService.java | 2 +- .../services/core/cache/UserCacheService.java | 25 +++ .../cache/UserLoginVoBuilderCacheService.java | 105 +++++++++ .../{ => core}/excel/I18nExcelListener.java | 2 +- .../excel/PermissionExcelListener.java | 2 +- .../{ => core}/excel/RoleExcelListener.java | 4 +- .../strategy/export/ExcelExportStrategy.java | 35 +++ .../core/strategy/export/ExportStrategy.java | 8 + .../strategy/export/JsonExportStrategy.java | 22 ++ .../strategy}/login/DefaultLoginStrategy.java | 2 +- .../strategy}/login/EmailLoginStrategy.java | 4 +- .../strategy}/login/LoginContext.java | 2 +- .../strategy}/login/LoginStrategy.java | 2 +- .../helper => core/strategy}/login/ReadMe.md | 0 .../template/PermissionTreeProcessor.java | 28 +++ .../email/AbstractSenderEmailTemplate.java | 4 +- .../email/ConcreteSenderEmailTemplate.java | 2 +- .../utils/RoleHelper.java} | 4 +- .../utils/RouterServiceHelper.java} | 6 +- .../utils}/UserServiceHelper.java | 65 +++++- .../service/PermissionCheckService.java | 6 +- .../service/TokenValidationService.java | 2 +- .../configuration/helper/i18n/I18nHelper.java | 122 ----------- .../configuration/impl/I18nServiceImpl.java | 60 +++++- .../system/helper/PermissionHelper.java | 123 ----------- .../system/impl/PermissionServiceImpl.java | 47 ++-- .../impl/RolePermissionServiceImpl.java | 2 +- .../service/system/impl/RoleServiceImpl.java | 5 +- .../system/impl/RouterServiceImpl.java | 12 +- .../system/impl/UserLoginServiceImpl.java | 31 +-- .../system/impl/UserRoleServiceImpl.java | 6 +- .../service/system/impl/UserServiceImpl.java | 13 +- 44 files changed, 489 insertions(+), 926 deletions(-) create mode 100644 auh-api/src/test/java/impl/PermissionServiceImplTest.java create mode 100644 auth-core/src/main/java/cn/bunny/services/processor/TreeProcessor.java delete mode 100644 auth-core/src/test/java/MinioTest.java delete mode 100644 generator-code/src/test/java/cn/bunny/JDBCTest.java delete mode 100644 generator-code/src/test/java/cn/bunny/SqlParserTest.java delete mode 100644 generator-code/src/test/java/cn/bunny/StringFormatTest.java delete mode 100644 generator-code/src/test/java/cn/bunny/TimeTest.java delete mode 100644 generator-code/src/test/java/cn/bunny/service/impl/VmsServiceImplTest.java delete mode 100644 generator-code/src/test/java/cn/bunny/utils/DatabaseInfoCoreTest.java delete mode 100644 service/src/main/java/cn/bunny/services/cache/UserCacheService.java rename service/src/main/java/cn/bunny/services/{ => core}/cache/EmailCacheService.java (97%) rename service/src/main/java/cn/bunny/services/{ => core}/cache/RedisService.java (97%) rename service/src/main/java/cn/bunny/services/{ => core}/cache/UserAuthorizationCacheService.java (99%) create mode 100644 service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java create mode 100644 service/src/main/java/cn/bunny/services/core/cache/UserLoginVoBuilderCacheService.java rename service/src/main/java/cn/bunny/services/{ => core}/excel/I18nExcelListener.java (98%) rename service/src/main/java/cn/bunny/services/{ => core}/excel/PermissionExcelListener.java (98%) rename service/src/main/java/cn/bunny/services/{ => core}/excel/RoleExcelListener.java (98%) create mode 100644 service/src/main/java/cn/bunny/services/core/strategy/export/ExcelExportStrategy.java create mode 100644 service/src/main/java/cn/bunny/services/core/strategy/export/ExportStrategy.java create mode 100644 service/src/main/java/cn/bunny/services/core/strategy/export/JsonExportStrategy.java rename service/src/main/java/cn/bunny/services/{service/system/helper => core/strategy}/login/DefaultLoginStrategy.java (95%) rename service/src/main/java/cn/bunny/services/{service/system/helper => core/strategy}/login/EmailLoginStrategy.java (95%) rename service/src/main/java/cn/bunny/services/{service/system/helper => core/strategy}/login/LoginContext.java (95%) rename service/src/main/java/cn/bunny/services/{service/system/helper => core/strategy}/login/LoginStrategy.java (91%) rename service/src/main/java/cn/bunny/services/{service/system/helper => core/strategy}/login/ReadMe.md (100%) create mode 100644 service/src/main/java/cn/bunny/services/core/template/PermissionTreeProcessor.java rename service/src/main/java/cn/bunny/services/{service/configuration/helper => core/template}/email/AbstractSenderEmailTemplate.java (98%) rename service/src/main/java/cn/bunny/services/{service/configuration/helper => core/template}/email/ConcreteSenderEmailTemplate.java (96%) rename service/src/main/java/cn/bunny/services/{service/system/helper/RoleServiceHelper.java => core/utils/RoleHelper.java} (96%) rename service/src/main/java/cn/bunny/services/{service/system/helper/RouterHelper.java => core/utils/RouterServiceHelper.java} (97%) rename service/src/main/java/cn/bunny/services/{service/system/helper => core/utils}/UserServiceHelper.java (61%) delete mode 100644 service/src/main/java/cn/bunny/services/service/configuration/helper/i18n/I18nHelper.java delete mode 100644 service/src/main/java/cn/bunny/services/service/system/helper/PermissionHelper.java diff --git a/auh-api/src/test/java/impl/PermissionServiceImplTest.java b/auh-api/src/test/java/impl/PermissionServiceImplTest.java new file mode 100644 index 0000000..248e4b1 --- /dev/null +++ b/auh-api/src/test/java/impl/PermissionServiceImplTest.java @@ -0,0 +1,38 @@ +package impl; + +import cn.bunny.services.AuthServiceApplication; +import cn.bunny.services.core.template.PermissionTreeProcessor; +import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; +import cn.bunny.services.domain.system.system.entity.Permission; +import cn.bunny.services.mapper.system.PermissionMapper; +import com.alibaba.fastjson2.JSON; +import org.junit.jupiter.api.Test; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +@SpringBootTest(classes = AuthServiceApplication.class) +class PermissionServiceImplTest { + + @Autowired + private PermissionMapper permissionMapper; + + @Test + void exportPermission() { + + List permissionList = permissionMapper.selectList(null); + List permissionExcelList = permissionList.stream().map(permission -> { + PermissionExcel permissionExcel = new PermissionExcel(); + BeanUtils.copyProperties(permission, permissionExcel); + + return permissionExcel; + }).toList(); + + PermissionTreeProcessor permissionTreeProcessor = new PermissionTreeProcessor(); + List buildTree = permissionTreeProcessor.process(permissionExcelList); + + System.out.println(JSON.toJSONString(buildTree)); + } +} \ No newline at end of file diff --git a/auth-core/src/main/java/cn/bunny/services/processor/TreeProcessor.java b/auth-core/src/main/java/cn/bunny/services/processor/TreeProcessor.java new file mode 100644 index 0000000..a0b3f87 --- /dev/null +++ b/auth-core/src/main/java/cn/bunny/services/processor/TreeProcessor.java @@ -0,0 +1,18 @@ +package cn.bunny.services.processor; + +import java.util.List; + +/* 构建树型结构模板处理器 */ +public abstract class TreeProcessor { + public final List process(List list) { + List roots = findRoots(list); + for (T root : roots) { + buildChildren(root, list); + } + return roots; + } + + protected abstract List findRoots(List list); + + protected abstract void buildChildren(T parent, List list); +} diff --git a/auth-core/src/test/java/MinioTest.java b/auth-core/src/test/java/MinioTest.java deleted file mode 100644 index 28930c3..0000000 --- a/auth-core/src/test/java/MinioTest.java +++ /dev/null @@ -1,14 +0,0 @@ -import org.junit.jupiter.api.Test; - -import java.text.SimpleDateFormat; -import java.util.Date; - -public class MinioTest { - - @Test - void test() { - SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM-dd"); - String date = formatter.format(new Date()); - System.out.println(date); - } -} diff --git a/generator-code/src/test/java/cn/bunny/JDBCTest.java b/generator-code/src/test/java/cn/bunny/JDBCTest.java deleted file mode 100644 index 2753380..0000000 --- a/generator-code/src/test/java/cn/bunny/JDBCTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package cn.bunny; - - -import cn.bunny.core.TypeConvertCore; -import cn.bunny.dao.entity.ColumnMetaData; -import cn.bunny.dao.entity.TableMetaData; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -@SpringBootTest -public class JDBCTest { - - DatabaseMetaData metaData; - - private final DataSource dataSource; - - public JDBCTest(DataSource dataSource) { - this.dataSource = dataSource; - } - - - @BeforeEach - public void setUp() throws Exception { - try (Connection connection = dataSource.getConnection()) { - metaData = connection.getMetaData(); - } - } - - @Test - void testComment() throws SQLException { - String tableName = "sys_i18n"; - TableMetaData tableMetaData; - ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"}); - - // 获取表的注释信息 - if (tables.next()) { - String remarks = tables.getString("REMARKS"); - String tableCat = tables.getString("TABLE_CAT"); - - tableMetaData = TableMetaData.builder() - .tableName(tableName) - .comment(remarks) - .tableCat(tableCat) - .build(); - - System.out.println(tableMetaData); - } - } - - @Test - void testAllTableComment() throws SQLException { - ResultSet tables = metaData.getTables(null, null, "%", new String[]{"TABLE"}); - List list = new ArrayList<>(); - - while (tables.next()) { - String tableName = tables.getString("TABLE_NAME"); - String remarks = tables.getString("REMARKS"); - String tableCat = tables.getString("TABLE_CAT"); - - TableMetaData tableMetaData = TableMetaData.builder() - .tableName(tableName).comment(remarks) - .tableCat(tableCat) - .build(); - list.add(tableMetaData); - } - - System.out.println(list); - } - - @Test - void testColumnInfo() throws SQLException { - List columns = new ArrayList<>(); - - try (ResultSet columnsRs = metaData.getColumns(null, null, "sys_i18n", null)) { - while (columnsRs.next()) { - ColumnMetaData column = new ColumnMetaData(); - column.setColumnName(columnsRs.getString("COLUMN_NAME")); - column.setLowercaseName(TypeConvertCore.convertToCamelCase(column.getColumnName())); - column.setJdbcType(columnsRs.getString("TYPE_NAME")); - column.setJavaType(TypeConvertCore.convertToJavaType(column.getJdbcType())); - column.setComment(columnsRs.getString("REMARKS")); - - columns.add(column); - System.out.println(column); - } - } - - System.out.println(columns); - } -} diff --git a/generator-code/src/test/java/cn/bunny/SqlParserTest.java b/generator-code/src/test/java/cn/bunny/SqlParserTest.java deleted file mode 100644 index 859ef28..0000000 --- a/generator-code/src/test/java/cn/bunny/SqlParserTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package cn.bunny; - -import cn.bunny.core.TypeConvertCore; -import cn.bunny.dao.entity.ColumnMetaData; -import cn.bunny.dao.entity.TableMetaData; -import net.sf.jsqlparser.JSQLParserException; -import net.sf.jsqlparser.parser.CCJSqlParserUtil; -import net.sf.jsqlparser.statement.Statement; -import net.sf.jsqlparser.statement.create.table.CreateTable; -import org.apache.commons.lang3.StringUtils; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class SqlParserTest { - - @Test - public void test() throws JSQLParserException { - String sql = """ - CREATE TABLE `sys_files` ( - `id` bigint NOT NULL COMMENT '文件的唯一标识符,自动递增', - `filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件的名称', - `filepath` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件在服务器上的存储路径', - `file_size` int NOT NULL COMMENT '文件的大小,以字节为单位', - `file_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文件的MIME类型', - `download_count` int NULL DEFAULT 0 COMMENT '下载数量', - `create_user` bigint NOT NULL COMMENT '创建用户', - `update_user` bigint NULL DEFAULT NULL COMMENT '操作用户', - `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录文件最后修改的时间戳', - `is_deleted` tinyint(1) UNSIGNED ZEROFILL NOT NULL DEFAULT 0 COMMENT '文件是否被删除', - PRIMARY KEY (`id`) USING BTREE, - INDEX `idx_filename`(`filename` ASC) USING BTREE COMMENT '索引文件名', - INDEX `idx_filepath`(`filepath` ASC) USING BTREE COMMENT '索引文件路径', - INDEX `idx_file_type`(`file_type` ASC) USING BTREE COMMENT '索引文件类型', - INDEX `idx_update_user`(`update_user` ASC) USING BTREE COMMENT '索引创更新用户', - INDEX `idx_create_user`(`create_user` ASC) USING BTREE COMMENT '索引创建用户', - INDEX `idx_user`(`update_user` ASC, `create_user` ASC) USING BTREE COMMENT '索引创建用户和更新用户', - INDEX `idx_time`(`update_time` ASC, `create_time` ASC) USING BTREE COMMENT '索引创建时间和更新时间' - ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统文件表' ROW_FORMAT = DYNAMIC; - """; - - TableMetaData tableInfo = new TableMetaData(); - - // 解析sql - Statement statement = CCJSqlParserUtil.parse(sql); - if (!(statement instanceof CreateTable createTable)) { - throw new IllegalArgumentException("Not a CREATE TABLE statement"); - } - - // 设置表基本信息 - tableInfo.setTableName(createTable.getTable().getName()); - tableInfo.setTableType("TABLE"); - String tableOptionsStrings = String.join(" ", createTable.getTableOptionsStrings()); - - // 注释信息 - Pattern pattern = Pattern.compile("COMMENT\\s*=\\s*'(.*?)'", Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(tableOptionsStrings); - if (matcher.find()) { - tableInfo.setComment(matcher.group(1)); - } - - // 解析列信息 - List columnMetaData = createTable.getColumnDefinitions() - .stream().map(column -> { - // 列信息 - ColumnMetaData columnInfo = new ColumnMetaData(); - - // 列名称 - columnInfo.setColumnName(column.getColumnName()); - - // 设置 JDBC 类型 - String dataType = column.getColDataType().getDataType(); - columnInfo.setJdbcType(dataType); - - // 设置 Java 类型 - String javaType = TypeConvertCore.convertToJavaType(dataType.contains("varchar") ? "varchar" : dataType); - columnInfo.setJavaType(javaType); - - // 设置 JavaScript 类型 - columnInfo.setJavascriptType(StringUtils.uncapitalize(javaType)); - - // 列字段转成 下划线 -> 小驼峰 - columnInfo.setLowercaseName(TypeConvertCore.convertToCamelCase(column.getColumnName())); - // 列字段转成 下划线 -> 大驼峰名称 - columnInfo.setUppercaseName(TypeConvertCore.convertToCamelCase(column.getColumnName(), true)); - - // 解析注释 - List columnSpecs = column.getColumnSpecs(); - String columnSpecsString = String.join(" ", columnSpecs); - Matcher columnSpecsStringMatcher = Pattern.compile("COMMENT\\s*'(.*?)'", Pattern.CASE_INSENSITIVE).matcher(columnSpecsString); - if (columnSpecsStringMatcher.find()) { - columnInfo.setComment(columnSpecsStringMatcher.group(1)); - } - - return columnInfo; - }).toList(); - - System.out.println(tableInfo); - System.out.println("----------------------------------------------------------------------------------------"); - System.out.println(columnMetaData); - } -} diff --git a/generator-code/src/test/java/cn/bunny/StringFormatTest.java b/generator-code/src/test/java/cn/bunny/StringFormatTest.java deleted file mode 100644 index f9a2680..0000000 --- a/generator-code/src/test/java/cn/bunny/StringFormatTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.bunny; - -import cn.bunny.core.TypeConvertCore; -import org.apache.commons.lang3.StringUtils; -import org.assertj.core.util.introspection.CaseFormatUtils; -import org.junit.jupiter.api.Test; - -public class StringFormatTest { - - @Test - void test1() { - System.out.println(CaseFormatUtils.toCamelCase("user_login" )); - System.out.println(CaseFormatUtils.toCamelCase("userLogin" )); - System.out.println(CaseFormatUtils.toCamelCase("UserLogin" )); - - System.out.println("--------------------------------" ); - - System.out.println(StringUtils.lowerCase("user_login" )); - System.out.println(StringUtils.lowerCase("userLogin" )); - System.out.println(StringUtils.lowerCase("UserLogin" )); - - System.out.println("--------------------------------" ); - - System.out.println(StringUtils.upperCase("user_login" )); - System.out.println(StringUtils.upperCase("userLogin" )); - System.out.println(StringUtils.upperCase("UserLogin" )); - } - - @Test - void test2() { - System.out.println(TypeConvertCore.convertToCamelCase("user_login_A" )); - System.out.println(TypeConvertCore.convertToCamelCase("User_Login_A" )); - System.out.println(TypeConvertCore.convertToCamelCase("userLoginA" )); - System.out.println(TypeConvertCore.convertToCamelCase("UserLoginA" )); - - System.out.println("--------------------------------" ); - - System.out.println(TypeConvertCore.convertToCamelCase("i18n_type_A" , true)); - System.out.println(TypeConvertCore.convertToCamelCase("User_Login_A" , true)); - System.out.println(TypeConvertCore.convertToCamelCase("userLoginA" , true)); - System.out.println(TypeConvertCore.convertToCamelCase("UserLoginA" , true)); - } -} diff --git a/generator-code/src/test/java/cn/bunny/TimeTest.java b/generator-code/src/test/java/cn/bunny/TimeTest.java deleted file mode 100644 index a765a7a..0000000 --- a/generator-code/src/test/java/cn/bunny/TimeTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.bunny; - -import cn.hutool.crypto.digest.MD5; -import org.junit.jupiter.api.Test; - -public class TimeTest { - @Test - void timeTest() { - long currentTimeMillis = System.currentTimeMillis(); - String digestHex = MD5.create().digestHex(currentTimeMillis + ""); - System.out.println(currentTimeMillis); - System.out.println(digestHex); - } -} diff --git a/generator-code/src/test/java/cn/bunny/service/impl/VmsServiceImplTest.java b/generator-code/src/test/java/cn/bunny/service/impl/VmsServiceImplTest.java deleted file mode 100644 index 58ddb9b..0000000 --- a/generator-code/src/test/java/cn/bunny/service/impl/VmsServiceImplTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.bunny.service.impl; - -import cn.bunny.core.ResourceFileCore; -import cn.bunny.dao.vo.VmsPathVo; -import com.alibaba.fastjson2.JSON; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -class VmsServiceImplTest { - - - @Test - void vmsResourcePathList() throws IOException, URISyntaxException { - List vmsFiles = ResourceFileCore.getAbsoluteFiles("vms"); - System.out.println(vmsFiles); - - System.out.println("--------------------------------------------------------------"); - - List vmsRelativeFiles = ResourceFileCore.getRelativeFiles("vms"); - System.out.println(vmsRelativeFiles); - - System.out.println("--------------------------集合对象模式------------------------------------"); - - Map> map = vmsRelativeFiles.stream().map(vmFile -> { - String[] filepathList = vmFile.split("/"); - String filename = filepathList[filepathList.length - 1].replace(".vm", ""); - - return VmsPathVo.builder().name(vmFile).label(filename).type(filepathList[0]).build(); - }).collect(Collectors.groupingBy(VmsPathVo::getType)); - - System.out.println(JSON.toJSONString(map)); - - System.out.println("----------------------------二维数组格式----------------------------------"); - List> listMap = vmsRelativeFiles.stream().map(vmFile -> { - String[] filepathList = vmFile.split("/"); - String filename = filepathList[filepathList.length - 1].replace(".vm", ""); - - return VmsPathVo.builder().name(vmFile).label(filename).type(filepathList[0]).build(); - }) - .collect(Collectors.groupingBy(VmsPathVo::getType)) - .values().stream().toList(); - - System.out.println(JSON.toJSONString(listMap)); - } -} \ No newline at end of file diff --git a/generator-code/src/test/java/cn/bunny/utils/DatabaseInfoCoreTest.java b/generator-code/src/test/java/cn/bunny/utils/DatabaseInfoCoreTest.java deleted file mode 100644 index 033ffd1..0000000 --- a/generator-code/src/test/java/cn/bunny/utils/DatabaseInfoCoreTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package cn.bunny.utils; - -import cn.bunny.dao.entity.TableMetaData; -import lombok.SneakyThrows; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.List; - -@SpringBootTest -class DatabaseInfoCoreTest { - - String tableName = "sys_i18n"; - - @Autowired - private DataSource dataSource; - - - @Test - void testTableInfoMetaData() { - TableMetaData tableMetaData; - - try (Connection connection = dataSource.getConnection()) { - DatabaseMetaData metaData = connection.getMetaData(); - ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"}); - - // 获取表的注释信息 - if (tables.next()) { - String remarks = tables.getString("REMARKS"); - String tableCat = tables.getString("TABLE_CAT"); - String tableType = tables.getString("TABLE_TYPE"); - - tableMetaData = TableMetaData.builder() - .tableName(tableName) - .comment(remarks) - .tableCat(tableCat) - .tableType(tableType) - .build(); - } else { - throw new RuntimeException("数据表不存在"); - } - - System.out.println(tableMetaData); - - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @SneakyThrows - @Test - void getDbTableList() { - String dbName = "auth_admin"; - - try (Connection connection = dataSource.getConnection()) { - DatabaseMetaData metaData = connection.getMetaData(); - ResultSet tables = metaData.getTables(dbName, null, "%", new String[]{"TABLE"}); - - List list = new ArrayList<>(); - - while (tables.next()) { - dbName = tables.getString("TABLE_NAME"); - list.add(dbName); - } - - System.out.println(list); - } - } -} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/cache/UserCacheService.java b/service/src/main/java/cn/bunny/services/cache/UserCacheService.java deleted file mode 100644 index 1c23781..0000000 --- a/service/src/main/java/cn/bunny/services/cache/UserCacheService.java +++ /dev/null @@ -1,202 +0,0 @@ -package cn.bunny.services.cache; - -import cn.bunny.services.domain.common.constant.LocalDateTimeConstant; -import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.domain.common.model.vo.LoginVo; -import cn.bunny.services.domain.system.system.entity.AdminUser; -import cn.bunny.services.domain.system.system.entity.Permission; -import cn.bunny.services.domain.system.system.entity.Role; -import cn.bunny.services.mapper.system.PermissionMapper; -import cn.bunny.services.mapper.system.RoleMapper; -import cn.bunny.services.mapper.system.UserMapper; -import cn.bunny.services.minio.MinioHelper; -import cn.bunny.services.service.system.helper.RoleServiceHelper; -import cn.bunny.services.utils.JwtTokenUtil; -import com.alibaba.fastjson2.JSON; -import jakarta.annotation.Resource; -import org.springframework.beans.BeanUtils; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Service; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -@Service -public class UserCacheService { - - @Resource - private RedisTemplate redisTemplate; - - @Resource - private MinioHelper minioHelper; - - @Resource - private UserMapper userMapper; - - @Resource - private RoleMapper roleMapper; - - @Resource - private PermissionMapper permissionMapper; - - @Resource - private UserAuthorizationCacheService userAuthorizationCacheService; - - /** - * 根据用户名获取缓存中内容 - * - * @param username 用户名 - * @return LoginVo - */ - public LoginVo getLoginVoByUsername(String username) { - Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(username)); - return JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); - } - - /** - * 构建用户登录返回对象(LoginVo) 更新用户相关就用这个包括登录 - * - *

主要处理流程:

- *
    - *
  1. 参数校验:检查用户对象是否为空
  2. - *
  3. 权限处理: - *
      - *
    • 查询用户角色和权限数据
    • - *
    • 非管理员用户:从数据库加载权限信息
    • - *
    • 管理员用户:通过RoleUtil.checkAdmin()自动设置管理员权限
    • - *
    • (可选)对角色和权限列表去重
    • - *
    - *
  4. - *
  5. 信息装配: - *
      - *
    • 记录用户IP等访问信息
    • - *
    • 使用BeanUtils.copyProperties()复制用户基础属性
    • - *
    • 设置记住我功能及token过期时间
    • - *
    - *
  6. - *
  7. 缓存处理:将完整用户信息存入Redis
  8. - *
- * - *

注意事项:

- *
    - *
  • 属性复制操作放在流程最后,确保所有字段正确同步
  • - *
  • IP信息需要同时更新到用户实体和返回对象
  • - *
- * - * @param user 用户实体对象(不可为空) - * @param readMeDay 记住我时长(单位:天) - * @return 完整的登录响应对象 - * @throws IllegalArgumentException 当用户对象为空时抛出 - */ - public LoginVo buildLoginUserVo(AdminUser user, long readMeDay) { - String username = user.getUsername(); - Long userId = user.getId(); - - // 用户角色 - List roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList()); - - // 判断是否是 admin 如果是admin 赋予所有权限 - List permissions = new ArrayList<>(); - boolean isAdmin = RoleServiceHelper.checkAdmin(roles, permissions, user); - if (!isAdmin) { - permissions = permissionMapper.selectListByUserId(userId).stream() - .map(Permission::getPowerCode) - .toList(); - } - - // 为这两个去重,在判断 checkAdmin 会重新赋值 - permissions = permissions.stream().distinct().toList(); - roles = roles.stream().distinct().toList(); - - // 设置用户返回对象 - LoginVo loginVo = new LoginVo(); - BeanUtils.copyProperties(user, loginVo); - loginVo.setPersonDescription(user.getSummary()); - loginVo.setRoles(roles); - loginVo.setPermissions(permissions); - - // 使用用户名创建token - String token = JwtTokenUtil.createToken(userId, username, (int) readMeDay); - loginVo.setToken(token); - loginVo.setRefreshToken(token); - loginVo.setReadMeDay(readMeDay); - - // 计算过期时间,并格式化返回 - LocalDateTime localDateTime = LocalDateTime.now(); - LocalDateTime plusDay = localDateTime.plusDays(readMeDay); - DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_SLASH); - String expires = plusDay.format(dateTimeFormatter); - loginVo.setExpires(expires); - - // 设置用户头像 - String userAvatar = minioHelper.getUserAvatar(user.getAvatar()); - loginVo.setAvatar(userAvatar); - - String loginInfoPrefix = RedisUserConstant.getUserLoginInfoPrefix(username); - redisTemplate.opsForValue().set(loginInfoPrefix, loginVo, readMeDay, TimeUnit.DAYS); - return loginVo; - } - - /** - * 批量更新Redis中用户权限信息,设计用户和角色就用这个 - * - *

使用场景:当用户角色或权限变更时,同步更新Redis中的用户权限数据

- * - *

实现策略

- *
    - *
  1. 主动更新(当前实现):重新构建用户权限信息并更新Redis缓存
  2. - *
  3. 强制下线:删除用户登录态,强制重新认证获取最新权限
  4. - *
- * - *

技术实现

- *
    - *
  • 采用Spring事件驱动机制触发更新
  • - *
  • 使用并行流(parallelStream)提高批量处理效率
  • - *
  • 仅更新Redis中存在登录态的用户
  • - *
- * - * @param userIds 需要更新的用户ID集合 - * (仅处理集合中存在的有效用户) - * @see RedisUserConstant Redis键前缀常量 - */ - public void updateUserRedisInfo(List userIds) { - if (userIds.isEmpty()) return; - - // 批量查询用户 - List adminUsers = userMapper.selectBatchIds(userIds); - // 并行处理用户更新 - adminUsers.stream() - .filter(user -> redisTemplate.hasKey(RedisUserConstant.getUserLoginInfoPrefix(user.getUsername()))) - .forEach(user -> { - // 更新时清除缓存中的角色和权限 - String username = user.getUsername(); - userAuthorizationCacheService.deleteRoleAndPermissionCache(username); - - // 更新用户权限信息 - buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); - }); - } - - /** - * 清除用户登录时的缓存 - * - * @param username 用户名 - */ - public void deleteLoginUserCache(String username) { - String userRolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(username); - redisTemplate.delete(userRolesCodePrefix); - } - - /** - * 清除用户登录时的缓存 - * - * @param username 用户名 - */ - public void deleteUserCache(String username) { - userAuthorizationCacheService.deleteRoleAndPermissionCache(username); - deleteLoginUserCache(username); - } -} diff --git a/service/src/main/java/cn/bunny/services/cache/EmailCacheService.java b/service/src/main/java/cn/bunny/services/core/cache/EmailCacheService.java similarity index 97% rename from service/src/main/java/cn/bunny/services/cache/EmailCacheService.java rename to service/src/main/java/cn/bunny/services/core/cache/EmailCacheService.java index 2476ba4..a3118e4 100644 --- a/service/src/main/java/cn/bunny/services/cache/EmailCacheService.java +++ b/service/src/main/java/cn/bunny/services/core/cache/EmailCacheService.java @@ -1,4 +1,4 @@ -package cn.bunny.services.cache; +package cn.bunny.services.core.cache; import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.enums.ResultCodeEnum; diff --git a/service/src/main/java/cn/bunny/services/cache/RedisService.java b/service/src/main/java/cn/bunny/services/core/cache/RedisService.java similarity index 97% rename from service/src/main/java/cn/bunny/services/cache/RedisService.java rename to service/src/main/java/cn/bunny/services/core/cache/RedisService.java index 4d6e17f..207d6a9 100644 --- a/service/src/main/java/cn/bunny/services/cache/RedisService.java +++ b/service/src/main/java/cn/bunny/services/core/cache/RedisService.java @@ -1,4 +1,4 @@ -package cn.bunny.services.cache; +package cn.bunny.services.core.cache; import cn.bunny.services.domain.common.constant.RedisUserConstant; import jakarta.annotation.Resource; diff --git a/service/src/main/java/cn/bunny/services/cache/UserAuthorizationCacheService.java b/service/src/main/java/cn/bunny/services/core/cache/UserAuthorizationCacheService.java similarity index 99% rename from service/src/main/java/cn/bunny/services/cache/UserAuthorizationCacheService.java rename to service/src/main/java/cn/bunny/services/core/cache/UserAuthorizationCacheService.java index 4ebb9bf..3b19f6e 100644 --- a/service/src/main/java/cn/bunny/services/cache/UserAuthorizationCacheService.java +++ b/service/src/main/java/cn/bunny/services/core/cache/UserAuthorizationCacheService.java @@ -1,4 +1,4 @@ -package cn.bunny.services.cache; +package cn.bunny.services.core.cache; import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.system.system.entity.Permission; diff --git a/service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java b/service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java new file mode 100644 index 0000000..3122705 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java @@ -0,0 +1,25 @@ +package cn.bunny.services.core.cache; + +import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.domain.common.model.vo.LoginVo; +import com.alibaba.fastjson2.JSON; +import jakarta.annotation.Resource; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +@Service +public class UserCacheService { + @Resource + private RedisTemplate redisTemplate; + + /** + * 根据用户名获取缓存中内容 + * + * @param username 用户名 + * @return LoginVo + */ + public LoginVo getLoginVoByUsername(String username) { + Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(username)); + return JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); + } +} diff --git a/service/src/main/java/cn/bunny/services/core/cache/UserLoginVoBuilderCacheService.java b/service/src/main/java/cn/bunny/services/core/cache/UserLoginVoBuilderCacheService.java new file mode 100644 index 0000000..60861c4 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/cache/UserLoginVoBuilderCacheService.java @@ -0,0 +1,105 @@ +package cn.bunny.services.core.cache; + +import cn.bunny.services.core.utils.RoleHelper; +import cn.bunny.services.domain.common.constant.LocalDateTimeConstant; +import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.domain.common.model.vo.LoginVo; +import cn.bunny.services.domain.system.system.entity.AdminUser; +import cn.bunny.services.domain.system.system.entity.Permission; +import cn.bunny.services.domain.system.system.entity.Role; +import cn.bunny.services.mapper.system.PermissionMapper; +import cn.bunny.services.mapper.system.RoleMapper; +import cn.bunny.services.minio.MinioHelper; +import cn.bunny.services.utils.JwtTokenUtil; +import jakarta.annotation.Resource; +import lombok.Value; +import org.springframework.beans.BeanUtils; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Service +public class UserLoginVoBuilderCacheService { + + @Resource + private RedisTemplate redisTemplate; + + @Resource + private MinioHelper minioHelper; + + @Resource + private RoleMapper roleMapper; + + @Resource + private PermissionMapper permissionMapper; + + public LoginVo buildLoginUserVo(AdminUser user, long readMeDay) { + String username = user.getUsername(); + Long userId = user.getId(); + + UserAuthInfo authInfo = getAuthInfo(userId, user); + + // 设置用户返回对象 + LoginVo loginVo = new LoginVo(); + BeanUtils.copyProperties(user, loginVo); + loginVo.setPersonDescription(user.getSummary()); + loginVo.setRoles(authInfo.getRoles()); + loginVo.setPermissions(authInfo.getPermissions()); + + // 使用用户名创建token + String token = JwtTokenUtil.createToken(userId, username, (int) readMeDay); + loginVo.setToken(token); + loginVo.setRefreshToken(token); + loginVo.setReadMeDay(readMeDay); + + // 计算过期时间,并格式化返回 + String expires = calculateExpires(readMeDay); + loginVo.setExpires(expires); + + // 设置用户头像 + String userAvatar = minioHelper.getUserAvatar(user.getAvatar()); + loginVo.setAvatar(userAvatar); + + String loginInfoPrefix = RedisUserConstant.getUserLoginInfoPrefix(username); + redisTemplate.opsForValue().set(loginInfoPrefix, loginVo, readMeDay, TimeUnit.DAYS); + return loginVo; + } + + private UserAuthInfo getAuthInfo(Long userId, AdminUser user) { + // 用户角色 + List roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList()); + + // 判断是否是 admin 如果是admin 赋予所有权限 + List permissions = new ArrayList<>(); + boolean isAdmin = RoleHelper.checkAdmin(roles, permissions, user); + if (!isAdmin) { + permissions = permissionMapper.selectListByUserId(userId).stream() + .map(Permission::getPowerCode) + .toList(); + } + + // 为这两个去重,在判断 checkAdmin 会重新赋值 + permissions = permissions.stream().distinct().toList(); + roles = roles.stream().distinct().toList(); + + return new UserAuthInfo(roles, permissions); + } + + private String calculateExpires(long readMeDay) { + LocalDateTime localDateTime = LocalDateTime.now(); + LocalDateTime plusDay = localDateTime.plusDays(readMeDay); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_SLASH); + return plusDay.format(dateTimeFormatter); + } + + @Value + private static class UserAuthInfo { + List roles; + List permissions; + } +} diff --git a/service/src/main/java/cn/bunny/services/excel/I18nExcelListener.java b/service/src/main/java/cn/bunny/services/core/excel/I18nExcelListener.java similarity index 98% rename from service/src/main/java/cn/bunny/services/excel/I18nExcelListener.java rename to service/src/main/java/cn/bunny/services/core/excel/I18nExcelListener.java index e4e3a68..5d42d35 100644 --- a/service/src/main/java/cn/bunny/services/excel/I18nExcelListener.java +++ b/service/src/main/java/cn/bunny/services/core/excel/I18nExcelListener.java @@ -1,4 +1,4 @@ -package cn.bunny.services.excel; +package cn.bunny.services.core.excel; import cn.bunny.services.domain.common.model.dto.excel.I18nExcel; import cn.bunny.services.domain.system.i18n.entity.I18n; diff --git a/service/src/main/java/cn/bunny/services/excel/PermissionExcelListener.java b/service/src/main/java/cn/bunny/services/core/excel/PermissionExcelListener.java similarity index 98% rename from service/src/main/java/cn/bunny/services/excel/PermissionExcelListener.java rename to service/src/main/java/cn/bunny/services/core/excel/PermissionExcelListener.java index 4fbc8a6..6a92746 100644 --- a/service/src/main/java/cn/bunny/services/excel/PermissionExcelListener.java +++ b/service/src/main/java/cn/bunny/services/core/excel/PermissionExcelListener.java @@ -1,4 +1,4 @@ -package cn.bunny.services.excel; +package cn.bunny.services.core.excel; import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; import cn.bunny.services.domain.system.system.entity.Permission; diff --git a/service/src/main/java/cn/bunny/services/excel/RoleExcelListener.java b/service/src/main/java/cn/bunny/services/core/excel/RoleExcelListener.java similarity index 98% rename from service/src/main/java/cn/bunny/services/excel/RoleExcelListener.java rename to service/src/main/java/cn/bunny/services/core/excel/RoleExcelListener.java index 9ebbe95..cc92624 100644 --- a/service/src/main/java/cn/bunny/services/excel/RoleExcelListener.java +++ b/service/src/main/java/cn/bunny/services/core/excel/RoleExcelListener.java @@ -1,7 +1,7 @@ -package cn.bunny.services.excel; +package cn.bunny.services.core.excel; -import cn.bunny.services.domain.common.model.dto.excel.RoleExcel; import cn.bunny.services.domain.common.enums.ResultCodeEnum; +import cn.bunny.services.domain.common.model.dto.excel.RoleExcel; import cn.bunny.services.domain.system.system.entity.Role; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.service.system.RoleService; diff --git a/service/src/main/java/cn/bunny/services/core/strategy/export/ExcelExportStrategy.java b/service/src/main/java/cn/bunny/services/core/strategy/export/ExcelExportStrategy.java new file mode 100644 index 0000000..56063e4 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/strategy/export/ExcelExportStrategy.java @@ -0,0 +1,35 @@ +package cn.bunny.services.core.strategy.export; + +import com.alibaba.excel.EasyExcel; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class ExcelExportStrategy implements ExportStrategy> { + + private final Class clazz; + private final String sheetName; + + public ExcelExportStrategy(Class clazz, String sheetName) { + this.clazz = clazz; + this.sheetName = sheetName; + } + + @Override + public void export(List data, ZipOutputStream zipOutputStream, String filename) { + try { + ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream(); + EasyExcel.write(excelOutputStream, clazz).sheet(sheetName).doWrite(data); + + // 将Excel写入到Zip中 + ZipEntry zipEntry = new ZipEntry(filename); + zipOutputStream.putNextEntry(zipEntry); + zipOutputStream.write(excelOutputStream.toByteArray()); + zipOutputStream.closeEntry(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/core/strategy/export/ExportStrategy.java b/service/src/main/java/cn/bunny/services/core/strategy/export/ExportStrategy.java new file mode 100644 index 0000000..7c364ee --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/strategy/export/ExportStrategy.java @@ -0,0 +1,8 @@ +package cn.bunny.services.core.strategy.export; + +import java.io.IOException; +import java.util.zip.ZipOutputStream; + +public interface ExportStrategy { + void export(T data, ZipOutputStream zipOutputStream, String filename) throws IOException; +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/core/strategy/export/JsonExportStrategy.java b/service/src/main/java/cn/bunny/services/core/strategy/export/JsonExportStrategy.java new file mode 100644 index 0000000..6f6dc01 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/strategy/export/JsonExportStrategy.java @@ -0,0 +1,22 @@ +package cn.bunny.services.core.strategy.export; + +import com.alibaba.fastjson2.JSON; + +import java.nio.charset.StandardCharsets; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class JsonExportStrategy implements ExportStrategy { + + @Override + public void export(Object data, ZipOutputStream zipOutputStream, String filename) { + try { + ZipEntry zipEntry = new ZipEntry(filename); + zipOutputStream.putNextEntry(zipEntry); + zipOutputStream.write(JSON.toJSONString(data).getBytes(StandardCharsets.UTF_8)); + zipOutputStream.closeEntry(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/DefaultLoginStrategy.java b/service/src/main/java/cn/bunny/services/core/strategy/login/DefaultLoginStrategy.java similarity index 95% rename from service/src/main/java/cn/bunny/services/service/system/helper/login/DefaultLoginStrategy.java rename to service/src/main/java/cn/bunny/services/core/strategy/login/DefaultLoginStrategy.java index 9962ed9..a97b2a7 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/login/DefaultLoginStrategy.java +++ b/service/src/main/java/cn/bunny/services/core/strategy/login/DefaultLoginStrategy.java @@ -1,4 +1,4 @@ -package cn.bunny.services.service.system.helper.login; +package cn.bunny.services.core.strategy.login; import cn.bunny.services.domain.system.system.dto.user.LoginDto; import cn.bunny.services.domain.system.system.entity.AdminUser; diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java b/service/src/main/java/cn/bunny/services/core/strategy/login/EmailLoginStrategy.java similarity index 95% rename from service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java rename to service/src/main/java/cn/bunny/services/core/strategy/login/EmailLoginStrategy.java index c1c7cad..cd548a1 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/login/EmailLoginStrategy.java +++ b/service/src/main/java/cn/bunny/services/core/strategy/login/EmailLoginStrategy.java @@ -1,6 +1,6 @@ -package cn.bunny.services.service.system.helper.login; +package cn.bunny.services.core.strategy.login; -import cn.bunny.services.cache.EmailCacheService; +import cn.bunny.services.core.cache.EmailCacheService; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.LoginDto; import cn.bunny.services.domain.system.system.entity.AdminUser; diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginContext.java b/service/src/main/java/cn/bunny/services/core/strategy/login/LoginContext.java similarity index 95% rename from service/src/main/java/cn/bunny/services/service/system/helper/login/LoginContext.java rename to service/src/main/java/cn/bunny/services/core/strategy/login/LoginContext.java index 2f67cae..ad99251 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginContext.java +++ b/service/src/main/java/cn/bunny/services/core/strategy/login/LoginContext.java @@ -1,4 +1,4 @@ -package cn.bunny.services.service.system.helper.login; +package cn.bunny.services.core.strategy.login; import cn.bunny.services.domain.system.system.dto.user.LoginDto; import cn.bunny.services.domain.system.system.entity.AdminUser; diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginStrategy.java b/service/src/main/java/cn/bunny/services/core/strategy/login/LoginStrategy.java similarity index 91% rename from service/src/main/java/cn/bunny/services/service/system/helper/login/LoginStrategy.java rename to service/src/main/java/cn/bunny/services/core/strategy/login/LoginStrategy.java index 3e2fb67..b96ce3f 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/login/LoginStrategy.java +++ b/service/src/main/java/cn/bunny/services/core/strategy/login/LoginStrategy.java @@ -1,4 +1,4 @@ -package cn.bunny.services.service.system.helper.login; +package cn.bunny.services.core.strategy.login; import cn.bunny.services.domain.system.system.dto.user.LoginDto; diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/login/ReadMe.md b/service/src/main/java/cn/bunny/services/core/strategy/login/ReadMe.md similarity index 100% rename from service/src/main/java/cn/bunny/services/service/system/helper/login/ReadMe.md rename to service/src/main/java/cn/bunny/services/core/strategy/login/ReadMe.md diff --git a/service/src/main/java/cn/bunny/services/core/template/PermissionTreeProcessor.java b/service/src/main/java/cn/bunny/services/core/template/PermissionTreeProcessor.java new file mode 100644 index 0000000..8f74ed8 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/template/PermissionTreeProcessor.java @@ -0,0 +1,28 @@ +package cn.bunny.services.core.template; + +import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; +import cn.bunny.services.processor.TreeProcessor; + +import java.util.List; +import java.util.stream.Collectors; + +public class PermissionTreeProcessor extends TreeProcessor { + @Override + public List findRoots(List list) { + return list.stream() + .filter(p -> p.getParentId() == null || p.getParentId() == 0) + .collect(Collectors.toList()); + } + + @Override + public void buildChildren(PermissionExcel parent, List list) { + List children = list.stream() + .filter(p -> parent.getId().equals(p.getParentId())) + .collect(Collectors.toList()); + + if (!children.isEmpty()) { + parent.setChildren(children); + children.forEach(child -> buildChildren(child, list)); + } + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/service/configuration/helper/email/AbstractSenderEmailTemplate.java b/service/src/main/java/cn/bunny/services/core/template/email/AbstractSenderEmailTemplate.java similarity index 98% rename from service/src/main/java/cn/bunny/services/service/configuration/helper/email/AbstractSenderEmailTemplate.java rename to service/src/main/java/cn/bunny/services/core/template/email/AbstractSenderEmailTemplate.java index 1665ad0..b3dad97 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/helper/email/AbstractSenderEmailTemplate.java +++ b/service/src/main/java/cn/bunny/services/core/template/email/AbstractSenderEmailTemplate.java @@ -1,9 +1,9 @@ -package cn.bunny.services.service.configuration.helper.email; +package cn.bunny.services.core.template.email; import cn.bunny.services.config.mail.MailSenderConfiguration; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.email.EmailSend; import cn.bunny.services.domain.common.model.dto.email.EmailSendInit; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.domain.system.email.entity.EmailUsers; import cn.bunny.services.exception.AuthCustomerException; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/helper/email/ConcreteSenderEmailTemplate.java b/service/src/main/java/cn/bunny/services/core/template/email/ConcreteSenderEmailTemplate.java similarity index 96% rename from service/src/main/java/cn/bunny/services/service/configuration/helper/email/ConcreteSenderEmailTemplate.java rename to service/src/main/java/cn/bunny/services/core/template/email/ConcreteSenderEmailTemplate.java index ea0d5f0..011fd26 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/helper/email/ConcreteSenderEmailTemplate.java +++ b/service/src/main/java/cn/bunny/services/core/template/email/ConcreteSenderEmailTemplate.java @@ -1,4 +1,4 @@ -package cn.bunny.services.service.configuration.helper.email; +package cn.bunny.services.core.template.email; import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.mapper.configuration.EmailTemplateMapper; diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/RoleServiceHelper.java b/service/src/main/java/cn/bunny/services/core/utils/RoleHelper.java similarity index 96% rename from service/src/main/java/cn/bunny/services/service/system/helper/RoleServiceHelper.java rename to service/src/main/java/cn/bunny/services/core/utils/RoleHelper.java index 54c189d..770e98c 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/RoleServiceHelper.java +++ b/service/src/main/java/cn/bunny/services/core/utils/RoleHelper.java @@ -1,4 +1,4 @@ -package cn.bunny.services.service.system.helper; +package cn.bunny.services.core.utils; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.common.constant.SecurityConfigConstant; @@ -6,7 +6,7 @@ import cn.bunny.services.domain.system.system.entity.AdminUser; import java.util.List; -public class RoleServiceHelper { +public class RoleHelper { /** * 判断用户是否具有管理员权限 diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/RouterHelper.java b/service/src/main/java/cn/bunny/services/core/utils/RouterServiceHelper.java similarity index 97% rename from service/src/main/java/cn/bunny/services/service/system/helper/RouterHelper.java rename to service/src/main/java/cn/bunny/services/core/utils/RouterServiceHelper.java index b29fb8a..084badb 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/RouterHelper.java +++ b/service/src/main/java/cn/bunny/services/core/utils/RouterServiceHelper.java @@ -1,4 +1,4 @@ -package cn.bunny.services.service.system.helper; +package cn.bunny.services.core.utils; import cn.bunny.services.context.BaseContext; import cn.bunny.services.domain.system.system.entity.RouterRole; @@ -20,7 +20,7 @@ import java.util.*; @Slf4j @Component -public class RouterHelper { +public class RouterServiceHelper { @Resource private RouterRoleService routerRoleService; @@ -89,7 +89,7 @@ public class RouterHelper { public List getWebUserRouterVos(List routerList, Map> routerRoleList, Map> rolePermissionList) { // 检查当前是否是 admin 用户 List roles = BaseContext.getLoginVo().getRoles(); - List allAuths = !RoleServiceHelper.checkAdmin(roles) ? new ArrayList<>() : List.of("*:*:*", "*:*", "*", "admin"); + List allAuths = !RoleHelper.checkAdmin(roles) ? new ArrayList<>() : List.of("*:*:*", "*:*", "*", "admin"); // 查询路由所有数据,整理前端需要的路和、角色、权限 return routerList.stream().map(view -> { diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/UserServiceHelper.java b/service/src/main/java/cn/bunny/services/core/utils/UserServiceHelper.java similarity index 61% rename from service/src/main/java/cn/bunny/services/service/system/helper/UserServiceHelper.java rename to service/src/main/java/cn/bunny/services/core/utils/UserServiceHelper.java index 83b1a3e..2395f05 100644 --- a/service/src/main/java/cn/bunny/services/service/system/helper/UserServiceHelper.java +++ b/service/src/main/java/cn/bunny/services/core/utils/UserServiceHelper.java @@ -1,16 +1,20 @@ -package cn.bunny.services.service.system.helper; +package cn.bunny.services.core.utils; -import cn.bunny.services.cache.UserCacheService; +import cn.bunny.services.core.cache.UserAuthorizationCacheService; +import cn.bunny.services.core.cache.UserLoginVoBuilderCacheService; +import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.system.log.entity.UserLoginLog; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.domain.system.system.entity.RolePermission; import cn.bunny.services.domain.system.system.entity.UserRole; import cn.bunny.services.mapper.log.UserLoginLogMapper; import cn.bunny.services.mapper.system.RolePermissionMapper; +import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.mapper.system.UserRoleMapper; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.BeanUtils; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.context.request.RequestContextHolder; @@ -25,7 +29,7 @@ public class UserServiceHelper { private UserRoleMapper userRoleMapper; @Resource - private UserCacheService userCacheService; + private UserLoginVoBuilderCacheService userLoginVoBuilderCacheService; @Resource private UserLoginLogMapper userLoginLogMapper; @@ -33,6 +37,15 @@ public class UserServiceHelper { @Resource private RolePermissionMapper rolePermissionMapper; + @Resource + private RedisTemplate redisTemplate; + + @Resource + private UserMapper userMapper; + + @Resource + private UserAuthorizationCacheService userAuthorizationCacheService; + /** * 设置用户登录日志内容 *

@@ -74,6 +87,31 @@ public class UserServiceHelper { userLoginLogMapper.insert(userLoginLog); } + /** + * 批量更新Redis中用户权限信息,设计用户和角色就用这个 + * + * @param userIds 需要更新的用户ID集合 + * (仅处理集合中存在的有效用户) + * @see RedisUserConstant Redis键前缀常量 + */ + public void updateUserRedisInfo(List userIds) { + if (userIds.isEmpty()) return; + + // 批量查询用户 + List adminUsers = userMapper.selectBatchIds(userIds); + // 并行处理用户更新 + adminUsers.stream() + .filter(user -> redisTemplate.hasKey(RedisUserConstant.getUserLoginInfoPrefix(user.getUsername()))) + .forEach(user -> { + // 更新时清除缓存中的角色和权限 + String username = user.getUsername(); + userAuthorizationCacheService.deleteRoleAndPermissionCache(username); + + // 更新用户权限信息 + userLoginVoBuilderCacheService.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); + }); + } + /** * 处理角色更新事件 * @@ -84,7 +122,7 @@ public class UserServiceHelper { // 批量查询关联用户ID List userRoles = userRoleMapper.selectListByRoleIds(roleIds); List userIds = userRoles.stream().map(UserRole::getUserId).toList(); - userCacheService.updateUserRedisInfo(userIds); + updateUserRedisInfo(userIds); } /** @@ -100,4 +138,23 @@ public class UserServiceHelper { updateBatchUserRedisInfoByRoleId(roleIds); } + /** + * 清除用户登录时的缓存 + * + * @param username 用户名 + */ + public void deleteLoginUserCache(String username) { + String userRolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(username); + redisTemplate.delete(userRolesCodePrefix); + } + + /** + * 清除用户登录时的缓存 + * + * @param username 用户名 + */ + public void deleteUserCache(String username) { + userAuthorizationCacheService.deleteRoleAndPermissionCache(username); + deleteLoginUserCache(username); + } } diff --git a/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java b/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java index 2aa2713..894d225 100644 --- a/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java +++ b/service/src/main/java/cn/bunny/services/security/service/PermissionCheckService.java @@ -1,11 +1,11 @@ package cn.bunny.services.security.service; -import cn.bunny.services.cache.UserAuthorizationCacheService; import cn.bunny.services.context.BaseContext; +import cn.bunny.services.core.cache.UserAuthorizationCacheService; +import cn.bunny.services.core.utils.RoleHelper; import cn.bunny.services.domain.system.system.entity.Permission; import cn.bunny.services.domain.system.system.entity.Role; import cn.bunny.services.security.config.WebSecurityConfig; -import cn.bunny.services.service.system.helper.RoleServiceHelper; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @@ -42,7 +42,7 @@ public class PermissionCheckService { List roleCodeList = roleList.stream().map(Role::getRoleCode).toList(); // 判断是否是管理员用户 - boolean checkedAdmin = RoleServiceHelper.checkAdmin(roleCodeList); + boolean checkedAdmin = RoleHelper.checkAdmin(roleCodeList); if (checkedAdmin) return true; // 判断请求地址是否是登录之后才需要访问的,已经登录了不需要验证的 diff --git a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java index 61fa2e2..e8740a5 100644 --- a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java +++ b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java @@ -1,6 +1,6 @@ package cn.bunny.services.security.service; -import cn.bunny.services.cache.UserCacheService; +import cn.bunny.services.core.cache.UserCacheService; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.security.TokenInfo; import cn.bunny.services.domain.common.model.vo.LoginVo; diff --git a/service/src/main/java/cn/bunny/services/service/configuration/helper/i18n/I18nHelper.java b/service/src/main/java/cn/bunny/services/service/configuration/helper/i18n/I18nHelper.java deleted file mode 100644 index a6a052c..0000000 --- a/service/src/main/java/cn/bunny/services/service/configuration/helper/i18n/I18nHelper.java +++ /dev/null @@ -1,122 +0,0 @@ -package cn.bunny.services.service.configuration.helper.i18n; - -import cn.bunny.services.domain.common.model.dto.excel.I18nExcel; -import cn.bunny.services.domain.system.i18n.entity.I18n; -import cn.bunny.services.service.configuration.impl.I18nServiceImpl; -import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson2.JSON; -import org.jetbrains.annotations.NotNull; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -public class I18nHelper { - /** - * 将国际化资源列表写入Excel并打包到ZIP输出流 - * - *

处理流程:

- *
    - *
  1. 按资源类型(typeName)分组 --- 多语言的类型,英文?中文?
  2. - *
  3. 每组数据生成单独多语言 key的Excel工作表
  4. - *
  5. 将Excel文件写入ZIP输出流
  6. - *
- * - * @param i18nList 国际化资源列表,包含key-value对和类型信息 - * @param zipOutputStream ZIP输出流,用于写入打包后的Excel文件 - * @throws RuntimeException 当IO操作失败时抛出 - */ - public static void writeExcel(List i18nList, ZipOutputStream zipOutputStream) { - Map> hashMap = i18nList.stream() - .collect(Collectors.groupingBy( - I18n::getTypeName, - Collectors.mapping((I18n i18n) -> { - String keyName = i18n.getKeyName(); - String translation = i18n.getTranslation(); - return I18nExcel.builder().keyName(keyName).translation(translation).build(); - }, Collectors.toList()) - )); - - - hashMap.forEach((key, value) -> { - try { - // 创建临时ByteArrayOutputStream - ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream(); - - ZipEntry zipEntry = new ZipEntry(key + ".xlsx"); - zipOutputStream.putNextEntry(zipEntry); - - // 先写入到临时流 - EasyExcel.write(excelOutputStream, I18nExcel.class).sheet(key).doWrite(value); - zipOutputStream.write(excelOutputStream.toByteArray()); - zipOutputStream.closeEntry(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - } - - /** - * 将国际化资源列表写入JSON并打包到ZIP输出流 - * - *

处理流程:

- *
    - *
  1. 按资源类型(typeName)分组 --- 多语言的类型,英文?中文?
  2. - *
  3. 每组数据生成单独多语言 key的Excel工作表
  4. - *
  5. 将JSON文件写入ZIP输出流
  6. - *
- * - * @param i18nList 国际化资源列表 - * @param zipOutputStream ZIP输出流 - * @throws RuntimeException 当IO操作失败时抛出 - */ - public static void writeJson(List i18nList, ZipOutputStream zipOutputStream) { - HashMap hashMap = getMapByI18nList(i18nList); - - hashMap.forEach((k, v) -> { - try { - ZipEntry zipEntry = new ZipEntry(k + ".json"); - zipOutputStream.putNextEntry(zipEntry); - - zipOutputStream.write(JSON.toJSONString(v).getBytes(StandardCharsets.UTF_8)); - zipOutputStream.closeEntry(); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - } - - /** - * 将国际化资源列表转换为结构化Map - * - *

转换规则:

- *
    - *
  • 外层Key: 资源类型(typeName)
  • - *
  • 内层Key: 资源键名(keyName)
  • - *
  • 值: 翻译文本(translation)
  • - *
- *

详细结构和结果示例看前端传递的 {@link I18nServiceImpl#getI18nMap} 控制器

- *

/api/i18n/public

- * - * @param i18nList 国际化资源列表 - * @return 结构化Map {typeName: {keyName: translation}} - * @throws IllegalArgumentException 当参数为null时抛出 - */ - @NotNull - public static HashMap getMapByI18nList(@NotNull List i18nList) { - // 整理集合 - Map> map = i18nList.stream() - .collect(Collectors.groupingBy( - I18n::getTypeName, - Collectors.toMap(I18n::getKeyName, I18n::getTranslation))); - - // 返回集合 - return new HashMap<>(map); - } -} diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java index c3d6993..a516725 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java @@ -1,5 +1,8 @@ package cn.bunny.services.service.configuration.impl; +import cn.bunny.services.core.excel.I18nExcelListener; +import cn.bunny.services.core.strategy.export.ExcelExportStrategy; +import cn.bunny.services.core.strategy.export.JsonExportStrategy; import cn.bunny.services.domain.common.constant.FileType; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.I18nExcel; @@ -12,12 +15,10 @@ import cn.bunny.services.domain.system.i18n.dto.I18nUpdateDto; import cn.bunny.services.domain.system.i18n.entity.I18n; import cn.bunny.services.domain.system.i18n.entity.I18nType; import cn.bunny.services.domain.system.i18n.vo.I18nVo; -import cn.bunny.services.excel.I18nExcelListener; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.I18nMapper; import cn.bunny.services.mapper.configuration.I18nTypeMapper; import cn.bunny.services.service.configuration.I18nService; -import cn.bunny.services.service.configuration.helper.i18n.I18nHelper; import cn.bunny.services.utils.FileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.fastjson2.JSON; @@ -29,6 +30,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; import jakarta.validation.Valid; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; @@ -47,6 +49,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import java.util.zip.ZipOutputStream; /** @@ -77,7 +80,7 @@ public class I18nServiceImpl extends ServiceImpl implements I1 I18nType i18nType = i18nTypeMapper.selectOne(Wrappers.lambdaQuery().eq(I18nType::getIsDefault, true)); List i18nList = list(); - HashMap hashMap = I18nHelper.getMapByI18nList(i18nList); + HashMap hashMap = getMapByI18nList(i18nList); hashMap.put("local", Objects.requireNonNull(i18nType.getTypeName(), "zh")); return hashMap; @@ -164,18 +167,35 @@ public class I18nServiceImpl extends ServiceImpl implements I1 @Override public ResponseEntity downloadI18n(String type) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) { + try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) { // 查找默认语言内容 List i18nList = list(); // 类型是Excel写入Excel if (type.equals(FileType.EXCEL)) { - I18nHelper.writeExcel(i18nList, zipOutputStream); + i18nList.stream() + .collect(Collectors.groupingBy( + I18n::getTypeName, + Collectors.mapping((I18n i18n) -> { + String keyName = i18n.getKeyName(); + String translation = i18n.getTranslation(); + return I18nExcel.builder().keyName(keyName).translation(translation).build(); + }, Collectors.toList()) + )) + .forEach((key, value) -> { + ExcelExportStrategy excelExportStrategy = new ExcelExportStrategy(I18nExcel.class, key); + excelExportStrategy.export(value, zipOutputStream, key + ".xlsx"); + }); } // 其他格式写入JSON else { - I18nHelper.writeJson(i18nList, zipOutputStream); + HashMap hashMap = getMapByI18nList(i18nList); + + hashMap.forEach((k, v) -> { + JsonExportStrategy jsonExportStrategy = new JsonExportStrategy(); + jsonExportStrategy.export(v, zipOutputStream, k + ".json"); + }); } // 设置响应头 @@ -241,4 +261,32 @@ public class I18nServiceImpl extends ServiceImpl implements I1 throw new RuntimeException(e); } } + + /** + * 将国际化资源列表转换为结构化Map + * + *

转换规则:

+ *
    + *
  • 外层Key: 资源类型(typeName)
  • + *
  • 内层Key: 资源键名(keyName)
  • + *
  • 值: 翻译文本(translation)
  • + *
+ *

详细结构和结果示例看前端传递的 {@link I18nServiceImpl#getI18nMap} 控制器

+ *

/api/i18n/public

+ * + * @param i18nList 国际化资源列表 + * @return 结构化Map {typeName: {keyName: translation}} + * @throws IllegalArgumentException 当参数为null时抛出 + */ + @NotNull + public HashMap getMapByI18nList(@NotNull List i18nList) { + // 整理集合 + Map> map = i18nList.stream() + .collect(Collectors.groupingBy( + I18n::getTypeName, + Collectors.toMap(I18n::getKeyName, I18n::getTranslation))); + + // 返回集合 + return new HashMap<>(map); + } } diff --git a/service/src/main/java/cn/bunny/services/service/system/helper/PermissionHelper.java b/service/src/main/java/cn/bunny/services/service/system/helper/PermissionHelper.java deleted file mode 100644 index 86708e4..0000000 --- a/service/src/main/java/cn/bunny/services/service/system/helper/PermissionHelper.java +++ /dev/null @@ -1,123 +0,0 @@ -package cn.bunny.services.service.system.helper; - -import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; -import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson2.JSON; - -import java.io.ByteArrayOutputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -/** - * 权限数据处理工具类 - * - *

提供权限数据的树形结构处理、扁平化处理以及导出功能

- */ -public class PermissionHelper { - - /** - * 将树形结构权限数据扁平化为列表 - * - *

使用递归处理树形结构

- * - * @param list 树形结构的权限列表,每个节点可能包含children子节点 - * @return 扁平化后的权限列表( - */ - public static List flattenTree(List list) { - List result = new ArrayList<>(); - - for (PermissionExcel node : list) { - result.add(node); - if (node.getChildren() != null && !node.getChildren().isEmpty()) { - result.addAll(flattenTree(node.getChildren())); - } - } - - return result; - } - - /** - * 递归设置子节点(内部方法) - * - *

为父节点查找并设置所有子节点,递归处理子节点的子节点

- * - * @param parent 当前父节点 - * @param list 完整的权限数据列表 - */ - private static void setChildren(PermissionExcel parent, List list) { - List children = list.stream() - .filter(p -> parent.getId().equals(p.getParentId())) - .toList(); - - if (!children.isEmpty()) { - parent.setChildren(children); - - for (PermissionExcel child : children) { - setChildren(child, list); - } - } - } - - /** - * 构建权限树形结构 - * - *

从扁平列表中构建树形结构,根节点的判断条件为parentId为null或0

- * - * @param list 扁平化的权限数据列表 - * @return 构建完成的树形结构列表(只包含根节点) - */ - public static List buildTree(List list) { - List permissionExcels = list.stream() - .filter(permissionExcel -> permissionExcel.getParentId() == null || permissionExcel.getParentId() == 0) - .toList(); - - for (PermissionExcel permission : permissionExcels) { - setChildren(permission, list); - } - return permissionExcels; - } - - /** - * 将权限数据写入JSON格式到ZIP压缩包 - * - * @param list 要导出的权限数据列表 - * @param zipOutputStream ZIP输出流 - * @param zipName 在ZIP包中的文件名 - */ - public static void writeJson(List list, ZipOutputStream zipOutputStream, String zipName) { - try { - ZipEntry zipEntry = new ZipEntry(zipName); - zipOutputStream.putNextEntry(zipEntry); - zipOutputStream.write(JSON.toJSONString(list).getBytes(StandardCharsets.UTF_8)); - zipOutputStream.closeEntry(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * 将权限数据写入Excel格式到ZIP压缩包 - * - * @param list 要导出的权限数据列表 - * @param zipOutputStream ZIP输出流 - * @param zipName 在ZIP包中的文件名(需包含.xlsx后缀) - */ - public static void writExcel(List list, ZipOutputStream zipOutputStream, String zipName) { - try { - ByteArrayOutputStream excelOutputStream = new ByteArrayOutputStream(); - - EasyExcel.write(excelOutputStream, PermissionExcel.class).sheet("permission").doWrite(list); - - // 将Excel写入到Zip中 - ZipEntry zipEntry = new ZipEntry(zipName); - zipOutputStream.putNextEntry(zipEntry); - zipOutputStream.write(excelOutputStream.toByteArray()); - zipOutputStream.closeEntry(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java index a3dd484..8d9c752 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java @@ -1,6 +1,10 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.cache.UserAuthorizationCacheService; +import cn.bunny.services.core.excel.PermissionExcelListener; +import cn.bunny.services.core.strategy.export.ExcelExportStrategy; +import cn.bunny.services.core.strategy.export.JsonExportStrategy; +import cn.bunny.services.core.template.PermissionTreeProcessor; +import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.common.constant.FileType; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; @@ -11,12 +15,9 @@ import cn.bunny.services.domain.system.system.dto.power.PermissionUpdateBatchByP import cn.bunny.services.domain.system.system.dto.power.PermissionUpdateDto; import cn.bunny.services.domain.system.system.entity.Permission; import cn.bunny.services.domain.system.system.vo.PermissionVo; -import cn.bunny.services.excel.PermissionExcelListener; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.system.PermissionMapper; import cn.bunny.services.service.system.PermissionService; -import cn.bunny.services.service.system.helper.PermissionHelper; -import cn.bunny.services.service.system.helper.UserServiceHelper; import cn.bunny.services.utils.FileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.fastjson2.JSON; @@ -43,6 +44,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.zip.ZipOutputStream; @@ -60,12 +62,30 @@ import java.util.zip.ZipOutputStream; public class PermissionServiceImpl extends ServiceImpl implements PermissionService { private static final String CACHE_NAMES = "permission"; - @Resource - private UserAuthorizationCacheService userAuthorizationCacheService; - @Resource private UserServiceHelper userServiceHelper; + /** + * 将树形结构权限数据扁平化为列表 + * + *

使用递归处理树形结构

+ * + * @param list 树形结构的权限列表,每个节点可能包含children子节点 + * @return 扁平化后的权限列表( + */ + public static List flattenTree(List list) { + List result = new ArrayList<>(); + + for (PermissionExcel node : list) { + result.add(node); + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + result.addAll(flattenTree(node.getChildren())); + } + } + + return result; + } + /** * * 权限 服务实现类 * @@ -206,19 +226,21 @@ public class PermissionServiceImpl extends ServiceImpl buildTree = PermissionHelper.buildTree(permissionExcelList); + PermissionTreeProcessor permissionTreeProcessor = new PermissionTreeProcessor(); + List buildTree = permissionTreeProcessor.process(permissionExcelList); // 创建btye输出流 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Zip写入流 try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) { - // 判断导出类型是什么 if (type.equals(FileType.EXCEL)) { - PermissionHelper.writExcel(permissionExcelList, zipOutputStream, filename + ".xlsx"); + ExcelExportStrategy excelExportStrategy = new ExcelExportStrategy(PermissionExcel.class, "permission"); + excelExportStrategy.export(permissionExcelList, zipOutputStream, filename + ".xlsx"); } else { - PermissionHelper.writeJson(buildTree, zipOutputStream, filename + ".json"); + JsonExportStrategy jsonExportStrategy = new JsonExportStrategy(); + jsonExportStrategy.export(buildTree, zipOutputStream, filename + ".json"); } } catch (Exception e) { throw new RuntimeException(e); @@ -257,7 +279,7 @@ public class PermissionServiceImpl extends ServiceImpl list = JSON.parseObject(json, new TypeReference<>() { }); // 格式化数据,保存到数据库 - List flattenedTree = PermissionHelper.flattenTree(list); + List flattenedTree = flattenTree(list); List permissionList = flattenedTree.stream().map(permissionExcel -> { Permission permission = new Permission(); BeanUtils.copyProperties(permissionExcel, permission); @@ -292,5 +314,4 @@ public class PermissionServiceImpl extends ServiceImpl ids = list.stream().map(PermissionUpdateDto::getId).toList(); userServiceHelper.updateBatchUserRedisInfoByPermissionId(ids); } - } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java index e26aaf0..7ffe2c8 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java @@ -1,5 +1,6 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.system.system.dto.AssignPowersToRoleDto; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.domain.system.system.entity.RolePermission; @@ -8,7 +9,6 @@ import cn.bunny.services.mapper.system.RolePermissionMapper; import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.mapper.system.UserRoleMapper; import cn.bunny.services.service.system.RolePermissionService; -import cn.bunny.services.service.system.helper.UserServiceHelper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java index eca8e3b..e4620ae 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RoleServiceImpl.java @@ -1,5 +1,7 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.core.excel.RoleExcelListener; +import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.RoleExcel; import cn.bunny.services.domain.common.model.vo.result.PageResult; @@ -8,14 +10,12 @@ import cn.bunny.services.domain.system.system.dto.role.RoleDto; import cn.bunny.services.domain.system.system.dto.role.RoleUpdateDto; import cn.bunny.services.domain.system.system.entity.Role; import cn.bunny.services.domain.system.system.vo.RoleVo; -import cn.bunny.services.excel.RoleExcelListener; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.system.RoleMapper; import cn.bunny.services.mapper.system.RolePermissionMapper; import cn.bunny.services.mapper.system.RouterRoleMapper; import cn.bunny.services.mapper.system.UserRoleMapper; import cn.bunny.services.service.system.RoleService; -import cn.bunny.services.service.system.helper.UserServiceHelper; import cn.bunny.services.utils.FileUtil; import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -169,7 +169,6 @@ public class RoleServiceImpl extends ServiceImpl implements Ro try { fileInputStream = file.getInputStream(); EasyExcel.read(fileInputStream, RoleExcel.class, new RoleExcelListener(this)).sheet().doRead(); - } catch (IOException e) { throw new AuthCustomerException(ResultCodeEnum.UPLOAD_ERROR); } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java index 1149886..0ede64f 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RouterServiceImpl.java @@ -1,5 +1,6 @@ package cn.bunny.services.service.system.impl; +import cn.bunny.services.core.utils.RouterServiceHelper; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.router.RouterAddDto; import cn.bunny.services.domain.system.system.dto.router.RouterUpdateDto; @@ -16,7 +17,6 @@ import cn.bunny.services.mapper.system.RolePermissionMapper; import cn.bunny.services.mapper.system.RouterMapper; import cn.bunny.services.mapper.system.RouterRoleMapper; import cn.bunny.services.service.system.RouterService; -import cn.bunny.services.service.system.helper.RouterHelper; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -51,7 +51,7 @@ public class RouterServiceImpl extends ServiceImpl impleme private RouterRoleMapper routerRoleMapper; @Resource - private RouterHelper routerHelper; + private RouterServiceHelper routerServiceHelper; @Resource private RolePermissionMapper rolePermissionMapper; @@ -78,13 +78,13 @@ public class RouterServiceImpl extends ServiceImpl impleme .collect(Collectors.groupingBy(ViewRolePermission::getRoleId, Collectors.toList())); // 整理web用户所能看到的路由列表,并检查当前用户是否是admin - List webUserRouterVoList = routerHelper.getWebUserRouterVos(routerList, routerRoleList, rolePermissionList); + List webUserRouterVoList = routerServiceHelper.getWebUserRouterVos(routerList, routerRoleList, rolePermissionList); // 添加 admin 管理路由权限 webUserRouterVoList.forEach(routerVo -> { // 递归添加路由节点 if (routerVo.getParentId() == 0) { - routerVo.setChildren(routerHelper.buildTreeSetChildren(routerVo.getId(), webUserRouterVoList)); + routerVo.setChildren(routerServiceHelper.buildTreeSetChildren(routerVo.getId(), webUserRouterVoList)); voList.add(routerVo); } }); @@ -146,7 +146,7 @@ public class RouterServiceImpl extends ServiceImpl impleme // 将数据提出role 和 power 存储到数据库 Long id = router.getId(); - routerHelper.insertRouterRoleAndPermission(meta, id); + routerServiceHelper.insertRouterRoleAndPermission(meta, id); // 添加路由 save(router); @@ -175,7 +175,7 @@ public class RouterServiceImpl extends ServiceImpl impleme routerRoleMapper.deleteBatchIdsByRouterIds(List.of(id)); // 将数据提出role 和 power 存储到数据库 - routerHelper.insertRouterRoleAndPermission(meta, id); + routerServiceHelper.insertRouterRoleAndPermission(meta, id); // 更新路由信息 updateById(router); diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java index 4a6501e..3ebe811 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java @@ -1,8 +1,14 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.cache.EmailCacheService; -import cn.bunny.services.cache.UserCacheService; import cn.bunny.services.context.BaseContext; +import cn.bunny.services.core.cache.EmailCacheService; +import cn.bunny.services.core.cache.UserLoginVoBuilderCacheService; +import cn.bunny.services.core.strategy.login.DefaultLoginStrategy; +import cn.bunny.services.core.strategy.login.EmailLoginStrategy; +import cn.bunny.services.core.strategy.login.LoginContext; +import cn.bunny.services.core.strategy.login.LoginStrategy; +import cn.bunny.services.core.template.email.ConcreteSenderEmailTemplate; +import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.enums.EmailTemplateEnums; @@ -19,13 +25,7 @@ import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.EmailTemplateMapper; import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.minio.MinioHelper; -import cn.bunny.services.service.configuration.helper.email.ConcreteSenderEmailTemplate; import cn.bunny.services.service.system.UserLoginService; -import cn.bunny.services.service.system.helper.UserServiceHelper; -import cn.bunny.services.service.system.helper.login.DefaultLoginStrategy; -import cn.bunny.services.service.system.helper.login.EmailLoginStrategy; -import cn.bunny.services.service.system.helper.login.LoginContext; -import cn.bunny.services.service.system.helper.login.LoginStrategy; import cn.bunny.services.utils.IpUtil; import cn.bunny.services.utils.JwtTokenUtil; import cn.hutool.captcha.CaptchaUtil; @@ -64,11 +64,14 @@ public class UserLoginServiceImpl extends ServiceImpl imp private MinioHelper minioHelper; @Resource - private UserCacheService userCacheService; + private UserLoginVoBuilderCacheService userLoginVoBuilderCacheService; @Resource private EmailCacheService emailCacheService; + @Resource + private UserServiceHelper serviceHelper; + /** * 前台用户登录接口 * 这里不用判断用户是否为空,因为在登录时已经校验过了 @@ -125,7 +128,7 @@ public class UserLoginServiceImpl extends ServiceImpl imp // 构建用户返回对象 Long readMeDay = loginDto.getReadMeDay(); - LoginVo loginVo = userCacheService.buildLoginUserVo(user, readMeDay); + LoginVo loginVo = userLoginVoBuilderCacheService.buildLoginUserVo(user, readMeDay); // 将用户登录保存在用户登录日志表中 userServiceHelper.setUserLoginLog(user, loginVo.getToken(), UserConstant.LOGIN); @@ -197,7 +200,7 @@ public class UserLoginServiceImpl extends ServiceImpl imp if (adminUser.getStatus()) throw new AuthCustomerException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED); // 构建 LoginVo 对象 - LoginVo loginVo = userCacheService.buildLoginUserVo(adminUser, dto.getReadMeDay()); + LoginVo loginVo = userLoginVoBuilderCacheService.buildLoginUserVo(adminUser, dto.getReadMeDay()); RefreshTokenVo refreshTokenVo = new RefreshTokenVo(); BeanUtils.copyProperties(loginVo, refreshTokenVo); @@ -227,7 +230,7 @@ public class UserLoginServiceImpl extends ServiceImpl imp // 删除Redis中用户信息 String username = adminUser.getUsername(); - userCacheService.deleteUserCache(username); + serviceHelper.deleteUserCache(username); } @@ -253,7 +256,7 @@ public class UserLoginServiceImpl extends ServiceImpl imp updateById(user); // 重新生成用户信息到Redis中 - userCacheService.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); + userLoginVoBuilderCacheService.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); } /** @@ -286,6 +289,6 @@ public class UserLoginServiceImpl extends ServiceImpl imp updateById(adminUser); // 删除Redis中登录用户信息、角色、权限信息 - userCacheService.deleteUserCache(adminUser.getUsername()); + serviceHelper.deleteUserCache(adminUser.getUsername()); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java index d269dd5..4b63af0 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java @@ -1,6 +1,6 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.cache.UserCacheService; +import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.AssignRolesToUsersDto; import cn.bunny.services.domain.system.system.entity.AdminUser; @@ -36,7 +36,7 @@ public class UserRoleServiceImpl extends ServiceImpl i private UserMapper userMapper; @Resource - private UserCacheService userCacheService; + private UserServiceHelper serviceHelper; /** * * 根据用户id获取角色列表 @@ -81,6 +81,6 @@ public class UserRoleServiceImpl extends ServiceImpl i saveBatch(roleList); // 重新设置Redis中的用户存储信息vo对象 - userCacheService.updateUserRedisInfo(List.of(userId)); + serviceHelper.updateUserRedisInfo(List.of(userId)); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java index 739aacf..ee8e2c0 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java @@ -1,7 +1,8 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.cache.RedisService; -import cn.bunny.services.cache.UserCacheService; +import cn.bunny.services.core.cache.RedisService; +import cn.bunny.services.core.cache.UserCacheService; +import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.common.constant.MinioConstant; import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.enums.ResultCodeEnum; @@ -82,6 +83,8 @@ public class UserServiceImpl extends ServiceImpl implemen @Resource private UserCacheService userCacheService; + @Resource + private UserServiceHelper userServiceHelper; /** * 获取用户信息 @@ -141,7 +144,7 @@ public class UserServiceImpl extends ServiceImpl implemen // 删除Redis中用户信息 String username = adminUser.getUsername(); - userCacheService.deleteUserCache(username); + userServiceHelper.deleteUserCache(username); } /** @@ -302,7 +305,7 @@ public class UserServiceImpl extends ServiceImpl implemen updateById(adminUser); // 同步到 Redis - userCacheService.updateUserRedisInfo(List.of(adminUser.getId())); + userServiceHelper.updateUserRedisInfo(List.of(adminUser.getId())); } /** @@ -324,7 +327,7 @@ public class UserServiceImpl extends ServiceImpl implemen List adminUserList = list(Wrappers.lambdaQuery().eq(AdminUser::getId, ids)); adminUserList.parallelStream().forEach(adminUser -> { String username = adminUser.getUsername(); - userCacheService.deleteLoginUserCache(username); + userServiceHelper.deleteLoginUserCache(username); }); // 删除部门相关 From 94e0d7f264c140f2322b417ff397683aff60499d Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Tue, 6 May 2025 16:23:42 +0800 Subject: [PATCH 4/4] =?UTF-8?q?:art:=20feat:=20=E4=BF=AE=E6=94=B9=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=BC=93=E5=AD=98=E4=BD=BF=E7=94=A8=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9B=91=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auh-api/Dockerfile | 1 + .../EmailTemplateController.java | 8 +- auh-api/src/main/resources/application.yml | 4 +- .../cache/UserAuthorizationCacheService.java | 11 -- .../services/core/cache/UserCacheCleaner.java | 33 ++++ .../services/core/cache/UserCacheService.java | 25 --- .../event/event/ClearAllUserCacheEvent.java | 16 ++ .../UpdateUserinfoByPermissionIdsEvent.java | 18 ++ .../event/UpdateUserinfoByRoleIdsEvent.java | 18 ++ .../event/UpdateUserinfoByUserIdsEvent.java | 19 +++ .../listener}/excel/I18nExcelListener.java | 2 +- .../excel/PermissionExcelListener.java | 2 +- .../listener}/excel/RoleExcelListener.java | 2 +- .../user/AbstractUserInfoUpdateHandler.java | 34 ++++ .../listener/user/UserinfoUpdateListener.java | 68 ++++++++ .../core/utils/UserServiceHelper.java | 160 ------------------ .../service/TokenValidationService.java | 9 +- .../configuration/impl/I18nServiceImpl.java | 2 +- .../system/impl/PermissionServiceImpl.java | 19 ++- .../impl/RolePermissionServiceImpl.java | 10 +- .../service/system/impl/RoleServiceImpl.java | 24 +-- .../system/impl/UserLoginServiceImpl.java | 67 ++++++-- .../system/impl/UserRoleServiceImpl.java | 10 +- .../service/system/impl/UserServiceImpl.java | 26 +-- 24 files changed, 325 insertions(+), 263 deletions(-) create mode 100644 service/src/main/java/cn/bunny/services/core/cache/UserCacheCleaner.java delete mode 100644 service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java create mode 100644 service/src/main/java/cn/bunny/services/core/event/event/ClearAllUserCacheEvent.java create mode 100644 service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByPermissionIdsEvent.java create mode 100644 service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByRoleIdsEvent.java create mode 100644 service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByUserIdsEvent.java rename service/src/main/java/cn/bunny/services/core/{ => event/listener}/excel/I18nExcelListener.java (97%) rename service/src/main/java/cn/bunny/services/core/{ => event/listener}/excel/PermissionExcelListener.java (97%) rename service/src/main/java/cn/bunny/services/core/{ => event/listener}/excel/RoleExcelListener.java (97%) create mode 100644 service/src/main/java/cn/bunny/services/core/event/listener/user/AbstractUserInfoUpdateHandler.java create mode 100644 service/src/main/java/cn/bunny/services/core/event/listener/user/UserinfoUpdateListener.java delete mode 100644 service/src/main/java/cn/bunny/services/core/utils/UserServiceHelper.java diff --git a/auh-api/Dockerfile b/auh-api/Dockerfile index 0039cda..3673ff8 100644 --- a/auh-api/Dockerfile +++ b/auh-api/Dockerfile @@ -26,6 +26,7 @@ ENTRYPOINT ["java","-jar","/home/server/app.jar"] #暴露 8000 端口 EXPOSE 8000 +EXPOSE 7070 # 生产环境 # mvn clean package -Pprod -DskipTests diff --git a/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java b/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java index 72e0c5e..bcbfa22 100644 --- a/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java +++ b/auh-api/src/main/java/cn/bunny/services/controller/configuration/EmailTemplateController.java @@ -1,13 +1,13 @@ package cn.bunny.services.controller.configuration; +import cn.bunny.services.domain.common.enums.ResultCodeEnum; +import cn.bunny.services.domain.common.model.vo.result.PageResult; +import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.system.email.dto.EmailTemplateAddDto; import cn.bunny.services.domain.system.email.dto.EmailTemplateDto; import cn.bunny.services.domain.system.email.dto.EmailTemplateUpdateDto; import cn.bunny.services.domain.system.email.entity.EmailTemplate; import cn.bunny.services.domain.system.email.vo.EmailTemplateVo; -import cn.bunny.services.domain.common.model.vo.result.PageResult; -import cn.bunny.services.domain.common.model.vo.result.Result; -import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.service.configuration.EmailTemplateService; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; @@ -71,7 +71,7 @@ public class EmailTemplateController { } @Operation(summary = "全部邮件类型列表", description = "获取全部邮件类型列表", tags = "emailTemplate::query") - @GetMapping("public") + @GetMapping("private") public Result>> getEmailTypeList() { List> list = emailTemplateService.getEmailTypeList(); return Result.success(list); diff --git a/auh-api/src/main/resources/application.yml b/auh-api/src/main/resources/application.yml index eb9d205..d49babf 100644 --- a/auh-api/src/main/resources/application.yml +++ b/auh-api/src/main/resources/application.yml @@ -1,6 +1,8 @@ server: port: 8000 - + tomcat: + threads: + max: 1000 spring: profiles: active: @profiles.active@ diff --git a/service/src/main/java/cn/bunny/services/core/cache/UserAuthorizationCacheService.java b/service/src/main/java/cn/bunny/services/core/cache/UserAuthorizationCacheService.java index 3b19f6e..8c705e8 100644 --- a/service/src/main/java/cn/bunny/services/core/cache/UserAuthorizationCacheService.java +++ b/service/src/main/java/cn/bunny/services/core/cache/UserAuthorizationCacheService.java @@ -107,15 +107,4 @@ public class UserAuthorizationCacheService { return permissionList; } - - /** - * 清除缓存 - * 如有需要清除当前服务缓存 - */ - public void deleteRoleAndPermissionCache(String key) { - String permissionCodePrefix = RedisUserConstant.getUserPermissionCodePrefix(key); - String rolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(key); - redisTemplate.delete(permissionCodePrefix); - redisTemplate.delete(rolesCodePrefix); - } } diff --git a/service/src/main/java/cn/bunny/services/core/cache/UserCacheCleaner.java b/service/src/main/java/cn/bunny/services/core/cache/UserCacheCleaner.java new file mode 100644 index 0000000..e660828 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/cache/UserCacheCleaner.java @@ -0,0 +1,33 @@ +package cn.bunny.services.core.cache; + +import cn.bunny.services.domain.common.constant.RedisUserConstant; +import jakarta.annotation.Resource; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +@Component +public class UserCacheCleaner { + @Resource + private RedisTemplate redisTemplate; + + public void cleanUserLoginCache(String username) { + String key = RedisUserConstant.getUserLoginInfoPrefix(username); + redisTemplate.delete(key); + } + + public void cleanUserRoleCache(String username) { + String key = RedisUserConstant.getUserRolesCodePrefix(username); + redisTemplate.delete(key); + } + + public void cleanUserPermissionCache(String username) { + String key = RedisUserConstant.getUserPermissionCodePrefix(username); + redisTemplate.delete(key); + } + + public void cleanAllUserCache(String username) { + cleanUserLoginCache(username); + cleanUserRoleCache(username); + cleanUserPermissionCache(username); + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java b/service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java deleted file mode 100644 index 3122705..0000000 --- a/service/src/main/java/cn/bunny/services/core/cache/UserCacheService.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.bunny.services.core.cache; - -import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.domain.common.model.vo.LoginVo; -import com.alibaba.fastjson2.JSON; -import jakarta.annotation.Resource; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Service; - -@Service -public class UserCacheService { - @Resource - private RedisTemplate redisTemplate; - - /** - * 根据用户名获取缓存中内容 - * - * @param username 用户名 - * @return LoginVo - */ - public LoginVo getLoginVoByUsername(String username) { - Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(username)); - return JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); - } -} diff --git a/service/src/main/java/cn/bunny/services/core/event/event/ClearAllUserCacheEvent.java b/service/src/main/java/cn/bunny/services/core/event/event/ClearAllUserCacheEvent.java new file mode 100644 index 0000000..80d3352 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/event/event/ClearAllUserCacheEvent.java @@ -0,0 +1,16 @@ +package cn.bunny.services.core.event.event; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.context.ApplicationEvent; + +@Getter +@Setter +public class ClearAllUserCacheEvent extends ApplicationEvent { + private final String key; + + public ClearAllUserCacheEvent(Object source, String key) { + super(source); + this.key = key; + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByPermissionIdsEvent.java b/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByPermissionIdsEvent.java new file mode 100644 index 0000000..b6300f4 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByPermissionIdsEvent.java @@ -0,0 +1,18 @@ +package cn.bunny.services.core.event.event; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.context.ApplicationEvent; + +import java.util.List; + +@Getter +@Setter +public class UpdateUserinfoByPermissionIdsEvent extends ApplicationEvent { + private final List permissionIds; + + public UpdateUserinfoByPermissionIdsEvent(Object source, List permissionIds) { + super(source); + this.permissionIds = permissionIds; + } +} diff --git a/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByRoleIdsEvent.java b/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByRoleIdsEvent.java new file mode 100644 index 0000000..9bbdc00 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByRoleIdsEvent.java @@ -0,0 +1,18 @@ +package cn.bunny.services.core.event.event; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.context.ApplicationEvent; + +import java.util.List; + +@Getter +@Setter +public class UpdateUserinfoByRoleIdsEvent extends ApplicationEvent { + private final List roleIds; + + public UpdateUserinfoByRoleIdsEvent(Object source, List roleIds) { + super(source); + this.roleIds = roleIds; + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByUserIdsEvent.java b/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByUserIdsEvent.java new file mode 100644 index 0000000..b4c3b06 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/event/event/UpdateUserinfoByUserIdsEvent.java @@ -0,0 +1,19 @@ +package cn.bunny.services.core.event.event; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.context.ApplicationEvent; + +import java.util.List; + +@Getter +@Setter +public class UpdateUserinfoByUserIdsEvent extends ApplicationEvent { + private final List userIds; + + public UpdateUserinfoByUserIdsEvent(Object source, List userIds) { + super(source); + this.userIds = userIds; + } +} + diff --git a/service/src/main/java/cn/bunny/services/core/excel/I18nExcelListener.java b/service/src/main/java/cn/bunny/services/core/event/listener/excel/I18nExcelListener.java similarity index 97% rename from service/src/main/java/cn/bunny/services/core/excel/I18nExcelListener.java rename to service/src/main/java/cn/bunny/services/core/event/listener/excel/I18nExcelListener.java index 5d42d35..6017ff6 100644 --- a/service/src/main/java/cn/bunny/services/core/excel/I18nExcelListener.java +++ b/service/src/main/java/cn/bunny/services/core/event/listener/excel/I18nExcelListener.java @@ -1,4 +1,4 @@ -package cn.bunny.services.core.excel; +package cn.bunny.services.core.event.listener.excel; import cn.bunny.services.domain.common.model.dto.excel.I18nExcel; import cn.bunny.services.domain.system.i18n.entity.I18n; diff --git a/service/src/main/java/cn/bunny/services/core/excel/PermissionExcelListener.java b/service/src/main/java/cn/bunny/services/core/event/listener/excel/PermissionExcelListener.java similarity index 97% rename from service/src/main/java/cn/bunny/services/core/excel/PermissionExcelListener.java rename to service/src/main/java/cn/bunny/services/core/event/listener/excel/PermissionExcelListener.java index 6a92746..87014c8 100644 --- a/service/src/main/java/cn/bunny/services/core/excel/PermissionExcelListener.java +++ b/service/src/main/java/cn/bunny/services/core/event/listener/excel/PermissionExcelListener.java @@ -1,4 +1,4 @@ -package cn.bunny.services.core.excel; +package cn.bunny.services.core.event.listener.excel; import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; import cn.bunny.services.domain.system.system.entity.Permission; diff --git a/service/src/main/java/cn/bunny/services/core/excel/RoleExcelListener.java b/service/src/main/java/cn/bunny/services/core/event/listener/excel/RoleExcelListener.java similarity index 97% rename from service/src/main/java/cn/bunny/services/core/excel/RoleExcelListener.java rename to service/src/main/java/cn/bunny/services/core/event/listener/excel/RoleExcelListener.java index cc92624..39f5f85 100644 --- a/service/src/main/java/cn/bunny/services/core/excel/RoleExcelListener.java +++ b/service/src/main/java/cn/bunny/services/core/event/listener/excel/RoleExcelListener.java @@ -1,4 +1,4 @@ -package cn.bunny.services.core.excel; +package cn.bunny.services.core.event.listener.excel; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.RoleExcel; diff --git a/service/src/main/java/cn/bunny/services/core/event/listener/user/AbstractUserInfoUpdateHandler.java b/service/src/main/java/cn/bunny/services/core/event/listener/user/AbstractUserInfoUpdateHandler.java new file mode 100644 index 0000000..638be36 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/event/listener/user/AbstractUserInfoUpdateHandler.java @@ -0,0 +1,34 @@ +package cn.bunny.services.core.event.listener.user; + +import cn.bunny.services.core.cache.UserCacheCleaner; +import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.domain.system.system.entity.AdminUser; +import cn.bunny.services.mapper.system.UserMapper; +import jakarta.annotation.Resource; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.function.Consumer; + +@Component("AbstractUserInfoUpdateHandler") +public abstract class AbstractUserInfoUpdateHandler { + + @Resource + protected UserMapper userMapper; + + @Resource + protected UserCacheCleaner userCacheCleaner; + + @Resource + private RedisTemplate redisTemplate; + + public void processUserUpdate(List userIds, Consumer postProcess) { + if (userIds.isEmpty()) return; + + List adminUsers = userMapper.selectBatchIds(userIds); + adminUsers.stream() + .filter(user -> redisTemplate.hasKey(RedisUserConstant.getUserLoginInfoPrefix(user.getUsername()))) + .forEach(postProcess); + } +} \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/core/event/listener/user/UserinfoUpdateListener.java b/service/src/main/java/cn/bunny/services/core/event/listener/user/UserinfoUpdateListener.java new file mode 100644 index 0000000..77a45e6 --- /dev/null +++ b/service/src/main/java/cn/bunny/services/core/event/listener/user/UserinfoUpdateListener.java @@ -0,0 +1,68 @@ +package cn.bunny.services.core.event.listener.user; + +import cn.bunny.services.core.cache.UserLoginVoBuilderCacheService; +import cn.bunny.services.core.event.event.ClearAllUserCacheEvent; +import cn.bunny.services.core.event.event.UpdateUserinfoByPermissionIdsEvent; +import cn.bunny.services.core.event.event.UpdateUserinfoByRoleIdsEvent; +import cn.bunny.services.core.event.event.UpdateUserinfoByUserIdsEvent; +import cn.bunny.services.domain.common.constant.RedisUserConstant; +import cn.bunny.services.domain.system.system.entity.RolePermission; +import cn.bunny.services.domain.system.system.entity.UserRole; +import cn.bunny.services.mapper.system.RolePermissionMapper; +import cn.bunny.services.mapper.system.UserRoleMapper; +import jakarta.annotation.Resource; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component("UserinfoUpdateListener") +public class UserinfoUpdateListener extends AbstractUserInfoUpdateHandler { + + @Resource + private UserLoginVoBuilderCacheService userLoginVoBuilderCacheService; + + @Resource + private UserRoleMapper userRoleMapper; + + @Resource + private RolePermissionMapper rolePermissionMapper; + + /* 根据用户id更新用户信息,重新生成LoginVo对象 */ + @EventListener + public void handlerUpdateUserinfoByUserIds(UpdateUserinfoByUserIdsEvent event) { + List userIds = event.getUserIds(); + processUserUpdate(userIds, user -> { + userCacheCleaner.cleanAllUserCache(user.getUsername()); + userLoginVoBuilderCacheService.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); + }); + } + + /* 根据角色id更新用户信息,重新生成LoginVo对象 */ + @EventListener + public void handlerUserinfoUpdateByRoleId(UpdateUserinfoByRoleIdsEvent event) { + List roleIds = event.getRoleIds(); + List userRoles = userRoleMapper.selectListByRoleIds(roleIds); + List userIds = userRoles.stream().map(UserRole::getUserId).toList(); + + UpdateUserinfoByUserIdsEvent userIdsEvent = new UpdateUserinfoByUserIdsEvent(event.getSource(), userIds); + handlerUpdateUserinfoByUserIds(userIdsEvent); + } + + /* 根据角色id更新用户信息,重新生成LoginVo对象 */ + @EventListener + public void handlerUserinfoUpdateByPermissionId(UpdateUserinfoByPermissionIdsEvent event) { + List permissionIds = event.getPermissionIds(); + List rolePermissions = rolePermissionMapper.selectRolePermissionListByPermissionIds(permissionIds); + List roleIds = rolePermissions.stream().map(RolePermission::getRoleId).toList(); + + UpdateUserinfoByRoleIdsEvent roleIdsEvent = new UpdateUserinfoByRoleIdsEvent(event.getSource(), roleIds); + handlerUserinfoUpdateByRoleId(roleIdsEvent); + } + + /* 清除用户登录、角色、权限所有缓存 */ + @EventListener + public void handlerDeleteAllUserCache(ClearAllUserCacheEvent event) { + userCacheCleaner.cleanAllUserCache(event.getKey()); + } +} diff --git a/service/src/main/java/cn/bunny/services/core/utils/UserServiceHelper.java b/service/src/main/java/cn/bunny/services/core/utils/UserServiceHelper.java deleted file mode 100644 index 2395f05..0000000 --- a/service/src/main/java/cn/bunny/services/core/utils/UserServiceHelper.java +++ /dev/null @@ -1,160 +0,0 @@ -package cn.bunny.services.core.utils; - -import cn.bunny.services.core.cache.UserAuthorizationCacheService; -import cn.bunny.services.core.cache.UserLoginVoBuilderCacheService; -import cn.bunny.services.domain.common.constant.RedisUserConstant; -import cn.bunny.services.domain.system.log.entity.UserLoginLog; -import cn.bunny.services.domain.system.system.entity.AdminUser; -import cn.bunny.services.domain.system.system.entity.RolePermission; -import cn.bunny.services.domain.system.system.entity.UserRole; -import cn.bunny.services.mapper.log.UserLoginLogMapper; -import cn.bunny.services.mapper.system.RolePermissionMapper; -import cn.bunny.services.mapper.system.UserMapper; -import cn.bunny.services.mapper.system.UserRoleMapper; -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletRequest; -import org.springframework.beans.BeanUtils; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - -import java.util.List; - -@Service -public class UserServiceHelper { - - @Resource - private UserRoleMapper userRoleMapper; - - @Resource - private UserLoginVoBuilderCacheService userLoginVoBuilderCacheService; - - @Resource - private UserLoginLogMapper userLoginLogMapper; - - @Resource - private RolePermissionMapper rolePermissionMapper; - - @Resource - private RedisTemplate redisTemplate; - - @Resource - private UserMapper userMapper; - - @Resource - private UserAuthorizationCacheService userAuthorizationCacheService; - - /** - * 设置用户登录日志内容 - *

- * 该方法用于将管理员用户信息复制到用户登录日志对象中,同时处理特殊字段映射关系。 - *

- * 实现说明: - * 1. 使用BeanUtils.copyProperties()复制属性时,会自动将AdminUser.id复制到UserLoginLog.id - * 2. 由于UserLoginLog实际需要的是userId字段而非id字段,需要特殊处理: - * - 先进行属性复制 - * - 然后将UserLoginLog.userId设置为AdminUser.id - * - 最后将UserLoginLog.id显式设为null(避免自动生成的id被覆盖) - * - * @param user 管理员用户实体对象,包含用户基本信息 - * @param token 本次登录/退出的认证令牌 - * @param type 操作类型(LOGIN-登录/LOGOUT-退出) - */ - public void setUserLoginLog(AdminUser user, String token, String type) { - UserLoginLog userLoginLog = new UserLoginLog(); - BeanUtils.copyProperties(user, userLoginLog); - userLoginLog.setUserId(user.getId()); - userLoginLog.setId(null); - userLoginLog.setToken(token); - userLoginLog.setType(type); - - // 当前请求request - ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (requestAttributes != null) { - HttpServletRequest request = requestAttributes.getRequest(); - - // 获取User-Agent - String userAgent = request.getHeader("User-Agent"); - userLoginLog.setUserAgent(userAgent); - - // 获取X-Requested-With - String xRequestedWith = request.getHeader("X-Requested-With"); - userLoginLog.setXRequestedWith(xRequestedWith); - } - - userLoginLogMapper.insert(userLoginLog); - } - - /** - * 批量更新Redis中用户权限信息,设计用户和角色就用这个 - * - * @param userIds 需要更新的用户ID集合 - * (仅处理集合中存在的有效用户) - * @see RedisUserConstant Redis键前缀常量 - */ - public void updateUserRedisInfo(List userIds) { - if (userIds.isEmpty()) return; - - // 批量查询用户 - List adminUsers = userMapper.selectBatchIds(userIds); - // 并行处理用户更新 - adminUsers.stream() - .filter(user -> redisTemplate.hasKey(RedisUserConstant.getUserLoginInfoPrefix(user.getUsername()))) - .forEach(user -> { - // 更新时清除缓存中的角色和权限 - String username = user.getUsername(); - userAuthorizationCacheService.deleteRoleAndPermissionCache(username); - - // 更新用户权限信息 - userLoginVoBuilderCacheService.buildLoginUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME); - }); - } - - /** - * 处理角色更新事件 - * - * @param roleIds 角色ID - */ - @Async - public void updateBatchUserRedisInfoByRoleId(List roleIds) { - // 批量查询关联用户ID - List userRoles = userRoleMapper.selectListByRoleIds(roleIds); - List userIds = userRoles.stream().map(UserRole::getUserId).toList(); - updateUserRedisInfo(userIds); - } - - /** - * 处理权限更新事件 - * - * @param permissionIds 权限ID - */ - @Async - public void updateBatchUserRedisInfoByPermissionId(List permissionIds) { - // 批量查询关联用户ID - List rolePermissions = rolePermissionMapper.selectRolePermissionListByPermissionIds(permissionIds); - List roleIds = rolePermissions.stream().map(RolePermission::getRoleId).toList(); - updateBatchUserRedisInfoByRoleId(roleIds); - } - - /** - * 清除用户登录时的缓存 - * - * @param username 用户名 - */ - public void deleteLoginUserCache(String username) { - String userRolesCodePrefix = RedisUserConstant.getUserRolesCodePrefix(username); - redisTemplate.delete(userRolesCodePrefix); - } - - /** - * 清除用户登录时的缓存 - * - * @param username 用户名 - */ - public void deleteUserCache(String username) { - userAuthorizationCacheService.deleteRoleAndPermissionCache(username); - deleteLoginUserCache(username); - } -} diff --git a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java index e8740a5..6554cf8 100644 --- a/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java +++ b/service/src/main/java/cn/bunny/services/security/service/TokenValidationService.java @@ -1,13 +1,15 @@ package cn.bunny.services.security.service; -import cn.bunny.services.core.cache.UserCacheService; +import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.security.TokenInfo; import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.security.exception.CustomAuthenticationException; import cn.bunny.services.utils.JwtTokenUtil; +import com.alibaba.fastjson2.JSON; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; /** @@ -17,7 +19,7 @@ import org.springframework.stereotype.Service; public class TokenValidationService { @Resource - private UserCacheService userCacheService; + private RedisTemplate redisTemplate; public TokenInfo validateToken(HttpServletRequest request) { // 判断是否有 token @@ -37,7 +39,8 @@ public class TokenValidationService { Long userId = JwtTokenUtil.getUserId(token); // 查找 Redis - LoginVo loginVo = userCacheService.getLoginVoByUsername(username); + Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(username)); + LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); return TokenInfo.builder().userId(userId).username(username).token(token).loginVo(loginVo).build(); } diff --git a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java index a516725..994b247 100644 --- a/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/configuration/impl/I18nServiceImpl.java @@ -1,6 +1,6 @@ package cn.bunny.services.service.configuration.impl; -import cn.bunny.services.core.excel.I18nExcelListener; +import cn.bunny.services.core.event.listener.excel.I18nExcelListener; import cn.bunny.services.core.strategy.export.ExcelExportStrategy; import cn.bunny.services.core.strategy.export.JsonExportStrategy; import cn.bunny.services.domain.common.constant.FileType; diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java index 8d9c752..bd7fb4f 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/PermissionServiceImpl.java @@ -1,10 +1,10 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.core.excel.PermissionExcelListener; +import cn.bunny.services.core.event.event.UpdateUserinfoByPermissionIdsEvent; +import cn.bunny.services.core.event.listener.excel.PermissionExcelListener; import cn.bunny.services.core.strategy.export.ExcelExportStrategy; import cn.bunny.services.core.strategy.export.JsonExportStrategy; import cn.bunny.services.core.template.PermissionTreeProcessor; -import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.common.constant.FileType; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel; @@ -32,6 +32,7 @@ import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Caching; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -63,7 +64,7 @@ public class PermissionServiceImpl extends ServiceImpl ids = List.of(dto.getId()); + applicationEventPublisher.publishEvent(new UpdateUserinfoByPermissionIdsEvent(this, ids)); } /** @@ -174,7 +176,7 @@ public class PermissionServiceImpl extends ServiceImpl permissionList = dto.getIds().stream().map(id -> { + List ids = dto.getIds(); + List permissionList = ids.stream().map(id -> { Permission permission = new Permission(); permission.setId(id); permission.setParentId(dto.getParentId()); @@ -198,7 +201,7 @@ public class PermissionServiceImpl extends ServiceImpl ids = list.stream().map(PermissionUpdateDto::getId).toList(); - userServiceHelper.updateBatchUserRedisInfoByPermissionId(ids); + applicationEventPublisher.publishEvent(new UpdateUserinfoByPermissionIdsEvent(this, ids)); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java index 7ffe2c8..561c089 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/RolePermissionServiceImpl.java @@ -1,6 +1,6 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.core.utils.UserServiceHelper; +import cn.bunny.services.core.event.event.UpdateUserinfoByRoleIdsEvent; import cn.bunny.services.domain.system.system.dto.AssignPowersToRoleDto; import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.domain.system.system.entity.RolePermission; @@ -12,6 +12,7 @@ import cn.bunny.services.service.system.RolePermissionService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -36,7 +37,7 @@ public class RolePermissionServiceImpl extends ServiceImpl ids = List.of(roleId); + baseMapper.deleteBatchRoleIds(ids); // 保存分配数据 List rolePermissionList = powerIds.stream().map(powerId -> { @@ -85,6 +87,6 @@ public class RolePermissionServiceImpl extends ServiceImpl implements Ro private static final String CACHE_NAMES = "role"; @Resource - private UserRoleMapper userRoleMapper; - - @Resource - private RolePermissionMapper rolePermissionMapper; - - @Resource - private RouterRoleMapper routerRoleMapper; - - @Resource - private UserServiceHelper userServiceHelper; + private ApplicationEventPublisher applicationEventPublisher; /** * 角色 服务实现类 @@ -231,7 +220,8 @@ public class RoleServiceImpl extends ServiceImpl implements Ro updateById(role); // 发布角色更新事件 - userServiceHelper.updateBatchUserRedisInfoByRoleId(List.of(roleId)); + List ids = List.of(roleId); + applicationEventPublisher.publishEvent(new UpdateUserinfoByRoleIdsEvent(this, ids)); } /** @@ -249,7 +239,7 @@ public class RoleServiceImpl extends ServiceImpl implements Ro if (ids.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.REQUEST_IS_EMPTY); // 重新构建角色和用户缓存 - userServiceHelper.updateBatchUserRedisInfoByRoleId(ids); + applicationEventPublisher.publishEvent(new UpdateUserinfoByRoleIdsEvent(this, ids)); // 删除角色 removeByIds(ids); diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java index 3ebe811..4b8bea3 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserLoginServiceImpl.java @@ -3,12 +3,12 @@ package cn.bunny.services.service.system.impl; import cn.bunny.services.context.BaseContext; import cn.bunny.services.core.cache.EmailCacheService; import cn.bunny.services.core.cache.UserLoginVoBuilderCacheService; +import cn.bunny.services.core.event.event.ClearAllUserCacheEvent; import cn.bunny.services.core.strategy.login.DefaultLoginStrategy; import cn.bunny.services.core.strategy.login.EmailLoginStrategy; import cn.bunny.services.core.strategy.login.LoginContext; import cn.bunny.services.core.strategy.login.LoginStrategy; import cn.bunny.services.core.template.email.ConcreteSenderEmailTemplate; -import cn.bunny.services.core.utils.UserServiceHelper; import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.enums.EmailTemplateEnums; @@ -16,6 +16,7 @@ import cn.bunny.services.domain.common.enums.LoginEnums; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.vo.LoginVo; import cn.bunny.services.domain.system.email.entity.EmailTemplate; +import cn.bunny.services.domain.system.log.entity.UserLoginLog; import cn.bunny.services.domain.system.system.dto.user.AdminUserUpdateByLocalUserDto; import cn.bunny.services.domain.system.system.dto.user.LoginDto; import cn.bunny.services.domain.system.system.dto.user.RefreshTokenDto; @@ -23,6 +24,7 @@ import cn.bunny.services.domain.system.system.entity.AdminUser; import cn.bunny.services.domain.system.system.vo.user.RefreshTokenVo; import cn.bunny.services.exception.AuthCustomerException; import cn.bunny.services.mapper.configuration.EmailTemplateMapper; +import cn.bunny.services.mapper.log.UserLoginLogMapper; import cn.bunny.services.mapper.system.UserMapper; import cn.bunny.services.minio.MinioHelper; import cn.bunny.services.service.system.UserLoginService; @@ -34,20 +36,21 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeanUtils; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; import java.util.HashMap; @Service public class UserLoginServiceImpl extends ServiceImpl implements UserLoginService { - @Resource - private UserServiceHelper userServiceHelper; - @Resource private PasswordEncoder passwordEncoder; @@ -57,6 +60,9 @@ public class UserLoginServiceImpl extends ServiceImpl imp @Resource private EmailTemplateMapper emailTemplateMapper; + @Resource + private UserLoginLogMapper userLoginLogMapper; + @Resource private ConcreteSenderEmailTemplate concreteSenderEmailTemplate; @@ -70,7 +76,7 @@ public class UserLoginServiceImpl extends ServiceImpl imp private EmailCacheService emailCacheService; @Resource - private UserServiceHelper serviceHelper; + private ApplicationEventPublisher applicationEventPublisher; /** * 前台用户登录接口 @@ -131,7 +137,7 @@ public class UserLoginServiceImpl extends ServiceImpl imp LoginVo loginVo = userLoginVoBuilderCacheService.buildLoginUserVo(user, readMeDay); // 将用户登录保存在用户登录日志表中 - userServiceHelper.setUserLoginLog(user, loginVo.getToken(), UserConstant.LOGIN); + setUserLoginLog(user, loginVo.getToken(), UserConstant.LOGIN); return loginVo; } @@ -225,12 +231,11 @@ public class UserLoginServiceImpl extends ServiceImpl imp AdminUser adminUser = getOne(Wrappers.lambdaQuery().eq(AdminUser::getId, userId)); adminUser.setIpAddress(ipAddr); adminUser.setIpRegion(ipRegion); - userServiceHelper.setUserLoginLog(adminUser, token, UserConstant.LOGOUT); + setUserLoginLog(adminUser, token, UserConstant.LOGOUT); // 删除Redis中用户信息 String username = adminUser.getUsername(); - - serviceHelper.deleteUserCache(username); + applicationEventPublisher.publishEvent(new ClearAllUserCacheEvent(this, username)); } @@ -289,6 +294,48 @@ public class UserLoginServiceImpl extends ServiceImpl imp updateById(adminUser); // 删除Redis中登录用户信息、角色、权限信息 - serviceHelper.deleteUserCache(adminUser.getUsername()); + String username = adminUser.getUsername(); + applicationEventPublisher.publishEvent(new ClearAllUserCacheEvent(this, username)); + } + + /** + * 设置用户登录日志内容 + *

+ * 该方法用于将管理员用户信息复制到用户登录日志对象中,同时处理特殊字段映射关系。 + *

+ * 实现说明: + * 1. 使用BeanUtils.copyProperties()复制属性时,会自动将AdminUser.id复制到UserLoginLog.id + * 2. 由于UserLoginLog实际需要的是userId字段而非id字段,需要特殊处理: + * - 先进行属性复制 + * - 然后将UserLoginLog.userId设置为AdminUser.id + * - 最后将UserLoginLog.id显式设为null(避免自动生成的id被覆盖) + * + * @param user 管理员用户实体对象,包含用户基本信息 + * @param token 本次登录/退出的认证令牌 + * @param type 操作类型(LOGIN-登录/LOGOUT-退出) + */ + public void setUserLoginLog(AdminUser user, String token, String type) { + UserLoginLog userLoginLog = new UserLoginLog(); + BeanUtils.copyProperties(user, userLoginLog); + userLoginLog.setUserId(user.getId()); + userLoginLog.setId(null); + userLoginLog.setToken(token); + userLoginLog.setType(type); + + // 当前请求request + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (requestAttributes != null) { + HttpServletRequest request = requestAttributes.getRequest(); + + // 获取User-Agent + String userAgent = request.getHeader("User-Agent"); + userLoginLog.setUserAgent(userAgent); + + // 获取X-Requested-With + String xRequestedWith = request.getHeader("X-Requested-With"); + userLoginLog.setXRequestedWith(xRequestedWith); + } + + userLoginLogMapper.insert(userLoginLog); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java index 4b63af0..6931ece 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserRoleServiceImpl.java @@ -1,6 +1,6 @@ package cn.bunny.services.service.system.impl; -import cn.bunny.services.core.utils.UserServiceHelper; +import cn.bunny.services.core.event.event.UpdateUserinfoByUserIdsEvent; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.system.system.dto.user.AssignRolesToUsersDto; import cn.bunny.services.domain.system.system.entity.AdminUser; @@ -12,6 +12,7 @@ import cn.bunny.services.service.system.UserRoleService; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -36,7 +37,7 @@ public class UserRoleServiceImpl extends ServiceImpl i private UserMapper userMapper; @Resource - private UserServiceHelper serviceHelper; + private ApplicationEventPublisher applicationEventPublisher; /** * * 根据用户id获取角色列表 @@ -69,7 +70,8 @@ public class UserRoleServiceImpl extends ServiceImpl i } // 删除这个用户下所有已经分配好的角色内容 - baseMapper.deleteBatchIdsByUserIds(List.of(userId)); + List ids = List.of(userId); + baseMapper.deleteBatchIdsByUserIds(ids); // 保存分配好的角色信息 List roleList = roleIds.stream().map(roleId -> { @@ -81,6 +83,6 @@ public class UserRoleServiceImpl extends ServiceImpl i saveBatch(roleList); // 重新设置Redis中的用户存储信息vo对象 - serviceHelper.updateUserRedisInfo(List.of(userId)); + applicationEventPublisher.publishEvent(new UpdateUserinfoByUserIdsEvent(this, ids)); } } diff --git a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java index ee8e2c0..867ca1b 100644 --- a/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/system/impl/UserServiceImpl.java @@ -1,9 +1,10 @@ package cn.bunny.services.service.system.impl; import cn.bunny.services.core.cache.RedisService; -import cn.bunny.services.core.cache.UserCacheService; -import cn.bunny.services.core.utils.UserServiceHelper; +import cn.bunny.services.core.event.event.ClearAllUserCacheEvent; +import cn.bunny.services.core.event.event.UpdateUserinfoByUserIdsEvent; import cn.bunny.services.domain.common.constant.MinioConstant; +import cn.bunny.services.domain.common.constant.RedisUserConstant; import cn.bunny.services.domain.common.constant.UserConstant; import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.model.vo.LoginVo; @@ -29,6 +30,7 @@ import cn.bunny.services.mapper.system.UserRoleMapper; import cn.bunny.services.minio.MinioHelper; import cn.bunny.services.service.system.FilesService; import cn.bunny.services.service.system.UserService; +import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -37,6 +39,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; import jakarta.validation.Valid; import org.springframework.beans.BeanUtils; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -81,10 +85,10 @@ public class UserServiceImpl extends ServiceImpl implemen private RedisService redisService; @Resource - private UserCacheService userCacheService; + private RedisTemplate redisTemplate; @Resource - private UserServiceHelper userServiceHelper; + private ApplicationEventPublisher applicationEventPublisher; /** * 获取用户信息 @@ -144,7 +148,7 @@ public class UserServiceImpl extends ServiceImpl implemen // 删除Redis中用户信息 String username = adminUser.getUsername(); - userServiceHelper.deleteUserCache(username); + applicationEventPublisher.publishEvent(new ClearAllUserCacheEvent(this, username)); } /** @@ -189,7 +193,8 @@ public class UserServiceImpl extends ServiceImpl implemen List keys = redisService.scannerRedisKeyByPage(pageNum, pageSize); List list = keys.stream().map(key -> { - LoginVo loginVo = userCacheService.getLoginVoByUsername(key); + Object loginVoObject = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(key)); + LoginVo loginVo = JSON.parseObject(JSON.toJSONString(loginVoObject), LoginVo.class); UserVo userVo = new UserVo(); BeanUtils.copyProperties(loginVo, userVo); @@ -305,7 +310,8 @@ public class UserServiceImpl extends ServiceImpl implemen updateById(adminUser); // 同步到 Redis - userServiceHelper.updateUserRedisInfo(List.of(adminUser.getId())); + List ids = List.of(adminUser.getId()); + applicationEventPublisher.publishEvent(new UpdateUserinfoByUserIdsEvent(this, ids)); } /** @@ -324,11 +330,7 @@ public class UserServiceImpl extends ServiceImpl implemen if (!roleList.isEmpty()) throw new AuthCustomerException(ResultCodeEnum.ADMIN_ROLE_CAN_NOT_DELETED); // 清除Redis中数据 - List adminUserList = list(Wrappers.lambdaQuery().eq(AdminUser::getId, ids)); - adminUserList.parallelStream().forEach(adminUser -> { - String username = adminUser.getUsername(); - userServiceHelper.deleteLoginUserCache(username); - }); + applicationEventPublisher.publishEvent(new UpdateUserinfoByUserIdsEvent(this, ids)); // 删除部门相关 userDeptMapper.deleteBatchIdsByUserIds(ids);