From 8188c82c3dc2b958ae900242d06d71b403542309 Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Tue, 24 Mar 2026 07:52:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E5=B9=B6=E6=96=B0=E5=A2=9E=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=AE=A4=E8=AF=81=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 +- pom.xml | 7 +- sql/mysql/youlai_admin.sql | 46 ++-- sql/mysql/youlai_admin_template.sql | 46 ++-- .../boot/auth/controller/AuthController.java | 25 +- ...ontroller.java => WxMaAuthController.java} | 50 ++-- .../{dto/LoginRequest.java => LoginReq.java} | 7 +- .../boot/auth/model/WxMaBindMobileReq.java | 28 ++ .../youlai/boot/auth/model/WxMaLoginResp.java | 42 +++ .../boot/auth/model/WxMaPhoneLoginReq.java | 24 ++ .../model/vo/WechatMiniappLoginResult.java | 63 ----- .../youlai/boot/auth/service/AuthService.java | 8 +- ...pAuthService.java => WxMaAuthService.java} | 8 +- .../auth/service/impl/AuthServiceImpl.java | 84 ++---- ...viceImpl.java => WxMaAuthServiceImpl.java} | 53 ++-- .../youlai/boot/common/annotation/Log.java | 36 ++- .../boot/common/annotation/ValidField.java | 2 +- .../youlai/boot/common/aspect/LogAspect.java | 136 ++++++++++ .../aspect/RepeatSubmitAspect.java | 6 +- .../boot/common/enums/ActionTypeEnum.java | 56 ++++ .../boot/common/enums/LogModuleEnum.java | 47 +++- .../boot/common/enums/RequestMethodEnum.java | 52 ---- .../exception/BusinessException.java | 4 +- .../web => common/result}/ExcelResult.java | 2 +- .../web => common/result}/IResultCode.java | 2 +- .../web => common/result}/PageResult.java | 2 +- .../result/ResponseWriter.java} | 14 +- .../{core/web => common/result}/Result.java | 2 +- .../web => common/result}/ResultCode.java | 2 +- .../youlai/boot/common/util/DateUtils.java | 61 ----- .../validator/FieldValidator.java | 6 +- .../youlai/boot/core/aspect/LogAspect.java | 243 ------------------ .../cache}/config/CaffeineConfig.java | 2 +- .../cache}/config/RedisCacheConfig.java | 2 +- .../cache}/config/RedisConfig.java | 2 +- .../captcha}/config/CaptchaConfig.java | 2 +- .../captcha/exception/CaptchaException.java | 19 ++ .../captcha/model/CaptchaInfo.java} | 15 +- .../captcha/service/CaptchaService.java | 102 ++++++++ .../integration/mail}/config/MailConfig.java | 2 +- .../mail/service/MailService.java | 2 +- .../integration}/sms/enums/SmsTypeEnum.java | 2 +- .../integration}/sms/service/SmsService.java | 4 +- .../sms/service/impl/AliyunSmsService.java | 6 +- .../integration/wxma}/config/WxMaConfig.java | 2 +- .../job}/config/XxlJobConfig.java | 2 +- .../persistence}/config/MybatisConfig.java | 6 +- .../handler}/MyMetaObjectHandler.java | 2 +- .../interceptor}/MyDataPermissionHandler.java | 10 +- .../config/PasswordEncoderConfig.java | 2 +- .../security}/config/SecurityConfig.java | 26 +- .../exception/CaptchaValidationException.java | 2 +- .../exception/NeedBindMobileException.java | 2 +- .../filter/CaptchaValidationFilter.java | 41 +-- .../filter/TokenAuthenticationFilter.java | 12 +- .../handler/MyAccessDeniedHandler.java | 8 +- .../handler/MyAuthenticationEntryPoint.java | 12 +- .../security/model/AuthenticationToken.java | 2 +- .../security/model/RoleDataScope.java | 2 +- .../model/SmsAuthenticationToken.java | 2 +- .../security/model/SysUserDetails.java | 2 +- .../security/model/UserAuthInfo.java | 2 +- .../security/model/UserSession.java | 2 +- .../model/WechatMiniAuthenticationToken.java | 2 +- .../provider/SmsAuthenticationProvider.java | 10 +- .../WechatMiniAuthenticationProvider.java | 12 +- .../security/service/PermissionService.java | 4 +- .../service/SysUserDetailsService.java | 6 +- .../security/token/JwtTokenManager.java | 12 +- .../security/token/RedisTokenManager.java | 12 +- .../security/token/TokenManager.java | 4 +- .../security/util/SecurityUtils.java | 8 +- .../web/advice}/GlobalExceptionHandler.java | 9 +- .../web}/config/CorsConfig.java | 2 +- .../web}/config/JacksonConfig.java | 2 +- .../web}/filter/RateLimiterFilter.java | 10 +- .../web}/filter/RequestLogFilter.java | 2 +- .../interfaces/openapi/OpenApiController.java | 17 ++ .../sse/controller}/SseController.java | 9 +- .../sse/dto/DictChangeEvent.java | 2 +- .../sse/dto/OnlineUserDTO.java | 2 +- .../sse/job}/OnlineUserCountJob.java | 4 +- .../sse/registry}/SseSessionRegistry.java | 4 +- .../sse/service}/SseService.java | 8 +- .../sse/topic}/SseTopics.java | 2 +- .../codegen/controller/CodegenController.java | 11 +- .../service/impl/CodegenServiceImpl.java | 2 +- .../service/impl/GenTableServiceImpl.java | 2 +- .../file/controller/FileController.java | 2 +- .../file/service/impl/MinioFileService.java | 4 +- .../constant/SystemConstants.java | 2 +- .../model => shared/dto}/KeyValue.java | 4 +- .../{common/model => shared/dto}/Option.java | 4 +- .../enums/DataScopeEnum.java | 2 +- .../boot/shared/enums/LogModuleEnum.java | 33 +++ .../{common => shared}/enums/StatusEnum.java | 2 +- .../system/controller/ConfigController.java | 15 +- .../system/controller/DeptController.java | 10 +- .../system/controller/DictController.java | 17 +- .../boot/system/controller/LogController.java | 31 ++- .../system/controller/MenuController.java | 11 +- .../system/controller/NoticeController.java | 13 +- .../system/controller/RoleController.java | 14 +- .../controller/StatisticsController.java | 47 ---- .../system/controller/UserController.java | 60 +++-- .../system/converter/DictItemConverter.java | 2 +- .../system/converter/NoticeConverter.java | 13 +- .../boot/system/converter/RoleConverter.java | 6 +- .../boot/system/converter/UserConverter.java | 34 +-- .../system/listener/UserImportListener.java | 17 +- .../youlai/boot/system/mapper/LogMapper.java | 17 +- .../boot/system/mapper/NoticeMapper.java | 6 +- .../boot/system/mapper/RoleMenuMapper.java | 4 +- .../youlai/boot/system/mapper/UserMapper.java | 17 +- .../boot/system/mapper/UserSocialMapper.java | 2 +- .../youlai/boot/system/model/bo/NoticeBO.java | 77 ------ .../youlai/boot/system/model/bo/UserBO.java | 72 ------ .../boot/system/model/bo/VisitCountBO.java | 23 -- .../boot/system/model/bo/VisitStatsBO.java | 30 --- .../RolePermsDTO.java} | 8 +- .../boot/system/model/dto/UserSessionDTO.java | 39 --- .../boot/system/model/dto/VisitCountDTO.java | 21 ++ .../model/entity/{Log.java => SysLog.java} | 73 +++--- .../model/entity/{User.java => SysUser.java} | 2 +- .../boot/system/model/form/MenuForm.java | 2 +- .../UserImportForm.java} | 10 +- .../boot/system/model/query/LogQuery.java | 8 +- .../CurrentUserVO.java} | 13 +- .../boot/system/model/vo/LogPageVO.java | 38 ++- .../{dto/NoticeDTO.java => vo/NoticeVO.java} | 10 +- .../UserExportVO.java} | 8 +- ...VisitStatsVO.java => VisitOverviewVO.java} | 10 +- .../boot/system/service/DeptService.java | 2 +- .../boot/system/service/DictService.java | 2 +- .../boot/system/service/LogService.java | 9 +- .../boot/system/service/MenuService.java | 2 +- .../boot/system/service/RoleService.java | 4 +- .../boot/system/service/UserService.java | 20 +- .../system/service/UserSocialService.java | 2 +- .../service/impl/ConfigServiceImpl.java | 2 +- .../system/service/impl/DeptServiceImpl.java | 8 +- .../system/service/impl/DictServiceImpl.java | 4 +- .../system/service/impl/LogServiceImpl.java | 38 +-- .../system/service/impl/MenuServiceImpl.java | 10 +- .../service/impl/NoticeServiceImpl.java | 54 ++-- .../service/impl/RoleMenuServiceImpl.java | 12 +- .../system/service/impl/RoleServiceImpl.java | 14 +- .../service/impl/UserNoticeServiceImpl.java | 2 +- .../service/impl/UserRoleServiceImpl.java | 2 +- .../system/service/impl/UserServiceImpl.java | 167 ++++++------ .../service/impl/UserSocialServiceImpl.java | 2 +- src/main/resources/application-dev.yml | 7 +- src/main/resources/application-prod.yml | 6 +- .../resources/mapper/system/LogMapper.xml | 45 ++-- .../resources/mapper/system/NoticeMapper.xml | 4 +- .../mapper/system/RoleMenuMapper.xml | 2 +- .../resources/mapper/system/UserMapper.xml | 12 +- .../mapper/system/UserSocialMapper.xml | 2 +- 158 files changed, 1342 insertions(+), 1562 deletions(-) rename src/main/java/com/youlai/boot/auth/controller/{WechatMiniappAuthController.java => WxMaAuthController.java} (56%) rename src/main/java/com/youlai/boot/auth/model/{dto/LoginRequest.java => LoginReq.java} (91%) create mode 100644 src/main/java/com/youlai/boot/auth/model/WxMaBindMobileReq.java create mode 100644 src/main/java/com/youlai/boot/auth/model/WxMaLoginResp.java create mode 100644 src/main/java/com/youlai/boot/auth/model/WxMaPhoneLoginReq.java delete mode 100644 src/main/java/com/youlai/boot/auth/model/vo/WechatMiniappLoginResult.java rename src/main/java/com/youlai/boot/auth/service/{WechatMiniappAuthService.java => WxMaAuthService.java} (86%) rename src/main/java/com/youlai/boot/auth/service/impl/{WechatMiniappAuthServiceImpl.java => WxMaAuthServiceImpl.java} (81%) create mode 100644 src/main/java/com/youlai/boot/common/aspect/LogAspect.java rename src/main/java/com/youlai/boot/{core => common}/aspect/RepeatSubmitAspect.java (96%) create mode 100644 src/main/java/com/youlai/boot/common/enums/ActionTypeEnum.java delete mode 100644 src/main/java/com/youlai/boot/common/enums/RequestMethodEnum.java rename src/main/java/com/youlai/boot/{core => common}/exception/BusinessException.java (91%) rename src/main/java/com/youlai/boot/{core/web => common/result}/ExcelResult.java (94%) rename src/main/java/com/youlai/boot/{core/web => common/result}/IResultCode.java (78%) rename src/main/java/com/youlai/boot/{core/web => common/result}/PageResult.java (97%) rename src/main/java/com/youlai/boot/{core/web/WebResponseWriter.java => common/result/ResponseWriter.java} (96%) rename src/main/java/com/youlai/boot/{core/web => common/result}/Result.java (98%) rename src/main/java/com/youlai/boot/{core/web => common/result}/ResultCode.java (99%) delete mode 100644 src/main/java/com/youlai/boot/common/util/DateUtils.java rename src/main/java/com/youlai/boot/{core => common}/validator/FieldValidator.java (78%) delete mode 100644 src/main/java/com/youlai/boot/core/aspect/LogAspect.java rename src/main/java/com/youlai/boot/{ => framework/cache}/config/CaffeineConfig.java (95%) rename src/main/java/com/youlai/boot/{ => framework/cache}/config/RedisCacheConfig.java (98%) rename src/main/java/com/youlai/boot/{ => framework/cache}/config/RedisConfig.java (97%) rename src/main/java/com/youlai/boot/{ => framework/integration/captcha}/config/CaptchaConfig.java (96%) create mode 100644 src/main/java/com/youlai/boot/framework/integration/captcha/exception/CaptchaException.java rename src/main/java/com/youlai/boot/{auth/model/vo/CaptchaVO.java => framework/integration/captcha/model/CaptchaInfo.java} (56%) create mode 100644 src/main/java/com/youlai/boot/framework/integration/captcha/service/CaptchaService.java rename src/main/java/com/youlai/boot/{ => framework/integration/mail}/config/MailConfig.java (96%) rename src/main/java/com/youlai/boot/{support => framework/integration}/mail/service/MailService.java (97%) rename src/main/java/com/youlai/boot/{support => framework/integration}/sms/enums/SmsTypeEnum.java (93%) rename src/main/java/com/youlai/boot/{support => framework/integration}/sms/service/SmsService.java (82%) rename src/main/java/com/youlai/boot/{support => framework/integration}/sms/service/impl/AliyunSmsService.java (92%) rename src/main/java/com/youlai/boot/{ => framework/integration/wxma}/config/WxMaConfig.java (94%) rename src/main/java/com/youlai/boot/{ => framework/job}/config/XxlJobConfig.java (97%) rename src/main/java/com/youlai/boot/{ => framework/persistence}/config/MybatisConfig.java (91%) rename src/main/java/com/youlai/boot/{config => framework/persistence/handler}/MyMetaObjectHandler.java (95%) rename src/main/java/com/youlai/boot/{config => framework/persistence/interceptor}/MyDataPermissionHandler.java (97%) rename src/main/java/com/youlai/boot/{ => framework/security}/config/PasswordEncoderConfig.java (91%) rename src/main/java/com/youlai/boot/{ => framework/security}/config/SecurityConfig.java (87%) rename src/main/java/com/youlai/boot/{ => framework}/security/exception/CaptchaValidationException.java (84%) rename src/main/java/com/youlai/boot/{ => framework}/security/exception/NeedBindMobileException.java (91%) rename src/main/java/com/youlai/boot/{ => framework}/security/filter/CaptchaValidationFilter.java (76%) rename src/main/java/com/youlai/boot/{ => framework}/security/filter/TokenAuthenticationFilter.java (88%) rename src/main/java/com/youlai/boot/{ => framework}/security/handler/MyAccessDeniedHandler.java (69%) rename src/main/java/com/youlai/boot/{ => framework}/security/handler/MyAuthenticationEntryPoint.java (78%) rename src/main/java/com/youlai/boot/{ => framework}/security/model/AuthenticationToken.java (92%) rename src/main/java/com/youlai/boot/{ => framework}/security/model/RoleDataScope.java (97%) rename src/main/java/com/youlai/boot/{ => framework}/security/model/SmsAuthenticationToken.java (98%) rename src/main/java/com/youlai/boot/{ => framework}/security/model/SysUserDetails.java (98%) rename src/main/java/com/youlai/boot/{ => framework}/security/model/UserAuthInfo.java (95%) rename src/main/java/com/youlai/boot/{ => framework}/security/model/UserSession.java (94%) rename src/main/java/com/youlai/boot/{ => framework}/security/model/WechatMiniAuthenticationToken.java (97%) rename src/main/java/com/youlai/boot/{ => framework}/security/provider/SmsAuthenticationProvider.java (93%) rename src/main/java/com/youlai/boot/{ => framework}/security/provider/WechatMiniAuthenticationProvider.java (89%) rename src/main/java/com/youlai/boot/{ => framework}/security/service/PermissionService.java (95%) rename src/main/java/com/youlai/boot/{ => framework}/security/service/SysUserDetailsService.java (93%) rename src/main/java/com/youlai/boot/{ => framework}/security/token/JwtTokenManager.java (97%) rename src/main/java/com/youlai/boot/{ => framework}/security/token/RedisTokenManager.java (97%) rename src/main/java/com/youlai/boot/{ => framework}/security/token/TokenManager.java (93%) rename src/main/java/com/youlai/boot/{ => framework}/security/util/SecurityUtils.java (93%) rename src/main/java/com/youlai/boot/{core/exception => framework/web/advice}/GlobalExceptionHandler.java (98%) rename src/main/java/com/youlai/boot/{ => framework/web}/config/CorsConfig.java (97%) rename src/main/java/com/youlai/boot/{ => framework/web}/config/JacksonConfig.java (97%) rename src/main/java/com/youlai/boot/{core => framework/web}/filter/RateLimiterFilter.java (91%) rename src/main/java/com/youlai/boot/{core => framework/web}/filter/RequestLogFilter.java (95%) create mode 100644 src/main/java/com/youlai/boot/interfaces/openapi/OpenApiController.java rename src/main/java/com/youlai/boot/{support/sse => interfaces/sse/controller}/SseController.java (82%) rename src/main/java/com/youlai/boot/{support => interfaces}/sse/dto/DictChangeEvent.java (95%) rename src/main/java/com/youlai/boot/{support => interfaces}/sse/dto/OnlineUserDTO.java (93%) rename src/main/java/com/youlai/boot/{support/sse => interfaces/sse/job}/OnlineUserCountJob.java (85%) rename src/main/java/com/youlai/boot/{support/sse => interfaces/sse/registry}/SseSessionRegistry.java (98%) rename src/main/java/com/youlai/boot/{support/sse => interfaces/sse/service}/SseService.java (93%) rename src/main/java/com/youlai/boot/{support/sse => interfaces/sse/topic}/SseTopics.java (88%) rename src/main/java/com/youlai/boot/{common => shared}/constant/SystemConstants.java (91%) rename src/main/java/com/youlai/boot/{common/model => shared/dto}/KeyValue.java (92%) rename src/main/java/com/youlai/boot/{common/model => shared/dto}/Option.java (96%) rename src/main/java/com/youlai/boot/{common => shared}/enums/DataScopeEnum.java (98%) create mode 100644 src/main/java/com/youlai/boot/shared/enums/LogModuleEnum.java rename src/main/java/com/youlai/boot/{common => shared}/enums/StatusEnum.java (91%) delete mode 100644 src/main/java/com/youlai/boot/system/controller/StatisticsController.java delete mode 100644 src/main/java/com/youlai/boot/system/model/bo/NoticeBO.java delete mode 100644 src/main/java/com/youlai/boot/system/model/bo/UserBO.java delete mode 100644 src/main/java/com/youlai/boot/system/model/bo/VisitCountBO.java delete mode 100644 src/main/java/com/youlai/boot/system/model/bo/VisitStatsBO.java rename src/main/java/com/youlai/boot/system/model/{bo/RolePermsBO.java => dto/RolePermsDTO.java} (77%) delete mode 100644 src/main/java/com/youlai/boot/system/model/dto/UserSessionDTO.java create mode 100644 src/main/java/com/youlai/boot/system/model/dto/VisitCountDTO.java rename src/main/java/com/youlai/boot/system/model/entity/{Log.java => SysLog.java} (61%) rename src/main/java/com/youlai/boot/system/model/entity/{User.java => SysUser.java} (96%) rename src/main/java/com/youlai/boot/system/model/{dto/UserImportDTO.java => form/UserImportForm.java} (85%) rename src/main/java/com/youlai/boot/system/model/{dto/CurrentUserDTO.java => vo/CurrentUserVO.java} (82%) rename src/main/java/com/youlai/boot/system/model/{dto/NoticeDTO.java => vo/NoticeVO.java} (85%) rename src/main/java/com/youlai/boot/system/model/{dto/UserExportDTO.java => vo/UserExportVO.java} (91%) rename src/main/java/com/youlai/boot/system/model/vo/{VisitStatsVO.java => VisitOverviewVO.java} (87%) diff --git a/README.md b/README.md index 45db9948..37f3992a 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ spring: --- -## 📁 项目结构 +## 📁 目录结构 ``` youlai-boot @@ -105,15 +105,13 @@ youlai-boot ├── sql/ # 数据库脚本 ├── src/main/java/com/youlai/boot/ │ ├── auth/ # 认证模块 -│ ├── common/ # 公共模块 -│ ├── config/ # 配置模块 -│ ├── core/ # 核心模块(AOP、异常、过滤器) -│ ├── file/ # 文件服务 -│ ├── plugin/ # 插件扩展(Knife4j、MyBatis) -│ ├── security/ # 安全模块(JWT、Token) -│ ├── support/ # 支撑服务(邮件、短信、WebSocket) │ ├── system/ # 系统模块(用户、角色、菜单、部门) -│ ├── tool/ # 工具模块(代码生成) +│ ├── module/ # 业务模块(文件、代码生成) +│ ├── framework/ # 技术中台(安全、缓存、持久化、集成) +│ ├── interfaces/ # 对外接口(SSE) +│ ├── shared/ # 跨模块共享(DTO、枚举、常量) +│ ├── common/ # 基础能力(结果、异常、切面、工具) +│ ├── config/ # 全局配置 │ └── YouLaiBootApplication.java # 启动类 └── pom.xml # Maven 配置 ``` diff --git a/pom.xml b/pom.xml index 1116596a..7a6fd2fc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.youlai youlai-boot - 4.1.0 + 4.3.0 基于 Java 17 + SpringBoot 4 + Spring Security 构建的权限管理系统。 @@ -133,11 +133,6 @@ spring-boot-starter-validation - - org.springframework.boot - spring-boot-starter-websocket - - org.springframework.boot spring-boot-starter-mail diff --git a/sql/mysql/youlai_admin.sql b/sql/mysql/youlai_admin.sql index e123baa8..af2e99a1 100644 --- a/sql/mysql/youlai_admin.sql +++ b/sql/mysql/youlai_admin.sql @@ -372,7 +372,7 @@ CREATE TABLE `sys_user` ( -- Records of sys_user -- ---------------------------- INSERT INTO `sys_user` VALUES (1, 'root', '有来技术', 0, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', NULL, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345677', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); -INSERT INTO `sys_user` VALUES (2, 'admin', '系统管理员', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345678', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); +INSERT INTO `sys_user` VALUES (2, 'admin', '系统管理员', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18888888888', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); INSERT INTO `sys_user` VALUES (3, 'test', '测试小用户', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 3, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345679', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); INSERT INTO `sys_user` VALUES (4, 'dept_manager', '部门主管', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345680', 1, 'manager@youlaitech.com', now(), NULL, now(), NULL, 0); INSERT INTO `sys_user` VALUES (5, 'dept_member', '部门成员', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345681', 1, 'member@youlaitech.com', now(), NULL, now(), NULL, 0); @@ -406,26 +406,30 @@ INSERT IGNORE INTO `sys_user_role` VALUES (7, 7); -- ---------------------------- DROP TABLE IF EXISTS `sys_log`; CREATE TABLE `sys_log` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `module` varchar(50) NOT NULL COMMENT '日志模块', - `request_method` varchar(64) NOT NULL COMMENT '请求方式', - `request_params` text COMMENT '请求参数(批量请求参数可能会超过text)', - `response_content` mediumtext COMMENT '返回参数', - `content` varchar(255) NOT NULL COMMENT '日志内容', - `request_uri` varchar(255) COMMENT '请求路径', - `method` varchar(255) COMMENT '方法名', - `ip` varchar(45) COMMENT 'IP地址', - `province` varchar(100) COMMENT '省份', - `city` varchar(100) COMMENT '城市', - `execution_time` bigint COMMENT '执行时间(ms)', - `browser` varchar(100) COMMENT '浏览器', - `browser_version` varchar(100) COMMENT '浏览器版本', - `os` varchar(100) COMMENT '终端系统', - `create_by` bigint COMMENT '创建人ID', - `create_time` datetime COMMENT '创建时间', - PRIMARY KEY (`id`) USING BTREE, - KEY `idx_create_time` (`create_time`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='系统操作日志表'; + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键', + `module` TINYINT NOT NULL COMMENT '模块,数字枚举,参考 LogModule 枚举', + `action_type` TINYINT NOT NULL COMMENT '操作类型,数字枚举,参考 ActionType 枚举', + `title` VARCHAR(100) NOT NULL COMMENT '前端显示标题', + `content` TEXT COMMENT '自定义日志内容', + `operator_id` BIGINT NOT NULL COMMENT '操作人ID', + `operator_name` VARCHAR(50) COMMENT '操作人名称', + `request_uri` VARCHAR(255) COMMENT '请求路径', + `request_method` VARCHAR(10) COMMENT '请求方法', + `ip` VARCHAR(45) COMMENT 'IP地址', + `province` VARCHAR(100) COMMENT '省份', + `city` VARCHAR(100) COMMENT '城市', + `device` VARCHAR(100) COMMENT '设备', + `os` VARCHAR(100) COMMENT '操作系统', + `browser` VARCHAR(100) COMMENT '浏览器', + `status` TINYINT DEFAULT 1 COMMENT '0失败 1成功', + `error_msg` VARCHAR(255) COMMENT '错误信息', + `execution_time` INT COMMENT '执行时间(ms)', + `create_time` DATETIME COMMENT '操作时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_module_action_time` (`module`, `action_type`, `create_time`), + KEY `idx_operator_time` (`operator_id`, `create_time`), + KEY `idx_time` (`create_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统操作日志表'; -- ---------------------------- -- Table structure for gen_table diff --git a/sql/mysql/youlai_admin_template.sql b/sql/mysql/youlai_admin_template.sql index c1764792..9ed4db22 100644 --- a/sql/mysql/youlai_admin_template.sql +++ b/sql/mysql/youlai_admin_template.sql @@ -333,7 +333,7 @@ CREATE TABLE `sys_user` ( -- Records of sys_user -- ---------------------------- INSERT INTO `sys_user` VALUES (1, 'root', '有来技术', 0, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', NULL, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345677', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); -INSERT INTO `sys_user` VALUES (2, 'admin', '系统管理员', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345678', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); +INSERT INTO `sys_user` VALUES (2, 'admin', '系统管理员', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18888888888', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); INSERT INTO `sys_user` VALUES (3, 'test', '测试小用户', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 3, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345679', 1, 'youlaitech@163.com', now(), NULL, now(), NULL, 0); INSERT INTO `sys_user` VALUES (4, 'dept_manager', '部门主管', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345680', 1, 'manager@youlaitech.com', now(), NULL, now(), NULL, 0); INSERT INTO `sys_user` VALUES (5, 'dept_member', '部门成员', 1, '$2a$10$xVWsNOhHrCxh5UbpCE7/HuJ.PAOKcYAqRxD2CO2nVnJS.IAXkr5aq', 1, 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif', '18812345681', 1, 'member@youlaitech.com', now(), NULL, now(), NULL, 0); @@ -366,26 +366,30 @@ INSERT IGNORE INTO `sys_user_role` VALUES (7, 7); -- ---------------------------- DROP TABLE IF EXISTS `sys_log`; CREATE TABLE `sys_log` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `module` varchar(50) NOT NULL COMMENT '日志模块', - `request_method` varchar(64) NOT NULL COMMENT '请求方式', - `request_params` text COMMENT '请求参数(批量请求参数可能会超过text)', - `response_content` mediumtext COMMENT '返回参数', - `content` varchar(255) NOT NULL COMMENT '日志内容', - `request_uri` varchar(255) COMMENT '请求路径', - `method` varchar(255) COMMENT '方法名', - `ip` varchar(45) COMMENT 'IP地址', - `province` varchar(100) COMMENT '省份', - `city` varchar(100) COMMENT '城市', - `execution_time` bigint COMMENT '执行时间(ms)', - `browser` varchar(100) COMMENT '浏览器', - `browser_version` varchar(100) COMMENT '浏览器版本', - `os` varchar(100) COMMENT '终端系统', - `create_by` bigint COMMENT '创建人ID', - `create_time` datetime COMMENT '创建时间', - PRIMARY KEY (`id`) USING BTREE, - KEY `idx_create_time` (`create_time`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='系统操作日志表'; + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键', + `module` TINYINT NOT NULL COMMENT '模块,数字枚举,参考 LogModule 枚举', + `action_type` TINYINT NOT NULL COMMENT '操作类型,数字枚举,参考 ActionType 枚举', + `title` VARCHAR(100) NOT NULL COMMENT '前端显示标题', + `content` TEXT COMMENT '自定义日志内容', + `operator_id` BIGINT NOT NULL COMMENT '操作人ID', + `operator_name` VARCHAR(50) COMMENT '操作人名称', + `request_uri` VARCHAR(255) COMMENT '请求路径', + `request_method` VARCHAR(10) COMMENT '请求方法', + `ip` VARCHAR(45) COMMENT 'IP地址', + `province` VARCHAR(100) COMMENT '省份', + `city` VARCHAR(100) COMMENT '城市', + `device` VARCHAR(100) COMMENT '设备', + `os` VARCHAR(100) COMMENT '操作系统', + `browser` VARCHAR(100) COMMENT '浏览器', + `status` TINYINT DEFAULT 1 COMMENT '0失败 1成功', + `error_msg` VARCHAR(255) COMMENT '错误信息', + `execution_time` INT COMMENT '执行时间(ms)', + `create_time` DATETIME COMMENT '操作时间', + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_module_action_time` (`module`, `action_type`, `create_time`), + KEY `idx_operator_time` (`operator_id`, `create_time`), + KEY `idx_time` (`create_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统操作日志表'; -- ---------------------------- -- Table structure for gen_table diff --git a/src/main/java/com/youlai/boot/auth/controller/AuthController.java b/src/main/java/com/youlai/boot/auth/controller/AuthController.java index 8a458437..ae78c7eb 100644 --- a/src/main/java/com/youlai/boot/auth/controller/AuthController.java +++ b/src/main/java/com/youlai/boot/auth/controller/AuthController.java @@ -1,12 +1,13 @@ package com.youlai.boot.auth.controller; -import com.youlai.boot.auth.model.vo.CaptchaVO; -import com.youlai.boot.auth.model.dto.LoginRequest; +import com.youlai.boot.auth.model.LoginReq; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.common.result.Result; import com.youlai.boot.auth.service.AuthService; import com.youlai.boot.common.annotation.Log; -import com.youlai.boot.security.model.AuthenticationToken; +import com.youlai.boot.framework.integration.captcha.model.CaptchaInfo; +import com.youlai.boot.framework.security.model.AuthenticationToken; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -32,24 +33,24 @@ public class AuthController { @Operation(summary = "获取验证码") @GetMapping("/captcha") - public Result getCaptcha() { - CaptchaVO captcha = authService.getCaptcha(); + public Result getCaptcha() { + CaptchaInfo captcha = authService.getCaptcha(); return Result.success(captcha); } @Operation(summary = "账号密码登录") @PostMapping("/login") - @Log(value = "登录", module = LogModuleEnum.LOGIN) - public Result login(@RequestBody @Valid LoginRequest request) { + @Log(module = LogModuleEnum.LOGIN, value = ActionTypeEnum.LOGIN) + public Result login(@RequestBody @Valid LoginReq request) { AuthenticationToken authenticationToken = authService.login(request.getUsername(), request.getPassword()); return Result.success(authenticationToken); } @Operation(summary = "短信验证码登录") @PostMapping("/login/sms") - @Log(value = "短信验证码登录", module = LogModuleEnum.LOGIN) + @Log(module = LogModuleEnum.LOGIN, value = ActionTypeEnum.LOGIN) public Result loginBySms( - @Parameter(description = "手机号", example = "18812345678") @RequestParam String mobile, + @Parameter(description = "手机号", example = "18888888888") @RequestParam String mobile, @Parameter(description = "验证码", example = "123456") @RequestParam String code ) { AuthenticationToken loginResult = authService.loginBySms(mobile, code); @@ -59,7 +60,7 @@ public class AuthController { @Operation(summary = "发送登录短信验证码") @PostMapping("/sms/code") public Result sendSmsCode( - @Parameter(description = "手机号", example = "18812345678") @RequestParam String mobile + @Parameter(description = "手机号", example = "18888888888") @RequestParam String mobile ) { authService.sendSmsCode(mobile); return Result.success(); @@ -67,7 +68,7 @@ public class AuthController { @Operation(summary = "退出登录") @DeleteMapping("/logout") - @Log(value = "退出登录", module = LogModuleEnum.LOGIN) + @Log(module = LogModuleEnum.LOGIN, value = ActionTypeEnum.LOGOUT) public Result logout() { authService.logout(); return Result.success(); diff --git a/src/main/java/com/youlai/boot/auth/controller/WechatMiniappAuthController.java b/src/main/java/com/youlai/boot/auth/controller/WxMaAuthController.java similarity index 56% rename from src/main/java/com/youlai/boot/auth/controller/WechatMiniappAuthController.java rename to src/main/java/com/youlai/boot/auth/controller/WxMaAuthController.java index cb677b8e..60bc3eaa 100644 --- a/src/main/java/com/youlai/boot/auth/controller/WechatMiniappAuthController.java +++ b/src/main/java/com/youlai/boot/auth/controller/WxMaAuthController.java @@ -1,21 +1,27 @@ package com.youlai.boot.auth.controller; -import com.youlai.boot.auth.model.vo.WechatMiniappLoginResult; -import com.youlai.boot.auth.service.WechatMiniappAuthService; +import com.youlai.boot.auth.model.WxMaBindMobileReq; +import com.youlai.boot.auth.model.WxMaPhoneLoginReq; +import com.youlai.boot.auth.model.WxMaLoginResp; +import com.youlai.boot.auth.service.WxMaAuthService; import com.youlai.boot.common.annotation.Log; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; -import com.youlai.boot.core.web.Result; -import com.youlai.boot.security.model.AuthenticationToken; +import com.youlai.boot.common.result.Result; +import com.youlai.boot.framework.security.model.AuthenticationToken; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; + /** * 微信小程序认证控制层 * @@ -24,12 +30,12 @@ import org.springframework.web.bind.annotation.RestController; */ @Tag(name = "13.微信小程序认证") @RestController -@RequestMapping("/api/v1/wechat/miniapp/auth") +@RequestMapping("/api/v1/wxma/auth") @RequiredArgsConstructor @Slf4j -public class WechatMiniappAuthController { +public class WxMaAuthController { - private final WechatMiniappAuthService wechatMiniappAuthService; + private final WxMaAuthService wxMaAuthService; /** * 静默登录 @@ -42,12 +48,12 @@ public class WechatMiniappAuthController { */ @Operation(summary = "静默登录", description = "通过微信 code 登录,已绑定用户直接返回 token,未绑定用户返回 openid 需绑定手机号") @PostMapping("/silent-login") - @Log(value = "微信小程序静默登录", module = LogModuleEnum.LOGIN) - public Result silentLogin( + @Log(module = LogModuleEnum.LOGIN, value = ActionTypeEnum.LOGIN) + public Result silentLogin( @Parameter(description = "微信登录凭证(wx.login 获取)", required = true, example = "0xxx") @RequestParam String code ) { - WechatMiniappLoginResult result = wechatMiniappAuthService.silentLogin(code); + WxMaLoginResp result = wxMaAuthService.silentLogin(code); return Result.success(result); } @@ -60,14 +66,9 @@ public class WechatMiniappAuthController { */ @Operation(summary = "手机号快捷登录", description = "同时使用微信 code 和手机号授权 code 登录,适用于企业认证小程序") @PostMapping("/phone-login") - @Log(value = "微信小程序手机号快捷登录", module = LogModuleEnum.LOGIN) - public Result phoneLogin( - @Parameter(description = "微信登录凭证(wx.login 获取)", required = true, example = "0xxx") - @RequestParam String loginCode, - @Parameter(description = "手机号授权凭证(getPhoneNumber 事件获取)", required = true, example = "0xxx") - @RequestParam String phoneCode - ) { - AuthenticationToken result = wechatMiniappAuthService.phoneLogin(loginCode, phoneCode); + @Log(module = LogModuleEnum.LOGIN, value = ActionTypeEnum.LOGIN) + public Result phoneLogin(@Valid @RequestBody WxMaPhoneLoginReq req) { + AuthenticationToken result = wxMaAuthService.phoneLogin(req.getLoginCode(), req.getPhoneCode()); return Result.success(result); } @@ -80,16 +81,9 @@ public class WechatMiniappAuthController { */ @Operation(summary = "绑定手机号", description = "为静默登录用户绑定手机号,绑定成功后自动登录") @PostMapping("/bind-mobile") - @Log(value = "微信小程序绑定手机号", module = LogModuleEnum.LOGIN) - public Result bindMobile( - @Parameter(description = "微信用户唯一标识(静默登录返回)", required = true) - @RequestParam String openid, - @Parameter(description = "手机号码", required = true, example = "18812345678") - @RequestParam String mobile, - @Parameter(description = "短信验证码", required = true, example = "123456") - @RequestParam String smsCode - ) { - AuthenticationToken result = wechatMiniappAuthService.bindMobile(openid, mobile, smsCode); + @Log(module = LogModuleEnum.LOGIN, value = ActionTypeEnum.LOGIN) + public Result bindMobile(@Valid @RequestBody WxMaBindMobileReq req) { + AuthenticationToken result = wxMaAuthService.bindMobile(req.getOpenid(), req.getMobile(), req.getSmsCode()); return Result.success(result); } } diff --git a/src/main/java/com/youlai/boot/auth/model/dto/LoginRequest.java b/src/main/java/com/youlai/boot/auth/model/LoginReq.java similarity index 91% rename from src/main/java/com/youlai/boot/auth/model/dto/LoginRequest.java rename to src/main/java/com/youlai/boot/auth/model/LoginReq.java index 57b77de5..7faaa424 100644 --- a/src/main/java/com/youlai/boot/auth/model/dto/LoginRequest.java +++ b/src/main/java/com/youlai/boot/auth/model/LoginReq.java @@ -1,4 +1,4 @@ -package com.youlai.boot.auth.model.dto; +package com.youlai.boot.auth.model; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -13,7 +13,7 @@ import jakarta.validation.constraints.NotBlank; */ @Schema(description = "登录请求参数") @Data -public class LoginRequest { +public class LoginReq { @Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin") @NotBlank(message = "用户名不能为空") @@ -28,5 +28,4 @@ public class LoginRequest { @Schema(description = "验证码", example = "123456") private String captchaCode; -} - +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/auth/model/WxMaBindMobileReq.java b/src/main/java/com/youlai/boot/auth/model/WxMaBindMobileReq.java new file mode 100644 index 00000000..cbd3d729 --- /dev/null +++ b/src/main/java/com/youlai/boot/auth/model/WxMaBindMobileReq.java @@ -0,0 +1,28 @@ +package com.youlai.boot.auth.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * 微信小程序绑定手机号请求 + * + * @author Ray.Hao + * @since 3.0.0 + */ +@Schema(description = "微信小程序绑定手机号请求") +@Data +public class WxMaBindMobileReq { + + @NotBlank(message = "openid 不能为空") + @Schema(description = "微信用户唯一标识(静默登录返回)", example = "oVBkZ0aYgDMDIywRdgPW8-joxXc4") + private String openid; + + @NotBlank(message = "手机号不能为空") + @Schema(description = "手机号码", example = "18888888888") + private String mobile; + + @NotBlank(message = "短信验证码不能为空") + @Schema(description = "短信验证码", example = "123456") + private String smsCode; +} diff --git a/src/main/java/com/youlai/boot/auth/model/WxMaLoginResp.java b/src/main/java/com/youlai/boot/auth/model/WxMaLoginResp.java new file mode 100644 index 00000000..30e45ad5 --- /dev/null +++ b/src/main/java/com/youlai/boot/auth/model/WxMaLoginResp.java @@ -0,0 +1,42 @@ +package com.youlai.boot.auth.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 微信小程序登录响应 + * + * @author Ray.Hao + * @since 2.4.0 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "微信小程序登录响应") +public class WxMaLoginResp { + + @Schema(description = "是否新用户") + private Boolean isNewUser; + + @Schema(description = "是否需要绑定手机号") + private Boolean needBindMobile; + + @Schema(description = "微信openid(绑定手机号时需要)") + private String openid; + + @Schema(description = "访问令牌") + private String accessToken; + + @Schema(description = "刷新令牌") + private String refreshToken; + + @Schema(description = "令牌类型") + private String tokenType; + + @Schema(description = "过期时间(秒)") + private Integer expiresIn; +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/auth/model/WxMaPhoneLoginReq.java b/src/main/java/com/youlai/boot/auth/model/WxMaPhoneLoginReq.java new file mode 100644 index 00000000..cf3ad390 --- /dev/null +++ b/src/main/java/com/youlai/boot/auth/model/WxMaPhoneLoginReq.java @@ -0,0 +1,24 @@ +package com.youlai.boot.auth.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * 微信小程序手机号快捷登录请求 + * + * @author Ray.Hao + * @since 3.0.0 + */ +@Schema(description = "微信小程序手机号快捷登录请求") +@Data +public class WxMaPhoneLoginReq { + + @NotBlank(message = "微信登录凭证不能为空") + @Schema(description = "微信登录凭证(wx.login 获取)", example = "0xxx") + private String loginCode; + + @NotBlank(message = "手机号授权凭证不能为空") + @Schema(description = "手机号授权凭证(getPhoneNumber 事件获取)", example = "0xxx") + private String phoneCode; +} diff --git a/src/main/java/com/youlai/boot/auth/model/vo/WechatMiniappLoginResult.java b/src/main/java/com/youlai/boot/auth/model/vo/WechatMiniappLoginResult.java deleted file mode 100644 index deae4d36..00000000 --- a/src/main/java/com/youlai/boot/auth/model/vo/WechatMiniappLoginResult.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.youlai.boot.auth.model.vo; - -import com.youlai.boot.security.model.AuthenticationToken; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -/** - * 微信小程序登录结果 - * - * @author Ray.Hao - * @since 2.4.0 - */ -@Data -@Schema(description = "微信小程序登录结果") -public class WechatMiniappLoginResult { - - @Schema(description = "是否新用户") - private Boolean isNewUser; - - @Schema(description = "是否需要绑定手机号") - private Boolean needBindMobile; - - @Schema(description = "微信openid(绑定手机号时需要)") - private String openid; - - @Schema(description = "访问令牌") - private String accessToken; - - @Schema(description = "刷新令牌") - private String refreshToken; - - @Schema(description = "令牌类型") - private String tokenType; - - @Schema(description = "过期时间(秒)") - private Integer expiresIn; - - /** - * 创建需要绑定手机号的结果 - */ - public static WechatMiniappLoginResult needBindMobile(String openid) { - WechatMiniappLoginResult result = new WechatMiniappLoginResult(); - result.setIsNewUser(true); - result.setNeedBindMobile(true); - result.setOpenid(openid); - return result; - } - - /** - * 创建登录成功的结果 - */ - public static WechatMiniappLoginResult success(AuthenticationToken token) { - WechatMiniappLoginResult result = new WechatMiniappLoginResult(); - result.setIsNewUser(false); - result.setNeedBindMobile(false); - result.setAccessToken(token.getAccessToken()); - result.setRefreshToken(token.getRefreshToken()); - result.setTokenType(token.getTokenType()); - result.setExpiresIn(token.getExpiresIn()); - return result; - } - -} diff --git a/src/main/java/com/youlai/boot/auth/service/AuthService.java b/src/main/java/com/youlai/boot/auth/service/AuthService.java index 6b478533..65ec2a52 100644 --- a/src/main/java/com/youlai/boot/auth/service/AuthService.java +++ b/src/main/java/com/youlai/boot/auth/service/AuthService.java @@ -1,7 +1,7 @@ package com.youlai.boot.auth.service; -import com.youlai.boot.auth.model.vo.CaptchaVO; -import com.youlai.boot.security.model.AuthenticationToken; +import com.youlai.boot.framework.integration.captcha.model.CaptchaInfo; +import com.youlai.boot.framework.security.model.AuthenticationToken; /** * 认证服务接口 @@ -43,10 +43,8 @@ public interface AuthService { /** * 获取验证码 - * - * @return 验证码 */ - CaptchaVO getCaptcha(); + CaptchaInfo getCaptcha(); /** * 刷新令牌 diff --git a/src/main/java/com/youlai/boot/auth/service/WechatMiniappAuthService.java b/src/main/java/com/youlai/boot/auth/service/WxMaAuthService.java similarity index 86% rename from src/main/java/com/youlai/boot/auth/service/WechatMiniappAuthService.java rename to src/main/java/com/youlai/boot/auth/service/WxMaAuthService.java index 3ffaadd2..4e8db970 100644 --- a/src/main/java/com/youlai/boot/auth/service/WechatMiniappAuthService.java +++ b/src/main/java/com/youlai/boot/auth/service/WxMaAuthService.java @@ -1,7 +1,7 @@ package com.youlai.boot.auth.service; -import com.youlai.boot.auth.model.vo.WechatMiniappLoginResult; -import com.youlai.boot.security.model.AuthenticationToken; +import com.youlai.boot.auth.model.WxMaLoginResp; +import com.youlai.boot.framework.security.model.AuthenticationToken; /** * 微信小程序认证服务接口 @@ -9,7 +9,7 @@ import com.youlai.boot.security.model.AuthenticationToken; * @author Ray.Hao * @since 2.4.0 */ -public interface WechatMiniappAuthService { +public interface WxMaAuthService { /** * 静默登录 @@ -21,7 +21,7 @@ public interface WechatMiniappAuthService { * @param code 微信登录凭证(wx.login 获取) * @return 登录结果(成功返回 token,需绑定返回 openid) */ - WechatMiniappLoginResult silentLogin(String code); + WxMaLoginResp silentLogin(String code); /** * 手机号快捷登录 diff --git a/src/main/java/com/youlai/boot/auth/service/impl/AuthServiceImpl.java b/src/main/java/com/youlai/boot/auth/service/impl/AuthServiceImpl.java index b9d382c8..f2ef1981 100644 --- a/src/main/java/com/youlai/boot/auth/service/impl/AuthServiceImpl.java +++ b/src/main/java/com/youlai/boot/auth/service/impl/AuthServiceImpl.java @@ -1,24 +1,21 @@ package com.youlai.boot.auth.service.impl; -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.hutool.captcha.AbstractCaptcha; -import cn.hutool.captcha.CaptchaUtil; -import cn.hutool.captcha.generator.CodeGenerator; -import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; -import com.youlai.boot.auth.model.vo.CaptchaVO; import com.youlai.boot.auth.service.AuthService; import com.youlai.boot.common.constant.RedisConstants; -import com.youlai.boot.common.enums.CaptchaTypeEnum; -import com.youlai.boot.config.property.CaptchaProperties; -import com.youlai.boot.security.model.AuthenticationToken; -import com.youlai.boot.security.model.SmsAuthenticationToken; -import com.youlai.boot.security.token.TokenManager; -import com.youlai.boot.security.util.SecurityUtils; -import com.youlai.boot.support.sms.enums.SmsTypeEnum; -import com.youlai.boot.support.sms.service.SmsService; -import com.youlai.boot.system.service.UserSocialService; -import com.youlai.boot.system.service.UserService; +import com.youlai.boot.common.enums.ActionTypeEnum; +import com.youlai.boot.common.util.IPUtils; +import com.youlai.boot.framework.integration.captcha.model.CaptchaInfo; +import com.youlai.boot.framework.integration.captcha.service.CaptchaService; +import com.youlai.boot.framework.security.model.AuthenticationToken; +import com.youlai.boot.framework.security.model.SmsAuthenticationToken; +import com.youlai.boot.framework.security.token.TokenManager; +import com.youlai.boot.framework.security.util.SecurityUtils; +import com.youlai.boot.framework.integration.sms.enums.SmsTypeEnum; +import com.youlai.boot.framework.integration.sms.service.SmsService; +import com.youlai.boot.system.model.entity.SysLog; +import com.youlai.boot.system.service.LogService; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; @@ -27,8 +24,10 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; -import java.awt.*; +import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -47,12 +46,10 @@ public class AuthServiceImpl implements AuthService { private final AuthenticationManager authenticationManager; private final TokenManager tokenManager; - private final Font captchaFont; - private final CaptchaProperties captchaProperties; - private final CodeGenerator codeGenerator; - private final SmsService smsService; private final RedisTemplate redisTemplate; + private final CaptchaService captchaService; + private final LogService logService; /** * 用户名密码登录 * @@ -124,7 +121,6 @@ public class AuthServiceImpl implements AuthService { // 3. 认证成功后生成 JWT 令牌,并存入 Security 上下文,供登录日志 AOP 使用(已认证) AuthenticationToken authenticationToken = tokenManager.generateToken(authentication); SecurityContextHolder.getContext().setAuthentication(authentication); - return authenticationToken; } @@ -143,50 +139,10 @@ public class AuthServiceImpl implements AuthService { /** * 获取验证码 - * - * @return 验证码 */ @Override - public CaptchaVO getCaptcha() { - - String captchaType = captchaProperties.getType(); - int width = captchaProperties.getWidth(); - int height = captchaProperties.getHeight(); - int interfereCount = captchaProperties.getInterfereCount(); - int codeLength = captchaProperties.getCode().getLength(); - - AbstractCaptcha captcha; - if (CaptchaTypeEnum.CIRCLE.name().equalsIgnoreCase(captchaType)) { - captcha = CaptchaUtil.createCircleCaptcha(width, height, codeLength, interfereCount); - } else if (CaptchaTypeEnum.GIF.name().equalsIgnoreCase(captchaType)) { - captcha = CaptchaUtil.createGifCaptcha(width, height, codeLength); - } else if (CaptchaTypeEnum.LINE.name().equalsIgnoreCase(captchaType)) { - captcha = CaptchaUtil.createLineCaptcha(width, height, codeLength, interfereCount); - } else if (CaptchaTypeEnum.SHEAR.name().equalsIgnoreCase(captchaType)) { - captcha = CaptchaUtil.createShearCaptcha(width, height, codeLength, interfereCount); - } else { - throw new IllegalArgumentException("Invalid captcha type: " + captchaType); - } - captcha.setGenerator(codeGenerator); - captcha.setTextAlpha(captchaProperties.getTextAlpha()); - captcha.setFont(captchaFont); - - String captchaCode = captcha.getCode(); - String imageBase64Data = captcha.getImageBase64Data(); - - // 验证码文本缓存至Redis,用于登录校验 - String captchaId = IdUtil.fastSimpleUUID(); - redisTemplate.opsForValue().set( - StrUtil.format(RedisConstants.Captcha.IMAGE_CODE, captchaId), - captchaCode, - captchaProperties.getExpireSeconds(), - TimeUnit.SECONDS - ); - - return CaptchaVO.builder() - .captchaId(captchaId) - .captchaBase64(imageBase64Data) - .build(); + public CaptchaInfo getCaptcha() { + return captchaService.generate(); } /** diff --git a/src/main/java/com/youlai/boot/auth/service/impl/WechatMiniappAuthServiceImpl.java b/src/main/java/com/youlai/boot/auth/service/impl/WxMaAuthServiceImpl.java similarity index 81% rename from src/main/java/com/youlai/boot/auth/service/impl/WechatMiniappAuthServiceImpl.java rename to src/main/java/com/youlai/boot/auth/service/impl/WxMaAuthServiceImpl.java index 314b5848..1586f0c5 100644 --- a/src/main/java/com/youlai/boot/auth/service/impl/WechatMiniappAuthServiceImpl.java +++ b/src/main/java/com/youlai/boot/auth/service/impl/WxMaAuthServiceImpl.java @@ -5,16 +5,16 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; -import com.youlai.boot.auth.model.vo.WechatMiniappLoginResult; -import com.youlai.boot.auth.service.WechatMiniappAuthService; +import com.youlai.boot.auth.model.WxMaLoginResp; +import com.youlai.boot.auth.service.WxMaAuthService; import com.youlai.boot.common.constant.RedisConstants; -import com.youlai.boot.security.exception.NeedBindMobileException; -import com.youlai.boot.security.model.AuthenticationToken; -import com.youlai.boot.security.model.SysUserDetails; -import com.youlai.boot.security.model.WechatMiniAuthenticationToken; -import com.youlai.boot.security.token.TokenManager; +import com.youlai.boot.framework.security.exception.NeedBindMobileException; +import com.youlai.boot.framework.security.model.AuthenticationToken; +import com.youlai.boot.framework.security.model.SysUserDetails; +import com.youlai.boot.framework.security.model.WechatMiniAuthenticationToken; +import com.youlai.boot.framework.security.token.TokenManager; import com.youlai.boot.system.enums.SocialPlatformEnum; -import com.youlai.boot.system.model.entity.User; +import com.youlai.boot.system.model.entity.SysUser; import com.youlai.boot.system.service.UserSocialService; import com.youlai.boot.system.service.UserService; import com.youlai.boot.system.service.UserRoleService; @@ -35,12 +35,12 @@ import java.util.Collections; * 微信小程序认证服务实现 * * @author Ray.Hao - * @since 2.4.0 + * @since 4.0.0 */ @Service @RequiredArgsConstructor @Slf4j -public class WechatMiniappAuthServiceImpl implements WechatMiniappAuthService { +public class WxMaAuthServiceImpl implements WxMaAuthService { private final WxMaService wxMaService; private final AuthenticationManager authenticationManager; @@ -54,16 +54,27 @@ public class WechatMiniappAuthServiceImpl implements WechatMiniappAuthService { * 静默登录 */ @Override - public WechatMiniappLoginResult silentLogin(String code) { + public WxMaLoginResp silentLogin(String code) { WechatMiniAuthenticationToken token = new WechatMiniAuthenticationToken(code); try { Authentication authentication = authenticationManager.authenticate(token); AuthenticationToken authToken = tokenManager.generateToken(authentication); SecurityContextHolder.getContext().setAuthentication(authentication); - return WechatMiniappLoginResult.success(authToken); + return WxMaLoginResp.builder() + .isNewUser(false) + .needBindMobile(false) + .accessToken(authToken.getAccessToken()) + .refreshToken(authToken.getRefreshToken()) + .tokenType(authToken.getTokenType()) + .expiresIn(authToken.getExpiresIn()) + .build(); } catch (NeedBindMobileException e) { - return WechatMiniappLoginResult.needBindMobile(e.getOpenid()); + return WxMaLoginResp.builder() + .isNewUser(true) + .needBindMobile(true) + .openid(e.getOpenid()) + .build(); } } @@ -83,7 +94,7 @@ public class WechatMiniappAuthServiceImpl implements WechatMiniappAuthService { log.info("微信小程序手机号快捷登录:openid={}, mobile={}", openid, mobile); // 3. 查询或创建用户 - User user = findOrCreateUser(mobile); + SysUser user = findOrCreateUser(mobile); // 4. 绑定微信 openid bindWechatOpenid(user, session); @@ -102,7 +113,7 @@ public class WechatMiniappAuthServiceImpl implements WechatMiniappAuthService { validateSmsCode(mobile, smsCode); // 2. 查询或创建用户 - User user = findOrCreateUser(mobile); + SysUser user = findOrCreateUser(mobile); // 3. 绑定微信 openid userSocialService.bindOrUpdate( @@ -148,9 +159,9 @@ public class WechatMiniappAuthServiceImpl implements WechatMiniappAuthService { /** * 查询或创建用户 */ - private User findOrCreateUser(String mobile) { - User user = userService.lambdaQuery() - .eq(User::getMobile, mobile) + private SysUser findOrCreateUser(String mobile) { + SysUser user = userService.lambdaQuery() + .eq(SysUser::getMobile, mobile) .one(); if (user == null) { @@ -167,8 +178,8 @@ public class WechatMiniappAuthServiceImpl implements WechatMiniappAuthService { * 新用户默认分配 GUEST(访问游客)角色 *

*/ - private User createNewUser(String mobile) { - User user = new User(); + private SysUser createNewUser(String mobile) { + SysUser user = new SysUser(); user.setMobile(mobile); user.setUsername("wx_" + IdUtil.fastSimpleUUID().substring(0, 8)); user.setNickname("微信用户"); @@ -187,7 +198,7 @@ public class WechatMiniappAuthServiceImpl implements WechatMiniappAuthService { /** * 绑定微信 openid */ - private void bindWechatOpenid(User user, WxMaJscode2SessionResult session) { + private void bindWechatOpenid(SysUser user, WxMaJscode2SessionResult session) { try { userSocialService.bindOrUpdate( user.getId(), diff --git a/src/main/java/com/youlai/boot/common/annotation/Log.java b/src/main/java/com/youlai/boot/common/annotation/Log.java index 3d2002f4..a9caa742 100644 --- a/src/main/java/com/youlai/boot/common/annotation/Log.java +++ b/src/main/java/com/youlai/boot/common/annotation/Log.java @@ -1,5 +1,6 @@ package com.youlai.boot.common.annotation; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import java.lang.annotation.*; @@ -16,34 +17,31 @@ import java.lang.annotation.*; public @interface Log { /** - * 日志描述 + * 模块 * - * @return 日志描述 + * @return 模块 */ - String value() default ""; - - /** - * 日志模块 - * - * @return 日志模块 - */ - LogModuleEnum module(); /** - * 是否记录请求参数 + * 操作类型 * - * @return 是否记录请求参数 + * @return 操作类型 */ - boolean params() default true; + ActionTypeEnum value(); /** - * 是否记录响应结果 - *
- * 响应结果默认不记录,避免日志过大 - * @return 是否记录响应结果 + * 操作标题(可选,默认使用枚举描述) + * + * @return 标题 */ - boolean result() default false; + String title() default ""; + /** + * 自定义日志内容(可选,用于记录操作细节) + * + * @return 日志内容 + */ + String content() default ""; -} \ No newline at end of file +} diff --git a/src/main/java/com/youlai/boot/common/annotation/ValidField.java b/src/main/java/com/youlai/boot/common/annotation/ValidField.java index 14b3ae44..559b06e1 100644 --- a/src/main/java/com/youlai/boot/common/annotation/ValidField.java +++ b/src/main/java/com/youlai/boot/common/annotation/ValidField.java @@ -1,6 +1,6 @@ package com.youlai.boot.common.annotation; -import com.youlai.boot.core.validator.FieldValidator; +import com.youlai.boot.common.validator.FieldValidator; import jakarta.validation.Constraint; import jakarta.validation.Payload; diff --git a/src/main/java/com/youlai/boot/common/aspect/LogAspect.java b/src/main/java/com/youlai/boot/common/aspect/LogAspect.java new file mode 100644 index 00000000..c22552ea --- /dev/null +++ b/src/main/java/com/youlai/boot/common/aspect/LogAspect.java @@ -0,0 +1,136 @@ +package com.youlai.boot.common.aspect; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.useragent.UserAgent; +import cn.hutool.http.useragent.UserAgentUtil; +import com.youlai.boot.common.annotation.Log; +import com.youlai.boot.common.enums.ActionTypeEnum; +import com.youlai.boot.common.enums.LogModuleEnum; +import com.youlai.boot.common.util.IPUtils; +import com.youlai.boot.framework.security.util.SecurityUtils; +import com.youlai.boot.system.model.entity.SysLog; +import com.youlai.boot.system.service.LogService; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.time.LocalDateTime; + +/** + * 日志切面 + * + * @author Ray.Hao + * @since 2.10.0 + */ +@Aspect +@Component +@RequiredArgsConstructor +@Slf4j +public class LogAspect { + + private final LogService logService; + + /** + * 日志注解切点 + */ + @Pointcut("@annotation(logAnnotation)") + public void logPointCut(Log logAnnotation) { + } + + /** + * 环绕通知:记录操作日志 + */ + @Around(value = "logPointCut(logAnnotation)", argNames = "pjp,logAnnotation") + public Object around(ProceedingJoinPoint pjp, Log logAnnotation) throws Throwable { + + long startTime = System.currentTimeMillis(); + Object result = null; + Exception exception = null; + + try { + result = pjp.proceed(); + return result; + } catch (Exception e) { + exception = e; + throw e; + } finally { + long executionTime = System.currentTimeMillis() - startTime; + saveLogAsync(logAnnotation, executionTime, exception); + } + } + + /** + * 异步保存日志 + */ + @Async + public void saveLogAsync(Log logAnnotation, long executionTime, Exception exception) { + try { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes == null) { + return; + } + + HttpServletRequest request = attributes.getRequest(); + + // 解析 User-Agent + String userAgentStr = request.getHeader("User-Agent"); + UserAgent userAgent = UserAgentUtil.parse(userAgentStr); + + // 解析 IP 地区 + String ip = IPUtils.getIpAddr(request); + String region = IPUtils.getRegion(ip); + String province = null; + String city = null; + if (StrUtil.isNotBlank(region)) { + String[] parts = region.split("\\|"); + if (parts.length >= 3) { + province = StrUtil.blankToDefault(parts[2], null); + city = StrUtil.blankToDefault(parts[3], null); + } + } + + // 获取当前用户信息 + Long userId = SecurityUtils.getUserId(); + String username = SecurityUtils.getUsername(); + + // 构建日志实体 + LogModuleEnum module = logAnnotation.module(); + ActionTypeEnum actionType = logAnnotation.value(); + String title = StrUtil.blankToDefault(logAnnotation.title(), + module.getLabel() + "-" + actionType.getLabel()); + String content = logAnnotation.content(); + + SysLog logEntity = new SysLog(); + logEntity.setModule(module); + logEntity.setActionType(actionType); + logEntity.setTitle(title); + logEntity.setContent(content); + logEntity.setOperatorId(userId); + logEntity.setOperatorName(username); + logEntity.setRequestUri(request.getRequestURI()); + logEntity.setRequestMethod(request.getMethod()); + logEntity.setIp(ip); + logEntity.setProvince(province); + logEntity.setCity(city); + logEntity.setDevice(userAgent.getOs().getName()); + logEntity.setOs(userAgent.getOs().getName()); + logEntity.setBrowser(userAgent.getBrowser().getName()); + logEntity.setStatus(exception == null ? 1 : 0); + logEntity.setErrorMsg(exception != null ? exception.getMessage() : null); + logEntity.setExecutionTime((int) executionTime); + logEntity.setCreateTime(LocalDateTime.now()); + + logService.save(logEntity); + } catch (Exception e) { + log.error("保存操作日志异常: {}", e.getMessage()); + } + } +} diff --git a/src/main/java/com/youlai/boot/core/aspect/RepeatSubmitAspect.java b/src/main/java/com/youlai/boot/common/aspect/RepeatSubmitAspect.java similarity index 96% rename from src/main/java/com/youlai/boot/core/aspect/RepeatSubmitAspect.java rename to src/main/java/com/youlai/boot/common/aspect/RepeatSubmitAspect.java index d2e04468..97011be1 100644 --- a/src/main/java/com/youlai/boot/core/aspect/RepeatSubmitAspect.java +++ b/src/main/java/com/youlai/boot/common/aspect/RepeatSubmitAspect.java @@ -1,11 +1,11 @@ -package com.youlai.boot.core.aspect; +package com.youlai.boot.common.aspect; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.DigestUtil; import com.youlai.boot.common.constant.RedisConstants; import com.youlai.boot.common.constant.SecurityConstants; -import com.youlai.boot.core.web.ResultCode; -import com.youlai.boot.core.exception.BusinessException; +import com.youlai.boot.common.result.ResultCode; +import com.youlai.boot.common.exception.BusinessException; import com.youlai.boot.common.annotation.RepeatSubmit; import com.youlai.boot.common.util.IPUtils; import jakarta.servlet.http.HttpServletRequest; diff --git a/src/main/java/com/youlai/boot/common/enums/ActionTypeEnum.java b/src/main/java/com/youlai/boot/common/enums/ActionTypeEnum.java new file mode 100644 index 00000000..3b71821a --- /dev/null +++ b/src/main/java/com/youlai/boot/common/enums/ActionTypeEnum.java @@ -0,0 +1,56 @@ +package com.youlai.boot.common.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonValue; +import com.youlai.boot.common.base.IBaseEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +/** + * 操作类型枚举 + * + * @author Ray + * @since 2.10.0 + */ +@Schema(enumAsRef = true) +@Getter +public enum ActionTypeEnum implements IBaseEnum { + + LOGIN(1, "登录"), + LOGOUT(2, "登出"), + INSERT(3, "新增"), + UPDATE(4, "修改"), + DELETE(5, "删除"), + GRANT(6, "授权"), + EXPORT(7, "导出"), + IMPORT(8, "导入"), + UPLOAD(9, "上传"), + DOWNLOAD(10, "下载"), + CHANGE_PASSWORD(11, "修改密码"), + RESET_PASSWORD(12, "重置密码"), + ENABLE(13, "启用"), + DISABLE(14, "禁用"), + LIST(15, "查询列表"), + OTHER(99, "其他"); + + @EnumValue + private final Integer value; + + @JsonValue + private final String label; + + ActionTypeEnum(Integer value, String label) { + this.value = value; + this.label = label; + } + + @Override + public Integer getValue() { + return this.value; + } + + @Override + public String getLabel() { + return this.label; + } +} diff --git a/src/main/java/com/youlai/boot/common/enums/LogModuleEnum.java b/src/main/java/com/youlai/boot/common/enums/LogModuleEnum.java index 34acd80e..dce1ea3b 100644 --- a/src/main/java/com/youlai/boot/common/enums/LogModuleEnum.java +++ b/src/main/java/com/youlai/boot/common/enums/LogModuleEnum.java @@ -1,6 +1,8 @@ package com.youlai.boot.common.enums; +import com.baomidou.mybatisplus.annotation.EnumValue; import com.fasterxml.jackson.annotation.JsonValue; +import com.youlai.boot.common.base.IBaseEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; @@ -12,22 +14,39 @@ import lombok.Getter; */ @Schema(enumAsRef = true) @Getter -public enum LogModuleEnum { +public enum LogModuleEnum implements IBaseEnum { - EXCEPTION("异常"), - LOGIN("登录"), - USER("用户"), - DEPT("部门"), - ROLE("角色"), - MENU("菜单"), - DICT("字典"), - SETTING("系统配置"), - OTHER("其他"); + LOGIN(1, "登录"), + USER(2, "用户管理"), + ROLE(3, "角色管理"), + DEPT(4, "部门管理"), + MENU(5, "菜单管理"), + DICT(6, "字典管理"), + CONFIG(7, "系统配置"), + FILE(8, "文件管理"), + NOTICE(9, "通知公告"), + LOG(10, "日志管理"), + CODEGEN(11, "代码生成"), + OTHER(99, "其他"); + + @EnumValue + private final Integer value; @JsonValue - private final String moduleName; + private final String label; - LogModuleEnum(String moduleName) { - this.moduleName = moduleName; + LogModuleEnum(Integer value, String label) { + this.value = value; + this.label = label; } -} \ No newline at end of file + + @Override + public Integer getValue() { + return this.value; + } + + @Override + public String getLabel() { + return this.label; + } +} diff --git a/src/main/java/com/youlai/boot/common/enums/RequestMethodEnum.java b/src/main/java/com/youlai/boot/common/enums/RequestMethodEnum.java deleted file mode 100644 index b5538a21..00000000 --- a/src/main/java/com/youlai/boot/common/enums/RequestMethodEnum.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.youlai.boot.common.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public enum RequestMethodEnum { - /** - * 搜寻 @AnonymousGetMapping - */ - GET("GET"), - - /** - * 搜寻 @AnonymousPostMapping - */ - POST("POST"), - - /** - * 搜寻 @AnonymousPutMapping - */ - PUT("PUT"), - - /** - * 搜寻 @AnonymousPatchMapping - */ - PATCH("PATCH"), - - /** - * 搜寻 @AnonymousDeleteMapping - */ - DELETE("DELETE"), - - /** - * 否则就是所有 Request 接口都放行 - */ - ALL("All"); - - /** - * Request 类型 - */ - private final String type; - - public static RequestMethodEnum find(String type) { - for (RequestMethodEnum value : RequestMethodEnum.values()) { - if (value.getType().equals(type)) { - return value; - } - } - return ALL; - } -} diff --git a/src/main/java/com/youlai/boot/core/exception/BusinessException.java b/src/main/java/com/youlai/boot/common/exception/BusinessException.java similarity index 91% rename from src/main/java/com/youlai/boot/core/exception/BusinessException.java rename to src/main/java/com/youlai/boot/common/exception/BusinessException.java index 033981c5..06467091 100644 --- a/src/main/java/com/youlai/boot/core/exception/BusinessException.java +++ b/src/main/java/com/youlai/boot/common/exception/BusinessException.java @@ -1,6 +1,6 @@ -package com.youlai.boot.core.exception; +package com.youlai.boot.common.exception; -import com.youlai.boot.core.web.IResultCode; +import com.youlai.boot.common.result.IResultCode; import lombok.Getter; import org.slf4j.helpers.MessageFormatter; diff --git a/src/main/java/com/youlai/boot/core/web/ExcelResult.java b/src/main/java/com/youlai/boot/common/result/ExcelResult.java similarity index 94% rename from src/main/java/com/youlai/boot/core/web/ExcelResult.java rename to src/main/java/com/youlai/boot/common/result/ExcelResult.java index c73ef6e5..d9d6590a 100644 --- a/src/main/java/com/youlai/boot/core/web/ExcelResult.java +++ b/src/main/java/com/youlai/boot/common/result/ExcelResult.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.web; +package com.youlai.boot.common.result; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/core/web/IResultCode.java b/src/main/java/com/youlai/boot/common/result/IResultCode.java similarity index 78% rename from src/main/java/com/youlai/boot/core/web/IResultCode.java rename to src/main/java/com/youlai/boot/common/result/IResultCode.java index 0f5930ae..741d604a 100644 --- a/src/main/java/com/youlai/boot/core/web/IResultCode.java +++ b/src/main/java/com/youlai/boot/common/result/IResultCode.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.web; +package com.youlai.boot.common.result; /** * 响应码接口 diff --git a/src/main/java/com/youlai/boot/core/web/PageResult.java b/src/main/java/com/youlai/boot/common/result/PageResult.java similarity index 97% rename from src/main/java/com/youlai/boot/core/web/PageResult.java rename to src/main/java/com/youlai/boot/common/result/PageResult.java index 8653cdd3..72fee0b1 100644 --- a/src/main/java/com/youlai/boot/core/web/PageResult.java +++ b/src/main/java/com/youlai/boot/common/result/PageResult.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.web; +package com.youlai.boot.common.result; import com.baomidou.mybatisplus.core.metadata.IPage; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/core/web/WebResponseWriter.java b/src/main/java/com/youlai/boot/common/result/ResponseWriter.java similarity index 96% rename from src/main/java/com/youlai/boot/core/web/WebResponseWriter.java rename to src/main/java/com/youlai/boot/common/result/ResponseWriter.java index 91244372..2bec9994 100644 --- a/src/main/java/com/youlai/boot/core/web/WebResponseWriter.java +++ b/src/main/java/com/youlai/boot/common/result/ResponseWriter.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.web; +package com.youlai.boot.common.result; import cn.hutool.extra.servlet.JakartaServletUtil; import cn.hutool.json.JSONUtil; @@ -10,7 +10,7 @@ import org.springframework.http.MediaType; import java.nio.charset.StandardCharsets; /** - * Web响应写入器 + * 响应写入器 *

* 用于在过滤器、Security处理器等无法使用 @RestControllerAdvice 的场景中统一写入HTTP响应。 * 支持写入成功响应和错误响应。 @@ -20,12 +20,12 @@ import java.nio.charset.StandardCharsets; * @since 2.0.0 */ @Slf4j -public final class WebResponseWriter { +public final class ResponseWriter { /** * 私有构造函数,防止实例化 */ - private WebResponseWriter() { + private ResponseWriter() { throw new UnsupportedOperationException("工具类不允许实例化"); } @@ -115,8 +115,4 @@ public final class WebResponseWriter { default -> HttpStatus.BAD_REQUEST.value(); }; } -} - - - - +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/core/web/Result.java b/src/main/java/com/youlai/boot/common/result/Result.java similarity index 98% rename from src/main/java/com/youlai/boot/core/web/Result.java rename to src/main/java/com/youlai/boot/common/result/Result.java index 528c57bc..94153792 100644 --- a/src/main/java/com/youlai/boot/core/web/Result.java +++ b/src/main/java/com/youlai/boot/common/result/Result.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.web; +package com.youlai.boot.common.result; import cn.hutool.core.util.StrUtil; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/core/web/ResultCode.java b/src/main/java/com/youlai/boot/common/result/ResultCode.java similarity index 99% rename from src/main/java/com/youlai/boot/core/web/ResultCode.java rename to src/main/java/com/youlai/boot/common/result/ResultCode.java index 52784d93..a0833d1d 100644 --- a/src/main/java/com/youlai/boot/core/web/ResultCode.java +++ b/src/main/java/com/youlai/boot/common/result/ResultCode.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.web; +package com.youlai.boot.common.result; import java.io.Serializable; diff --git a/src/main/java/com/youlai/boot/common/util/DateUtils.java b/src/main/java/com/youlai/boot/common/util/DateUtils.java deleted file mode 100644 index 0a3c30a9..00000000 --- a/src/main/java/com/youlai/boot/common/util/DateUtils.java +++ /dev/null @@ -1,61 +0,0 @@ - -package com.youlai.boot.common.util; - -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.ReflectUtil; -import cn.hutool.core.util.StrUtil; -import org.springframework.format.annotation.DateTimeFormat; - -import java.lang.reflect.Field; - -/** - * 日期工具类 - * - * @author haoxr - * @since 2.4.2 - */ -public class DateUtils { - - /** - * 区间日期格式化为数据库日期格式 - *

- * eg:2021-01-01 → 2021-01-01 00:00:00 - * - * @param obj 要处理的对象 - * @param startTimeFieldName 起始时间字段名 - * @param endTimeFieldName 结束时间字段名 - */ - public static void toDatabaseFormat(Object obj, String startTimeFieldName, String endTimeFieldName) { - Field startTimeField = ReflectUtil.getField(obj.getClass(), startTimeFieldName); - Field endTimeField = ReflectUtil.getField(obj.getClass(), endTimeFieldName); - - if (startTimeField != null) { - processDateTimeField(obj, startTimeField, startTimeFieldName, "yyyy-MM-dd 00:00:00"); - } - - if (endTimeField != null) { - processDateTimeField(obj, endTimeField, endTimeFieldName, "yyyy-MM-dd 23:59:59"); - } - } - - /** - * 处理日期字段 - * - * @param obj 要处理的对象 - * @param field 字段 - * @param fieldName 字段名 - * @param targetPattern 目标数据库日期格式 - */ - private static void processDateTimeField(Object obj, Field field, String fieldName, String targetPattern) { - Object fieldValue = ReflectUtil.getFieldValue(obj, fieldName); - if (fieldValue != null) { - // 得到原始的日期格式 - String pattern = field.isAnnotationPresent(DateTimeFormat.class) ? field.getAnnotation(DateTimeFormat.class).pattern() : "yyyy-MM-dd"; - // 转换为日期对象 - DateTime dateTime = DateUtil.parse(StrUtil.toString(fieldValue), pattern); - // 转换为目标数据库日期格式 - ReflectUtil.setFieldValue(obj, fieldName, dateTime.toString(targetPattern)); - } - } -} diff --git a/src/main/java/com/youlai/boot/core/validator/FieldValidator.java b/src/main/java/com/youlai/boot/common/validator/FieldValidator.java similarity index 78% rename from src/main/java/com/youlai/boot/core/validator/FieldValidator.java rename to src/main/java/com/youlai/boot/common/validator/FieldValidator.java index d65d4f3c..200e67c8 100644 --- a/src/main/java/com/youlai/boot/core/validator/FieldValidator.java +++ b/src/main/java/com/youlai/boot/common/validator/FieldValidator.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.validator; +package com.youlai.boot.common.validator; import com.youlai.boot.common.annotation.ValidField; import jakarta.validation.ConstraintValidator; @@ -18,16 +18,14 @@ public class FieldValidator implements ConstraintValidator { @Override public void initialize(ValidField constraintAnnotation) { - // 初始化允许的值列表 this.allowedValues = constraintAnnotation.allowedValues(); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (value == null) { - return true; // 如果字段允许为空,可以返回 true + return true; } - // 检查值是否在允许列表中 return Arrays.asList(allowedValues).contains(value); } } diff --git a/src/main/java/com/youlai/boot/core/aspect/LogAspect.java b/src/main/java/com/youlai/boot/core/aspect/LogAspect.java deleted file mode 100644 index e113c429..00000000 --- a/src/main/java/com/youlai/boot/core/aspect/LogAspect.java +++ /dev/null @@ -1,243 +0,0 @@ -package com.youlai.boot.core.aspect; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.date.TimeInterval; -import cn.hutool.core.util.StrUtil; -import cn.hutool.crypto.digest.DigestUtil; -import cn.hutool.http.useragent.UserAgent; -import cn.hutool.http.useragent.UserAgentUtil; -import cn.hutool.json.JSONUtil; -import com.aliyun.oss.HttpMethod; -import com.youlai.boot.common.util.IPUtils; -import com.youlai.boot.security.util.SecurityUtils; -import com.youlai.boot.system.model.entity.Log; -import com.youlai.boot.system.service.LogService; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.*; -import org.springframework.cache.CacheManager; -import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.HandlerMapping; - -import java.util.Collection; -import java.util.Map; -import java.util.Objects; - -/** - * 日志切面 - * - * @author Ray.Hao - * @since 2024/6/25 - */ -@Slf4j -@Aspect -@Component -@RequiredArgsConstructor -public class LogAspect { - private final LogService logService; - private final HttpServletRequest request; - private final CacheManager cacheManager; - - /** - * 切点 - */ - @Pointcut("@annotation(com.youlai.boot.common.annotation.Log)") - public void logPointcut() { - } - - /** - * 处理完请求后执行 - * - * @param joinPoint 切点 - */ - @Around("logPointcut() && @annotation(logAnnotation)") - public Object doAround(ProceedingJoinPoint joinPoint, com.youlai.boot.common.annotation.Log logAnnotation) throws Throwable { - // 在方法执行前获取用户ID,避免在方法执行过程中清除上下文导致获取不到用户ID - Long userId = SecurityUtils.getUserId(); - - TimeInterval timer = DateUtil.timer(); - Object result = null; - Exception exception = null; - - try { - result = joinPoint.proceed(); - } catch (Exception e) { - exception = e; - throw e; - } finally { - long executionTime = timer.interval(); // 执行时长 - this.saveLog(joinPoint, exception, result, logAnnotation, executionTime, userId); - } - return result; - } - - - /** - * 保存日志 - * - * @param joinPoint 切点 - * @param e 异常 - * @param jsonResult 响应结果 - * @param logAnnotation 日志注解 - * @param userId 用户ID - */ - private void saveLog(final JoinPoint joinPoint, final Exception e, Object jsonResult, com.youlai.boot.common.annotation.Log logAnnotation, long executionTime, Long userId) { - String requestURI = request.getRequestURI(); - // 创建日志记录 - Log log = new Log(); - log.setExecutionTime(executionTime); - - // 设置日志模块和内容 - log.setModule(logAnnotation.module()); - - // 异常情况:追加异常信息到日志内容 - if (e != null) { - log.setContent(logAnnotation.value() + "(失败:" + e.getMessage() + ")"); - // 请求参数(异常时也记录,便于排查问题) - this.setRequestParameters(joinPoint, log); - // 异常堆栈(截取前 2000 字符,避免过长) - String stackTrace = JSONUtil.toJsonStr(e.getStackTrace()); - log.setResponseContent(StrUtil.sub(stackTrace, 0, 2000)); - } else { - // 正常情况 - log.setContent(logAnnotation.value()); - // 请求参数 - if (logAnnotation.params()) { - this.setRequestParameters(joinPoint, log); - } - // 响应结果 - if (logAnnotation.result() && jsonResult != null) { - log.setResponseContent(JSONUtil.toJsonStr(jsonResult)); - } - } - log.setRequestUri(requestURI); - log.setCreateBy(userId); - String ipAddr = IPUtils.getIpAddr(request); - if (StrUtil.isNotBlank(ipAddr)) { - log.setIp(ipAddr); - String region = IPUtils.getRegion(ipAddr); - // 中国|0|四川省|成都市|电信 解析省和市 - if (StrUtil.isNotBlank(region)) { - String[] regionArray = region.split("\\|"); - if (regionArray.length > 2) { - log.setProvince(regionArray[2]); - log.setCity(regionArray[3]); - } - } - } - - - // 获取浏览器和终端系统信息 - String userAgentString = request.getHeader("User-Agent"); - UserAgent userAgent = resolveUserAgent(userAgentString); - if (Objects.nonNull(userAgent)) { - // 系统信息 - log.setOs(userAgent.getOs().getName()); - // 浏览器信息 - log.setBrowser(userAgent.getBrowser().getName()); - log.setBrowserVersion(userAgent.getBrowser().getVersion(userAgentString)); - } - //获取方法名 - String methodName = joinPoint.getSignature().getName(); - log.setMethod(methodName); - // 保存日志到数据库 - logService.save(log); - } - - /** - * 设置请求参数到日志对象中 - * - * @param joinPoint 切点 - * @param log 操作日志 - */ - private void setRequestParameters(JoinPoint joinPoint, Log log) { - String requestMethod = request.getMethod(); - log.setRequestMethod(requestMethod); - if (HttpMethod.GET.name().equalsIgnoreCase(requestMethod) || HttpMethod.PUT.name().equalsIgnoreCase(requestMethod) || HttpMethod.POST.name().equalsIgnoreCase(requestMethod)) { - String params = convertArgumentsToString(joinPoint.getArgs()); - log.setRequestParams(StrUtil.sub(params, 0, 65535)); - } else { - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (attributes != null) { - Map paramsMap = (Map) attributes.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); - log.setRequestParams(StrUtil.sub(paramsMap.toString(), 0, 65535)); - } else { - log.setRequestParams(""); - } - } - } - - /** - * 将参数数组转换为字符串 - * - * @param paramsArray 参数数组 - * @return 参数字符串 - */ - private String convertArgumentsToString(Object[] paramsArray) { - StringBuilder params = new StringBuilder(); - if (paramsArray != null) { - for (Object param : paramsArray) { - if (!shouldFilterObject(param)) { - // 如果是基本类型或者枚举类型,直接添加到参数字符串中 - if(param.getClass().isPrimitive() || param.getClass().isEnum()) { - params.append(param).append(" "); - } else { - params.append(JSONUtil.toJsonStr(param)).append(" "); - } - } - } - } - return params.toString().trim(); - } - - /** - * 判断是否需要过滤的对象。 - * - * @param obj 对象信息。 - * @return 如果是需要过滤的对象,则返回true;否则返回false。 - */ - private boolean shouldFilterObject(Object obj) { - Class clazz = obj.getClass(); - if (clazz.isArray()) { - return MultipartFile.class.isAssignableFrom(clazz.getComponentType()); - } else if (Collection.class.isAssignableFrom(clazz)) { - Collection collection = (Collection) obj; - return collection.stream().anyMatch(item -> item instanceof MultipartFile); - } else if (Map.class.isAssignableFrom(clazz)) { - Map map = (Map) obj; - return map.values().stream().anyMatch(value -> value instanceof MultipartFile); - } - return obj instanceof MultipartFile || obj instanceof HttpServletRequest || obj instanceof HttpServletResponse; - } - - - /** - * 解析UserAgent - * - * @param userAgentString UserAgent字符串 - * @return UserAgent - */ - public UserAgent resolveUserAgent(String userAgentString) { - if (StrUtil.isBlank(userAgentString)) { - return null; - } - // 给userAgentStringMD5加密一次防止过长 - String userAgentStringMD5 = DigestUtil.md5Hex(userAgentString); - //判断是否命中缓存 - UserAgent userAgent = Objects.requireNonNull(cacheManager.getCache("userAgent")).get(userAgentStringMD5, UserAgent.class); - if (userAgent != null) { - return userAgent; - } - userAgent = UserAgentUtil.parse(userAgentString); - Objects.requireNonNull(cacheManager.getCache("userAgent")).put(userAgentStringMD5, userAgent); - return userAgent; - } - -} diff --git a/src/main/java/com/youlai/boot/config/CaffeineConfig.java b/src/main/java/com/youlai/boot/framework/cache/config/CaffeineConfig.java similarity index 95% rename from src/main/java/com/youlai/boot/config/CaffeineConfig.java rename to src/main/java/com/youlai/boot/framework/cache/config/CaffeineConfig.java index bba14491..35871f1e 100644 --- a/src/main/java/com/youlai/boot/config/CaffeineConfig.java +++ b/src/main/java/com/youlai/boot/framework/cache/config/CaffeineConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.cache.config; import com.github.benmanes.caffeine.cache.Caffeine; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/youlai/boot/config/RedisCacheConfig.java b/src/main/java/com/youlai/boot/framework/cache/config/RedisCacheConfig.java similarity index 98% rename from src/main/java/com/youlai/boot/config/RedisCacheConfig.java rename to src/main/java/com/youlai/boot/framework/cache/config/RedisCacheConfig.java index 9be08f3c..b462e6a8 100644 --- a/src/main/java/com/youlai/boot/config/RedisCacheConfig.java +++ b/src/main/java/com/youlai/boot/framework/cache/config/RedisCacheConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.cache.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.cache.autoconfigure.CacheProperties; diff --git a/src/main/java/com/youlai/boot/config/RedisConfig.java b/src/main/java/com/youlai/boot/framework/cache/config/RedisConfig.java similarity index 97% rename from src/main/java/com/youlai/boot/config/RedisConfig.java rename to src/main/java/com/youlai/boot/framework/cache/config/RedisConfig.java index dd28b81a..571a5005 100644 --- a/src/main/java/com/youlai/boot/config/RedisConfig.java +++ b/src/main/java/com/youlai/boot/framework/cache/config/RedisConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.cache.config; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/com/youlai/boot/config/CaptchaConfig.java b/src/main/java/com/youlai/boot/framework/integration/captcha/config/CaptchaConfig.java similarity index 96% rename from src/main/java/com/youlai/boot/config/CaptchaConfig.java rename to src/main/java/com/youlai/boot/framework/integration/captcha/config/CaptchaConfig.java index d5a68e1f..4456b308 100644 --- a/src/main/java/com/youlai/boot/config/CaptchaConfig.java +++ b/src/main/java/com/youlai/boot/framework/integration/captcha/config/CaptchaConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.integration.captcha.config; import cn.hutool.captcha.generator.CodeGenerator; import cn.hutool.captcha.generator.MathGenerator; diff --git a/src/main/java/com/youlai/boot/framework/integration/captcha/exception/CaptchaException.java b/src/main/java/com/youlai/boot/framework/integration/captcha/exception/CaptchaException.java new file mode 100644 index 00000000..63ea2ce2 --- /dev/null +++ b/src/main/java/com/youlai/boot/framework/integration/captcha/exception/CaptchaException.java @@ -0,0 +1,19 @@ +package com.youlai.boot.framework.integration.captcha.exception; + +import com.youlai.boot.common.result.ResultCode; +import lombok.Getter; + +/** + * 验证码异常 + */ +@Getter +public class CaptchaException extends RuntimeException { + + private final ResultCode resultCode; + + public CaptchaException(ResultCode resultCode) { + super(resultCode.getMsg()); + this.resultCode = resultCode; + } + +} diff --git a/src/main/java/com/youlai/boot/auth/model/vo/CaptchaVO.java b/src/main/java/com/youlai/boot/framework/integration/captcha/model/CaptchaInfo.java similarity index 56% rename from src/main/java/com/youlai/boot/auth/model/vo/CaptchaVO.java rename to src/main/java/com/youlai/boot/framework/integration/captcha/model/CaptchaInfo.java index a81fb3c6..ce31b2c4 100644 --- a/src/main/java/com/youlai/boot/auth/model/vo/CaptchaVO.java +++ b/src/main/java/com/youlai/boot/framework/integration/captcha/model/CaptchaInfo.java @@ -1,21 +1,22 @@ -package com.youlai.boot.auth.model.vo; +package com.youlai.boot.framework.integration.captcha.model; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 验证码信息 - * - * @author Ray。Hao - * @since 2023/03/24 */ -@Schema(description = "验证码信息") @Data @Builder -public class CaptchaVO { +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "验证码信息") +public class CaptchaInfo { - @Schema(description = "验证码缓存 ID") + @Schema(description = "验证码缓存ID") private String captchaId; @Schema(description = "验证码图片Base64字符串") diff --git a/src/main/java/com/youlai/boot/framework/integration/captcha/service/CaptchaService.java b/src/main/java/com/youlai/boot/framework/integration/captcha/service/CaptchaService.java new file mode 100644 index 00000000..b347db92 --- /dev/null +++ b/src/main/java/com/youlai/boot/framework/integration/captcha/service/CaptchaService.java @@ -0,0 +1,102 @@ +package com.youlai.boot.framework.integration.captcha.service; + +import cn.hutool.captcha.AbstractCaptcha; +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.generator.CodeGenerator; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.youlai.boot.common.constant.RedisConstants; +import com.youlai.boot.common.enums.CaptchaTypeEnum; +import com.youlai.boot.common.result.ResultCode; +import com.youlai.boot.config.property.CaptchaProperties; +import com.youlai.boot.framework.integration.captcha.exception.CaptchaException; +import com.youlai.boot.framework.integration.captcha.model.CaptchaInfo; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.awt.Font; +import java.util.concurrent.TimeUnit; + +/** + * 验证码服务 + */ +@Service +@RequiredArgsConstructor +public class CaptchaService { + + private final RedisTemplate redisTemplate; + private final CaptchaProperties captchaProperties; + private final CodeGenerator codeGenerator; + private final Font captchaFont; + + /** + * 生成验证码 + */ + public CaptchaInfo generate() { + String captchaType = captchaProperties.getType(); + int width = captchaProperties.getWidth(); + int height = captchaProperties.getHeight(); + int interfereCount = captchaProperties.getInterfereCount(); + int codeLength = captchaProperties.getCode().getLength(); + + AbstractCaptcha captcha; + if (CaptchaTypeEnum.CIRCLE.name().equalsIgnoreCase(captchaType)) { + captcha = CaptchaUtil.createCircleCaptcha(width, height, codeLength, interfereCount); + } else if (CaptchaTypeEnum.GIF.name().equalsIgnoreCase(captchaType)) { + captcha = CaptchaUtil.createGifCaptcha(width, height, codeLength); + } else if (CaptchaTypeEnum.LINE.name().equalsIgnoreCase(captchaType)) { + captcha = CaptchaUtil.createLineCaptcha(width, height, codeLength, interfereCount); + } else if (CaptchaTypeEnum.SHEAR.name().equalsIgnoreCase(captchaType)) { + captcha = CaptchaUtil.createShearCaptcha(width, height, codeLength, interfereCount); + } else { + throw new IllegalArgumentException("Invalid captcha type: " + captchaType); + } + + captcha.setGenerator(codeGenerator); + captcha.setTextAlpha(captchaProperties.getTextAlpha()); + captcha.setFont(captchaFont); + + String captchaCode = captcha.getCode(); + String imageBase64Data = captcha.getImageBase64Data(); + + String captchaId = IdUtil.fastSimpleUUID(); + redisTemplate.opsForValue().set( + StrUtil.format(RedisConstants.Captcha.IMAGE_CODE, captchaId), + captchaCode, + captchaProperties.getExpireSeconds(), + TimeUnit.SECONDS + ); + + return CaptchaInfo.builder() + .captchaId(captchaId) + .captchaBase64(imageBase64Data) + .build(); + } + + /** + * 校验验证码,失败抛异常 + * + * @param captchaId 验证码ID + * @param captchaCode 用户输入的验证码 + * @throws CaptchaException 验证码错误或过期 + */ + public void validate(String captchaId, String captchaCode) { + if (StrUtil.isBlank(captchaId) || StrUtil.isBlank(captchaCode)) { + throw new CaptchaException(ResultCode.USER_VERIFICATION_CODE_ERROR); + } + + String cacheKey = StrUtil.format(RedisConstants.Captcha.IMAGE_CODE, captchaId); + String cachedCode = (String) redisTemplate.opsForValue().get(cacheKey); + if (cachedCode == null) { + throw new CaptchaException(ResultCode.USER_VERIFICATION_CODE_EXPIRED); + } + + if (!codeGenerator.verify(cachedCode, captchaCode)) { + throw new CaptchaException(ResultCode.USER_VERIFICATION_CODE_ERROR); + } + + redisTemplate.delete(cacheKey); + } + +} diff --git a/src/main/java/com/youlai/boot/config/MailConfig.java b/src/main/java/com/youlai/boot/framework/integration/mail/config/MailConfig.java similarity index 96% rename from src/main/java/com/youlai/boot/config/MailConfig.java rename to src/main/java/com/youlai/boot/framework/integration/mail/config/MailConfig.java index 9911e8d6..1a48e55e 100644 --- a/src/main/java/com/youlai/boot/config/MailConfig.java +++ b/src/main/java/com/youlai/boot/framework/integration/mail/config/MailConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.integration.mail.config; import com.youlai.boot.config.property.MailProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; diff --git a/src/main/java/com/youlai/boot/support/mail/service/MailService.java b/src/main/java/com/youlai/boot/framework/integration/mail/service/MailService.java similarity index 97% rename from src/main/java/com/youlai/boot/support/mail/service/MailService.java rename to src/main/java/com/youlai/boot/framework/integration/mail/service/MailService.java index 0e558ce6..9923bf16 100644 --- a/src/main/java/com/youlai/boot/support/mail/service/MailService.java +++ b/src/main/java/com/youlai/boot/framework/integration/mail/service/MailService.java @@ -1,4 +1,4 @@ -package com.youlai.boot.support.mail.service; +package com.youlai.boot.framework.integration.mail.service; import com.youlai.boot.config.property.MailProperties; import jakarta.mail.MessagingException; diff --git a/src/main/java/com/youlai/boot/support/sms/enums/SmsTypeEnum.java b/src/main/java/com/youlai/boot/framework/integration/sms/enums/SmsTypeEnum.java similarity index 93% rename from src/main/java/com/youlai/boot/support/sms/enums/SmsTypeEnum.java rename to src/main/java/com/youlai/boot/framework/integration/sms/enums/SmsTypeEnum.java index a5cace33..ea062a59 100644 --- a/src/main/java/com/youlai/boot/support/sms/enums/SmsTypeEnum.java +++ b/src/main/java/com/youlai/boot/framework/integration/sms/enums/SmsTypeEnum.java @@ -1,4 +1,4 @@ -package com.youlai.boot.support.sms.enums; +package com.youlai.boot.framework.integration.sms.enums; import com.youlai.boot.common.base.IBaseEnum; import lombok.Getter; diff --git a/src/main/java/com/youlai/boot/support/sms/service/SmsService.java b/src/main/java/com/youlai/boot/framework/integration/sms/service/SmsService.java similarity index 82% rename from src/main/java/com/youlai/boot/support/sms/service/SmsService.java rename to src/main/java/com/youlai/boot/framework/integration/sms/service/SmsService.java index 1dc954e6..e56ecc0b 100644 --- a/src/main/java/com/youlai/boot/support/sms/service/SmsService.java +++ b/src/main/java/com/youlai/boot/framework/integration/sms/service/SmsService.java @@ -1,6 +1,6 @@ -package com.youlai.boot.support.sms.service; +package com.youlai.boot.framework.integration.sms.service; -import com.youlai.boot.support.sms.enums.SmsTypeEnum; +import com.youlai.boot.framework.integration.sms.enums.SmsTypeEnum; import java.util.Map; diff --git a/src/main/java/com/youlai/boot/support/sms/service/impl/AliyunSmsService.java b/src/main/java/com/youlai/boot/framework/integration/sms/service/impl/AliyunSmsService.java similarity index 92% rename from src/main/java/com/youlai/boot/support/sms/service/impl/AliyunSmsService.java rename to src/main/java/com/youlai/boot/framework/integration/sms/service/impl/AliyunSmsService.java index bc5f27a6..1df6f484 100644 --- a/src/main/java/com/youlai/boot/support/sms/service/impl/AliyunSmsService.java +++ b/src/main/java/com/youlai/boot/framework/integration/sms/service/impl/AliyunSmsService.java @@ -1,4 +1,4 @@ -package com.youlai.boot.support.sms.service.impl; +package com.youlai.boot.framework.integration.sms.service.impl; import cn.hutool.json.JSONUtil; import com.aliyuncs.CommonRequest; @@ -9,8 +9,8 @@ import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.http.MethodType; import com.aliyuncs.profile.DefaultProfile; import com.youlai.boot.config.property.AliyunSmsProperties; -import com.youlai.boot.support.sms.enums.SmsTypeEnum; -import com.youlai.boot.support.sms.service.SmsService; +import com.youlai.boot.framework.integration.sms.enums.SmsTypeEnum; +import com.youlai.boot.framework.integration.sms.service.SmsService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/youlai/boot/config/WxMaConfig.java b/src/main/java/com/youlai/boot/framework/integration/wxma/config/WxMaConfig.java similarity index 94% rename from src/main/java/com/youlai/boot/config/WxMaConfig.java rename to src/main/java/com/youlai/boot/framework/integration/wxma/config/WxMaConfig.java index 8d6f952c..1e94fc77 100644 --- a/src/main/java/com/youlai/boot/config/WxMaConfig.java +++ b/src/main/java/com/youlai/boot/framework/integration/wxma/config/WxMaConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.integration.wxma.config; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; diff --git a/src/main/java/com/youlai/boot/config/XxlJobConfig.java b/src/main/java/com/youlai/boot/framework/job/config/XxlJobConfig.java similarity index 97% rename from src/main/java/com/youlai/boot/config/XxlJobConfig.java rename to src/main/java/com/youlai/boot/framework/job/config/XxlJobConfig.java index 0852a6cc..30c14abe 100644 --- a/src/main/java/com/youlai/boot/config/XxlJobConfig.java +++ b/src/main/java/com/youlai/boot/framework/job/config/XxlJobConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.job.config; import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/youlai/boot/config/MybatisConfig.java b/src/main/java/com/youlai/boot/framework/persistence/config/MybatisConfig.java similarity index 91% rename from src/main/java/com/youlai/boot/config/MybatisConfig.java rename to src/main/java/com/youlai/boot/framework/persistence/config/MybatisConfig.java index 4718c24b..20684c70 100644 --- a/src/main/java/com/youlai/boot/config/MybatisConfig.java +++ b/src/main/java/com/youlai/boot/framework/persistence/config/MybatisConfig.java @@ -1,12 +1,12 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.persistence.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; -import com.youlai.boot.config.MyDataPermissionHandler; -import com.youlai.boot.config.MyMetaObjectHandler; +import com.youlai.boot.framework.persistence.interceptor.MyDataPermissionHandler; +import com.youlai.boot.framework.persistence.handler.MyMetaObjectHandler; import org.apache.ibatis.mapping.DatabaseIdProvider; import org.apache.ibatis.mapping.VendorDatabaseIdProvider; import org.springframework.beans.factory.annotation.Value; diff --git a/src/main/java/com/youlai/boot/config/MyMetaObjectHandler.java b/src/main/java/com/youlai/boot/framework/persistence/handler/MyMetaObjectHandler.java similarity index 95% rename from src/main/java/com/youlai/boot/config/MyMetaObjectHandler.java rename to src/main/java/com/youlai/boot/framework/persistence/handler/MyMetaObjectHandler.java index 28efcbf3..917cacbd 100644 --- a/src/main/java/com/youlai/boot/config/MyMetaObjectHandler.java +++ b/src/main/java/com/youlai/boot/framework/persistence/handler/MyMetaObjectHandler.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.persistence.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/youlai/boot/config/MyDataPermissionHandler.java b/src/main/java/com/youlai/boot/framework/persistence/interceptor/MyDataPermissionHandler.java similarity index 97% rename from src/main/java/com/youlai/boot/config/MyDataPermissionHandler.java rename to src/main/java/com/youlai/boot/framework/persistence/interceptor/MyDataPermissionHandler.java index 7678fc9c..a6918f36 100644 --- a/src/main/java/com/youlai/boot/config/MyDataPermissionHandler.java +++ b/src/main/java/com/youlai/boot/framework/persistence/interceptor/MyDataPermissionHandler.java @@ -1,14 +1,14 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.persistence.interceptor; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler; import com.youlai.boot.common.annotation.DataPermission; -import com.youlai.boot.common.enums.DataScopeEnum; -import com.youlai.boot.security.model.RoleDataScope; -import com.youlai.boot.security.model.SysUserDetails; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.shared.enums.DataScopeEnum; +import com.youlai.boot.framework.security.model.RoleDataScope; +import com.youlai.boot.framework.security.model.SysUserDetails; +import com.youlai.boot.framework.security.util.SecurityUtils; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.expression.*; diff --git a/src/main/java/com/youlai/boot/config/PasswordEncoderConfig.java b/src/main/java/com/youlai/boot/framework/security/config/PasswordEncoderConfig.java similarity index 91% rename from src/main/java/com/youlai/boot/config/PasswordEncoderConfig.java rename to src/main/java/com/youlai/boot/framework/security/config/PasswordEncoderConfig.java index 3e6e0e0b..6ee0f46d 100644 --- a/src/main/java/com/youlai/boot/config/PasswordEncoderConfig.java +++ b/src/main/java/com/youlai/boot/framework/security/config/PasswordEncoderConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.security.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/youlai/boot/config/SecurityConfig.java b/src/main/java/com/youlai/boot/framework/security/config/SecurityConfig.java similarity index 87% rename from src/main/java/com/youlai/boot/config/SecurityConfig.java rename to src/main/java/com/youlai/boot/framework/security/config/SecurityConfig.java index 507acb27..404ca27c 100644 --- a/src/main/java/com/youlai/boot/config/SecurityConfig.java +++ b/src/main/java/com/youlai/boot/framework/security/config/SecurityConfig.java @@ -1,18 +1,18 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.security.config; import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.hutool.captcha.generator.CodeGenerator; +import com.youlai.boot.framework.integration.captcha.service.CaptchaService; import cn.hutool.core.util.ArrayUtil; import com.youlai.boot.config.property.SecurityProperties; -import com.youlai.boot.core.filter.RateLimiterFilter; -import com.youlai.boot.security.filter.CaptchaValidationFilter; -import com.youlai.boot.security.filter.TokenAuthenticationFilter; -import com.youlai.boot.security.handler.MyAccessDeniedHandler; -import com.youlai.boot.security.handler.MyAuthenticationEntryPoint; -import com.youlai.boot.security.provider.SmsAuthenticationProvider; -import com.youlai.boot.security.provider.WechatMiniAuthenticationProvider; -import com.youlai.boot.security.token.TokenManager; -import com.youlai.boot.security.service.SysUserDetailsService; +import com.youlai.boot.framework.web.filter.RateLimiterFilter; +import com.youlai.boot.framework.security.filter.CaptchaValidationFilter; +import com.youlai.boot.framework.security.filter.TokenAuthenticationFilter; +import com.youlai.boot.framework.security.handler.MyAccessDeniedHandler; +import com.youlai.boot.framework.security.handler.MyAuthenticationEntryPoint; +import com.youlai.boot.framework.security.provider.SmsAuthenticationProvider; +import com.youlai.boot.framework.security.provider.WechatMiniAuthenticationProvider; +import com.youlai.boot.framework.security.token.TokenManager; +import com.youlai.boot.framework.security.service.SysUserDetailsService; import com.youlai.boot.system.service.ConfigService; import com.youlai.boot.system.service.UserService; import lombok.RequiredArgsConstructor; @@ -55,7 +55,7 @@ public class SecurityConfig { private final UserService userService; private final SysUserDetailsService userDetailsService; - private final CodeGenerator codeGenerator; + private final CaptchaService captchaService; private final ConfigService configService; private final SecurityProperties securityProperties; @@ -97,7 +97,7 @@ public class SecurityConfig { // 限流过滤器 .addFilterBefore(new RateLimiterFilter(redisTemplate, configService), UsernamePasswordAuthenticationFilter.class) // 验证码校验过滤器 - .addFilterBefore(new CaptchaValidationFilter(redisTemplate, codeGenerator), UsernamePasswordAuthenticationFilter.class) + .addFilterBefore(new CaptchaValidationFilter(captchaService), UsernamePasswordAuthenticationFilter.class) // 验证和解析过滤器 .addFilterBefore(new TokenAuthenticationFilter(tokenManager), UsernamePasswordAuthenticationFilter.class) .build(); diff --git a/src/main/java/com/youlai/boot/security/exception/CaptchaValidationException.java b/src/main/java/com/youlai/boot/framework/security/exception/CaptchaValidationException.java similarity index 84% rename from src/main/java/com/youlai/boot/security/exception/CaptchaValidationException.java rename to src/main/java/com/youlai/boot/framework/security/exception/CaptchaValidationException.java index 23b5bf8e..b7c68cc4 100644 --- a/src/main/java/com/youlai/boot/security/exception/CaptchaValidationException.java +++ b/src/main/java/com/youlai/boot/framework/security/exception/CaptchaValidationException.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.exception; +package com.youlai.boot.framework.security.exception; import org.springframework.security.core.AuthenticationException; diff --git a/src/main/java/com/youlai/boot/security/exception/NeedBindMobileException.java b/src/main/java/com/youlai/boot/framework/security/exception/NeedBindMobileException.java similarity index 91% rename from src/main/java/com/youlai/boot/security/exception/NeedBindMobileException.java rename to src/main/java/com/youlai/boot/framework/security/exception/NeedBindMobileException.java index 7d38fd21..706b6179 100644 --- a/src/main/java/com/youlai/boot/security/exception/NeedBindMobileException.java +++ b/src/main/java/com/youlai/boot/framework/security/exception/NeedBindMobileException.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.exception; +package com.youlai.boot.framework.security.exception; import org.springframework.security.core.AuthenticationException; diff --git a/src/main/java/com/youlai/boot/security/filter/CaptchaValidationFilter.java b/src/main/java/com/youlai/boot/framework/security/filter/CaptchaValidationFilter.java similarity index 76% rename from src/main/java/com/youlai/boot/security/filter/CaptchaValidationFilter.java rename to src/main/java/com/youlai/boot/framework/security/filter/CaptchaValidationFilter.java index 0b4c7289..c928a0df 100644 --- a/src/main/java/com/youlai/boot/security/filter/CaptchaValidationFilter.java +++ b/src/main/java/com/youlai/boot/framework/security/filter/CaptchaValidationFilter.java @@ -1,20 +1,19 @@ -package com.youlai.boot.security.filter; +package com.youlai.boot.framework.security.filter; -import cn.hutool.captcha.generator.CodeGenerator; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; -import com.youlai.boot.common.constant.RedisConstants; import com.youlai.boot.common.constant.SecurityConstants; -import com.youlai.boot.core.web.ResultCode; -import com.youlai.boot.core.web.WebResponseWriter; +import com.youlai.boot.common.result.ResultCode; +import com.youlai.boot.common.result.ResponseWriter; +import com.youlai.boot.framework.integration.captcha.exception.CaptchaException; +import com.youlai.boot.framework.integration.captcha.service.CaptchaService; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletInputStream; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequestWrapper; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; @@ -40,12 +39,10 @@ public class CaptchaValidationFilter extends OncePerRequestFilter { public static final String CAPTCHA_CODE_PARAM_NAME = "captchaCode"; public static final String CAPTCHA_ID_PARAM_NAME = "captchaId"; - private final RedisTemplate redisTemplate; - private final CodeGenerator codeGenerator; + private final CaptchaService captchaService; - public CaptchaValidationFilter(RedisTemplate redisTemplate, CodeGenerator codeGenerator) { - this.redisTemplate = redisTemplate; - this.codeGenerator = codeGenerator; + public CaptchaValidationFilter(CaptchaService captchaService) { + this.captchaService = captchaService; } @Override @@ -61,7 +58,7 @@ public class CaptchaValidationFilter extends OncePerRequestFilter { // 仅支持 JSON 登录 String contentType = request.getContentType(); if (contentType == null || !contentType.contains(MediaType.APPLICATION_JSON_VALUE)) { - WebResponseWriter.writeError(response, ResultCode.USER_VERIFICATION_CODE_ERROR); + ResponseWriter.writeError(response, ResultCode.USER_VERIFICATION_CODE_ERROR); return; } @@ -79,24 +76,12 @@ public class CaptchaValidationFilter extends OncePerRequestFilter { captchaId = jsonObject.getStr(CAPTCHA_ID_PARAM_NAME); } - if (StrUtil.isBlank(captchaCode) || StrUtil.isBlank(captchaId)) { - WebResponseWriter.writeError(response, ResultCode.USER_VERIFICATION_CODE_ERROR); - return; - } - - String cacheVerifyCode = (String) redisTemplate.opsForValue().get( - StrUtil.format(RedisConstants.Captcha.IMAGE_CODE, captchaId) - ); - if (cacheVerifyCode == null) { - WebResponseWriter.writeError(response, ResultCode.USER_VERIFICATION_CODE_EXPIRED); - return; - } - - if (codeGenerator.verify(cacheVerifyCode, captchaCode)) { + try { + captchaService.validate(captchaId, captchaCode); HttpServletRequest repeatableRequest = new RepeatableReadRequestWrapper(requestWrapper, bodyBytes); chain.doFilter(repeatableRequest, response); - } else { - WebResponseWriter.writeError(response, ResultCode.USER_VERIFICATION_CODE_ERROR); + } catch (CaptchaException e) { + ResponseWriter.writeError(response, e.getResultCode()); } } diff --git a/src/main/java/com/youlai/boot/security/filter/TokenAuthenticationFilter.java b/src/main/java/com/youlai/boot/framework/security/filter/TokenAuthenticationFilter.java similarity index 88% rename from src/main/java/com/youlai/boot/security/filter/TokenAuthenticationFilter.java rename to src/main/java/com/youlai/boot/framework/security/filter/TokenAuthenticationFilter.java index f26a86ef..74fb6fbf 100644 --- a/src/main/java/com/youlai/boot/security/filter/TokenAuthenticationFilter.java +++ b/src/main/java/com/youlai/boot/framework/security/filter/TokenAuthenticationFilter.java @@ -1,10 +1,10 @@ -package com.youlai.boot.security.filter; +package com.youlai.boot.framework.security.filter; import cn.hutool.core.util.StrUtil; import com.youlai.boot.common.constant.SecurityConstants; -import com.youlai.boot.core.web.ResultCode; -import com.youlai.boot.core.web.WebResponseWriter; -import com.youlai.boot.security.token.TokenManager; +import com.youlai.boot.common.result.ResultCode; +import com.youlai.boot.common.result.ResponseWriter; +import com.youlai.boot.framework.security.token.TokenManager; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -47,7 +47,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { // 执行令牌有效性检查(包含密码学验签和过期时间验证) boolean isValidToken = tokenManager.validateToken(rawToken); if (!isValidToken) { - WebResponseWriter.writeError(response, ResultCode.ACCESS_TOKEN_INVALID); + ResponseWriter.writeError(response, ResultCode.ACCESS_TOKEN_INVALID); return; } @@ -58,7 +58,7 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { } catch (Exception ex) { // 安全上下文清除保障(防止上下文残留) SecurityContextHolder.clearContext(); - WebResponseWriter.writeError(response, ResultCode.ACCESS_TOKEN_INVALID); + ResponseWriter.writeError(response, ResultCode.ACCESS_TOKEN_INVALID); return; } diff --git a/src/main/java/com/youlai/boot/security/handler/MyAccessDeniedHandler.java b/src/main/java/com/youlai/boot/framework/security/handler/MyAccessDeniedHandler.java similarity index 69% rename from src/main/java/com/youlai/boot/security/handler/MyAccessDeniedHandler.java rename to src/main/java/com/youlai/boot/framework/security/handler/MyAccessDeniedHandler.java index 4631dfa6..6da8be19 100644 --- a/src/main/java/com/youlai/boot/security/handler/MyAccessDeniedHandler.java +++ b/src/main/java/com/youlai/boot/framework/security/handler/MyAccessDeniedHandler.java @@ -1,7 +1,7 @@ -package com.youlai.boot.security.handler; +package com.youlai.boot.framework.security.handler; -import com.youlai.boot.core.web.ResultCode; -import com.youlai.boot.core.web.WebResponseWriter; +import com.youlai.boot.common.result.ResultCode; +import com.youlai.boot.common.result.ResponseWriter; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; @@ -18,7 +18,7 @@ public class MyAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) { - WebResponseWriter.writeError(response, ResultCode.ACCESS_UNAUTHORIZED); + ResponseWriter.writeError(response, ResultCode.ACCESS_UNAUTHORIZED); } } diff --git a/src/main/java/com/youlai/boot/security/handler/MyAuthenticationEntryPoint.java b/src/main/java/com/youlai/boot/framework/security/handler/MyAuthenticationEntryPoint.java similarity index 78% rename from src/main/java/com/youlai/boot/security/handler/MyAuthenticationEntryPoint.java rename to src/main/java/com/youlai/boot/framework/security/handler/MyAuthenticationEntryPoint.java index 58259b7a..b5110142 100644 --- a/src/main/java/com/youlai/boot/security/handler/MyAuthenticationEntryPoint.java +++ b/src/main/java/com/youlai/boot/framework/security/handler/MyAuthenticationEntryPoint.java @@ -1,7 +1,7 @@ -package com.youlai.boot.security.handler; +package com.youlai.boot.framework.security.handler; -import com.youlai.boot.core.web.ResultCode; -import com.youlai.boot.core.web.WebResponseWriter; +import com.youlai.boot.common.result.ResultCode; +import com.youlai.boot.common.result.ResponseWriter; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.AuthenticationException; @@ -32,13 +32,13 @@ public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint { public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { if (authException instanceof BadCredentialsException) { // 用户名或密码错误 - WebResponseWriter.writeError(response, ResultCode.USER_PASSWORD_ERROR); + ResponseWriter.writeError(response, ResultCode.USER_PASSWORD_ERROR); } else if(authException instanceof InsufficientAuthenticationException){ // 请求头缺失Authorization、Token格式错误、Token过期、签名验证失败 - WebResponseWriter.writeError(response, ResultCode.ACCESS_TOKEN_INVALID); + ResponseWriter.writeError(response, ResultCode.ACCESS_TOKEN_INVALID); } else { // 其他未明确处理的认证异常(如账户被锁定、账户禁用等) - WebResponseWriter.writeError(response, ResultCode.USER_LOGIN_EXCEPTION, authException.getMessage()); + ResponseWriter.writeError(response, ResultCode.USER_LOGIN_EXCEPTION, authException.getMessage()); } } } diff --git a/src/main/java/com/youlai/boot/security/model/AuthenticationToken.java b/src/main/java/com/youlai/boot/framework/security/model/AuthenticationToken.java similarity index 92% rename from src/main/java/com/youlai/boot/security/model/AuthenticationToken.java rename to src/main/java/com/youlai/boot/framework/security/model/AuthenticationToken.java index 43ca5cb2..cd0dac5a 100644 --- a/src/main/java/com/youlai/boot/security/model/AuthenticationToken.java +++ b/src/main/java/com/youlai/boot/framework/security/model/AuthenticationToken.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.model; +package com.youlai.boot.framework.security.model; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; diff --git a/src/main/java/com/youlai/boot/security/model/RoleDataScope.java b/src/main/java/com/youlai/boot/framework/security/model/RoleDataScope.java similarity index 97% rename from src/main/java/com/youlai/boot/security/model/RoleDataScope.java rename to src/main/java/com/youlai/boot/framework/security/model/RoleDataScope.java index d00babaf..2fbcb6ba 100644 --- a/src/main/java/com/youlai/boot/security/model/RoleDataScope.java +++ b/src/main/java/com/youlai/boot/framework/security/model/RoleDataScope.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.model; +package com.youlai.boot.framework.security.model; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/security/model/SmsAuthenticationToken.java b/src/main/java/com/youlai/boot/framework/security/model/SmsAuthenticationToken.java similarity index 98% rename from src/main/java/com/youlai/boot/security/model/SmsAuthenticationToken.java rename to src/main/java/com/youlai/boot/framework/security/model/SmsAuthenticationToken.java index 8e6cdfd9..bdcb60fe 100644 --- a/src/main/java/com/youlai/boot/security/model/SmsAuthenticationToken.java +++ b/src/main/java/com/youlai/boot/framework/security/model/SmsAuthenticationToken.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.model; +package com.youlai.boot.framework.security.model; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; diff --git a/src/main/java/com/youlai/boot/security/model/SysUserDetails.java b/src/main/java/com/youlai/boot/framework/security/model/SysUserDetails.java similarity index 98% rename from src/main/java/com/youlai/boot/security/model/SysUserDetails.java rename to src/main/java/com/youlai/boot/framework/security/model/SysUserDetails.java index a532ad04..2e733b11 100644 --- a/src/main/java/com/youlai/boot/security/model/SysUserDetails.java +++ b/src/main/java/com/youlai/boot/framework/security/model/SysUserDetails.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.model; +package com.youlai.boot.framework.security.model; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; diff --git a/src/main/java/com/youlai/boot/security/model/UserAuthInfo.java b/src/main/java/com/youlai/boot/framework/security/model/UserAuthInfo.java similarity index 95% rename from src/main/java/com/youlai/boot/security/model/UserAuthInfo.java rename to src/main/java/com/youlai/boot/framework/security/model/UserAuthInfo.java index 1532836f..e6b17d21 100644 --- a/src/main/java/com/youlai/boot/security/model/UserAuthInfo.java +++ b/src/main/java/com/youlai/boot/framework/security/model/UserAuthInfo.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.model; +package com.youlai.boot.framework.security.model; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/security/model/UserSession.java b/src/main/java/com/youlai/boot/framework/security/model/UserSession.java similarity index 94% rename from src/main/java/com/youlai/boot/security/model/UserSession.java rename to src/main/java/com/youlai/boot/framework/security/model/UserSession.java index 114b4eae..a798a4c5 100644 --- a/src/main/java/com/youlai/boot/security/model/UserSession.java +++ b/src/main/java/com/youlai/boot/framework/security/model/UserSession.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.model; +package com.youlai.boot.framework.security.model; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/security/model/WechatMiniAuthenticationToken.java b/src/main/java/com/youlai/boot/framework/security/model/WechatMiniAuthenticationToken.java similarity index 97% rename from src/main/java/com/youlai/boot/security/model/WechatMiniAuthenticationToken.java rename to src/main/java/com/youlai/boot/framework/security/model/WechatMiniAuthenticationToken.java index b32af476..9bd78bcd 100644 --- a/src/main/java/com/youlai/boot/security/model/WechatMiniAuthenticationToken.java +++ b/src/main/java/com/youlai/boot/framework/security/model/WechatMiniAuthenticationToken.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.model; +package com.youlai.boot.framework.security.model; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; diff --git a/src/main/java/com/youlai/boot/security/provider/SmsAuthenticationProvider.java b/src/main/java/com/youlai/boot/framework/security/provider/SmsAuthenticationProvider.java similarity index 93% rename from src/main/java/com/youlai/boot/security/provider/SmsAuthenticationProvider.java rename to src/main/java/com/youlai/boot/framework/security/provider/SmsAuthenticationProvider.java index 919a44ac..ec5c63f1 100644 --- a/src/main/java/com/youlai/boot/security/provider/SmsAuthenticationProvider.java +++ b/src/main/java/com/youlai/boot/framework/security/provider/SmsAuthenticationProvider.java @@ -1,12 +1,12 @@ -package com.youlai.boot.security.provider; +package com.youlai.boot.framework.security.provider; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.youlai.boot.common.constant.RedisConstants; -import com.youlai.boot.security.exception.CaptchaValidationException; -import com.youlai.boot.security.model.SmsAuthenticationToken; -import com.youlai.boot.security.model.SysUserDetails; -import com.youlai.boot.security.model.UserAuthInfo; +import com.youlai.boot.framework.security.exception.CaptchaValidationException; +import com.youlai.boot.framework.security.model.SmsAuthenticationToken; +import com.youlai.boot.framework.security.model.SysUserDetails; +import com.youlai.boot.framework.security.model.UserAuthInfo; import com.youlai.boot.system.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; diff --git a/src/main/java/com/youlai/boot/security/provider/WechatMiniAuthenticationProvider.java b/src/main/java/com/youlai/boot/framework/security/provider/WechatMiniAuthenticationProvider.java similarity index 89% rename from src/main/java/com/youlai/boot/security/provider/WechatMiniAuthenticationProvider.java rename to src/main/java/com/youlai/boot/framework/security/provider/WechatMiniAuthenticationProvider.java index 3647705e..8c7dd2c3 100644 --- a/src/main/java/com/youlai/boot/security/provider/WechatMiniAuthenticationProvider.java +++ b/src/main/java/com/youlai/boot/framework/security/provider/WechatMiniAuthenticationProvider.java @@ -1,13 +1,13 @@ -package com.youlai.boot.security.provider; +package com.youlai.boot.framework.security.provider; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.hutool.core.util.ObjectUtil; -import com.youlai.boot.security.exception.NeedBindMobileException; -import com.youlai.boot.security.model.SysUserDetails; -import com.youlai.boot.security.model.UserAuthInfo; -import com.youlai.boot.security.model.WechatMiniAuthenticationToken; -import com.youlai.boot.security.service.SysUserDetailsService; +import com.youlai.boot.framework.security.exception.NeedBindMobileException; +import com.youlai.boot.framework.security.model.SysUserDetails; +import com.youlai.boot.framework.security.model.UserAuthInfo; +import com.youlai.boot.framework.security.model.WechatMiniAuthenticationToken; +import com.youlai.boot.framework.security.service.SysUserDetailsService; import com.youlai.boot.system.model.entity.UserSocial; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/youlai/boot/security/service/PermissionService.java b/src/main/java/com/youlai/boot/framework/security/service/PermissionService.java similarity index 95% rename from src/main/java/com/youlai/boot/security/service/PermissionService.java rename to src/main/java/com/youlai/boot/framework/security/service/PermissionService.java index 26b90cd4..98bf1c9a 100644 --- a/src/main/java/com/youlai/boot/security/service/PermissionService.java +++ b/src/main/java/com/youlai/boot/framework/security/service/PermissionService.java @@ -1,8 +1,8 @@ -package com.youlai.boot.security.service; +package com.youlai.boot.framework.security.service; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.system.service.RoleMenuService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/com/youlai/boot/security/service/SysUserDetailsService.java b/src/main/java/com/youlai/boot/framework/security/service/SysUserDetailsService.java similarity index 93% rename from src/main/java/com/youlai/boot/security/service/SysUserDetailsService.java rename to src/main/java/com/youlai/boot/framework/security/service/SysUserDetailsService.java index 0d7e670f..2bbe035b 100644 --- a/src/main/java/com/youlai/boot/security/service/SysUserDetailsService.java +++ b/src/main/java/com/youlai/boot/framework/security/service/SysUserDetailsService.java @@ -1,7 +1,7 @@ -package com.youlai.boot.security.service; +package com.youlai.boot.framework.security.service; -import com.youlai.boot.security.model.SysUserDetails; -import com.youlai.boot.security.model.UserAuthInfo; +import com.youlai.boot.framework.security.model.SysUserDetails; +import com.youlai.boot.framework.security.model.UserAuthInfo; import com.youlai.boot.system.enums.SocialPlatformEnum; import com.youlai.boot.system.model.entity.UserSocial; import com.youlai.boot.system.service.UserSocialService; diff --git a/src/main/java/com/youlai/boot/security/token/JwtTokenManager.java b/src/main/java/com/youlai/boot/framework/security/token/JwtTokenManager.java similarity index 97% rename from src/main/java/com/youlai/boot/security/token/JwtTokenManager.java rename to src/main/java/com/youlai/boot/framework/security/token/JwtTokenManager.java index c3dd612c..68a1d911 100644 --- a/src/main/java/com/youlai/boot/security/token/JwtTokenManager.java +++ b/src/main/java/com/youlai/boot/framework/security/token/JwtTokenManager.java @@ -1,4 +1,4 @@ -package com.youlai.boot.security.token; +package com.youlai.boot.framework.security.token; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; @@ -12,13 +12,13 @@ import cn.hutool.jwt.JWTUtil; import com.youlai.boot.common.constant.JwtClaimConstants; import com.youlai.boot.common.constant.RedisConstants; import com.youlai.boot.common.constant.SecurityConstants; -import com.youlai.boot.core.exception.BusinessException; -import com.youlai.boot.core.web.ResultCode; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.common.result.ResultCode; import com.youlai.boot.config.property.SecurityProperties; -import com.youlai.boot.security.model.AuthenticationToken; -import com.youlai.boot.security.model.RoleDataScope; +import com.youlai.boot.framework.security.model.AuthenticationToken; +import com.youlai.boot.framework.security.model.RoleDataScope; import org.apache.commons.lang3.StringUtils; -import com.youlai.boot.security.model.SysUserDetails; +import com.youlai.boot.framework.security.model.SysUserDetails; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; diff --git a/src/main/java/com/youlai/boot/security/token/RedisTokenManager.java b/src/main/java/com/youlai/boot/framework/security/token/RedisTokenManager.java similarity index 97% rename from src/main/java/com/youlai/boot/security/token/RedisTokenManager.java rename to src/main/java/com/youlai/boot/framework/security/token/RedisTokenManager.java index 7141c015..03d540a2 100644 --- a/src/main/java/com/youlai/boot/security/token/RedisTokenManager.java +++ b/src/main/java/com/youlai/boot/framework/security/token/RedisTokenManager.java @@ -1,16 +1,16 @@ -package com.youlai.boot.security.token; +package com.youlai.boot.framework.security.token; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.youlai.boot.common.constant.RedisConstants; import com.youlai.boot.common.constant.SecurityConstants; -import com.youlai.boot.core.exception.BusinessException; -import com.youlai.boot.core.web.ResultCode; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.common.result.ResultCode; import com.youlai.boot.config.property.SecurityProperties; -import com.youlai.boot.security.model.AuthenticationToken; -import com.youlai.boot.security.model.UserSession; -import com.youlai.boot.security.model.SysUserDetails; +import com.youlai.boot.framework.security.model.AuthenticationToken; +import com.youlai.boot.framework.security.model.UserSession; +import com.youlai.boot.framework.security.model.SysUserDetails; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; diff --git a/src/main/java/com/youlai/boot/security/token/TokenManager.java b/src/main/java/com/youlai/boot/framework/security/token/TokenManager.java similarity index 93% rename from src/main/java/com/youlai/boot/security/token/TokenManager.java rename to src/main/java/com/youlai/boot/framework/security/token/TokenManager.java index 9cadd3bb..7aef032e 100644 --- a/src/main/java/com/youlai/boot/security/token/TokenManager.java +++ b/src/main/java/com/youlai/boot/framework/security/token/TokenManager.java @@ -1,7 +1,7 @@ -package com.youlai.boot.security.token; +package com.youlai.boot.framework.security.token; -import com.youlai.boot.security.model.AuthenticationToken; +import com.youlai.boot.framework.security.model.AuthenticationToken; import org.springframework.security.core.Authentication; /** diff --git a/src/main/java/com/youlai/boot/security/util/SecurityUtils.java b/src/main/java/com/youlai/boot/framework/security/util/SecurityUtils.java similarity index 93% rename from src/main/java/com/youlai/boot/security/util/SecurityUtils.java rename to src/main/java/com/youlai/boot/framework/security/util/SecurityUtils.java index 5a723cd0..106c11f2 100644 --- a/src/main/java/com/youlai/boot/security/util/SecurityUtils.java +++ b/src/main/java/com/youlai/boot/framework/security/util/SecurityUtils.java @@ -1,11 +1,11 @@ -package com.youlai.boot.security.util; +package com.youlai.boot.framework.security.util; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.youlai.boot.common.constant.SecurityConstants; -import com.youlai.boot.common.constant.SystemConstants; -import com.youlai.boot.security.model.RoleDataScope; -import com.youlai.boot.security.model.SysUserDetails; +import com.youlai.boot.shared.constant.SystemConstants; +import com.youlai.boot.framework.security.model.RoleDataScope; +import com.youlai.boot.framework.security.model.SysUserDetails; import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.security.core.Authentication; diff --git a/src/main/java/com/youlai/boot/core/exception/GlobalExceptionHandler.java b/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java similarity index 98% rename from src/main/java/com/youlai/boot/core/exception/GlobalExceptionHandler.java rename to src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java index 26f39f7f..c6f61151 100644 --- a/src/main/java/com/youlai/boot/core/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java @@ -1,9 +1,10 @@ -package com.youlai.boot.core.exception; +package com.youlai.boot.framework.web.advice; import cn.hutool.core.util.StrUtil; import tools.jackson.core.JacksonException; -import com.youlai.boot.core.web.Result; -import com.youlai.boot.core.web.ResultCode; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.common.result.Result; +import com.youlai.boot.common.result.ResultCode; import jakarta.servlet.ServletException; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; @@ -275,4 +276,4 @@ public class GlobalExceptionHandler { } return group; } -} \ No newline at end of file +} diff --git a/src/main/java/com/youlai/boot/config/CorsConfig.java b/src/main/java/com/youlai/boot/framework/web/config/CorsConfig.java similarity index 97% rename from src/main/java/com/youlai/boot/config/CorsConfig.java rename to src/main/java/com/youlai/boot/framework/web/config/CorsConfig.java index ee3fc54e..38eb6d03 100644 --- a/src/main/java/com/youlai/boot/config/CorsConfig.java +++ b/src/main/java/com/youlai/boot/framework/web/config/CorsConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.web.config; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/com/youlai/boot/config/JacksonConfig.java b/src/main/java/com/youlai/boot/framework/web/config/JacksonConfig.java similarity index 97% rename from src/main/java/com/youlai/boot/config/JacksonConfig.java rename to src/main/java/com/youlai/boot/framework/web/config/JacksonConfig.java index f9ed47af..7ca0f637 100644 --- a/src/main/java/com/youlai/boot/config/JacksonConfig.java +++ b/src/main/java/com/youlai/boot/framework/web/config/JacksonConfig.java @@ -1,4 +1,4 @@ -package com.youlai.boot.config; +package com.youlai.boot.framework.web.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/youlai/boot/core/filter/RateLimiterFilter.java b/src/main/java/com/youlai/boot/framework/web/filter/RateLimiterFilter.java similarity index 91% rename from src/main/java/com/youlai/boot/core/filter/RateLimiterFilter.java rename to src/main/java/com/youlai/boot/framework/web/filter/RateLimiterFilter.java index a98475fc..a815c4c1 100644 --- a/src/main/java/com/youlai/boot/core/filter/RateLimiterFilter.java +++ b/src/main/java/com/youlai/boot/framework/web/filter/RateLimiterFilter.java @@ -1,12 +1,12 @@ -package com.youlai.boot.core.filter; +package com.youlai.boot.framework.web.filter; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import com.youlai.boot.common.constant.RedisConstants; -import com.youlai.boot.common.constant.SystemConstants; -import com.youlai.boot.core.web.ResultCode; +import com.youlai.boot.shared.constant.SystemConstants; +import com.youlai.boot.common.result.ResultCode; import com.youlai.boot.common.util.IPUtils; -import com.youlai.boot.core.web.WebResponseWriter; +import com.youlai.boot.common.result.ResponseWriter; import com.youlai.boot.system.service.ConfigService; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; @@ -88,7 +88,7 @@ public class RateLimiterFilter extends OncePerRequestFilter { // 判断是否限流 if (rateLimit(ip)) { // 返回限流错误信息 - WebResponseWriter.writeError(response, ResultCode.REQUEST_CONCURRENCY_LIMIT_EXCEEDED); + ResponseWriter.writeError(response, ResultCode.REQUEST_CONCURRENCY_LIMIT_EXCEEDED); return; } diff --git a/src/main/java/com/youlai/boot/core/filter/RequestLogFilter.java b/src/main/java/com/youlai/boot/framework/web/filter/RequestLogFilter.java similarity index 95% rename from src/main/java/com/youlai/boot/core/filter/RequestLogFilter.java rename to src/main/java/com/youlai/boot/framework/web/filter/RequestLogFilter.java index 200ddd88..f9ca070a 100644 --- a/src/main/java/com/youlai/boot/core/filter/RequestLogFilter.java +++ b/src/main/java/com/youlai/boot/framework/web/filter/RequestLogFilter.java @@ -1,4 +1,4 @@ -package com.youlai.boot.core.filter; +package com.youlai.boot.framework.web.filter; import com.youlai.boot.common.util.IPUtils; import jakarta.servlet.http.HttpServletRequest; diff --git a/src/main/java/com/youlai/boot/interfaces/openapi/OpenApiController.java b/src/main/java/com/youlai/boot/interfaces/openapi/OpenApiController.java new file mode 100644 index 00000000..9a04a8da --- /dev/null +++ b/src/main/java/com/youlai/boot/interfaces/openapi/OpenApiController.java @@ -0,0 +1,17 @@ +package com.youlai.boot.interfaces.openapi; + +/** + * 开放 API 控制器 + *

+ * 面向第三方系统的开放接口,使用 API Key 认证 + *

+ */ +// @RestController +// @RequestMapping("/api/v1/open") +// @Api(tags = "开放API") +public class OpenApiController { + + // TODO: 实现 API Key 认证拦截器 + // TODO: 定义开放接口规范 + +} diff --git a/src/main/java/com/youlai/boot/support/sse/SseController.java b/src/main/java/com/youlai/boot/interfaces/sse/controller/SseController.java similarity index 82% rename from src/main/java/com/youlai/boot/support/sse/SseController.java rename to src/main/java/com/youlai/boot/interfaces/sse/controller/SseController.java index ad07be4f..3ed4e883 100644 --- a/src/main/java/com/youlai/boot/support/sse/SseController.java +++ b/src/main/java/com/youlai/boot/interfaces/sse/controller/SseController.java @@ -1,8 +1,9 @@ -package com.youlai.boot.support.sse; +package com.youlai.boot.interfaces.sse.controller; -import com.youlai.boot.core.web.Result; -import com.youlai.boot.security.model.SysUserDetails; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.common.result.Result; +import com.youlai.boot.framework.security.model.SysUserDetails; +import com.youlai.boot.framework.security.util.SecurityUtils; +import com.youlai.boot.interfaces.sse.service.SseService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/youlai/boot/support/sse/dto/DictChangeEvent.java b/src/main/java/com/youlai/boot/interfaces/sse/dto/DictChangeEvent.java similarity index 95% rename from src/main/java/com/youlai/boot/support/sse/dto/DictChangeEvent.java rename to src/main/java/com/youlai/boot/interfaces/sse/dto/DictChangeEvent.java index 6064e0b2..ecb43a24 100644 --- a/src/main/java/com/youlai/boot/support/sse/dto/DictChangeEvent.java +++ b/src/main/java/com/youlai/boot/interfaces/sse/dto/DictChangeEvent.java @@ -1,4 +1,4 @@ -package com.youlai.boot.support.sse.dto; +package com.youlai.boot.interfaces.sse.dto; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/support/sse/dto/OnlineUserDTO.java b/src/main/java/com/youlai/boot/interfaces/sse/dto/OnlineUserDTO.java similarity index 93% rename from src/main/java/com/youlai/boot/support/sse/dto/OnlineUserDTO.java rename to src/main/java/com/youlai/boot/interfaces/sse/dto/OnlineUserDTO.java index 26f5d129..1956c7af 100644 --- a/src/main/java/com/youlai/boot/support/sse/dto/OnlineUserDTO.java +++ b/src/main/java/com/youlai/boot/interfaces/sse/dto/OnlineUserDTO.java @@ -1,4 +1,4 @@ -package com.youlai.boot.support.sse.dto; +package com.youlai.boot.interfaces.sse.dto; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/youlai/boot/support/sse/OnlineUserCountJob.java b/src/main/java/com/youlai/boot/interfaces/sse/job/OnlineUserCountJob.java similarity index 85% rename from src/main/java/com/youlai/boot/support/sse/OnlineUserCountJob.java rename to src/main/java/com/youlai/boot/interfaces/sse/job/OnlineUserCountJob.java index b30e015d..f3ccc55e 100644 --- a/src/main/java/com/youlai/boot/support/sse/OnlineUserCountJob.java +++ b/src/main/java/com/youlai/boot/interfaces/sse/job/OnlineUserCountJob.java @@ -1,5 +1,7 @@ -package com.youlai.boot.support.sse; +package com.youlai.boot.interfaces.sse.job; +import com.youlai.boot.interfaces.sse.registry.SseSessionRegistry; +import com.youlai.boot.interfaces.sse.service.SseService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; diff --git a/src/main/java/com/youlai/boot/support/sse/SseSessionRegistry.java b/src/main/java/com/youlai/boot/interfaces/sse/registry/SseSessionRegistry.java similarity index 98% rename from src/main/java/com/youlai/boot/support/sse/SseSessionRegistry.java rename to src/main/java/com/youlai/boot/interfaces/sse/registry/SseSessionRegistry.java index 95aedf1e..081c6c30 100644 --- a/src/main/java/com/youlai/boot/support/sse/SseSessionRegistry.java +++ b/src/main/java/com/youlai/boot/interfaces/sse/registry/SseSessionRegistry.java @@ -1,6 +1,6 @@ -package com.youlai.boot.support.sse; +package com.youlai.boot.interfaces.sse.registry; -import com.youlai.boot.support.sse.dto.OnlineUserDTO; +import com.youlai.boot.interfaces.sse.dto.OnlineUserDTO; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; diff --git a/src/main/java/com/youlai/boot/support/sse/SseService.java b/src/main/java/com/youlai/boot/interfaces/sse/service/SseService.java similarity index 93% rename from src/main/java/com/youlai/boot/support/sse/SseService.java rename to src/main/java/com/youlai/boot/interfaces/sse/service/SseService.java index f9424ab8..ea22881d 100644 --- a/src/main/java/com/youlai/boot/support/sse/SseService.java +++ b/src/main/java/com/youlai/boot/interfaces/sse/service/SseService.java @@ -1,7 +1,9 @@ -package com.youlai.boot.support.sse; +package com.youlai.boot.interfaces.sse.service; -import com.youlai.boot.support.sse.dto.DictChangeEvent; -import com.youlai.boot.support.sse.dto.OnlineUserDTO; +import com.youlai.boot.interfaces.sse.dto.DictChangeEvent; +import com.youlai.boot.interfaces.sse.dto.OnlineUserDTO; +import com.youlai.boot.interfaces.sse.registry.SseSessionRegistry; +import com.youlai.boot.interfaces.sse.topic.SseTopics; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/youlai/boot/support/sse/SseTopics.java b/src/main/java/com/youlai/boot/interfaces/sse/topic/SseTopics.java similarity index 88% rename from src/main/java/com/youlai/boot/support/sse/SseTopics.java rename to src/main/java/com/youlai/boot/interfaces/sse/topic/SseTopics.java index c3dcdf6d..542ce1aa 100644 --- a/src/main/java/com/youlai/boot/support/sse/SseTopics.java +++ b/src/main/java/com/youlai/boot/interfaces/sse/topic/SseTopics.java @@ -1,4 +1,4 @@ -package com.youlai.boot.support.sse; +package com.youlai.boot.interfaces.sse.topic; /** * SSE 主题常量 diff --git a/src/main/java/com/youlai/boot/module/codegen/controller/CodegenController.java b/src/main/java/com/youlai/boot/module/codegen/controller/CodegenController.java index 32514609..ebe05416 100644 --- a/src/main/java/com/youlai/boot/module/codegen/controller/CodegenController.java +++ b/src/main/java/com/youlai/boot/module/codegen/controller/CodegenController.java @@ -1,9 +1,10 @@ package com.youlai.boot.module.codegen.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.core.web.PageResult; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.common.result.PageResult; +import com.youlai.boot.common.result.Result; import com.youlai.boot.config.property.CodegenProperties; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.module.codegen.service.CodegenService; import com.youlai.boot.module.codegen.model.form.GenConfigForm; @@ -45,7 +46,6 @@ public class CodegenController { @Operation(summary = "获取数据表分页列表") @GetMapping("/table") - @Log(value = "代码生成分页列表", module = LogModuleEnum.OTHER) public PageResult getTablePage( TableQuery queryParams ) { @@ -64,7 +64,7 @@ public class CodegenController { @Operation(summary = "保存代码生成配置") @PostMapping("/{tableName}/config") - @Log(value = "生成代码", module = LogModuleEnum.OTHER) + @Log(module = LogModuleEnum.CODEGEN, value = ActionTypeEnum.UPDATE) public Result saveGenConfig(@RequestBody GenConfigForm formData) { genTableService.saveGenConfig(formData); return Result.success(); @@ -81,7 +81,6 @@ public class CodegenController { @Operation(summary = "获取预览生成代码") @GetMapping("/{tableName}/preview") - @Log(value = "预览生成代码", module = LogModuleEnum.OTHER) public Result> getTablePreviewData(@PathVariable String tableName, @RequestParam(value = "pageType", required = false, defaultValue = "classic") String pageType, @RequestParam(value = "type", required = false, defaultValue = "ts") String type) { @@ -91,7 +90,7 @@ public class CodegenController { @Operation(summary = "下载代码") @GetMapping("/{tableName}/download") - @Log(value = "下载代码", module = LogModuleEnum.OTHER) + @Log(module = LogModuleEnum.CODEGEN, value = ActionTypeEnum.DOWNLOAD) public void downloadZip(HttpServletResponse response, @PathVariable String tableName, @RequestParam(value = "pageType", required = false, defaultValue = "classic") String pageType, @RequestParam(value = "type", required = false, defaultValue = "ts") String type) { diff --git a/src/main/java/com/youlai/boot/module/codegen/service/impl/CodegenServiceImpl.java b/src/main/java/com/youlai/boot/module/codegen/service/impl/CodegenServiceImpl.java index c3485bbf..5e2125c4 100644 --- a/src/main/java/com/youlai/boot/module/codegen/service/impl/CodegenServiceImpl.java +++ b/src/main/java/com/youlai/boot/module/codegen/service/impl/CodegenServiceImpl.java @@ -16,7 +16,7 @@ import com.youlai.boot.config.property.CodegenProperties; import com.youlai.boot.module.codegen.service.GenTableService; import com.youlai.boot.module.codegen.service.GenTableColumnService; import com.youlai.boot.module.codegen.service.CodegenService; -import com.youlai.boot.core.exception.BusinessException; +import com.youlai.boot.common.exception.BusinessException; import com.youlai.boot.module.codegen.mapper.DatabaseMapper; import com.youlai.boot.module.codegen.model.entity.GenTable; import com.youlai.boot.module.codegen.model.entity.GenTableColumn; diff --git a/src/main/java/com/youlai/boot/module/codegen/service/impl/GenTableServiceImpl.java b/src/main/java/com/youlai/boot/module/codegen/service/impl/GenTableServiceImpl.java index 8bc3cbea..2ab5a592 100644 --- a/src/main/java/com/youlai/boot/module/codegen/service/impl/GenTableServiceImpl.java +++ b/src/main/java/com/youlai/boot/module/codegen/service/impl/GenTableServiceImpl.java @@ -10,7 +10,7 @@ import com.youlai.boot.common.enums.EnvEnum; import com.youlai.boot.module.codegen.enums.FormTypeEnum; import com.youlai.boot.module.codegen.enums.JavaTypeEnum; import com.youlai.boot.module.codegen.enums.QueryTypeEnum; -import com.youlai.boot.core.exception.BusinessException; +import com.youlai.boot.common.exception.BusinessException; import com.youlai.boot.config.property.CodegenProperties; import com.youlai.boot.module.codegen.converter.CodegenConverter; import com.youlai.boot.module.codegen.mapper.DatabaseMapper; diff --git a/src/main/java/com/youlai/boot/module/file/controller/FileController.java b/src/main/java/com/youlai/boot/module/file/controller/FileController.java index 8a0aaa42..47d57246 100644 --- a/src/main/java/com/youlai/boot/module/file/controller/FileController.java +++ b/src/main/java/com/youlai/boot/module/file/controller/FileController.java @@ -1,6 +1,6 @@ package com.youlai.boot.module.file.controller; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.common.result.Result; import com.youlai.boot.module.file.service.FileService; import com.youlai.boot.module.file.model.FileInfo; import io.swagger.v3.oas.annotations.Parameter; diff --git a/src/main/java/com/youlai/boot/module/file/service/impl/MinioFileService.java b/src/main/java/com/youlai/boot/module/file/service/impl/MinioFileService.java index 0c66f9d0..41125235 100644 --- a/src/main/java/com/youlai/boot/module/file/service/impl/MinioFileService.java +++ b/src/main/java/com/youlai/boot/module/file/service/impl/MinioFileService.java @@ -5,8 +5,8 @@ import cn.hutool.core.io.FileUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; -import com.youlai.boot.core.exception.BusinessException; -import com.youlai.boot.core.web.ResultCode; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.common.result.ResultCode; import com.youlai.boot.module.file.model.FileInfo; import com.youlai.boot.module.file.service.FileService; import io.minio.*; diff --git a/src/main/java/com/youlai/boot/common/constant/SystemConstants.java b/src/main/java/com/youlai/boot/shared/constant/SystemConstants.java similarity index 91% rename from src/main/java/com/youlai/boot/common/constant/SystemConstants.java rename to src/main/java/com/youlai/boot/shared/constant/SystemConstants.java index 43489745..60b8197f 100644 --- a/src/main/java/com/youlai/boot/common/constant/SystemConstants.java +++ b/src/main/java/com/youlai/boot/shared/constant/SystemConstants.java @@ -1,4 +1,4 @@ -package com.youlai.boot.common.constant; +package com.youlai.boot.shared.constant; /** * 系统常量 diff --git a/src/main/java/com/youlai/boot/common/model/KeyValue.java b/src/main/java/com/youlai/boot/shared/dto/KeyValue.java similarity index 92% rename from src/main/java/com/youlai/boot/common/model/KeyValue.java rename to src/main/java/com/youlai/boot/shared/dto/KeyValue.java index 2e33be82..1f368540 100644 --- a/src/main/java/com/youlai/boot/common/model/KeyValue.java +++ b/src/main/java/com/youlai/boot/shared/dto/KeyValue.java @@ -1,4 +1,4 @@ -package com.youlai.boot.common.model; +package com.youlai.boot.shared.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -27,4 +27,4 @@ public class KeyValue { @Schema(description = "选项的标签") private String value; -} \ No newline at end of file +} diff --git a/src/main/java/com/youlai/boot/common/model/Option.java b/src/main/java/com/youlai/boot/shared/dto/Option.java similarity index 96% rename from src/main/java/com/youlai/boot/common/model/Option.java rename to src/main/java/com/youlai/boot/shared/dto/Option.java index ba0fe9b8..1e0e5c7d 100644 --- a/src/main/java/com/youlai/boot/common/model/Option.java +++ b/src/main/java/com/youlai/boot/shared/dto/Option.java @@ -1,4 +1,4 @@ -package com.youlai.boot.common.model; +package com.youlai.boot.shared.dto; import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.v3.oas.annotations.media.Schema; @@ -50,4 +50,4 @@ public class Option { @JsonInclude(value = JsonInclude.Include.NON_EMPTY) private List> children; -} \ No newline at end of file +} diff --git a/src/main/java/com/youlai/boot/common/enums/DataScopeEnum.java b/src/main/java/com/youlai/boot/shared/enums/DataScopeEnum.java similarity index 98% rename from src/main/java/com/youlai/boot/common/enums/DataScopeEnum.java rename to src/main/java/com/youlai/boot/shared/enums/DataScopeEnum.java index 37a2636a..a5b9b9d9 100644 --- a/src/main/java/com/youlai/boot/common/enums/DataScopeEnum.java +++ b/src/main/java/com/youlai/boot/shared/enums/DataScopeEnum.java @@ -1,4 +1,4 @@ -package com.youlai.boot.common.enums; +package com.youlai.boot.shared.enums; import com.youlai.boot.common.base.IBaseEnum; import lombok.Getter; diff --git a/src/main/java/com/youlai/boot/shared/enums/LogModuleEnum.java b/src/main/java/com/youlai/boot/shared/enums/LogModuleEnum.java new file mode 100644 index 00000000..a090f730 --- /dev/null +++ b/src/main/java/com/youlai/boot/shared/enums/LogModuleEnum.java @@ -0,0 +1,33 @@ +package com.youlai.boot.shared.enums; + +import com.fasterxml.jackson.annotation.JsonValue; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +/** + * 日志模块枚举 + * + * @author Ray + * @since 2.10.0 + */ +@Schema(enumAsRef = true) +@Getter +public enum LogModuleEnum { + + EXCEPTION("异常"), + LOGIN("登录"), + USER("用户"), + DEPT("部门"), + ROLE("角色"), + MENU("菜单"), + DICT("字典"), + SETTING("系统配置"), + OTHER("其他"); + + @JsonValue + private final String moduleName; + + LogModuleEnum(String moduleName) { + this.moduleName = moduleName; + } +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/common/enums/StatusEnum.java b/src/main/java/com/youlai/boot/shared/enums/StatusEnum.java similarity index 91% rename from src/main/java/com/youlai/boot/common/enums/StatusEnum.java rename to src/main/java/com/youlai/boot/shared/enums/StatusEnum.java index 229086fa..ccf883f7 100644 --- a/src/main/java/com/youlai/boot/common/enums/StatusEnum.java +++ b/src/main/java/com/youlai/boot/shared/enums/StatusEnum.java @@ -1,4 +1,4 @@ -package com.youlai.boot.common.enums; +package com.youlai.boot.shared.enums; import com.youlai.boot.common.base.IBaseEnum; import lombok.Getter; diff --git a/src/main/java/com/youlai/boot/system/controller/ConfigController.java b/src/main/java/com/youlai/boot/system/controller/ConfigController.java index 113a6c59..e68280a8 100644 --- a/src/main/java/com/youlai/boot/system/controller/ConfigController.java +++ b/src/main/java/com/youlai/boot/system/controller/ConfigController.java @@ -1,9 +1,10 @@ package com.youlai.boot.system.controller; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; -import com.youlai.boot.core.web.PageResult; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.common.result.PageResult; +import com.youlai.boot.common.result.Result; import com.youlai.boot.common.annotation.Log; import com.youlai.boot.system.model.form.ConfigForm; import com.youlai.boot.system.model.query.ConfigQuery; @@ -37,7 +38,7 @@ public class ConfigController { @Operation(summary = "系统配置分页列表") @GetMapping @PreAuthorize("@ss.hasPerm('sys:config:list')") - @Log( value = "系统配置分页列表",module = LogModuleEnum.SETTING) + @Log(module = LogModuleEnum.CONFIG, value = ActionTypeEnum.LIST) public PageResult page(@ParameterObject ConfigQuery queryParams) { IPage result = configService.page(queryParams); return PageResult.success(result); @@ -46,7 +47,7 @@ public class ConfigController { @Operation(summary = "新增系统配置") @PostMapping @PreAuthorize("@ss.hasPerm('sys:config:create')") - @Log( value = "新增系统配置",module = LogModuleEnum.SETTING) + @Log(module = LogModuleEnum.CONFIG, value = ActionTypeEnum.INSERT) public Result save(@RequestBody @Valid ConfigForm configForm) { return Result.judge(configService.save(configForm)); } @@ -63,7 +64,7 @@ public class ConfigController { @Operation(summary = "刷新系统配置缓存") @PutMapping("/refresh") @PreAuthorize("@ss.hasPerm('sys:config:refresh')") - @Log( value = "刷新系统配置缓存",module = LogModuleEnum.SETTING) + @Log(module = LogModuleEnum.CONFIG, value = ActionTypeEnum.UPDATE) public Result refreshCache() { return Result.judge(configService.refreshCache()); } @@ -71,7 +72,7 @@ public class ConfigController { @Operation(summary = "修改系统配置") @PutMapping(value = "/{id}") @PreAuthorize("@ss.hasPerm('sys:config:update')") - @Log( value = "修改系统配置",module = LogModuleEnum.SETTING) + @Log(module = LogModuleEnum.CONFIG, value = ActionTypeEnum.UPDATE) public Result update(@Valid @PathVariable Long id, @RequestBody ConfigForm configForm) { return Result.judge(configService.edit(id, configForm)); } @@ -79,7 +80,7 @@ public class ConfigController { @Operation(summary = "删除系统配置") @DeleteMapping("/{id}") @PreAuthorize("@ss.hasPerm('sys:config:delete')") - @Log( value = "删除系统配置",module = LogModuleEnum.SETTING) + @Log(module = LogModuleEnum.CONFIG, value = ActionTypeEnum.DELETE) public Result delete(@PathVariable Long id) { return Result.judge(configService.delete(id)); } diff --git a/src/main/java/com/youlai/boot/system/controller/DeptController.java b/src/main/java/com/youlai/boot/system/controller/DeptController.java index bb7fae27..f3e6ea09 100644 --- a/src/main/java/com/youlai/boot/system/controller/DeptController.java +++ b/src/main/java/com/youlai/boot/system/controller/DeptController.java @@ -1,9 +1,10 @@ package com.youlai.boot.system.controller; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.common.annotation.RepeatSubmit; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.common.result.Result; import com.youlai.boot.system.model.form.DeptForm; import com.youlai.boot.system.model.query.DeptQuery; import com.youlai.boot.system.model.vo.DeptVO; @@ -35,7 +36,7 @@ public class DeptController { @Operation(summary = "部门列表") @GetMapping - @Log( value = "部门列表",module = LogModuleEnum.DEPT) + @Log(module = LogModuleEnum.DEPT, value = ActionTypeEnum.LIST) public Result> getDeptList( DeptQuery queryParams ) { @@ -54,6 +55,7 @@ public class DeptController { @PostMapping @PreAuthorize("@ss.hasPerm('sys:dept:create')") @RepeatSubmit + @Log(module = LogModuleEnum.DEPT, value = ActionTypeEnum.INSERT) public Result saveDept( @Valid @RequestBody DeptForm formData ) { @@ -73,6 +75,7 @@ public class DeptController { @Operation(summary = "修改部门") @PutMapping(value = "/{deptId}") @PreAuthorize("@ss.hasPerm('sys:dept:update')") + @Log(module = LogModuleEnum.DEPT, value = ActionTypeEnum.UPDATE) public Result updateDept( @PathVariable Long deptId, @Valid @RequestBody DeptForm formData @@ -84,6 +87,7 @@ public class DeptController { @Operation(summary = "删除部门") @DeleteMapping("/{ids}") @PreAuthorize("@ss.hasPerm('sys:dept:delete')") + @Log(module = LogModuleEnum.DEPT, value = ActionTypeEnum.DELETE) public Result deleteDepartments( @Parameter(description ="部门ID,多个以英文逗号(,)分割") @PathVariable("ids") String ids ) { diff --git a/src/main/java/com/youlai/boot/system/controller/DictController.java b/src/main/java/com/youlai/boot/system/controller/DictController.java index 700899f3..57090140 100644 --- a/src/main/java/com/youlai/boot/system/controller/DictController.java +++ b/src/main/java/com/youlai/boot/system/controller/DictController.java @@ -1,9 +1,10 @@ package com.youlai.boot.system.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.core.web.PageResult; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.common.result.PageResult; +import com.youlai.boot.common.result.Result; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.system.model.form.DictItemForm; import com.youlai.boot.system.model.query.DictItemQuery; @@ -16,7 +17,7 @@ import com.youlai.boot.system.model.form.DictForm; import com.youlai.boot.common.annotation.Log; import com.youlai.boot.system.service.DictItemService; import com.youlai.boot.system.service.DictService; -import com.youlai.boot.support.sse.SseService; +import com.youlai.boot.interfaces.sse.service.SseService; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; @@ -49,7 +50,7 @@ public class DictController { //--------------------------------------------------- @Operation(summary = "字典分页列表") @GetMapping - @Log( value = "字典分页列表",module = LogModuleEnum.DICT) + @Log(module = LogModuleEnum.DICT, value = ActionTypeEnum.LIST) public PageResult getDictPage( DictQuery queryParams ) { @@ -78,6 +79,7 @@ public class DictController { @PostMapping @PreAuthorize("@ss.hasPerm('sys:dict:create')") @RepeatSubmit + @Log(module = LogModuleEnum.DICT, value = ActionTypeEnum.INSERT) public Result saveDict(@Valid @RequestBody DictForm formData) { boolean result = dictService.saveDict(formData); // 发送字典更新通知 @@ -90,6 +92,7 @@ public class DictController { @Operation(summary = "修改字典") @PutMapping("/{id}") @PreAuthorize("@ss.hasPerm('sys:dict:update')") + @Log(module = LogModuleEnum.DICT, value = ActionTypeEnum.UPDATE) public Result updateDict( @PathVariable Long id, @RequestBody DictForm dictForm @@ -105,6 +108,7 @@ public class DictController { @Operation(summary = "删除字典") @DeleteMapping("/{ids}") @PreAuthorize("@ss.hasPerm('sys:dict:delete')") + @Log(module = LogModuleEnum.DICT, value = ActionTypeEnum.DELETE) public Result deleteDictionaries( @Parameter(description = "字典ID,多个以英文逗号(,)拼接") @PathVariable String ids ) { @@ -149,6 +153,7 @@ public class DictController { @PostMapping("/{dictCode}/items") @PreAuthorize("@ss.hasPerm('sys:dict-item:create')") @RepeatSubmit + @Log(module = LogModuleEnum.DICT, value = ActionTypeEnum.INSERT) public Result saveDictItem( @PathVariable String dictCode, @Valid @RequestBody DictItemForm formData @@ -178,6 +183,7 @@ public class DictController { @PutMapping("/{dictCode}/items/{itemId}") @PreAuthorize("@ss.hasPerm('sys:dict-item:update')") @RepeatSubmit + @Log(module = LogModuleEnum.DICT, value = ActionTypeEnum.UPDATE) public Result updateDictItem( @PathVariable String dictCode, @PathVariable Long itemId, @@ -198,6 +204,7 @@ public class DictController { @Operation(summary = "删除字典项") @DeleteMapping("/{dictCode}/items/{itemIds}") @PreAuthorize("@ss.hasPerm('sys:dict-item:delete')") + @Log(module = LogModuleEnum.DICT, value = ActionTypeEnum.DELETE) public Result deleteDictItems( @PathVariable String dictCode, @Parameter(description = "字典ID,多个以英文逗号(,)拼接") @PathVariable String itemIds diff --git a/src/main/java/com/youlai/boot/system/controller/LogController.java b/src/main/java/com/youlai/boot/system/controller/LogController.java index eae8cd31..df227efc 100644 --- a/src/main/java/com/youlai/boot/system/controller/LogController.java +++ b/src/main/java/com/youlai/boot/system/controller/LogController.java @@ -1,15 +1,24 @@ package com.youlai.boot.system.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.core.web.PageResult; +import com.youlai.boot.common.annotation.Log; +import com.youlai.boot.common.enums.ActionTypeEnum; +import com.youlai.boot.common.enums.LogModuleEnum; +import com.youlai.boot.common.result.PageResult; +import com.youlai.boot.common.result.Result; import com.youlai.boot.system.model.query.LogQuery; import com.youlai.boot.system.model.vo.LogPageVO; +import com.youlai.boot.system.model.vo.VisitOverviewVO; +import com.youlai.boot.system.model.vo.VisitTrendVO; import com.youlai.boot.system.service.LogService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import java.time.LocalDate; + /** * 日志控制层 * @@ -26,6 +35,7 @@ public class LogController { @Operation(summary = "日志分页列表") @GetMapping + @Log(module = LogModuleEnum.LOG, value = ActionTypeEnum.LIST) public PageResult getLogPage( LogQuery queryParams ) { @@ -33,4 +43,23 @@ public class LogController { return PageResult.success(result); } + @Operation(summary = "访问趋势统计") + @GetMapping("/views/trend") + public Result getVisitTrend( + @Parameter(description = "开始时间", example = "2024-01-01") @RequestParam String startDate, + @Parameter(description = "结束时间", example = "2024-12-31") @RequestParam String endDate + ) { + LocalDate start = LocalDate.parse(startDate); + LocalDate end = LocalDate.parse(endDate); + VisitTrendVO data = logService.getVisitTrend(start, end); + return Result.success(data); + } + + @Operation(summary = "访问统计概览") + @GetMapping("/views") + public Result getVisitOverview() { + VisitOverviewVO result = logService.getVisitStats(); + return Result.success(result); + } + } diff --git a/src/main/java/com/youlai/boot/system/controller/MenuController.java b/src/main/java/com/youlai/boot/system/controller/MenuController.java index e7e014a6..093e6d77 100644 --- a/src/main/java/com/youlai/boot/system/controller/MenuController.java +++ b/src/main/java/com/youlai/boot/system/controller/MenuController.java @@ -2,9 +2,10 @@ package com.youlai.boot.system.controller; import com.youlai.boot.common.annotation.Log; import com.youlai.boot.common.annotation.RepeatSubmit; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.common.result.Result; import com.youlai.boot.system.model.form.MenuForm; import com.youlai.boot.system.model.query.MenuQuery; import com.youlai.boot.system.model.vo.MenuVO; @@ -37,7 +38,7 @@ public class MenuController { @Operation(summary = "菜单列表") @GetMapping - @Log(value = "菜单列表", module = LogModuleEnum.MENU) + @Log(module = LogModuleEnum.MENU, value = ActionTypeEnum.LIST) public Result> getMenus(MenuQuery queryParams) { List menuList = menuService.listMenus(queryParams); return Result.success(menuList); @@ -74,6 +75,7 @@ public class MenuController { @PostMapping @PreAuthorize("@ss.hasPerm('sys:menu:create')") @RepeatSubmit + @Log(module = LogModuleEnum.MENU, value = ActionTypeEnum.INSERT) public Result addMenu(@RequestBody MenuForm menuForm) { boolean result = menuService.saveMenu(menuForm); return Result.judge(result); @@ -82,6 +84,7 @@ public class MenuController { @Operation(summary = "修改菜单") @PutMapping(value = "/{id}") @PreAuthorize("@ss.hasPerm('sys:menu:update')") + @Log(module = LogModuleEnum.MENU, value = ActionTypeEnum.UPDATE) public Result updateMenu( @RequestBody MenuForm menuForm ) { @@ -92,6 +95,7 @@ public class MenuController { @Operation(summary = "删除菜单") @DeleteMapping("/{id}") @PreAuthorize("@ss.hasPerm('sys:menu:delete')") + @Log(module = LogModuleEnum.MENU, value = ActionTypeEnum.DELETE) public Result deleteMenu( @Parameter(description = "菜单ID,多个以英文(,)分割") @PathVariable("id") Long id ) { @@ -102,6 +106,7 @@ public class MenuController { @Operation(summary = "修改菜单显示状态") @PatchMapping("/{menuId}") @PreAuthorize("@ss.hasPerm('sys:menu:update')") + @Log(module = LogModuleEnum.MENU, value = ActionTypeEnum.UPDATE) public Result updateMenuVisible( @Parameter(description = "菜单ID") @PathVariable Long menuId, @Parameter(description = "显示状态(1:显示;0:隐藏)") Integer visible diff --git a/src/main/java/com/youlai/boot/system/controller/NoticeController.java b/src/main/java/com/youlai/boot/system/controller/NoticeController.java index 04bfeecf..eafcad68 100644 --- a/src/main/java/com/youlai/boot/system/controller/NoticeController.java +++ b/src/main/java/com/youlai/boot/system/controller/NoticeController.java @@ -1,8 +1,11 @@ package com.youlai.boot.system.controller; import com.baomidou.mybatisplus.core.metadata.IPage; -import com.youlai.boot.core.web.PageResult; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.common.annotation.Log; +import com.youlai.boot.common.enums.ActionTypeEnum; +import com.youlai.boot.common.enums.LogModuleEnum; +import com.youlai.boot.common.result.PageResult; +import com.youlai.boot.common.result.Result; import com.youlai.boot.system.model.form.NoticeForm; import com.youlai.boot.system.model.query.NoticeQuery; import com.youlai.boot.system.model.vo.NoticeDetailVO; @@ -38,6 +41,7 @@ public class NoticeController { @Operation(summary = "通知公告分页列表") @GetMapping @PreAuthorize("@ss.hasPerm('sys:notice:list')") + @Log(module = LogModuleEnum.NOTICE, value = ActionTypeEnum.LIST) public PageResult getNoticePage(NoticeQuery queryParams) { IPage result = noticeService.getNoticePage(queryParams); return PageResult.success(result); @@ -46,6 +50,7 @@ public class NoticeController { @Operation(summary = "新增通知公告") @PostMapping @PreAuthorize("@ss.hasPerm('sys:notice:create')") + @Log(module = LogModuleEnum.NOTICE, value = ActionTypeEnum.INSERT) public Result saveNotice(@RequestBody @Valid NoticeForm formData) { boolean result = noticeService.saveNotice(formData); return Result.judge(result); @@ -73,6 +78,7 @@ public class NoticeController { @Operation(summary = "修改通知公告") @PutMapping(value = "/{id}") @PreAuthorize("@ss.hasPerm('sys:notice:update')") + @Log(module = LogModuleEnum.NOTICE, value = ActionTypeEnum.UPDATE) public Result updateNotice( @Parameter(description = "通知公告ID") @PathVariable Long id, @RequestBody @Validated NoticeForm formData @@ -84,6 +90,7 @@ public class NoticeController { @Operation(summary = "发布通知公告") @PutMapping("/{id}/publish") @PreAuthorize("@ss.hasPerm('sys:notice:publish')") + @Log(module = LogModuleEnum.NOTICE, value = ActionTypeEnum.UPDATE) public Result publishNotice( @Parameter(description = "通知公告ID") @PathVariable Long id ) { @@ -94,6 +101,7 @@ public class NoticeController { @Operation(summary = "撤回通知公告") @PutMapping("/{id}/revoke") @PreAuthorize("@ss.hasPerm('sys:notice:revoke')") + @Log(module = LogModuleEnum.NOTICE, value = ActionTypeEnum.UPDATE) public Result revokeNotice( @Parameter(description = "通知公告ID") @PathVariable Long id ) { @@ -104,6 +112,7 @@ public class NoticeController { @Operation(summary = "删除通知公告") @DeleteMapping("/{ids}") @PreAuthorize("@ss.hasPerm('sys:notice:delete')") + @Log(module = LogModuleEnum.NOTICE, value = ActionTypeEnum.DELETE) public Result deleteNotices( @Parameter(description = "通知公告ID,多个以英文逗号(,)分割") @PathVariable String ids ) { diff --git a/src/main/java/com/youlai/boot/system/controller/RoleController.java b/src/main/java/com/youlai/boot/system/controller/RoleController.java index 28beb430..0776ef6a 100644 --- a/src/main/java/com/youlai/boot/system/controller/RoleController.java +++ b/src/main/java/com/youlai/boot/system/controller/RoleController.java @@ -1,11 +1,12 @@ package com.youlai.boot.system.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.common.annotation.RepeatSubmit; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.core.web.PageResult; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.common.result.PageResult; +import com.youlai.boot.common.result.Result; import com.youlai.boot.system.model.form.RoleForm; import com.youlai.boot.system.model.query.RoleQuery; import com.youlai.boot.system.model.vo.RolePageVO; @@ -38,7 +39,7 @@ public class RoleController { @Operation(summary = "角色分页列表") @GetMapping - @Log(value = "角色分页列表", module = LogModuleEnum.ROLE) + @Log(module = LogModuleEnum.ROLE, value = ActionTypeEnum.LIST) public PageResult getRolePage( RoleQuery queryParams ) { @@ -57,6 +58,7 @@ public class RoleController { @PostMapping @PreAuthorize("@ss.hasPerm('sys:role:create')") @RepeatSubmit + @Log(module = LogModuleEnum.ROLE, value = ActionTypeEnum.INSERT) public Result addRole(@Valid @RequestBody RoleForm roleForm) { boolean result = roleService.saveRole(roleForm); return Result.judge(result); @@ -75,6 +77,7 @@ public class RoleController { @Operation(summary = "修改角色") @PutMapping(value = "/{id}") @PreAuthorize("@ss.hasPerm('sys:role:update')") + @Log(module = LogModuleEnum.ROLE, value = ActionTypeEnum.UPDATE) public Result updateRole(@Valid @RequestBody RoleForm roleForm) { boolean result = roleService.saveRole(roleForm); return Result.judge(result); @@ -83,6 +86,7 @@ public class RoleController { @Operation(summary = "删除角色") @DeleteMapping("/{ids}") @PreAuthorize("@ss.hasPerm('sys:role:delete')") + @Log(module = LogModuleEnum.ROLE, value = ActionTypeEnum.DELETE) public Result deleteRoles( @Parameter(description = "删除角色,多个以英文逗号(,)拼接") @PathVariable String ids ) { @@ -93,6 +97,7 @@ public class RoleController { @Operation(summary = "修改角色状态") @PutMapping(value = "/{roleId}/status") @PreAuthorize("@ss.hasPerm('sys:role:update')") + @Log(module = LogModuleEnum.ROLE, value = ActionTypeEnum.UPDATE) public Result updateRoleStatus( @Parameter(description = "角色ID") @PathVariable Long roleId, @Parameter(description = "状态(1:启用;0:禁用)") @RequestParam Integer status @@ -113,6 +118,7 @@ public class RoleController { @Operation(summary = "角色分配菜单权限") @PutMapping("/{roleId}/menus") @PreAuthorize("@ss.hasPerm('sys:role:assign')") + @Log(module = LogModuleEnum.ROLE, value = ActionTypeEnum.GRANT) public Result assignMenusToRole( @PathVariable Long roleId, @RequestBody List menuIds diff --git a/src/main/java/com/youlai/boot/system/controller/StatisticsController.java b/src/main/java/com/youlai/boot/system/controller/StatisticsController.java deleted file mode 100644 index 3014c230..00000000 --- a/src/main/java/com/youlai/boot/system/controller/StatisticsController.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.youlai.boot.system.controller; - -import com.youlai.boot.core.web.Result; -import com.youlai.boot.system.model.vo.VisitStatsVO; -import com.youlai.boot.system.model.vo.VisitTrendVO; -import com.youlai.boot.system.service.LogService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; - -import java.time.LocalDate; - -/** - * 统计分析控制层 - * - * @author Ray.Hao - * @since 2025-12-15 - */ -@Tag(name = "12.统计分析") -@RestController -@RequestMapping("/api/v1/statistics") -@RequiredArgsConstructor -public class StatisticsController { - - private final LogService logService; - - @Operation(summary = "访问趋势统计") - @GetMapping("/visits/trend") - public Result getVisitTrend( - @Parameter(description = "开始时间", example = "2024-01-01") @RequestParam String startDate, - @Parameter(description = "结束时间", example = "2024-12-31") @RequestParam String endDate - ) { - LocalDate start = LocalDate.parse(startDate); - LocalDate end = LocalDate.parse(endDate); - VisitTrendVO data = logService.getVisitTrend(start, end); - return Result.success(data); - } - - @Operation(summary = "访问概览统计") - @GetMapping("/visits/overview") - public Result getVisitOverview() { - VisitStatsVO result = logService.getVisitStats(); - return Result.success(result); - } -} diff --git a/src/main/java/com/youlai/boot/system/controller/UserController.java b/src/main/java/com/youlai/boot/system/controller/UserController.java index 7f381b43..aae8eca0 100644 --- a/src/main/java/com/youlai/boot/system/controller/UserController.java +++ b/src/main/java/com/youlai/boot/system/controller/UserController.java @@ -5,20 +5,21 @@ import cn.idev.excel.ExcelWriter; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.youlai.boot.common.annotation.Log; import com.youlai.boot.common.annotation.RepeatSubmit; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.core.web.ExcelResult; -import com.youlai.boot.core.web.PageResult; -import com.youlai.boot.core.web.Result; +import com.youlai.boot.framework.security.util.SecurityUtils; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.common.result.ExcelResult; +import com.youlai.boot.common.result.PageResult; +import com.youlai.boot.common.result.Result; import com.youlai.boot.common.util.ExcelUtils; -import com.youlai.boot.security.util.SecurityUtils; import com.youlai.boot.system.listener.UserImportListener; -import com.youlai.boot.system.model.dto.UserExportDTO; -import com.youlai.boot.system.model.dto.UserImportDTO; -import com.youlai.boot.system.model.entity.User; +import com.youlai.boot.system.model.vo.UserExportVO; +import com.youlai.boot.system.model.form.UserImportForm; +import com.youlai.boot.system.model.entity.SysUser; import com.youlai.boot.system.model.form.*; import com.youlai.boot.system.model.query.UserQuery; -import com.youlai.boot.system.model.dto.CurrentUserDTO; +import com.youlai.boot.system.model.vo.CurrentUserVO; import com.youlai.boot.system.model.vo.UserPageVO; import com.youlai.boot.system.model.vo.UserProfileVO; import com.youlai.boot.system.service.UserService; @@ -57,7 +58,7 @@ public class UserController { @Operation(summary = "用户列表") @GetMapping - @Log(value = "用户列表", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.LIST) public PageResult getUserList( @Valid UserQuery queryParams ) { @@ -68,7 +69,7 @@ public class UserController { @PostMapping @PreAuthorize("@ss.hasPerm('sys:user:create')") @RepeatSubmit - @Log(value = "新增用户", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.INSERT) public Result saveUser( @RequestBody @Valid UserForm userForm ) { @@ -79,7 +80,6 @@ public class UserController { @Operation(summary = "获取用户表单数据") @GetMapping("/{userId}/form") @PreAuthorize("@ss.hasPerm('sys:user:update')") - @Log(value = "用户表单数据", module = LogModuleEnum.USER) public Result getUserForm( @Parameter(description = "用户ID") @PathVariable Long userId ) { @@ -90,7 +90,7 @@ public class UserController { @Operation(summary = "修改用户") @PutMapping(value = "/{userId}") @PreAuthorize("@ss.hasPerm('sys:user:update')") - @Log(value = "修改用户", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.UPDATE) public Result updateUser( @Parameter(description = "用户ID") @PathVariable Long userId, @RequestBody @Valid UserForm userForm @@ -102,7 +102,7 @@ public class UserController { @Operation(summary = "删除用户") @DeleteMapping("/{ids}") @PreAuthorize("@ss.hasPerm('sys:user:delete')") - @Log(value = "删除用户", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.DELETE) public Result deleteUsers( @Parameter(description = "用户ID,多个以英文逗号(,)分割") @PathVariable String ids ) { @@ -113,14 +113,14 @@ public class UserController { @Operation(summary = "修改用户状态") @PatchMapping(value = "/{userId}/status") @PreAuthorize("@ss.hasPerm('sys:user:update')") - @Log(value = "修改用户状态", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.UPDATE) public Result updateUserStatus( @Parameter(description = "用户ID") @PathVariable Long userId, @Parameter(description = "用户状态(1:启用;0:禁用)") @RequestParam Integer status ) { - boolean result = userService.update(new LambdaUpdateWrapper() - .eq(User::getId, userId) - .set(User::getStatus, status) + boolean result = userService.update(new LambdaUpdateWrapper() + .eq(SysUser::getId, userId) + .set(SysUser::getStatus, status) ); return Result.judge(result); } @@ -128,6 +128,7 @@ public class UserController { @Operation(summary = "重置指定用户密码") @PutMapping(value = "/{userId}/password/reset") @PreAuthorize("@ss.hasPerm('sys:user:reset-password')") + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.RESET_PASSWORD) public Result resetUserPassword( @Parameter(description = "用户ID") @PathVariable Long userId, @RequestParam String password @@ -138,15 +139,13 @@ public class UserController { @Operation(summary = "获取当前登录用户信息") @GetMapping("/me") - @Log(value = "获取当前登录用户信息", module = LogModuleEnum.USER) - public Result getCurrentUser() { - CurrentUserDTO currentUserDto = userService.getCurrentUserInfo(); - return Result.success(currentUserDto); + public Result getCurrentUser() { + CurrentUserVO currentUserVo = userService.getCurrentUserInfo(); + return Result.success(currentUserVo); } @Operation(summary = "用户导入模板下载") @GetMapping("/template") - @Log(value = "用户导入模板下载", module = LogModuleEnum.USER) public void downloadTemplate(HttpServletResponse response) { String fileName = "用户导入模板.xlsx"; response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); @@ -166,24 +165,24 @@ public class UserController { @Operation(summary = "导入用户") @PostMapping("/import") @PreAuthorize("@ss.hasPerm('sys:user:import')") - @Log(value = "导入用户", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.IMPORT) public Result importUsers(MultipartFile file) throws IOException { UserImportListener listener = new UserImportListener(); - ExcelUtils.importExcel(file.getInputStream(), UserImportDTO.class, listener); + ExcelUtils.importExcel(file.getInputStream(), UserImportForm.class, listener); return Result.success(listener.getExcelResult()); } @Operation(summary = "导出用户") @GetMapping("/export") @PreAuthorize("@ss.hasPerm('sys:user:export')") - @Log(value = "导出用户", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.EXPORT) public void exportUsers(UserQuery queryParams, HttpServletResponse response) throws IOException { String fileName = "用户列表.xlsx"; response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8)); - List exportUserList = userService.listExportUsers(queryParams); - EasyExcel.write(response.getOutputStream(), UserExportDTO.class).sheet("用户列表") + List exportUserList = userService.listExportUsers(queryParams); + EasyExcel.write(response.getOutputStream(), UserExportVO.class).sheet("用户列表") .doWrite(exportUserList); } @@ -196,7 +195,6 @@ public class UserController { @Operation(summary = "获取个人中心用户信息") @GetMapping("/profile") - @Log(value = "获取个人中心用户信息", module = LogModuleEnum.USER) public Result getUserProfile() { Long userId = SecurityUtils.getUserId(); UserProfileVO userProfile = userService.getUserProfile(userId); @@ -205,7 +203,7 @@ public class UserController { @Operation(summary = "个人中心修改用户信息") @PutMapping("/profile") - @Log(value = "个人中心修改用户信息", module = LogModuleEnum.USER) + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.UPDATE) public Result updateUserProfile(@RequestBody UserProfileForm formData) { boolean result = userService.updateUserProfile(formData); return Result.judge(result); @@ -214,6 +212,7 @@ public class UserController { @Operation(summary = "当前用户修改密码") @PutMapping(value = "/password") + @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.CHANGE_PASSWORD) public Result changeCurrentUserPassword( @RequestBody PasswordUpdateForm data ) { @@ -276,5 +275,4 @@ public class UserController { return Result.judge(result); } - } diff --git a/src/main/java/com/youlai/boot/system/converter/DictItemConverter.java b/src/main/java/com/youlai/boot/system/converter/DictItemConverter.java index 99a354b0..60477288 100644 --- a/src/main/java/com/youlai/boot/system/converter/DictItemConverter.java +++ b/src/main/java/com/youlai/boot/system/converter/DictItemConverter.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.youlai.boot.system.model.entity.DictItem; import com.youlai.boot.system.model.form.DictItemForm; import com.youlai.boot.system.model.vo.DictPageVO; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.dto.Option; import org.mapstruct.Mapper; import java.util.List; diff --git a/src/main/java/com/youlai/boot/system/converter/NoticeConverter.java b/src/main/java/com/youlai/boot/system/converter/NoticeConverter.java index d16a719f..fdffda88 100644 --- a/src/main/java/com/youlai/boot/system/converter/NoticeConverter.java +++ b/src/main/java/com/youlai/boot/system/converter/NoticeConverter.java @@ -1,11 +1,7 @@ package com.youlai.boot.system.converter; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.system.model.bo.NoticeBO; import com.youlai.boot.system.model.entity.Notice; import com.youlai.boot.system.model.form.NoticeForm; -import com.youlai.boot.system.model.vo.NoticeDetailVO; -import com.youlai.boot.system.model.vo.NoticePageVO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @@ -17,8 +13,7 @@ import org.mapstruct.Mappings; * @since 2024-08-27 10:31 */ @Mapper(componentModel = "spring") -public interface NoticeConverter{ - +public interface NoticeConverter { @Mappings({ @Mapping(target = "targetUserIds", expression = "java(cn.hutool.core.util.StrUtil.split(entity.getTargetUserIds(),\",\"))") @@ -29,10 +24,4 @@ public interface NoticeConverter{ @Mapping(target = "targetUserIds", expression = "java(cn.hutool.core.collection.CollUtil.join(formData.getTargetUserIds(),\",\"))") }) Notice toEntity(NoticeForm formData); - - NoticePageVO toPageVo(NoticeBO bo); - - Page toPageVo(Page noticePage); - - NoticeDetailVO toDetailVo(NoticeBO noticeBo); } diff --git a/src/main/java/com/youlai/boot/system/converter/RoleConverter.java b/src/main/java/com/youlai/boot/system/converter/RoleConverter.java index ca89421b..7e016ffe 100644 --- a/src/main/java/com/youlai/boot/system/converter/RoleConverter.java +++ b/src/main/java/com/youlai/boot/system/converter/RoleConverter.java @@ -3,7 +3,7 @@ package com.youlai.boot.system.converter; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.youlai.boot.system.model.entity.Role; import com.youlai.boot.system.model.vo.RolePageVO; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.model.form.RoleForm; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -21,7 +21,7 @@ import java.util.List; public interface RoleConverter { @Mapping(target = "dataScope", source = "dataScope") - @Mapping(target = "dataScopeLabel", expression = "java(com.youlai.boot.common.enums.DataScopeEnum.getByValue(role.getDataScope()) == null ? null : com.youlai.boot.common.enums.DataScopeEnum.getByValue(role.getDataScope()).getLabel())") + @Mapping(target = "dataScopeLabel", expression = "java(com.youlai.boot.shared.enums.DataScopeEnum.getByValue(role.getDataScope()) == null ? null : com.youlai.boot.shared.enums.DataScopeEnum.getByValue(role.getDataScope()).getLabel())") RolePageVO toPageVo(Role role); Page toPageVo(Page page); @@ -37,4 +37,4 @@ public interface RoleConverter { Role toEntity(RoleForm roleForm); RoleForm toForm(Role entity); -} \ No newline at end of file +} diff --git a/src/main/java/com/youlai/boot/system/converter/UserConverter.java b/src/main/java/com/youlai/boot/system/converter/UserConverter.java index eb63ce58..b7a6c782 100644 --- a/src/main/java/com/youlai/boot/system/converter/UserConverter.java +++ b/src/main/java/com/youlai/boot/system/converter/UserConverter.java @@ -1,14 +1,11 @@ package com.youlai.boot.system.converter; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.system.model.entity.User; -import com.youlai.boot.system.model.dto.CurrentUserDTO; -import com.youlai.boot.system.model.vo.UserPageVO; -import com.youlai.boot.system.model.vo.UserProfileVO; -import com.youlai.boot.system.model.bo.UserBO; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.system.model.entity.SysUser; +import com.youlai.boot.system.model.vo.CurrentUserVO; import com.youlai.boot.system.model.form.UserForm; -import com.youlai.boot.system.model.dto.UserImportDTO; +import com.youlai.boot.system.model.form.UserImportForm; import com.youlai.boot.system.model.form.UserProfileForm; import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; @@ -26,34 +23,25 @@ import java.util.List; @Mapper(componentModel = "spring") public interface UserConverter { - UserPageVO toPageVo(UserBO bo); - - Page toPageVo(Page bo); - - List toPageVo(List bo); - - UserForm toForm(User entity); + UserForm toForm(SysUser entity); @InheritInverseConfiguration(name = "toForm") - User toEntity(UserForm entity); + SysUser toEntity(UserForm entity); @Mappings({ @Mapping(target = "userId", source = "id") }) - CurrentUserDTO toCurrentUserDto(User entity); + CurrentUserVO toCurrentUserVo(SysUser entity); - User toEntity(UserImportDTO vo); + SysUser toEntity(UserImportForm vo); - - UserProfileVO toProfileVo(UserBO bo); - - User toEntity(UserProfileForm formData); + SysUser toEntity(UserProfileForm formData); @Mappings({ @Mapping(target = "label", source = "nickname"), @Mapping(target = "value", source = "id") }) - Option toOption(User entity); + Option toOption(SysUser entity); - List> toOptions(List list); + List> toOptions(List list); } diff --git a/src/main/java/com/youlai/boot/system/listener/UserImportListener.java b/src/main/java/com/youlai/boot/system/listener/UserImportListener.java index 01e654cd..bcfa1a15 100644 --- a/src/main/java/com/youlai/boot/system/listener/UserImportListener.java +++ b/src/main/java/com/youlai/boot/system/listener/UserImportListener.java @@ -9,13 +9,14 @@ import cn.hutool.json.JSONUtil; import cn.idev.excel.context.AnalysisContext; import cn.idev.excel.event.AnalysisEventListener; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.youlai.boot.common.constant.SystemConstants; -import com.youlai.boot.common.enums.StatusEnum; -import com.youlai.boot.core.web.ExcelResult; +import com.youlai.boot.shared.constant.SystemConstants; +import com.youlai.boot.shared.enums.StatusEnum; +import com.youlai.boot.common.result.ExcelResult; import com.youlai.boot.system.converter.UserConverter; import com.youlai.boot.system.enums.DictCodeEnum; -import com.youlai.boot.system.model.dto.UserImportDTO; +import com.youlai.boot.system.model.entity.SysUser; import com.youlai.boot.system.model.entity.*; +import com.youlai.boot.system.model.form.UserImportForm; import com.youlai.boot.system.service.*; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -35,7 +36,7 @@ import java.util.stream.Collectors; * @since 2022/4/10 */ @Slf4j -public class UserImportListener extends AnalysisEventListener { +public class UserImportListener extends AnalysisEventListener { /** * Excel 导入结果 @@ -85,7 +86,7 @@ public class UserImportListener extends AnalysisEventListener { * @param userImportDto 一行数据,类似于 {@link AnalysisContext#readRowHolder()} */ @Override - public void invoke(UserImportDTO userImportDto, AnalysisContext analysisContext) { + public void invoke(UserImportForm userImportDto, AnalysisContext analysisContext) { log.info("解析到一条用户数据:{}", JSONUtil.toJsonStr(userImportDto)); boolean validation = true; @@ -95,7 +96,7 @@ public class UserImportListener extends AnalysisEventListener { errorMsg += "用户名为空;"; validation = false; } else { - long count = userService.count(new LambdaQueryWrapper().eq(User::getUsername, username)); + long count = userService.count(new LambdaQueryWrapper().eq(SysUser::getUsername, username)); if (count > 0) { errorMsg += "用户名已存在;"; validation = false; @@ -121,7 +122,7 @@ public class UserImportListener extends AnalysisEventListener { if (validation) { // 校验通过,持久化至数据库 - User entity = userConverter.toEntity(userImportDto); + SysUser entity = userConverter.toEntity(userImportDto); entity.setPassword(passwordEncoder.encode(SystemConstants.DEFAULT_PASSWORD)); // 默认密码 // 性别逆向翻译 根据字典标签得到字典值 String genderLabel = userImportDto.getGenderLabel(); diff --git a/src/main/java/com/youlai/boot/system/mapper/LogMapper.java b/src/main/java/com/youlai/boot/system/mapper/LogMapper.java index a11c5b65..7f673e5e 100644 --- a/src/main/java/com/youlai/boot/system/mapper/LogMapper.java +++ b/src/main/java/com/youlai/boot/system/mapper/LogMapper.java @@ -2,12 +2,13 @@ package com.youlai.boot.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.system.model.bo.VisitCountBO; -import com.youlai.boot.system.model.bo.VisitStatsBO; -import com.youlai.boot.system.model.entity.Log; +import com.youlai.boot.system.model.dto.VisitCountDTO; +import com.youlai.boot.system.model.vo.VisitOverviewVO; +import com.youlai.boot.system.model.entity.SysLog; import com.youlai.boot.system.model.query.LogQuery; import com.youlai.boot.system.model.vo.LogPageVO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -19,7 +20,7 @@ import java.util.List; * @since 2.10.0 */ @Mapper -public interface LogMapper extends BaseMapper { +public interface LogMapper extends BaseMapper { /** * 获取日志分页列表 @@ -32,7 +33,7 @@ public interface LogMapper extends BaseMapper { * @param startDate 开始日期 yyyy-MM-dd * @param endDate 结束日期 yyyy-MM-dd */ - List getPvCounts(String startDate, String endDate); + List getPvCounts(String startDate, String endDate); /** * 统计IP数 @@ -40,17 +41,17 @@ public interface LogMapper extends BaseMapper { * @param startDate 开始日期 yyyy-MM-dd * @param endDate 结束日期 yyyy-MM-dd */ - List getIpCounts(String startDate, String endDate); + List getIpCounts(String startDate, String endDate); /** * 获取浏览量(PV)统计 */ - VisitStatsBO getPvStats(); + VisitOverviewVO getPvStats(); /** * 获取访问IP统计 */ - VisitStatsBO getUvStats(); + VisitOverviewVO getUvStats(); } diff --git a/src/main/java/com/youlai/boot/system/mapper/NoticeMapper.java b/src/main/java/com/youlai/boot/system/mapper/NoticeMapper.java index deecc006..e26fa359 100644 --- a/src/main/java/com/youlai/boot/system/mapper/NoticeMapper.java +++ b/src/main/java/com/youlai/boot/system/mapper/NoticeMapper.java @@ -2,10 +2,10 @@ package com.youlai.boot.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.system.model.bo.NoticeBO; import com.youlai.boot.system.model.entity.Notice; import com.youlai.boot.system.model.query.NoticeQuery; import com.youlai.boot.system.model.vo.NoticePageVO; +import com.youlai.boot.system.model.vo.NoticeDetailVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -25,7 +25,7 @@ public interface NoticeMapper extends BaseMapper { * @param queryParams 查询参数 * @return 通知公告分页数据 */ - Page getNoticePage(Page page, NoticeQuery queryParams); + Page getNoticePage(Page page, NoticeQuery queryParams); /** * 获取阅读时通知公告详情 @@ -33,5 +33,5 @@ public interface NoticeMapper extends BaseMapper { * @param id 通知公告ID * @return 通知公告详情 */ - NoticeBO getNoticeDetail(@Param("id") Long id); + NoticeDetailVO getNoticeDetail(@Param("id") Long id); } diff --git a/src/main/java/com/youlai/boot/system/mapper/RoleMenuMapper.java b/src/main/java/com/youlai/boot/system/mapper/RoleMenuMapper.java index 5f68f18e..bfe929ac 100644 --- a/src/main/java/com/youlai/boot/system/mapper/RoleMenuMapper.java +++ b/src/main/java/com/youlai/boot/system/mapper/RoleMenuMapper.java @@ -1,7 +1,7 @@ package com.youlai.boot.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.youlai.boot.system.model.bo.RolePermsBO; +import com.youlai.boot.system.model.dto.RolePermsDTO; import com.youlai.boot.system.model.entity.RoleMenu; import org.apache.ibatis.annotations.Mapper; @@ -28,7 +28,7 @@ public interface RoleMenuMapper extends BaseMapper { /** * 获取权限和拥有权限的角色列表 */ - List getRolePermsList(String roleCode); + List getRolePermsList(String roleCode); /** diff --git a/src/main/java/com/youlai/boot/system/mapper/UserMapper.java b/src/main/java/com/youlai/boot/system/mapper/UserMapper.java index fc13fa64..d07fdcad 100644 --- a/src/main/java/com/youlai/boot/system/mapper/UserMapper.java +++ b/src/main/java/com/youlai/boot/system/mapper/UserMapper.java @@ -2,13 +2,14 @@ package com.youlai.boot.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.system.model.bo.UserBO; -import com.youlai.boot.system.model.entity.User; +import com.youlai.boot.system.model.entity.SysUser; import com.youlai.boot.system.model.query.UserQuery; import com.youlai.boot.system.model.form.UserForm; import com.youlai.boot.common.annotation.DataPermission; -import com.youlai.boot.security.model.UserAuthInfo; -import com.youlai.boot.system.model.dto.UserExportDTO; +import com.youlai.boot.framework.security.model.UserAuthInfo; +import com.youlai.boot.system.model.vo.UserExportVO; +import com.youlai.boot.system.model.vo.UserPageVO; +import com.youlai.boot.system.model.vo.UserProfileVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -21,7 +22,7 @@ import java.util.List; * @since 2022/1/14 */ @Mapper -public interface UserMapper extends BaseMapper { +public interface UserMapper extends BaseMapper { /** * 获取用户分页列表 @@ -31,7 +32,7 @@ public interface UserMapper extends BaseMapper { * @return 用户分页列表 */ @DataPermission(deptAlias = "u", userAlias = "u") - Page getUserPage(Page page, @Param("queryParams") UserQuery queryParams); + Page getUserPage(Page page, @Param("queryParams") UserQuery queryParams); /** * 获取用户表单详情 @@ -72,7 +73,7 @@ public interface UserMapper extends BaseMapper { * @return 导出用户列表 */ @DataPermission(deptAlias = "u", userAlias = "u") - List listExportUsers(UserQuery queryParams); + List listExportUsers(UserQuery queryParams); /** * 获取用户个人中心信息 @@ -80,6 +81,6 @@ public interface UserMapper extends BaseMapper { * @param userId 用户ID * @return 用户个人中心信息 */ - UserBO getUserProfile(Long userId); + UserProfileVO getUserProfile(Long userId); } diff --git a/src/main/java/com/youlai/boot/system/mapper/UserSocialMapper.java b/src/main/java/com/youlai/boot/system/mapper/UserSocialMapper.java index 13c8ffc4..430075d3 100644 --- a/src/main/java/com/youlai/boot/system/mapper/UserSocialMapper.java +++ b/src/main/java/com/youlai/boot/system/mapper/UserSocialMapper.java @@ -1,7 +1,7 @@ package com.youlai.boot.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.youlai.boot.security.model.UserAuthInfo; +import com.youlai.boot.framework.security.model.UserAuthInfo; import com.youlai.boot.system.model.entity.UserSocial; import org.apache.ibatis.annotations.Mapper; diff --git a/src/main/java/com/youlai/boot/system/model/bo/NoticeBO.java b/src/main/java/com/youlai/boot/system/model/bo/NoticeBO.java deleted file mode 100644 index 07ee80f6..00000000 --- a/src/main/java/com/youlai/boot/system/model/bo/NoticeBO.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.youlai.boot.system.model.bo; - -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * 通知公告业务对象 - * - * @author Theo - * @since 2024-09-01 10:31 - */ -@Data -public class NoticeBO { - - /** - * 通知ID - */ - private Long id; - - /** - * 通知标题 - */ - private String title; - - /** - * 通知类型 - */ - private Integer type; - - /** - * 通知类型标签 - */ - private String typeLabel; - - /** - * 通知内容 - */ - private String content; - - /** - * 发布人姓名 - */ - private String publisherName; - - /** - * 通知等级(L: 低, M: 中, H: 高) - */ - private String level; - - /** - * 目标类型(1: 全体 2: 指定) - */ - private Integer targetType; - - /** - * 发布状态(0: 未发布, 1: 已发布, -1: 已撤回) - */ - private Integer publishStatus; - - /** - * 创建时间 - */ - private LocalDateTime createTime; - - /** - * 发布时间 - */ - private LocalDateTime publishTime; - - /** - * 撤回时间 - */ - private LocalDateTime revokeTime; -} - - \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/bo/UserBO.java b/src/main/java/com/youlai/boot/system/model/bo/UserBO.java deleted file mode 100644 index 61b62ed2..00000000 --- a/src/main/java/com/youlai/boot/system/model/bo/UserBO.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.youlai.boot.system.model.bo; - -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * 用户持久化对象 - * - * @author Ray.Hao - * @since 2022/6/10 - */ -@Data -public class UserBO { - - /** - * 用户ID - */ - private Long id; - - /** - * 账户名 - */ - private String username; - - /** - * 昵称 - */ - private String nickname; - - /** - * 手机号 - */ - private String mobile; - - /** - * 性别(1->男;2->女) - */ - private Integer gender; - - /** - * 头像URL - */ - private String avatar; - - /** - * 邮箱 - */ - private String email; - - /** - * 状态: 1->启用;0->禁用 - */ - private Integer status; - - /** - * 部门名称 - */ - private String deptName; - - /** - * 角色名称,多个使用英文逗号(,)分割 - */ - private String roleNames; - - /** - * 创建时间 - */ - private LocalDateTime createTime; -} - - \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/bo/VisitCountBO.java b/src/main/java/com/youlai/boot/system/model/bo/VisitCountBO.java deleted file mode 100644 index cec119de..00000000 --- a/src/main/java/com/youlai/boot/system/model/bo/VisitCountBO.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.youlai.boot.system.model.bo; - -import lombok.Data; - -/** - * 特定日期访问统计 - * - * @author Ray - * @since 2.10.0 - */ -@Data -public class VisitCountBO { - - /** - * 日期 yyyy-MM-dd - */ - private String date; - - /** - * 访问次数 - */ - private Integer count; -} diff --git a/src/main/java/com/youlai/boot/system/model/bo/VisitStatsBO.java b/src/main/java/com/youlai/boot/system/model/bo/VisitStatsBO.java deleted file mode 100644 index 3b515826..00000000 --- a/src/main/java/com/youlai/boot/system/model/bo/VisitStatsBO.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.youlai.boot.system.model.bo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Getter; -import lombok.Setter; - -import java.math.BigDecimal; - -/** - * 访问量统计业务对象 - * - * @author Ray.Hao - * @since 2024/7/2 - */ -@Getter -@Setter -public class VisitStatsBO { - - @Schema(description = "今日访问量 (PV)") - private Integer todayCount; - - @Schema(description = "累计访问量 ") - private Integer totalCount; - - @Schema(description = "页面访问量增长率") - private BigDecimal growthRate; - -} - - \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/bo/RolePermsBO.java b/src/main/java/com/youlai/boot/system/model/dto/RolePermsDTO.java similarity index 77% rename from src/main/java/com/youlai/boot/system/model/bo/RolePermsBO.java rename to src/main/java/com/youlai/boot/system/model/dto/RolePermsDTO.java index 32b9fab8..68698ded 100644 --- a/src/main/java/com/youlai/boot/system/model/bo/RolePermsBO.java +++ b/src/main/java/com/youlai/boot/system/model/dto/RolePermsDTO.java @@ -1,4 +1,4 @@ -package com.youlai.boot.system.model.bo; +package com.youlai.boot.system.model.dto; import lombok.Data; import java.util.Set; @@ -10,7 +10,7 @@ import java.util.Set; * @since 3.0.0 */ @Data -public class RolePermsBO { +public class RolePermsDTO { /** * 角色编码 @@ -21,6 +21,4 @@ public class RolePermsBO { * 权限集合 */ private Set perms; -} - - +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/dto/UserSessionDTO.java b/src/main/java/com/youlai/boot/system/model/dto/UserSessionDTO.java deleted file mode 100644 index f7405d67..00000000 --- a/src/main/java/com/youlai/boot/system/model/dto/UserSessionDTO.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.youlai.boot.system.model.dto; - -import lombok.Data; - -import java.util.HashSet; -import java.util.Set; - -/** - * 用户会话Dto - * - * @author Ray.Hao - * @since 3.0.0 - */ -@Data -public class UserSessionDTO { - - /** - * 用户名 - */ - private String username; - - /** - * 用户会话ID集合 - */ - private Set sessionIds; - - /** - * 最后活动时间 - */ - private long lastActiveTime; - - public UserSessionDTO(String username) { - this.username = username; - this.sessionIds = new HashSet<>(); - this.lastActiveTime = System.currentTimeMillis(); - } -} - - \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/dto/VisitCountDTO.java b/src/main/java/com/youlai/boot/system/model/dto/VisitCountDTO.java new file mode 100644 index 00000000..f622de30 --- /dev/null +++ b/src/main/java/com/youlai/boot/system/model/dto/VisitCountDTO.java @@ -0,0 +1,21 @@ +package com.youlai.boot.system.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 访问计数数据传输对象 + * + * @author Ray.Hao + * @since 2.10.0 + */ +@Schema(description = "访问计数数据传输对象") +@Data +public class VisitCountDTO { + + @Schema(description = "日期 yyyy-MM-dd") + private String date; + + @Schema(description = "访问次数") + private Integer count; +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/entity/Log.java b/src/main/java/com/youlai/boot/system/model/entity/SysLog.java similarity index 61% rename from src/main/java/com/youlai/boot/system/model/entity/Log.java rename to src/main/java/com/youlai/boot/system/model/entity/SysLog.java index e028d77a..ae93c980 100644 --- a/src/main/java/com/youlai/boot/system/model/entity/Log.java +++ b/src/main/java/com/youlai/boot/system/model/entity/SysLog.java @@ -1,7 +1,7 @@ package com.youlai.boot.system.model.entity; import com.baomidou.mybatisplus.annotation.*; -import com.fasterxml.jackson.annotation.JsonInclude; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import lombok.Data; @@ -16,51 +16,55 @@ import java.time.LocalDateTime; */ @Data @TableName("sys_log") -public class Log implements Serializable { +public class SysLog implements Serializable { /** - * 主键 + * 主键 */ @TableId(type = IdType.AUTO) private Long id; /** - * 日志模块 + * 模块 */ private LogModuleEnum module; /** - * 请求方式 + * 操作类型 */ - @TableField(value = "request_method") - private String requestMethod; + @TableField(value = "action_type") + private ActionTypeEnum actionType; /** - * 请求参数 + * 操作标题 */ - @TableField(value = "request_params") - private String requestParams; + private String title; /** - * 响应参数 - */ - @TableField(value = "response_content") - private String responseContent; - - /** - * 日志内容 + * 自定义日志内容 */ private String content; + /** + * 操作人ID + */ + private Long operatorId; + + /** + * 操作人名称 + */ + private String operatorName; + /** * 请求路径 */ private String requestUri; /** - * 请求方法 + * 请求方式 */ - private String method; + @TableField(value = "request_method") + private String requestMethod; /** * IP 地址 @@ -77,35 +81,40 @@ public class Log implements Serializable { */ private String city; + /** + * 设备 + */ + private String device; + + /** + * 操作系统 + */ + private String os; + /** * 浏览器 */ private String browser; /** - * 浏览器版本 + * 状态:0失败 1成功 */ - private String browserVersion; + private Integer status; /** - * 终端系统 + * 错误信息 */ - private String os; + @TableField(value = "error_msg") + private String errorMsg; /** * 执行时间(毫秒) */ - private Long executionTime; + private Integer executionTime; /** - * 创建人ID + * 操作时间 */ - private Long createBy; - - /** - * 创建时间 - */ - @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; -} \ No newline at end of file +} diff --git a/src/main/java/com/youlai/boot/system/model/entity/User.java b/src/main/java/com/youlai/boot/system/model/entity/SysUser.java similarity index 96% rename from src/main/java/com/youlai/boot/system/model/entity/User.java rename to src/main/java/com/youlai/boot/system/model/entity/SysUser.java index 62535380..92cc9542 100644 --- a/src/main/java/com/youlai/boot/system/model/entity/User.java +++ b/src/main/java/com/youlai/boot/system/model/entity/SysUser.java @@ -11,7 +11,7 @@ import lombok.Setter; @TableName("sys_user") @Getter @Setter -public class User extends BaseEntity { +public class SysUser extends BaseEntity { /** * 用户名 diff --git a/src/main/java/com/youlai/boot/system/model/form/MenuForm.java b/src/main/java/com/youlai/boot/system/model/form/MenuForm.java index dabc73ce..886130ca 100644 --- a/src/main/java/com/youlai/boot/system/model/form/MenuForm.java +++ b/src/main/java/com/youlai/boot/system/model/form/MenuForm.java @@ -1,6 +1,6 @@ package com.youlai.boot.system.model.form; -import com.youlai.boot.common.model.KeyValue; +import com.youlai.boot.shared.dto.KeyValue; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.hibernate.validator.constraints.Range; diff --git a/src/main/java/com/youlai/boot/system/model/dto/UserImportDTO.java b/src/main/java/com/youlai/boot/system/model/form/UserImportForm.java similarity index 85% rename from src/main/java/com/youlai/boot/system/model/dto/UserImportDTO.java rename to src/main/java/com/youlai/boot/system/model/form/UserImportForm.java index c5dd7ec7..a5945d87 100644 --- a/src/main/java/com/youlai/boot/system/model/dto/UserImportDTO.java +++ b/src/main/java/com/youlai/boot/system/model/form/UserImportForm.java @@ -1,16 +1,16 @@ -package com.youlai.boot.system.model.dto; +package com.youlai.boot.system.model.form; import cn.idev.excel.annotation.ExcelProperty; import lombok.Data; /** - * 用户导入对象 + * 用户导入表单 * * @author Ray.Hao * @since 2022/4/10 */ @Data -public class UserImportDTO { +public class UserImportForm { @ExcelProperty(value = "用户名") private String username; @@ -33,6 +33,4 @@ public class UserImportDTO { @ExcelProperty("部门") private String deptCode; -} - - \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/query/LogQuery.java b/src/main/java/com/youlai/boot/system/model/query/LogQuery.java index f3d84c39..dbc8c2d2 100644 --- a/src/main/java/com/youlai/boot/system/model/query/LogQuery.java +++ b/src/main/java/com/youlai/boot/system/model/query/LogQuery.java @@ -7,18 +7,12 @@ import lombok.Setter; import java.util.List; -/** - * 日志查询对象 - * - * @author Ray - * @since 2.10.0 - */ @Schema(description = "日志查询对象") @Getter @Setter public class LogQuery extends BaseQuery { - @Schema(description="关键字(日志内容/请求路径/请求方法/地区/浏览器/终端系统)") + @Schema(description="关键字(IP/操作人)") private String keywords; @Schema(description="操作时间范围") diff --git a/src/main/java/com/youlai/boot/system/model/dto/CurrentUserDTO.java b/src/main/java/com/youlai/boot/system/model/vo/CurrentUserVO.java similarity index 82% rename from src/main/java/com/youlai/boot/system/model/dto/CurrentUserDTO.java rename to src/main/java/com/youlai/boot/system/model/vo/CurrentUserVO.java index 09a4cdca..67f3406c 100644 --- a/src/main/java/com/youlai/boot/system/model/dto/CurrentUserDTO.java +++ b/src/main/java/com/youlai/boot/system/model/vo/CurrentUserVO.java @@ -1,4 +1,4 @@ -package com.youlai.boot.system.model.dto; +package com.youlai.boot.system.model.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -6,14 +6,14 @@ import lombok.Data; import java.util.Set; /** - * 当前登录用户对象 + * 当前登录用户视图对象 * - * @author haoxr + * @author Ray.Hao * @since 2022/1/14 */ -@Schema(description ="当前登录用户对象") +@Schema(description ="当前登录用户视图对象") @Data -public class CurrentUserDTO { +public class CurrentUserVO { @Schema(description="用户ID") private Long userId; @@ -42,5 +42,4 @@ public class CurrentUserDTO { @Schema(description="用户权限标识集合") private Set perms; -} - +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/vo/LogPageVO.java b/src/main/java/com/youlai/boot/system/model/vo/LogPageVO.java index 3b38a162..cd8fd342 100644 --- a/src/main/java/com/youlai/boot/system/model/vo/LogPageVO.java +++ b/src/main/java/com/youlai/boot/system/model/vo/LogPageVO.java @@ -1,6 +1,7 @@ package com.youlai.boot.system.model.vo; import com.fasterxml.jackson.annotation.JsonFormat; +import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -21,17 +22,29 @@ public class LogPageVO implements Serializable { @Schema(description = "主键") private Long id; - @Schema(description = "日志模块") + @Schema(description = "模块") private LogModuleEnum module; - @Schema(description = "日志内容") + @Schema(description = "操作类型") + private ActionTypeEnum actionType; + + @Schema(description = "操作标题") + private String title; + + @Schema(description = "自定义日志内容") private String content; + @Schema(description = "操作人ID") + private Long operatorId; + + @Schema(description = "操作人名称") + private String operatorName; + @Schema(description = "请求路径") private String requestUri; @Schema(description = "请求方法") - private String method; + private String requestMethod; @Schema(description = "IP 地址") private String ip; @@ -39,23 +52,26 @@ public class LogPageVO implements Serializable { @Schema(description = "地区") private String region; + @Schema(description = "设备") + private String device; + + @Schema(description = "操作系统") + private String os; + @Schema(description = "浏览器") private String browser; - @Schema(description = "终端系统") - private String os; + @Schema(description = "状态:0失败 1成功") + private Integer status; @Schema(description = "执行时间(毫秒)") - private Long executionTime; + private Integer executionTime; - @Schema(description = "创建人ID") - private Long createBy; + @Schema(description = "错误信息") + private String errorMsg; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; - @Schema(description = "操作人") - private String operator; } - \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/dto/NoticeDTO.java b/src/main/java/com/youlai/boot/system/model/vo/NoticeVO.java similarity index 85% rename from src/main/java/com/youlai/boot/system/model/dto/NoticeDTO.java rename to src/main/java/com/youlai/boot/system/model/vo/NoticeVO.java index c90305fe..47f491cd 100644 --- a/src/main/java/com/youlai/boot/system/model/dto/NoticeDTO.java +++ b/src/main/java/com/youlai/boot/system/model/vo/NoticeVO.java @@ -1,4 +1,4 @@ -package com.youlai.boot.system.model.dto; +package com.youlai.boot.system.model.vo; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; @@ -7,13 +7,13 @@ import lombok.Data; import java.time.LocalDateTime; /** - * 通知传送对象 + * 通知视图对象 * * @author Theo * @since 2024-9-2 14:32:58 */ @Data -public class NoticeDTO { +public class NoticeVO { @Schema(description = "通知ID") private Long id; @@ -28,6 +28,4 @@ public class NoticeDTO { @JsonFormat(pattern = "yyyy-MM-dd HH:mm") private LocalDateTime publishTime; -} - - \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/dto/UserExportDTO.java b/src/main/java/com/youlai/boot/system/model/vo/UserExportVO.java similarity index 91% rename from src/main/java/com/youlai/boot/system/model/dto/UserExportDTO.java rename to src/main/java/com/youlai/boot/system/model/vo/UserExportVO.java index 29c8f3a6..c5383398 100644 --- a/src/main/java/com/youlai/boot/system/model/dto/UserExportDTO.java +++ b/src/main/java/com/youlai/boot/system/model/vo/UserExportVO.java @@ -1,4 +1,4 @@ -package com.youlai.boot.system.model.dto; +package com.youlai.boot.system.model.vo; import cn.idev.excel.annotation.ExcelProperty; import cn.idev.excel.annotation.format.DateTimeFormat; @@ -16,7 +16,7 @@ import java.time.LocalDateTime; @Data @ColumnWidth(20) -public class UserExportDTO { +public class UserExportVO { @ExcelProperty(value = "用户名") private String username; @@ -41,6 +41,4 @@ public class UserExportDTO { private LocalDateTime createTime; -} - - \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/model/vo/VisitStatsVO.java b/src/main/java/com/youlai/boot/system/model/vo/VisitOverviewVO.java similarity index 87% rename from src/main/java/com/youlai/boot/system/model/vo/VisitStatsVO.java rename to src/main/java/com/youlai/boot/system/model/vo/VisitOverviewVO.java index 7843e100..63cfb0d7 100644 --- a/src/main/java/com/youlai/boot/system/model/vo/VisitStatsVO.java +++ b/src/main/java/com/youlai/boot/system/model/vo/VisitOverviewVO.java @@ -7,15 +7,15 @@ import lombok.Setter; import java.math.BigDecimal; /** - * 访问量统计视图对象 + * 访问总览视图对象 * * @author Ray.Hao * @since 2024/7/2 */ -@Schema(description = "访问量统计视图对象") +@Schema(description = "访问总览视图对象") @Getter @Setter -public class VisitStatsVO { +public class VisitOverviewVO { @Schema(description = "今日独立访客数 (UV)") private Integer todayUvCount; @@ -34,6 +34,4 @@ public class VisitStatsVO { @Schema(description = "页面浏览量增长率") private BigDecimal pvGrowthRate; -} - - \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/system/service/DeptService.java b/src/main/java/com/youlai/boot/system/service/DeptService.java index 850a948e..7a9e4793 100644 --- a/src/main/java/com/youlai/boot/system/service/DeptService.java +++ b/src/main/java/com/youlai/boot/system/service/DeptService.java @@ -2,7 +2,7 @@ package com.youlai.boot.system.service; import com.baomidou.mybatisplus.extension.service.IService; import com.youlai.boot.system.model.entity.Dept; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.model.form.DeptForm; import com.youlai.boot.system.model.query.DeptQuery; import com.youlai.boot.system.model.vo.DeptVO; diff --git a/src/main/java/com/youlai/boot/system/service/DictService.java b/src/main/java/com/youlai/boot/system/service/DictService.java index a064deda..e8706e58 100644 --- a/src/main/java/com/youlai/boot/system/service/DictService.java +++ b/src/main/java/com/youlai/boot/system/service/DictService.java @@ -2,7 +2,7 @@ package com.youlai.boot.system.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.model.entity.Dict; import com.youlai.boot.system.model.form.DictForm; import com.youlai.boot.system.model.query.DictQuery; diff --git a/src/main/java/com/youlai/boot/system/service/LogService.java b/src/main/java/com/youlai/boot/system/service/LogService.java index b3bab2fb..bd2f4479 100644 --- a/src/main/java/com/youlai/boot/system/service/LogService.java +++ b/src/main/java/com/youlai/boot/system/service/LogService.java @@ -1,15 +1,14 @@ package com.youlai.boot.system.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.youlai.boot.system.model.entity.Log; +import com.youlai.boot.system.model.entity.SysLog; import com.baomidou.mybatisplus.extension.service.IService; import com.youlai.boot.system.model.query.LogQuery; import com.youlai.boot.system.model.vo.LogPageVO; -import com.youlai.boot.system.model.vo.VisitStatsVO; +import com.youlai.boot.system.model.vo.VisitOverviewVO; import com.youlai.boot.system.model.vo.VisitTrendVO; import java.time.LocalDate; -import java.util.List; /** * 系统日志 服务接口 @@ -17,7 +16,7 @@ import java.util.List; * @author Ray.Hao * @since 2.10.0 */ -public interface LogService extends IService { +public interface LogService extends IService { /** * 获取日志分页列表 @@ -36,6 +35,6 @@ public interface LogService extends IService { /** * 获取访问统计 */ - VisitStatsVO getVisitStats(); + VisitOverviewVO getVisitStats(); } diff --git a/src/main/java/com/youlai/boot/system/service/MenuService.java b/src/main/java/com/youlai/boot/system/service/MenuService.java index 124e0b5d..0c8697e9 100644 --- a/src/main/java/com/youlai/boot/system/service/MenuService.java +++ b/src/main/java/com/youlai/boot/system/service/MenuService.java @@ -3,7 +3,7 @@ package com.youlai.boot.system.service; import com.baomidou.mybatisplus.extension.service.IService; import com.youlai.boot.module.codegen.model.entity.GenTable; import com.youlai.boot.system.model.form.MenuForm; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.model.entity.Menu; import com.youlai.boot.system.model.query.MenuQuery; import com.youlai.boot.system.model.vo.MenuVO; diff --git a/src/main/java/com/youlai/boot/system/service/RoleService.java b/src/main/java/com/youlai/boot/system/service/RoleService.java index 00360d64..5a34d36b 100644 --- a/src/main/java/com/youlai/boot/system/service/RoleService.java +++ b/src/main/java/com/youlai/boot/system/service/RoleService.java @@ -3,9 +3,9 @@ package com.youlai.boot.system.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import com.youlai.boot.security.model.RoleDataScope; +import com.youlai.boot.framework.security.model.RoleDataScope; import com.youlai.boot.system.model.entity.Role; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.model.form.RoleForm; import com.youlai.boot.system.model.query.RoleQuery; import com.youlai.boot.system.model.vo.RolePageVO; diff --git a/src/main/java/com/youlai/boot/system/service/UserService.java b/src/main/java/com/youlai/boot/system/service/UserService.java index f98ef295..7c932746 100644 --- a/src/main/java/com/youlai/boot/system/service/UserService.java +++ b/src/main/java/com/youlai/boot/system/service/UserService.java @@ -2,11 +2,11 @@ package com.youlai.boot.system.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.security.model.UserAuthInfo; -import com.youlai.boot.system.model.dto.CurrentUserDTO; -import com.youlai.boot.system.model.dto.UserExportDTO; -import com.youlai.boot.system.model.entity.User; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.framework.security.model.UserAuthInfo; +import com.youlai.boot.system.model.vo.CurrentUserVO; +import com.youlai.boot.system.model.vo.UserExportVO; +import com.youlai.boot.system.model.entity.SysUser; import com.youlai.boot.system.model.query.UserQuery; import com.youlai.boot.system.model.vo.UserPageVO; import com.youlai.boot.system.model.vo.UserProfileVO; @@ -20,7 +20,7 @@ import java.util.List; * @author Ray.Hao * @since 2022/1/14 */ -public interface UserService extends IService { +public interface UserService extends IService { /** * 用户分页列表 @@ -82,17 +82,17 @@ public interface UserService extends IService { * 获取导出用户列表 * * @param queryParams 查询参数 - * @return {@link List} 导出用户列表 + * @return {@link List} 导出用户列表 */ - List listExportUsers(UserQuery queryParams); + List listExportUsers(UserQuery queryParams); /** * 获取登录用户信息 * - * @return {@link CurrentUserDTO} 登录用户信息 + * @return {@link CurrentUserVO} 登录用户信息 */ - CurrentUserDTO getCurrentUserInfo(); + CurrentUserVO getCurrentUserInfo(); /** * 获取个人中心用户信息 diff --git a/src/main/java/com/youlai/boot/system/service/UserSocialService.java b/src/main/java/com/youlai/boot/system/service/UserSocialService.java index 74f26e64..943792dc 100644 --- a/src/main/java/com/youlai/boot/system/service/UserSocialService.java +++ b/src/main/java/com/youlai/boot/system/service/UserSocialService.java @@ -1,7 +1,7 @@ package com.youlai.boot.system.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.youlai.boot.security.model.UserAuthInfo; +import com.youlai.boot.framework.security.model.UserAuthInfo; import com.youlai.boot.system.enums.SocialPlatformEnum; import com.youlai.boot.system.model.entity.UserSocial; diff --git a/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java index 022fe08b..711b90c2 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java @@ -12,7 +12,7 @@ import com.youlai.boot.system.model.form.ConfigForm; import com.youlai.boot.system.model.query.ConfigQuery; import com.youlai.boot.system.model.vo.ConfigVO; import com.youlai.boot.system.service.ConfigService; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.framework.security.util.SecurityUtils; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/com/youlai/boot/system/service/impl/DeptServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/DeptServiceImpl.java index 2d284935..5b7504a2 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/DeptServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/DeptServiceImpl.java @@ -6,16 +6,16 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.system.converter.DeptConverter; import com.youlai.boot.system.mapper.DeptMapper; import com.youlai.boot.system.model.entity.Dept; import com.youlai.boot.system.model.form.DeptForm; import com.youlai.boot.system.model.query.DeptQuery; import com.youlai.boot.system.model.vo.DeptVO; -import com.youlai.boot.common.constant.SystemConstants; -import com.youlai.boot.common.enums.StatusEnum; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.constant.SystemConstants; +import com.youlai.boot.shared.enums.StatusEnum; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.service.DeptService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/youlai/boot/system/service/impl/DictServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/DictServiceImpl.java index eccf6c52..765851c6 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/DictServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/DictServiceImpl.java @@ -4,8 +4,8 @@ import cn.hutool.core.lang.Assert; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.core.exception.BusinessException; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.converter.DictConverter; import com.youlai.boot.system.mapper.DictMapper; import com.youlai.boot.system.model.entity.Dict; diff --git a/src/main/java/com/youlai/boot/system/service/impl/LogServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/LogServiceImpl.java index 92454d2b..83833720 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/LogServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/LogServiceImpl.java @@ -3,12 +3,12 @@ package com.youlai.boot.system.service.impl; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.youlai.boot.system.mapper.LogMapper; -import com.youlai.boot.system.model.bo.VisitCountBO; -import com.youlai.boot.system.model.bo.VisitStatsBO; -import com.youlai.boot.system.model.entity.Log; +import com.youlai.boot.system.model.dto.VisitCountDTO; +import com.youlai.boot.system.model.vo.VisitOverviewVO; +import com.youlai.boot.system.model.entity.SysLog; import com.youlai.boot.system.model.query.LogQuery; import com.youlai.boot.system.model.vo.LogPageVO; -import com.youlai.boot.system.model.vo.VisitStatsVO; +import com.youlai.boot.system.model.vo.VisitOverviewVO; import com.youlai.boot.system.model.vo.VisitTrendVO; import com.youlai.boot.system.service.LogService; import org.springframework.stereotype.Service; @@ -26,7 +26,7 @@ import java.util.stream.Collectors; * @since 2.10.0 */ @Service -public class LogServiceImpl extends ServiceImpl +public class LogServiceImpl extends ServiceImpl implements LogService { /** @@ -61,12 +61,12 @@ public class LogServiceImpl extends ServiceImpl visitTrend.setDates(dates); // 获取访问量和访问 IP 数的统计数据 - List pvCounts = this.baseMapper.getPvCounts(dates.get(0) + " 00:00:00", dates.get(dates.size() - 1) + " 23:59:59"); - List ipCounts = this.baseMapper.getIpCounts(dates.get(0) + " 00:00:00", dates.get(dates.size() - 1) + " 23:59:59"); + List pvCounts = this.baseMapper.getPvCounts(dates.get(0) + " 00:00:00", dates.get(dates.size() - 1) + " 23:59:59"); + List ipCounts = this.baseMapper.getIpCounts(dates.get(0) + " 00:00:00", dates.get(dates.size() - 1) + " 23:59:59"); // 将统计数据转换为 Map - Map pvMap = pvCounts.stream().collect(Collectors.toMap(VisitCountBO::getDate, VisitCountBO::getCount)); - Map ipMap = ipCounts.stream().collect(Collectors.toMap(VisitCountBO::getDate, VisitCountBO::getCount)); + Map pvMap = pvCounts.stream().collect(Collectors.toMap(VisitCountDTO::getDate, VisitCountDTO::getCount)); + Map ipMap = ipCounts.stream().collect(Collectors.toMap(VisitCountDTO::getDate, VisitCountDTO::getCount)); // 匹配日期和访问量/访问 IP 数 List pvList = new ArrayList<>(); @@ -87,23 +87,23 @@ public class LogServiceImpl extends ServiceImpl * 访问量统计 */ @Override - public VisitStatsVO getVisitStats() { - VisitStatsVO result = new VisitStatsVO(); + public VisitOverviewVO getVisitStats() { + VisitOverviewVO result = new VisitOverviewVO(); // 访客数统计(UV) - VisitStatsBO uvStats = this.baseMapper.getUvStats(); + VisitOverviewVO uvStats = this.baseMapper.getUvStats(); if(uvStats!=null){ - result.setTodayUvCount(uvStats.getTodayCount()); - result.setTotalUvCount(uvStats.getTotalCount()); - result.setUvGrowthRate(uvStats.getGrowthRate()); + result.setTodayUvCount(uvStats.getTodayUvCount()); + result.setTotalUvCount(uvStats.getTotalUvCount()); + result.setUvGrowthRate(uvStats.getUvGrowthRate()); } // 浏览量统计(PV) - VisitStatsBO pvStats = this.baseMapper.getPvStats(); + VisitOverviewVO pvStats = this.baseMapper.getPvStats(); if(pvStats!=null){ - result.setTodayPvCount(pvStats.getTodayCount()); - result.setTotalPvCount(pvStats.getTotalCount()); - result.setPvGrowthRate(pvStats.getGrowthRate()); + result.setTodayPvCount(pvStats.getTodayPvCount()); + result.setTotalPvCount(pvStats.getTotalPvCount()); + result.setPvGrowthRate(pvStats.getPvGrowthRate()); } return result; diff --git a/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java index 3f87faa8..bc898b1d 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.youlai.boot.module.codegen.model.entity.GenTable; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.system.converter.MenuConverter; import com.youlai.boot.system.mapper.MenuMapper; import com.youlai.boot.system.model.entity.Menu; @@ -16,11 +16,11 @@ import com.youlai.boot.system.model.form.MenuForm; import com.youlai.boot.system.model.query.MenuQuery; import com.youlai.boot.system.model.vo.MenuVO; import com.youlai.boot.system.model.vo.RouteVO; -import com.youlai.boot.common.constant.SystemConstants; +import com.youlai.boot.shared.constant.SystemConstants; import com.youlai.boot.system.enums.MenuTypeEnum; -import com.youlai.boot.common.enums.StatusEnum; -import com.youlai.boot.common.model.KeyValue; -import com.youlai.boot.common.model.Option; +import com.youlai.boot.shared.enums.StatusEnum; +import com.youlai.boot.shared.dto.KeyValue; +import com.youlai.boot.shared.dto.Option; import com.youlai.boot.system.service.MenuService; import com.youlai.boot.system.service.RoleMenuService; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/youlai/boot/system/service/impl/NoticeServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/NoticeServiceImpl.java index 00bdf326..5f503536 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/NoticeServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/NoticeServiceImpl.java @@ -7,27 +7,26 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.core.exception.BusinessException; -import com.youlai.boot.support.sse.dto.OnlineUserDTO; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.interfaces.sse.dto.OnlineUserDTO; +import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.system.converter.NoticeConverter; import com.youlai.boot.system.enums.NoticePublishStatusEnum; import com.youlai.boot.system.enums.NoticeTargetEnum; import com.youlai.boot.system.mapper.NoticeMapper; -import com.youlai.boot.system.model.bo.NoticeBO; -import com.youlai.boot.system.model.dto.NoticeDTO; -import com.youlai.boot.system.model.entity.Notice; -import com.youlai.boot.system.model.entity.UserNotice; -import com.youlai.boot.system.model.entity.User; -import com.youlai.boot.system.model.form.NoticeForm; -import com.youlai.boot.system.model.query.NoticeQuery; import com.youlai.boot.system.model.vo.NoticePageVO; import com.youlai.boot.system.model.vo.UserNoticePageVO; import com.youlai.boot.system.model.vo.NoticeDetailVO; +import com.youlai.boot.system.model.vo.NoticeVO; +import com.youlai.boot.system.model.entity.Notice; +import com.youlai.boot.system.model.entity.UserNotice; +import com.youlai.boot.system.model.entity.SysUser; +import com.youlai.boot.system.model.form.NoticeForm; +import com.youlai.boot.system.model.query.NoticeQuery; import com.youlai.boot.system.service.NoticeService; import com.youlai.boot.system.service.UserNoticeService; import com.youlai.boot.system.service.UserService; -import com.youlai.boot.support.sse.SseService; +import com.youlai.boot.interfaces.sse.service.SseService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -62,11 +61,10 @@ public class NoticeServiceImpl extends ServiceImpl impleme */ @Override public IPage getNoticePage(NoticeQuery queryParams) { - Page noticePage = this.baseMapper.getNoticePage( + return this.baseMapper.getNoticePage( new Page<>(queryParams.getPageNum(), queryParams.getPageSize()), queryParams ); - return noticeConverter.toPageVo(noticePage); } /** @@ -188,12 +186,12 @@ public class NoticeServiceImpl extends ServiceImpl impleme targetUserIdList = Arrays.asList(targetUserIds.split(",")); } - List targetUserList = userService.list( - new LambdaQueryWrapper() + List targetUserList = userService.list( + new LambdaQueryWrapper() // 如果是指定用户,则筛选出指定用户 .in( NoticeTargetEnum.SPECIFIED.getValue().equals(targetType), - User::getId, + SysUser::getId, targetUserIdList ) ); @@ -210,7 +208,7 @@ public class NoticeServiceImpl extends ServiceImpl impleme userNoticeService.saveBatch(userNoticeList); } - Set receivers = targetUserList.stream().map(User::getUsername).collect(Collectors.toSet()); + Set receivers = targetUserList.stream().map(SysUser::getUsername).collect(Collectors.toSet()); // 获取在线用户名集合 Set allOnlineUsers = sseService.getOnlineUsers().stream() @@ -220,14 +218,14 @@ public class NoticeServiceImpl extends ServiceImpl impleme // 找出在线用户的通知接收者 Set onlineReceivers = new HashSet<>(CollectionUtil.intersection(receivers, allOnlineUsers)); - NoticeDTO noticeDto = new NoticeDTO(); - noticeDto.setId(id); - noticeDto.setTitle(notice.getTitle()); - noticeDto.setType(notice.getType()); - noticeDto.setPublishTime(notice.getPublishTime()); + NoticeVO noticeVo = new NoticeVO(); + noticeVo.setId(id); + noticeVo.setTitle(notice.getTitle()); + noticeVo.setType(notice.getType()); + noticeVo.setPublishTime(notice.getPublishTime()); // 向在线接收者推送通知 - onlineReceivers.forEach(receiver -> sseService.sendToUser(receiver, "notice", noticeDto)); + onlineReceivers.forEach(receiver -> sseService.sendToUser(receiver, "notice", noticeVo)); } return publishResult; } @@ -263,8 +261,8 @@ public class NoticeServiceImpl extends ServiceImpl impleme ); // 通知前端移除该通知 - NoticeDTO noticeDto = new NoticeDTO(); - noticeDto.setId(id); + NoticeVO noticeVo = new NoticeVO(); + noticeVo.setId(id); // 获取所有在线用户 Set allOnlineUsers = sseService.getOnlineUsers().stream() @@ -273,7 +271,7 @@ public class NoticeServiceImpl extends ServiceImpl impleme // 向所有在线用户推送撤回通知 allOnlineUsers.forEach(username -> - sseService.sendToUser(username, "notice-revoke", noticeDto)); + sseService.sendToUser(username, "notice-revoke", noticeVo)); } return revokeResult; } @@ -285,7 +283,7 @@ public class NoticeServiceImpl extends ServiceImpl impleme */ @Override public NoticeDetailVO getNoticeDetail(Long id) { - NoticeBO noticeBo = this.baseMapper.getNoticeDetail(id); + NoticeDetailVO detail = this.baseMapper.getNoticeDetail(id); // 更新用户通知公告的阅读状态 Long userId = SecurityUtils.getUserId(); userNoticeService.update(new LambdaUpdateWrapper() @@ -294,7 +292,7 @@ public class NoticeServiceImpl extends ServiceImpl impleme .eq(UserNotice::getIsRead, 0) .set(UserNotice::getIsRead, 1) ); - return noticeConverter.toDetailVo(noticeBo); + return detail; } /** diff --git a/src/main/java/com/youlai/boot/system/service/impl/RoleMenuServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/RoleMenuServiceImpl.java index 5e68745a..33c58220 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/RoleMenuServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/RoleMenuServiceImpl.java @@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.youlai.boot.common.constant.RedisConstants; import com.youlai.boot.system.mapper.RoleMenuMapper; -import com.youlai.boot.system.model.bo.RolePermsBO; +import com.youlai.boot.system.model.dto.RolePermsDTO; import com.youlai.boot.system.model.entity.RoleMenu; import com.youlai.boot.system.service.RoleMenuService; import lombok.RequiredArgsConstructor; @@ -39,7 +39,7 @@ public class RoleMenuServiceImpl extends ServiceImpl i redisTemplate.delete(cacheKey); // 预热权限缓存,避免后续请求触发频繁回源 - List list = this.baseMapper.getRolePermsList(null); + List list = this.baseMapper.getRolePermsList(null); if (CollectionUtil.isNotEmpty(list)) { list.forEach(item -> { String roleCode = item.getRoleCode(); @@ -64,9 +64,9 @@ public class RoleMenuServiceImpl extends ServiceImpl i redisTemplate.opsForHash().delete(cacheKey, roleCode); // 回源 DB 并更新缓存 - List list = this.baseMapper.getRolePermsList(roleCode); + List list = this.baseMapper.getRolePermsList(roleCode); if (CollectionUtil.isNotEmpty(list)) { - RolePermsBO rolePerms = list.get(0); + RolePermsDTO rolePerms = list.get(0); if (rolePerms != null) { Set perms = rolePerms.getPerms(); if (CollectionUtil.isNotEmpty(perms)) { @@ -90,9 +90,9 @@ public class RoleMenuServiceImpl extends ServiceImpl i redisTemplate.opsForHash().delete(cacheKey, newRoleCode); // 回源 DB 并更新新角色编码缓存 - List list = this.baseMapper.getRolePermsList(newRoleCode); + List list = this.baseMapper.getRolePermsList(newRoleCode); if (CollectionUtil.isNotEmpty(list)) { - RolePermsBO rolePerms = list.get(0); + RolePermsDTO rolePerms = list.get(0); if (rolePerms != null) { Set perms = rolePerms.getPerms(); if (CollectionUtil.isNotEmpty(perms)) { diff --git a/src/main/java/com/youlai/boot/system/service/impl/RoleServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/RoleServiceImpl.java index fabf28a6..bb7ce146 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/RoleServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/RoleServiceImpl.java @@ -4,14 +4,14 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; -import com.youlai.boot.security.token.TokenManager; +import com.youlai.boot.framework.security.token.TokenManager; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.common.constant.SystemConstants; -import com.youlai.boot.common.enums.DataScopeEnum; -import com.youlai.boot.core.exception.BusinessException; -import com.youlai.boot.security.model.RoleDataScope; +import com.youlai.boot.shared.constant.SystemConstants; +import com.youlai.boot.shared.enums.DataScopeEnum; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.framework.security.model.RoleDataScope; import com.youlai.boot.system.converter.RoleConverter; import com.youlai.boot.system.mapper.RoleMapper; import com.youlai.boot.system.model.entity.Role; @@ -19,8 +19,8 @@ import com.youlai.boot.system.model.entity.RoleMenu; import com.youlai.boot.system.model.form.RoleForm; import com.youlai.boot.system.model.query.RoleQuery; import com.youlai.boot.system.model.vo.RolePageVO; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.system.service.RoleDeptService; import com.youlai.boot.system.service.RoleMenuService; import com.youlai.boot.system.service.RoleService; diff --git a/src/main/java/com/youlai/boot/system/service/impl/UserNoticeServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/UserNoticeServiceImpl.java index 5eefda20..94e34d47 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/UserNoticeServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/UserNoticeServiceImpl.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.system.mapper.UserNoticeMapper; import com.youlai.boot.system.model.entity.UserNotice; import com.youlai.boot.system.model.query.NoticeQuery; diff --git a/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java index c8740e5d..c125575e 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java @@ -3,7 +3,7 @@ package com.youlai.boot.system.service.impl; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.security.token.TokenManager; +import com.youlai.boot.framework.security.token.TokenManager; import com.youlai.boot.system.mapper.UserRoleMapper; import com.youlai.boot.system.model.entity.UserRole; import com.youlai.boot.system.service.UserRoleService; diff --git a/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java index 963358d8..fd0c28cb 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java @@ -9,26 +9,25 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.youlai.boot.common.constant.RedisConstants; -import com.youlai.boot.common.constant.SystemConstants; -import com.youlai.boot.core.exception.BusinessException; -import com.youlai.boot.common.model.Option; -import com.youlai.boot.support.mail.service.MailService; -import com.youlai.boot.support.sms.enums.SmsTypeEnum; -import com.youlai.boot.support.sms.service.SmsService; -import com.youlai.boot.security.model.RoleDataScope; -import com.youlai.boot.security.model.UserAuthInfo; -import com.youlai.boot.security.token.TokenManager; -import com.youlai.boot.security.util.SecurityUtils; +import com.youlai.boot.shared.constant.SystemConstants; +import com.youlai.boot.common.exception.BusinessException; +import com.youlai.boot.shared.dto.Option; +import com.youlai.boot.framework.integration.mail.service.MailService; +import com.youlai.boot.framework.integration.sms.enums.SmsTypeEnum; +import com.youlai.boot.framework.integration.sms.service.SmsService; +import com.youlai.boot.framework.security.model.RoleDataScope; +import com.youlai.boot.framework.security.model.UserAuthInfo; +import com.youlai.boot.framework.security.token.TokenManager; +import com.youlai.boot.framework.security.util.SecurityUtils; import com.youlai.boot.system.converter.UserConverter; import com.youlai.boot.system.enums.DictCodeEnum; import com.youlai.boot.system.mapper.UserMapper; -import com.youlai.boot.system.model.bo.UserBO; -import com.youlai.boot.system.model.dto.CurrentUserDTO; -import com.youlai.boot.system.model.dto.UserExportDTO; +import com.youlai.boot.system.model.vo.CurrentUserVO; +import com.youlai.boot.system.model.vo.UserExportVO; import com.youlai.boot.system.model.entity.Dept; import com.youlai.boot.system.model.entity.DictItem; import com.youlai.boot.system.model.entity.Role; -import com.youlai.boot.system.model.entity.User; +import com.youlai.boot.system.model.entity.SysUser; import com.youlai.boot.system.model.form.*; import com.youlai.boot.system.model.query.UserQuery; import com.youlai.boot.system.model.vo.UserPageVO; @@ -54,7 +53,7 @@ import java.util.stream.Collectors; @Service @RequiredArgsConstructor @Slf4j -public class UserServiceImpl extends ServiceImpl implements UserService { +public class UserServiceImpl extends ServiceImpl implements UserService { private final PasswordEncoder passwordEncoder; @@ -91,16 +90,13 @@ public class UserServiceImpl extends ServiceImpl implements Us // 参数构建 int pageNum = queryParams.getPageNum(); int pageSize = queryParams.getPageSize(); - Page page = new Page<>(pageNum, pageSize); + Page page = new Page<>(pageNum, pageSize); boolean isRoot = SecurityUtils.isRoot(); queryParams.setIsRoot(isRoot); // 查询数据 - Page userPage = this.baseMapper.getUserPage(page, queryParams); - - // 实体转换 - return userConverter.toPageVo(userPage); + return this.baseMapper.getUserPage(page, queryParams); } /** @@ -127,11 +123,11 @@ public class UserServiceImpl extends ServiceImpl implements Us String username = userForm.getUsername(); // 实体转换 form->entity - User entity = userConverter.toEntity(userForm); + SysUser entity = userConverter.toEntity(userForm); // 检查用户名是否已存在 - long count = this.count(new LambdaQueryWrapper() - .eq(User::getUsername, username)); + long count = this.count(new LambdaQueryWrapper() + .eq(SysUser::getUsername, username)); Assert.isTrue(count == 0, "用户名已存在"); // 设置默认加密密码 @@ -163,18 +159,18 @@ public class UserServiceImpl extends ServiceImpl implements Us String username = userForm.getUsername(); // 获取原用户信息 - User oldUser = this.getById(userId); + SysUser oldUser = this.getById(userId); Assert.notNull(oldUser, "用户不存在"); // 检查用户名是否已存在(排除当前用户) - long count = this.count(new LambdaQueryWrapper() - .eq(User::getUsername, username) - .ne(User::getId, userId) + long count = this.count(new LambdaQueryWrapper() + .eq(SysUser::getUsername, username) + .ne(SysUser::getId, userId) ); Assert.isTrue(count == 0, "用户名已存在"); // form -> entity - User entity = userConverter.toEntity(userForm); + SysUser entity = userConverter.toEntity(userForm); entity.setUpdateBy(SecurityUtils.getUserId()); // 修改用户 @@ -249,15 +245,15 @@ public class UserServiceImpl extends ServiceImpl implements Us * 获取导出用户列表 * * @param queryParams 查询参数 - * @return {@link List} 导出用户列表 + * @return {@link List} 导出用户列表 */ @Override - public List listExportUsers(UserQuery queryParams) { + public List listExportUsers(UserQuery queryParams) { boolean isRoot = SecurityUtils.isRoot(); queryParams.setIsRoot(isRoot); - List exportUsers = this.baseMapper.listExportUsers(queryParams); + List exportUsers = this.baseMapper.listExportUsers(queryParams); if (CollectionUtil.isNotEmpty(exportUsers)) { //获取性别的字典项 Map genderMap = dictItemService.list( @@ -287,27 +283,27 @@ public class UserServiceImpl extends ServiceImpl implements Us /** * 获取登录用户信息 * - * @return {@link CurrentUserDTO} 用户信息 + * @return {@link CurrentUserVO} 用户信息 */ @Override - public CurrentUserDTO getCurrentUserInfo() { + public CurrentUserVO getCurrentUserInfo() { String username = SecurityUtils.getUsername(); // 获取登录用户基础信息 - User user = this.getOne(new LambdaQueryWrapper() - .eq(User::getUsername, username) + SysUser user = this.getOne(new LambdaQueryWrapper() + .eq(SysUser::getUsername, username) .select( - User::getId, - User::getUsername, - User::getNickname, - User::getAvatar, - User::getGender, - User::getDeptId + SysUser::getId, + SysUser::getUsername, + SysUser::getNickname, + SysUser::getAvatar, + SysUser::getGender, + SysUser::getDeptId ) ); // entity->Vo - CurrentUserDTO userInfoVo = userConverter.toCurrentUserDto(user); + CurrentUserVO userInfoVo = userConverter.toCurrentUserVo(user); // 性别 userInfoVo.setGender(user.getGender()); @@ -352,8 +348,7 @@ public class UserServiceImpl extends ServiceImpl implements Us */ @Override public UserProfileVO getUserProfile(Long userId) { - UserBO entity = this.baseMapper.getUserProfile(userId); - return userConverter.toProfileVo(entity); + return this.baseMapper.getUserProfile(userId); } /** @@ -370,11 +365,11 @@ public class UserServiceImpl extends ServiceImpl implements Us throw new BusinessException("请修改至少一个字段"); } - return this.update(new LambdaUpdateWrapper() - .eq(User::getId, userId) - .set(formData.getNickname() != null, User::getNickname, formData.getNickname()) - .set(formData.getAvatar() != null, User::getAvatar, formData.getAvatar()) - .set(formData.getGender() != null, User::getGender, formData.getGender()) + return this.update(new LambdaUpdateWrapper() + .eq(SysUser::getId, userId) + .set(formData.getNickname() != null, SysUser::getNickname, formData.getNickname()) + .set(formData.getAvatar() != null, SysUser::getAvatar, formData.getAvatar()) + .set(formData.getGender() != null, SysUser::getGender, formData.getGender()) ); } @@ -388,7 +383,7 @@ public class UserServiceImpl extends ServiceImpl implements Us @Override public boolean changeUserPassword(Long userId, PasswordUpdateForm data) { - User user = this.getById(userId); + SysUser user = this.getById(userId); if (user == null) { throw new BusinessException("用户不存在"); } @@ -410,9 +405,9 @@ public class UserServiceImpl extends ServiceImpl implements Us } String newPassword = data.getNewPassword(); - boolean result = this.update(new LambdaUpdateWrapper() - .eq(User::getId, userId) - .set(User::getPassword, passwordEncoder.encode(newPassword)) + boolean result = this.update(new LambdaUpdateWrapper() + .eq(SysUser::getId, userId) + .set(SysUser::getPassword, passwordEncoder.encode(newPassword)) ); if (result) { @@ -431,9 +426,9 @@ public class UserServiceImpl extends ServiceImpl implements Us */ @Override public boolean resetUserPassword(Long userId, String password) { - boolean result = this.update(new LambdaUpdateWrapper() - .eq(User::getId, userId) - .set(User::getPassword, passwordEncoder.encode(password)) + boolean result = this.update(new LambdaUpdateWrapper() + .eq(SysUser::getId, userId) + .set(SysUser::getPassword, passwordEncoder.encode(password)) ); if (result) { // 管理员重置用户密码后,使该用户的所有会话失效 @@ -452,9 +447,9 @@ public class UserServiceImpl extends ServiceImpl implements Us public boolean sendMobileCode(String mobile) { Long currentUserId = SecurityUtils.getUserId(); - long mobileCount = this.count(new LambdaQueryWrapper() - .eq(User::getMobile, mobile) - .ne(User::getId, currentUserId) + long mobileCount = this.count(new LambdaQueryWrapper() + .eq(SysUser::getMobile, mobile) + .ne(SysUser::getId, currentUserId) ); if (mobileCount > 0) { throw new BusinessException("手机号已被其他账号绑定"); @@ -485,7 +480,7 @@ public class UserServiceImpl extends ServiceImpl implements Us public boolean bindOrChangeMobile(MobileUpdateForm form) { Long currentUserId = SecurityUtils.getUserId(); - User currentUser = this.getById(currentUserId); + SysUser currentUser = this.getById(currentUserId); if (currentUser == null) { throw new BusinessException("用户不存在"); @@ -510,9 +505,9 @@ public class UserServiceImpl extends ServiceImpl implements Us throw new BusinessException("验证码错误"); } - long mobileCount = this.count(new LambdaQueryWrapper() - .eq(User::getMobile, mobile) - .ne(User::getId, currentUserId) + long mobileCount = this.count(new LambdaQueryWrapper() + .eq(SysUser::getMobile, mobile) + .ne(SysUser::getId, currentUserId) ); if (mobileCount > 0) { throw new BusinessException("手机号已被其他账号绑定"); @@ -522,9 +517,9 @@ public class UserServiceImpl extends ServiceImpl implements Us // 更新手机号码 return this.update( - new LambdaUpdateWrapper() - .eq(User::getId, currentUserId) - .set(User::getMobile, mobile) + new LambdaUpdateWrapper() + .eq(SysUser::getId, currentUserId) + .set(SysUser::getMobile, mobile) ); } @@ -537,9 +532,9 @@ public class UserServiceImpl extends ServiceImpl implements Us public void sendEmailCode(String email) { Long currentUserId = SecurityUtils.getUserId(); - long emailCount = this.count(new LambdaQueryWrapper() - .eq(User::getEmail, email) - .ne(User::getId, currentUserId) + long emailCount = this.count(new LambdaQueryWrapper() + .eq(SysUser::getEmail, email) + .ne(SysUser::getId, currentUserId) ); if (emailCount > 0) { throw new BusinessException("邮箱已被其他账号绑定"); @@ -566,7 +561,7 @@ public class UserServiceImpl extends ServiceImpl implements Us Long currentUserId = SecurityUtils.getUserId(); - User currentUser = this.getById(currentUserId); + SysUser currentUser = this.getById(currentUserId); if (currentUser == null) { throw new BusinessException("用户不存在"); } @@ -591,9 +586,9 @@ public class UserServiceImpl extends ServiceImpl implements Us throw new BusinessException("验证码错误"); } - long emailCount = this.count(new LambdaQueryWrapper() - .eq(User::getEmail, email) - .ne(User::getId, currentUserId) + long emailCount = this.count(new LambdaQueryWrapper() + .eq(SysUser::getEmail, email) + .ne(SysUser::getId, currentUserId) ); if (emailCount > 0) { throw new BusinessException("邮箱已被其他账号绑定"); @@ -603,9 +598,9 @@ public class UserServiceImpl extends ServiceImpl implements Us // 更新邮箱地址 return this.update( - new LambdaUpdateWrapper() - .eq(User::getId, currentUserId) - .set(User::getEmail, email) + new LambdaUpdateWrapper() + .eq(SysUser::getId, currentUserId) + .set(SysUser::getEmail, email) ); } @@ -619,7 +614,7 @@ public class UserServiceImpl extends ServiceImpl implements Us public boolean unbindMobile(PasswordVerifyForm form) { Long currentUserId = SecurityUtils.getUserId(); - User currentUser = this.getById(currentUserId); + SysUser currentUser = this.getById(currentUserId); if (currentUser == null) { throw new BusinessException("用户不存在"); @@ -633,9 +628,9 @@ public class UserServiceImpl extends ServiceImpl implements Us throw new BusinessException("当前密码错误"); } - return this.update(new LambdaUpdateWrapper() - .eq(User::getId, currentUserId) - .set(User::getMobile, null) + return this.update(new LambdaUpdateWrapper() + .eq(SysUser::getId, currentUserId) + .set(SysUser::getMobile, null) ); } @@ -649,7 +644,7 @@ public class UserServiceImpl extends ServiceImpl implements Us public boolean unbindEmail(PasswordVerifyForm form) { Long currentUserId = SecurityUtils.getUserId(); - User currentUser = this.getById(currentUserId); + SysUser currentUser = this.getById(currentUserId); if (currentUser == null) { throw new BusinessException("用户不存在"); @@ -663,9 +658,9 @@ public class UserServiceImpl extends ServiceImpl implements Us throw new BusinessException("当前密码错误"); } - return this.update(new LambdaUpdateWrapper() - .eq(User::getId, currentUserId) - .set(User::getEmail, null) + return this.update(new LambdaUpdateWrapper() + .eq(SysUser::getId, currentUserId) + .set(SysUser::getEmail, null) ); } @@ -676,8 +671,8 @@ public class UserServiceImpl extends ServiceImpl implements Us */ @Override public List> listUserOptions() { - List list = this.list(new LambdaQueryWrapper() - .eq(User::getStatus, 1) + List list = this.list(new LambdaQueryWrapper() + .eq(SysUser::getStatus, 1) ); return userConverter.toOptions(list); } diff --git a/src/main/java/com/youlai/boot/system/service/impl/UserSocialServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/UserSocialServiceImpl.java index 70d0c91e..f9a37c59 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/UserSocialServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/UserSocialServiceImpl.java @@ -3,7 +3,7 @@ package com.youlai.boot.system.service.impl; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.youlai.boot.security.model.UserAuthInfo; +import com.youlai.boot.framework.security.model.UserAuthInfo; import com.youlai.boot.system.enums.SocialPlatformEnum; import com.youlai.boot.system.mapper.UserSocialMapper; import com.youlai.boot.system.model.entity.UserSocial; diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index cdd5d77a..94128c64 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -85,8 +85,7 @@ security: - /api/v1/auth/sms/code # 发送登录短信验证码 - /api/v1/auth/refresh-token # 刷新令牌接口 - /api/v1/wechat/miniapp/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) - - /api/v1/statistics/** # 统计分析接口(访问趋势/访问概览) - - /ws/** # WebSocket接口 + - /api/v1/logs/** # 日志接口(访问日志列表) # 非安全端点路径,完全绕过 Spring Security 的过滤器 unsecured-urls: - ${springdoc.swagger-ui.path} @@ -157,8 +156,8 @@ springdoc: packages-to-scan: # 扫描的 Controller 包,限制只生成指定包的接口文档 - com.youlai.boot.auth.controller - com.youlai.boot.system.controller - - com.youlai.boot.file.controller - - com.youlai.boot.tool.codegen.controller + - com.youlai.boot.module.file.controller + - com.youlai.boot.module.codegen.controller default-flat-param-object: true # 将对象参数扁平化显示在文档中 # knife4j 配置 diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 3bd8d173..a9ebf76a 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -83,7 +83,7 @@ security: - /api/v1/auth/captcha # 验证码获取接口 - /api/v1/auth/refresh-token # 刷新令牌接口 - /api/v1/wechat/miniapp/auth/** # 微信小程序认证接口(静默登录/手机号快捷登录/绑定手机号) - - /ws/** # WebSocket接口 + - /api/v1/logs/** # 日志接口(访问日志列表) # 非安全端点路径,完全绕过 Spring Security 的过滤器 unsecured-urls: - ${springdoc.swagger-ui.path} @@ -154,8 +154,8 @@ springdoc: packages-to-scan: # 扫描的 Controller 包,限制只生成指定包的接口文档 - com.youlai.boot.auth.controller - com.youlai.boot.system.controller - - com.youlai.boot.file.controller - - com.youlai.boot.tool.codegen.controller + - com.youlai.boot.module.file.controller + - com.youlai.boot.module.codegen.controller default-flat-param-object: true # 将对象参数扁平化显示在文档中 # knife4j 配置 diff --git a/src/main/resources/mapper/system/LogMapper.xml b/src/main/resources/mapper/system/LogMapper.xml index cc00db1a..fce80aaf 100644 --- a/src/main/resources/mapper/system/LogMapper.xml +++ b/src/main/resources/mapper/system/LogMapper.xml @@ -10,26 +10,34 @@ SELECT t1.id, t1.module, + t1.action_type AS actionType, + t1.title, t1.content, - t1.request_uri, + t1.operator_id AS operatorId, + t1.operator_name AS operatorName, + t1.request_uri AS requestUri, + t1.request_method AS requestMethod, t1.ip, - CONCAT(t1.province," ", t1.city) AS region, - t1.execution_time, - CONCAT(t1.browser," ", t1.browser_version) AS browser, + CONCAT(t1.province, " ", t1.city) AS region, + t1.device, t1.os, - t1.create_time, - t2.nickname AS operator + t1.browser, + t1.status, + t1.execution_time AS executionTime, + t1.error_msg AS errorMsg, + t1.create_time AS createTime FROM sys_log t1 - LEFT JOIN sys_user t2 ON t1.create_by = t2.id AND ( + t1.title LIKE concat('%',#{queryParams.keywords},'%') + OR t1.content LIKE concat('%',#{queryParams.keywords},'%') OR t1.ip LIKE concat('%',#{queryParams.keywords},'%') OR - t2.nickname LIKE concat('%',#{queryParams.keywords},'%') + t1.operator_name LIKE concat('%',#{queryParams.keywords},'%') ) @@ -48,7 +56,7 @@ - SELECT COUNT(1) AS count, DATE_FORMAT(create_time,'%Y-%m-%d') AS date @@ -61,7 +69,7 @@ - SELECT COUNT(DISTINCT ip) AS count, DATE_FORMAT(create_time, '%Y-%m-%d') AS date @@ -74,10 +82,10 @@ - SELECT - COUNT(CASE WHEN DATE(create_time) = CURDATE() THEN 1 END) AS todayCount, - COUNT(*) AS totalCount, + COUNT(CASE WHEN DATE(create_time) = CURDATE() THEN 1 END) AS todayPvCount, + COUNT(*) AS totalPvCount, ROUND( CASE WHEN COUNT(CASE WHEN DATE(create_time) = CURDATE() - INTERVAL 1 DAY AND TIME(create_time) <= TIME(NOW()) THEN 1 END) = 0 THEN 0 @@ -86,16 +94,16 @@ COUNT(CASE WHEN DATE(create_time) = CURDATE() - INTERVAL 1 DAY AND TIME(create_time) <= TIME(NOW()) THEN 1 END)) / COUNT(CASE WHEN DATE(create_time) = CURDATE() - INTERVAL 1 DAY AND TIME(create_time) <= TIME(NOW()) THEN 1 END) END, - 2) AS growthRate + 2) AS pvGrowthRate FROM sys_log - SELECT - COUNT(DISTINCT CASE WHEN DATE(create_time) = CURDATE() THEN ip END) AS todayCount, - COUNT(DISTINCT ip) AS totalCount, + COUNT(DISTINCT CASE WHEN DATE(create_time) = CURDATE() THEN ip END) AS todayUvCount, + COUNT(DISTINCT ip) AS totalUvCount, ROUND( CASE WHEN COUNT(DISTINCT CASE WHEN DATE(create_time) = CURDATE() - INTERVAL 1 DAY AND TIME(create_time) <= TIME(NOW()) THEN ip END) = 0 THEN 0 @@ -104,9 +112,10 @@ COUNT(DISTINCT CASE WHEN DATE(create_time) = CURDATE() - INTERVAL 1 DAY AND TIME(create_time) <= TIME(NOW()) THEN ip END)) / COUNT(DISTINCT CASE WHEN DATE(create_time) = CURDATE() - INTERVAL 1 DAY AND TIME(create_time) <= TIME(NOW()) THEN ip END) END, - 2) AS growthRate + 2) AS uvGrowthRate FROM sys_log + diff --git a/src/main/resources/mapper/system/NoticeMapper.xml b/src/main/resources/mapper/system/NoticeMapper.xml index 3e25389f..29a8f997 100644 --- a/src/main/resources/mapper/system/NoticeMapper.xml +++ b/src/main/resources/mapper/system/NoticeMapper.xml @@ -3,7 +3,7 @@ - SELECT t1.id, t1.title, @@ -42,7 +42,7 @@ - SELECT t1.id, t1.title, diff --git a/src/main/resources/mapper/system/RoleMenuMapper.xml b/src/main/resources/mapper/system/RoleMenuMapper.xml index 75403b12..06723807 100644 --- a/src/main/resources/mapper/system/RoleMenuMapper.xml +++ b/src/main/resources/mapper/system/RoleMenuMapper.xml @@ -16,7 +16,7 @@ - + diff --git a/src/main/resources/mapper/system/UserMapper.xml b/src/main/resources/mapper/system/UserMapper.xml index 1f018609..64e155cf 100644 --- a/src/main/resources/mapper/system/UserMapper.xml +++ b/src/main/resources/mapper/system/UserMapper.xml @@ -6,7 +6,7 @@ - SELECT u.id, u.username, @@ -34,7 +34,7 @@ INNER JOIN sys_role r ON sur.role_id = r.id WHERE sur.user_id = u.id - AND r.code = '${@com.youlai.boot.common.constant.SystemConstants@ROOT_ROLE_CODE}' + AND r.code = '${@com.youlai.boot.shared.constant.SystemConstants@ROOT_ROLE_CODE}' ) AND ( @@ -118,7 +118,7 @@ - + @@ -165,7 +165,7 @@ - SELECT u.username, u.nickname, @@ -186,7 +186,7 @@ INNER JOIN sys_role r ON sur.role_id = r.id WHERE sur.user_id = u.id - AND r.code = '${@com.youlai.boot.common.constant.SystemConstants@ROOT_ROLE_CODE}' + AND r.code = '${@com.youlai.boot.shared.constant.SystemConstants@ROOT_ROLE_CODE}' ) AND (u.username LIKE CONCAT('%',#{keywords},'%') @@ -204,7 +204,7 @@ - SELECT u.id, u.username, diff --git a/src/main/resources/mapper/system/UserSocialMapper.xml b/src/main/resources/mapper/system/UserSocialMapper.xml index 2fb66fc7..abd7bd64 100644 --- a/src/main/resources/mapper/system/UserSocialMapper.xml +++ b/src/main/resources/mapper/system/UserSocialMapper.xml @@ -5,7 +5,7 @@ - +