From 06fa85a35356dd3bf8155e599022de9fa219867a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 27 Jan 2022 13:34:25 +0800 Subject: [PATCH] 多模块重构 1:将 yudao-user-server 涉及到 member 模块的逻辑,都迁移到 yudao-module-member 中 --- pom.xml | 4 +++- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/package-info.java | 6 ------ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 - yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/dataobject/user/MbrUserDO.java | 70 ---------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/mysql/user/MbrUserCoreMapper.java | 10 ---------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/package-info.java | 7 ------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/MbrUserCoreService.java | 19 ------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/impl/MbrUserCoreServiceImpl.java | 28 ---------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/tool/package-info.java | 7 ------- yudao-dependencies/pom.xml | 2 +- yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/AbstractSignUpUrlAuthenticationSuccessHandler.java | 53 ----------------------------------------------------- yudao-module-member/pom.xml | 24 ++++++++++++++++++++++++ yudao-module-member/yudao-module-member-api/pom.xml | 26 ++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java | 4 ++++ yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java | 20 ++++++++++++++++++++ yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java | 32 ++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/pom.xml | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http | 31 +++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java | 40 ++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java | 31 +++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java | 20 ++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java | 33 +++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindReqVO.java | 35 +++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLogin2ReqVO.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java | 35 +++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialUnbindReqVO.java | 31 +++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java | 30 ++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java | 27 +++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/package-info.java | 1 + yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.http | 11 +++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java | 20 ++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java | 47 +++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/package-info.java | 6 ++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java | 23 +++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/package-info.java | 6 ++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java | 14 ++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 + yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/sms/SysSmsCodeDO.java | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java | 29 +++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java | 19 +++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java | 7 +++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java | 1 + yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCodeConstants.java | 18 ++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/SysErrorCodeConstants.java | 32 ++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsSceneEnum.java | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsTemplateCodeConstants.java | 25 +++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/package-info.java | 6 ++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java | 29 +++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeConfiguration.java | 9 +++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeProperties.java | 43 +++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/package-info.java | 1 + yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java | 356 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java | 1 + yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java | 1 + yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/RedisTestConfiguration.java | 30 ++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml | 44 ++++++++++++++++++++++++++++++++++++++++++++ yudao-module-member/yudao-module-member-impl/src/test/resources/file/erweima.jpg | Bin 0 -> 18385 bytes yudao-module-member/yudao-module-member-impl/src/test/resources/logback-spring.xml | 4 ++++ yudao-module-member/yudao-module-member-impl/src/test/resources/sql/clean.sql | 2 ++ yudao-module-member/yudao-module-member-impl/src/test/resources/sql/create_tables.sql | 33 +++++++++++++++++++++++++++++++++ yudao-server/pom.xml | 22 ++++++++++++++++++++++ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/package-info.java | 6 ------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/security/SecurityConfiguration.java | 29 ----------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/package-info.java | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.http | 11 ----------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java | 73 ------------------------------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserInfoRespVO.java | 20 -------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java | 48 ------------------------------------------------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java | 6 ------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/user/UserProfileConvert.java | 15 --------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/dal/mysql/user/MbrUserMapper.java | 19 ------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java | 17 ----------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/package-info.java | 8 -------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/package-info.java | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java | 81 --------------------------------------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java | 161 ----------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http | 31 ------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java | 130 ---------------------------------------------------------------------------------------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java | 38 -------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialBindReqVO.java | 35 ----------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLogin2ReqVO.java | 49 ------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLoginReqVO.java | 35 ----------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialUnbindReqVO.java | 31 ------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthUpdatePasswordReqVO.java | 30 ------------------------------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java | 40 ---------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginReqVO.java | 31 ------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java | 20 -------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java | 27 --------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java | 33 --------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/package-info.java | 4 ---- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/auth/SysAuthConvert.java | 23 ----------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java | 6 ------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/package-info.java | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/sms/SysSmsCodeDO.java | 64 ---------------------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java | 28 ---------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/redis/package-info.java | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java | 32 -------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java | 54 ------------------------------------------------------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java | 25 ------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/package-info.java | 6 ------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeConfiguration.java | 9 --------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeProperties.java | 43 ------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/package-info.java | 7 ------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java | 78 ------------------------------------------------------------------------------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java | 355 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/package-info.java | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java | 52 ---------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java | 141 --------------------------------------------------------------------------------------------------------------------------------------------- yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbAndRedisUnitTest.java | 48 ------------------------------------------------ yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbUnitTest.java | 39 --------------------------------------- yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/config/RedisTestConfiguration.java | 30 ------------------------------ yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java | 152 -------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java | 127 ------------------------------------------------------------------------------------------------------------------------------- yudao-user-server/src/test/resources/application-unit-test.yaml | 44 -------------------------------------------- yudao-user-server/src/test/resources/file/erweima.jpg | Bin 18385 -> 0 bytes yudao-user-server/src/test/resources/logback-spring.xml | 4 ---- yudao-user-server/src/test/resources/sql/clean.sql | 2 -- yudao-user-server/src/test/resources/sql/create_tables.sql | 33 --------------------------------- 134 files changed, 2740 insertions(+), 2641 deletions(-) delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/package-info.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/dataobject/user/MbrUserDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/mysql/user/MbrUserCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/package-info.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/MbrUserCoreService.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/impl/MbrUserCoreServiceImpl.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/tool/package-info.java delete mode 100644 yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/AbstractSignUpUrlAuthenticationSuccessHandler.java create mode 100644 yudao-module-member/pom.xml create mode 100644 yudao-module-member/yudao-module-member-api/pom.xml create mode 100644 yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java create mode 100644 yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java create mode 100644 yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java create mode 100644 yudao-module-member/yudao-module-member-impl/pom.xml create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLogin2ReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialUnbindReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.http create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/sms/SysSmsCodeDO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCodeConstants.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/SysErrorCodeConstants.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsSceneEnum.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsTemplateCodeConstants.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeConfiguration.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeProperties.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/RedisTestConfiguration.java create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/resources/file/erweima.jpg create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/resources/logback-spring.xml create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/resources/sql/clean.sql create mode 100644 yudao-module-member/yudao-module-member-impl/src/test/resources/sql/create_tables.sql create mode 100644 yudao-server/pom.xml delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/security/SecurityConfiguration.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.http delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserInfoRespVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/user/UserProfileConvert.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/dal/mysql/user/MbrUserMapper.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialBindReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLogin2ReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLoginReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialUnbindReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthUpdatePasswordReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/auth/SysAuthConvert.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/sms/SysSmsCodeDO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/redis/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeConfiguration.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeProperties.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java delete mode 100644 yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbAndRedisUnitTest.java delete mode 100644 yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbUnitTest.java delete mode 100644 yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/config/RedisTestConfiguration.java delete mode 100644 yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java delete mode 100644 yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java delete mode 100644 yudao-user-server/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-user-server/src/test/resources/file/erweima.jpg delete mode 100644 yudao-user-server/src/test/resources/logback-spring.xml delete mode 100644 yudao-user-server/src/test/resources/sql/clean.sql delete mode 100644 yudao-user-server/src/test/resources/sql/create_tables.sql diff --git a/pom.xml b/pom.xml index 0f791a8..c76c9a2 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,8 @@ yudao-admin-server yudao-user-server yudao-core-service + yudao-module-member + yudao-server ${artifactId} @@ -20,7 +22,7 @@ https://github.com/YunaiV/ruoyi-vue-pro - 1.3.0-snapshot + 1.4.0-snapshot 1.8 ${java.version} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/package-info.java deleted file mode 100644 index 230bbc0..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 POJO 类的实体转换 - * - * 目前使用 MapStruct 框架 - */ -package cn.iocoder.yudao.coreservice.modules.member.convert; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md deleted file mode 100644 index 8153487..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/dataobject/user/MbrUserDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/dataobject/user/MbrUserDO.java deleted file mode 100644 index 02efd59..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/dataobject/user/MbrUserDO.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; - -import java.util.Date; - -/** - * 会员中心的用户 DO - * - * uk_mobile 索引:基于 {@link #mobile} 字段 - * - * @author 芋道源码 - */ -@TableName(value = "mbr_user", autoResultMap = true) -@Data -@EqualsAndHashCode(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class MbrUserDO extends TenantBaseDO { - - /** - * 用户ID - */ - @TableId - private Long id; - /** - * 用户昵称 - */ - private String nickname; - /** - * 用户头像 - */ - private String avatar; - /** - * 帐号状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - - /** - * 手机 - */ - private String mobile; - /** - * 加密后的密码 - * - * 因为目前使用 {@link BCryptPasswordEncoder} 加密器,所以无需自己处理 salt 盐 - */ - private String password; - /** - * 注册 IP - */ - private String registerIp; - /** - * 最后登录IP - */ - private String loginIp; - /** - * 最后登录时间 - */ - private Date loginDate; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/mysql/user/MbrUserCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/mysql/user/MbrUserCoreMapper.java deleted file mode 100644 index 27c0c95..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/dal/mysql/user/MbrUserCoreMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.member.dal.mysql.user; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface MbrUserCoreMapper extends BaseMapperX { - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/package-info.java deleted file mode 100644 index 17abe90..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * member 包下,我们放会员业务. - * 例如说:会员中心等等 - * - * 缩写:mbr - */ -package cn.iocoder.yudao.coreservice.modules.member; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/MbrUserCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/MbrUserCoreService.java deleted file mode 100644 index 9344139..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/MbrUserCoreService.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.member.service.user; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; - -/** - * 前台用户 Core Service 接口 - * - * @author 芋道源码 - */ -public interface MbrUserCoreService { - /** - * 通过用户 ID 查询用户 - * - * @param id 用户ID - * @return 用户对象信息 - */ - MbrUserDO getUser(Long id); - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/impl/MbrUserCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/impl/MbrUserCoreServiceImpl.java deleted file mode 100644 index 08ee22c..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/member/service/user/impl/MbrUserCoreServiceImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.member.service.user.impl; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.coreservice.modules.member.dal.mysql.user.MbrUserCoreMapper; -import cn.iocoder.yudao.coreservice.modules.member.service.user.MbrUserCoreService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; - -/** - * User Core Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Slf4j -public class MbrUserCoreServiceImpl implements MbrUserCoreService { - - @Resource - private MbrUserCoreMapper userCoreMapper; - - @Override - public MbrUserDO getUser(Long id) { - return userCoreMapper.selectById(id); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/tool/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/tool/package-info.java deleted file mode 100644 index dd3c3e9..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/tool/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * tool 包下,我们放研发工具,提升研发效率与质量。 - * 例如说:代码生成器、接口文档等等 - * - * 缩写:tool - */ -package cn.iocoder.yudao.coreservice.modules.tool; diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 5e05711..3973ed2 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -14,7 +14,7 @@ https://github.com/YunaiV/ruoyi-vue-pro - 1.3.0-snapshot + 1.4.0-snapshot 2.4.12 diff --git a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/AbstractSignUpUrlAuthenticationSuccessHandler.java b/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/AbstractSignUpUrlAuthenticationSuccessHandler.java deleted file mode 100644 index 01fdf08..0000000 --- a/yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/handler/AbstractSignUpUrlAuthenticationSuccessHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * MIT License - * Copyright (c) 2020-2029 YongWu zheng (dcenter.top and gitee.com/pcore and github.com/ZeroOrInfinity) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package cn.iocoder.yudao.framework.security.core.handler; - -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import org.springframework.security.web.savedrequest.HttpSessionRequestCache; -import org.springframework.security.web.savedrequest.RequestCache; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -/** - * @author weir - */ -public class AbstractSignUpUrlAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { - private RequestCache requestCache = new HttpSessionRequestCache(); - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - if (requestCache.getRequest(request, response) != null) { - requestCache.getRequest(request, response); - } - super.onAuthenticationSuccess(request,response,authentication); - } - - @Override - public void setRequestCache(RequestCache requestCache) { - this.requestCache = requestCache; - } -} diff --git a/yudao-module-member/pom.xml b/yudao-module-member/pom.xml new file mode 100644 index 0000000..cf15072 --- /dev/null +++ b/yudao-module-member/pom.xml @@ -0,0 +1,24 @@ + + + + cn.iocoder.boot + yudao + ${revision} + + 4.0.0 + + yudao-module-member-api + yudao-module-member-impl + + yudao-module-member + pom + + ${artifactId} + + member 模块,我们放会员业务。 + 例如说:会员中心等等 + + + diff --git a/yudao-module-member/yudao-module-member-api/pom.xml b/yudao-module-member/yudao-module-member-api/pom.xml new file mode 100644 index 0000000..914d910 --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/pom.xml @@ -0,0 +1,26 @@ + + + + cn.iocoder.boot + yudao-module-member + ${revision} + + 4.0.0 + yudao-module-member-api + jar + + ${artifactId} + + member 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java new file mode 100644 index 0000000..56cd985 --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/package-info.java @@ -0,0 +1,4 @@ +/** + * member API 包,定义暴露给其它模块的 API + */ +package cn.iocoder.yudao.module.member.api; diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java new file mode 100644 index 0000000..3ac616a --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.member.api.user; + +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; + +/** + * 会员用户的 API 接口 + * + * @author 芋道源码 + */ +public interface MemberUserApi { + + /** + * 获得会员用户信息 + * + * @param id 用户编号 + * @return 用户信息 + */ + MemberUserRespDTO getMemberUser(Long id); + +} diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java new file mode 100644 index 0000000..82eec95 --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/MemberUserRespDTO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.member.api.user.dto; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; + +/** + * 用户信息 Response DTO + * + * @author 芋道源码 + */ +public class MemberUserRespDTO { + + /** + * 用户ID + */ + private Long id; + /** + * 用户昵称 + */ + private String nickname; + /** + * 帐号状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + + /** + * 手机 + */ + private String mobile; + +} diff --git a/yudao-module-member/yudao-module-member-impl/pom.xml b/yudao-module-member/yudao-module-member-impl/pom.xml new file mode 100644 index 0000000..d4b064f --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/pom.xml @@ -0,0 +1,120 @@ + + + + cn.iocoder.boot + yudao-module-member + ${revision} + + 4.0.0 + yudao-module-member-impl + jar + + ${artifactId} + + member 模块,我们放会员业务。 + 例如说:会员中心等等 + + + + + + cn.iocoder.boot + yudao-core-service + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-dict + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-sms + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-weixin + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + cn.iocoder.boot + yudao-spring-boot-starter-redis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-config + + + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mq + + + + + cn.iocoder.boot + yudao-spring-boot-starter-protection + + + + + cn.iocoder.boot + yudao-spring-boot-starter-monitor + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + test + + + + + + + + ${artifactId} + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + repackage + + + + + + + + diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http new file mode 100644 index 0000000..c9caded --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http @@ -0,0 +1,31 @@ +### 请求 /login 接口 => 成功 +POST {{userServerUrl}}/login +Content-Type: application/json + +{ + "mobile": "15601691300", + "password": "admin123" +} + +### 请求 /send-sms-code 接口 => 成功 +POST {{userServerUrl}}/send-sms-code +Content-Type: application/json + +{ + "mobile": "15601691399", + "scene": 1 +} + +### 请求 /sms-login 接口 => 成功 +POST {{userServerUrl}}/sms-login +Content-Type: application/json + +{ + "mobile": "15601691301", + "code": 9999 +} + +### 请求 /logout 接口 => 成功 +POST {{userServerUrl}}/logout +Content-Type: application/json +Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66 diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java new file mode 100644 index 0000000..76437eb --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.member.controller.app.auth; + +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; +import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Api(tags = "APP 端 - 认证") +@RestController +@RequestMapping("/") +@Validated +@Slf4j +public class AppAuthController { + + @Resource + private SysAuthService authService; + @Resource + private SysSmsCodeService smsCodeService; + @Resource + private SysSocialCoreService socialService; + + @PostMapping("/login") + @ApiOperation("使用手机 + 密码登录") + public CommonResult login(@RequestBody @Valid AppAuthLoginReqVO reqVO) { + String token = authService.login(reqVO, getClientIP(), getUserAgent()); + // 返回结果 + return success(AppAuthLoginRespVO.builder().token(token).build()); + } + + @PostMapping("/sms-login") + @ApiOperation("使用手机 + 验证码登录") + public CommonResult smsLogin(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) { + String token = authService.smsLogin(reqVO, getClientIP(), getUserAgent()); + // 返回结果 + return success(AppAuthLoginRespVO.builder().token(token).build()); + } + + @PostMapping("/send-sms-code") + @ApiOperation(value = "发送手机验证码") + public CommonResult sendSmsCode(@RequestBody @Valid SysAuthSendSmsReqVO reqVO) { + smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); + return success(true); + } + + @GetMapping("/send-sms-code-login") + @ApiOperation(value = "向已登录用户发送验证码",notes = "修改手机时验证原手机号使用") + public CommonResult sendSmsCodeLogin() { + smsCodeService.sendSmsCodeLogin(getLoginUserId()); + return success(true); + } + + @PostMapping("/reset-password") + @ApiOperation(value = "重置密码", notes = "用户忘记密码时使用") + @PreAuthenticated + public CommonResult resetPassword(@RequestBody @Valid AppAuthResetPasswordReqVO reqVO) { + authService.resetPassword(reqVO); + return success(true); + } + + @PostMapping("/update-password") + @ApiOperation(value = "修改用户密码",notes = "用户修改密码时使用") + @PreAuthenticated + public CommonResult updatePassword(@RequestBody @Valid AppAuthUpdatePasswordReqVO reqVO) { + authService.updatePassword(getLoginUserId(), reqVO); + return success(true); + } + + // ========== 社交登录相关 ========== + + @GetMapping("/social-auth-redirect") + @ApiOperation("社交授权的跳转") + @ApiImplicitParams({ + @ApiImplicitParam(name = "type", value = "社交类型", required = true, dataTypeClass = Integer.class), + @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) + }) + public CommonResult socialAuthRedirect(@RequestParam("type") Integer type, + @RequestParam("redirectUri") String redirectUri) { + return CommonResult.success(socialService.getAuthorizeUrl(type, redirectUri)); + } + + @PostMapping("/social-login") + @ApiOperation("社交登录,使用 code 授权码") + public CommonResult socialLogin(@RequestBody @Valid AppAuthSocialLoginReqVO reqVO) { + String token = authService.socialLogin(reqVO, getClientIP(), getUserAgent()); + return success(AppAuthLoginRespVO.builder().token(token).build()); + } + + @PostMapping("/social-login2") + @ApiOperation("社交登录,使用 手机号 + 手机验证码") + public CommonResult socialLogin2(@RequestBody @Valid AppAuthSocialLogin2ReqVO reqVO) { + String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent()); + return success(AppAuthLoginRespVO.builder().token(token).build()); + } + + @PostMapping("/social-bind") + @ApiOperation("社交绑定,使用 code 授权码") + public CommonResult socialBind(@RequestBody @Valid AppAuthSocialBindReqVO reqVO) { + authService.socialBind(getLoginUserId(), reqVO); + return CommonResult.success(true); + } + + @DeleteMapping("/social-unbind") + @ApiOperation("取消社交绑定") + public CommonResult socialUnbind(@RequestBody AppAuthSocialUnbindReqVO reqVO) { + socialService.unbindSocialUser(getLoginUserId(), reqVO.getType(), reqVO.getUnionId(), UserTypeEnum.MEMBER); + return CommonResult.success(true); + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java new file mode 100644 index 0000000..64cc22a --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +@ApiModel("APP 端 - 校验验证码 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthCheckCodeReqVO { + + @ApiModelProperty(value = "手机号", example = "15601691234") + @NotBlank(message = "手机号不能为空") + @Mobile + private String mobile; + + @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @NotBlank(message = "手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String code; + + @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 MbrSmsSceneEnum 枚举") + @NotNull(message = "发送场景不能为空") + @InEnum(SysSmsSceneEnum.class) + private Integer scene; +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java new file mode 100644 index 0000000..25875fd --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.framework.common.validation.Mobile; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; + +@ApiModel("APP 端 - 手机 + 密码登录 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthLoginReqVO { + + @ApiModelProperty(value = "手机号", required = true, example = "15601691300") + @NotEmpty(message = "手机号不能为空") + @Mobile + private String mobile; + + @ApiModelProperty(value = "密码", required = true, example = "buzhidao") + @NotEmpty(message = "密码不能为空") + @Length(min = 4, max = 16, message = "密码长度为 4-16 位") + private String password; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java new file mode 100644 index 0000000..935b3ec --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@ApiModel("APP 端 - 手机密码登录 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthLoginRespVO { + + @ApiModelProperty(value = "token", required = true, example = "yudaoyuanma") + private String token; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java new file mode 100644 index 0000000..5ae291f --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.framework.common.validation.Mobile; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +@ApiModel("APP 端 - 重置密码 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthResetPasswordReqVO { + + @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") + @NotEmpty(message = "新密码不能为空") + @Length(min = 4, max = 16, message = "密码长度为 4-16 位") + private String password; + + @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @NotEmpty(message = "手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String code; + + @ApiModelProperty(value = "手机号",required = true,example = "15878962356") + @NotBlank(message = "手机号不能为空") + @Mobile + private String mobile; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java new file mode 100644 index 0000000..452e7e8 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.framework.common.validation.Mobile; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +@ApiModel("APP 端 - 手机 + 验证码登录 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthSmsLoginReqVO { + + @ApiModelProperty(value = "手机号", required = true, example = "15601691300") + @NotEmpty(message = "手机号不能为空") + @Mobile + private String mobile; + + @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @NotEmpty(message = "手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String code; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindReqVO.java new file mode 100644 index 0000000..d595e74 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindReqVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@ApiModel("APP 端 - 社交绑定 Request VO,使用 code 授权码") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthSocialBindReqVO { + + @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @InEnum(SysSocialTypeEnum.class) + @NotNull(message = "社交平台的类型不能为空") + private Integer type; + + @ApiModelProperty(value = "授权码", required = true, example = "1024") + @NotEmpty(message = "授权码不能为空") + private String code; + + @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @NotEmpty(message = "state 不能为空") + private String state; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLogin2ReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLogin2ReqVO.java new file mode 100644 index 0000000..cc832e3 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLogin2ReqVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +@ApiModel("APP 端 - 社交登录 Request VO,使用 code 授权码 + 账号密码") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthSocialLogin2ReqVO { + + @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @InEnum(SysSocialTypeEnum.class) + @NotNull(message = "社交平台的类型不能为空") + private Integer type; + + @ApiModelProperty(value = "授权码", required = true, example = "1024") + @NotEmpty(message = "授权码不能为空") + private String code; + + @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @NotEmpty(message = "state 不能为空") + private String state; + + @ApiModelProperty(value = "手机号", required = true, example = "15119100000") + @NotEmpty(message = "手机号不能为空") + @Length(min = 11, max = 11, message = "手机号是11位数字") + private String mobile; + + @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @NotEmpty(message = "手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String smsCode; + + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java new file mode 100644 index 0000000..3d15625 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@ApiModel("APP 端 - 社交登录 Request VO,使用 code 授权码") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthSocialLoginReqVO { + + @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @InEnum(SysSocialTypeEnum.class) + @NotNull(message = "社交平台的类型不能为空") + private Integer type; + + @ApiModelProperty(value = "授权码", required = true, example = "1024") + @NotEmpty(message = "授权码不能为空") + private String code; + + @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @NotEmpty(message = "state 不能为空") + private String state; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialUnbindReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialUnbindReqVO.java new file mode 100644 index 0000000..9225080 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialUnbindReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@ApiModel("APP 端 - 取消社交绑定 Request VO,使用 code 授权码") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthSocialUnbindReqVO { + + @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @InEnum(SysSocialTypeEnum.class) + @NotNull(message = "社交平台的类型不能为空") + private Integer type; + + @ApiModelProperty(value = "社交的全局编号", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") + @NotEmpty(message = "社交的全局编号不能为空") + private String unionId; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java new file mode 100644 index 0000000..cbbd17f --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; + +@ApiModel("APP 端 - 修改密码 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppAuthUpdatePasswordReqVO { + + @ApiModelProperty(value = "用户旧密码", required = true, example = "123456") + @NotBlank(message = "旧密码不能为空") + @Length(min = 4, max = 16, message = "密码长度为 4-16 位") + private String oldPassword; + + @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") + @NotEmpty(message = "新密码不能为空") + @Length(min = 4, max = 16, message = "密码长度为 4-16 位") + private String password; +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java new file mode 100644 index 0000000..7a7620d --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppSendSmsReqVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotNull; + +@ApiModel("APP 端 - 发送手机验证码 Response VO") +@Data +@Accessors(chain = true) +public class AppSendSmsReqVO { + + @ApiModelProperty(value = "手机号", example = "15601691234") + @Mobile + private String mobile; + + @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 MbrSmsSceneEnum 枚举") + @NotNull(message = "发送场景不能为空") + @InEnum(SysSmsSceneEnum.class) + private Integer scene; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/package-info.java new file mode 100644 index 0000000..7f013ea --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.controller.app; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.http b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.http new file mode 100644 index 0000000..26bd55a --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.http @@ -0,0 +1,11 @@ +### 请求 /member/user/profile/get 接口 => 没有权限 +GET {{userServerUrl}}/member/user/profile/get +Authorization: Bearer test245 + +### 请求 /member/user/profile/revise-nickname 接口 成功 +PUT {{userServerUrl}}/member/user/profile/update-nickname?nickName=yunai222 +Authorization: Bearer test245 + +### 请求 /member/user/profile/get-user-info 接口 成功 +GET {{userServerUrl}}/member/user/profile/get-user-info?id=245 +Authorization: Bearer test245 diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java new file mode 100644 index 0000000..758eb7b --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java @@ -0,0 +1,73 @@ +package cn.iocoder.yudao.module.member.controller.app.user; + +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import java.io.IOException; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.FILE_IS_EMPTY; + +@Api(tags = "APP 端 - 用户个人中心") +@RestController +@RequestMapping("/member/user") +@Validated +@Slf4j +public class AppUserController { + + @Resource + private MbrUserService userService; + + @PutMapping("/update-nickname") + @ApiOperation("修改用户昵称") + @PreAuthenticated + public CommonResult updateNickname(@RequestParam("nickname") String nickname) { + userService.updateNickname(getLoginUserId(), nickname); + return success(true); + } + + @PutMapping("/update-avatar") + @ApiOperation("修改用户头像") + @PreAuthenticated + public CommonResult updateAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException { + if (file.isEmpty()) { + throw ServiceExceptionUtil.exception(MbrErrorCodeConstants.FILE_IS_EMPTY); + } + String avatar = userService.updateAvatar(getLoginUserId(), file.getInputStream()); + return success(avatar); + } + + @GetMapping("/get") + @ApiOperation("获得基本信息") + @PreAuthenticated + public CommonResult getUserInfo() { + return success(userService.getUserInfo(getLoginUserId())); + } + + @PostMapping("/update-mobile") + @ApiOperation(value = "修改用户手机") + @PreAuthenticated + public CommonResult updateMobile(@RequestBody @Valid MbrUserUpdateMobileReqVO reqVO) { + userService.updateMobile(getLoginUserId(), reqVO); + return success(true); + } + +} + diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java new file mode 100644 index 0000000..f8d9d20 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.member.controller.app.user.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@ApiModel("APP 端 - 用户个人信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AppUserInfoRespVO { + + @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + private String nickname; + + @ApiModelProperty(value = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952") + private String avatar; +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java new file mode 100644 index 0000000..fe91566 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.member.controller.app.user.vo; + +import cn.iocoder.yudao.framework.common.validation.Mobile; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +@ApiModel("APP 端 - 修改手机 Request VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppUserUpdateMobileReqVO { + + @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @NotEmpty(message = "手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String code; + + @ApiModelProperty(value = "手机号",required = true,example = "15823654487") + @NotBlank(message = "手机号不能为空") + @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") + @Mobile + private String mobile; + + @ApiModelProperty(value = "原手机验证码", required = true, example = "1024") + @NotEmpty(message = "原手机验证码不能为空") + @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") + @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") + private String oldCode; + + @ApiModelProperty(value = "原手机号",required = true,example = "15823654487") + @NotBlank(message = "手机号不能为空") + @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") + @Mobile + private String oldMobile; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/package-info.java new file mode 100644 index 0000000..ea9687d --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/controller/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 RESTful API 给前端: + * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目 + * 2. app 包:提供给用户 APP yudao-ui-app 前端项目 + */ +package cn.iocoder.yudao.module.member.controller; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java new file mode 100644 index 0000000..df9a353 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/auth/SysAuthConvert.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.member.convert.auth; + +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.security.core.LoginUser; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SysAuthConvert { + + SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class); + + @Mapping(source = "mobile", target = "username") + LoginUser convert0(MbrUserDO bean); + + default LoginUser convert(MbrUserDO bean) { + // 目的,为了设置 UserTypeEnum.MEMBER.getValue() + return convert0(bean).setUserType(UserTypeEnum.MEMBER.getValue()); + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/package-info.java new file mode 100644 index 0000000..6523a66 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 POJO 类的实体转换 + * + * 目前使用 MapStruct 框架 + */ +package cn.iocoder.yudao.module.member.convert; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java new file mode 100644 index 0000000..139b6ef --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.member.convert.user; + +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface UserConvert { + + UserConvert INSTANCE = Mappers.getMapper(UserConvert.class); + + AppUserInfoRespVO convert(MemberUserDO bean); + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md new file mode 100644 index 0000000..8153487 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md @@ -0,0 +1 @@ + diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/sms/SysSmsCodeDO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/sms/SysSmsCodeDO.java new file mode 100644 index 0000000..eb51770 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/sms/SysSmsCodeDO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.member.dal.dataobject.sms; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.util.Date; + +/** + * 手机验证码 DO + * + * idx_mobile 索引:基于 {@link #mobile} 字段 + * + * @author 芋道源码 + */ +@TableName("sys_sms_code") +@Data +@EqualsAndHashCode(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SysSmsCodeDO extends BaseDO { + + /** + * 编号 + */ + private Integer id; + /** + * 手机号 + */ + private String mobile; + /** + * 验证码 + */ + private String code; + /** + * 发送场景 + * + * 枚举 {@link SysSmsCodeDO} + */ + private Integer scene; + /** + * 创建 IP + */ + private String createIp; + /** + * 今日发送的第几条 + */ + private Integer todayIndex; + /** + * 是否使用 + */ + private Boolean used; + /** + * 使用时间 + */ + private Date usedTime; + /** + * 使用 IP + */ + private String usedIp; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java new file mode 100644 index 0000000..0b77f4e --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.member.dal.dataobject.user; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +import java.util.Date; + +/** + * 会员中心的用户 DO + * + * uk_mobile 索引:基于 {@link #mobile} 字段 + * + * @author 芋道源码 + */ +@TableName(value = "member_user", autoResultMap = true) +@Data +@EqualsAndHashCode(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MemberUserDO extends TenantBaseDO { + + /** + * 用户ID + */ + @TableId + private Long id; + /** + * 用户昵称 + */ + private String nickname; + /** + * 用户头像 + */ + private String avatar; + /** + * 帐号状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + + /** + * 手机 + */ + private String mobile; + /** + * 加密后的密码 + * + * 因为目前使用 {@link BCryptPasswordEncoder} 加密器,所以无需自己处理 salt 盐 + */ + private String password; + /** + * 注册 IP + */ + private String registerIp; + /** + * 最后登录IP + */ + private String loginIp; + /** + * 最后登录时间 + */ + private Date loginDate; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java new file mode 100644 index 0000000..8007911 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/sms/SysSmsCodeMapper.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.member.dal.mysql.sms; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; +import cn.iocoder.yudao.module.member.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; +import org.apache.ibatis.annotations.Mapper; + +// TODO @芋艿: +@Mapper +public interface SysSmsCodeMapper extends BaseMapperX { + + /** + * 获得手机号的最后一个手机验证码 + * + * @param mobile 手机号 + * @param scene 发送场景,选填 + * @param code 验证码 选填 + * @return 手机验证码 + */ + default SysSmsCodeDO selectLastByMobile(String mobile,String code,Integer scene) { + return selectOne(new QueryWrapperX() + .eq("mobile", mobile) + .eqIfPresent("scene", scene) + .eqIfPresent("code", code) + .orderByDesc("id") + .last("LIMIT 1")); + } +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java new file mode 100644 index 0000000..49b6a9f --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MbrUserMapper.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.member.dal.mysql.user; + +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import org.apache.ibatis.annotations.Mapper; + +/** + * MbrUserDO Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface MbrUserMapper extends BaseMapperX { + + default MbrUserDO selectByMobile(String mobile) { + return selectOne(MbrUserDO::getMobile, mobile); + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java new file mode 100644 index 0000000..06c6545 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/package-info.java @@ -0,0 +1,7 @@ +/** + * DAL = Data Access Layer 数据访问层 + * 1. data object:数据对象 + * 2. redis:Redis 的 CRUD 操作 + * 3. mysql:MySQL 的 CRUD 操作 + */ +package cn.iocoder.yudao.module.member.dal; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java new file mode 100644 index 0000000..f5d6e64 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/dal/redis/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.dal.redis; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCodeConstants.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCodeConstants.java new file mode 100644 index 0000000..4ee545b --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/MemberErrorCodeConstants.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.member.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * Member 错误码枚举类 + * + * member 系统,使用 1-004-000-000 段 + */ +public interface MemberErrorCodeConstants { + + // ==========用户相关 1004001000============ + ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在"); + + // ==========文件相关 1004002000 =========== + ErrorCode FILE_IS_EMPTY = new ErrorCode(1004002000, "文件为空"); + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/SysErrorCodeConstants.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/SysErrorCodeConstants.java new file mode 100644 index 0000000..b1b23a3 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/SysErrorCodeConstants.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.member.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * System 错误码枚举类 + * + * system 系统,使用 1-005-000-000 段 + */ +public interface SysErrorCodeConstants { + + // ========== AUTH 模块 1005000000 ========== + ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1005000000, "登录失败,账号密码不正确"); + ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); + ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 + ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1005000003, "Token 已经过期"); + ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1005000004, "未绑定账号,需要进行绑定"); + + // ========== SMS CODE 模块 1005001000 ========== + ErrorCode USER_SMS_CODE_NOT_FOUND = new ErrorCode(1005001000, "验证码不存在"); + ErrorCode USER_SMS_CODE_EXPIRED = new ErrorCode(1005001001, "验证码已过期"); + ErrorCode USER_SMS_CODE_USED = new ErrorCode(1005001002, "验证码已使用"); + ErrorCode USER_SMS_CODE_NOT_CORRECT = new ErrorCode(1005001003, "验证码不正确"); + ErrorCode USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1005001004, "超过每日短信发送数量"); + ErrorCode USER_SMS_CODE_SEND_TOO_FAST = new ErrorCode(1005001005, "短信发送过于频率"); + ErrorCode USER_SMS_CODE_IS_EXISTS = new ErrorCode(1005001006, "手机号已被使用"); + ErrorCode USER_SMS_CODE_IS_UNUSED = new ErrorCode(1005001006, "验证码未被使用"); + + // ========== 用户模块 1005002000 ========== + ErrorCode USER_NOT_EXISTS = new ErrorCode(1005002001, "用户不存在"); + ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1005002003, "密码校验失败"); +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsSceneEnum.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsSceneEnum.java new file mode 100644 index 0000000..a471901 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsSceneEnum.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.member.enums.sms; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 用户短信验证码发送场景的枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum SysSmsSceneEnum implements IntArrayValuable { + + LOGIN_BY_SMS(1,SysSmsTemplateCodeConstants.USER_SMS_LOGIN, "手机号登陆"), + CHANGE_MOBILE_BY_SMS(2,SysSmsTemplateCodeConstants.USER_SMS_UPDATE_MOBILE, "更换手机号"), + FORGET_MOBILE_BY_SMS(3,SysSmsTemplateCodeConstants.USER_SMS_RESET_PASSWORD, "忘记密码"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysSmsSceneEnum::getScene).toArray(); + + /** + * 验证那场景编号 + */ + private final Integer scene; + + /** + * 模版编码 + */ + private final String code; + + /** + * 描述 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + + public static String getCodeByScene(Integer scene){ + for (SysSmsSceneEnum value : values()) { + if (value.getScene().equals(scene)){ + return value.getCode(); + } + } + return null; + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsTemplateCodeConstants.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsTemplateCodeConstants.java new file mode 100644 index 0000000..3ad8439 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/enums/sms/SysSmsTemplateCodeConstants.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.member.enums.sms; + +/** + * yudao-user-server 使用到的短信模板的 Code 编码的枚举 + * + * @author 芋道源码 + */ +public interface SysSmsTemplateCodeConstants { + + /** + * 前台用户短信登录 + */ + String USER_SMS_LOGIN = "user-sms-login"; + + /** + * 用户忘记密码 + */ + String USER_SMS_RESET_PASSWORD = "user-sms-reset-password"; + + /** + * 用户更新手机号 + */ + String USER_SMS_UPDATE_MOBILE = "user-sms-update-mobile"; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/package-info.java new file mode 100644 index 0000000..7342570 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/package-info.java @@ -0,0 +1,6 @@ +/** + * 属于 yudao-module-member-impl 的封装 + * + * @author 芋道源码 + */ +package cn.iocoder.yudao.module.member.framework; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java new file mode 100644 index 0000000..32368f8 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/security/SecurityConfiguration.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.member.framework.security; + +import cn.iocoder.yudao.framework.web.config.WebProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; + +import javax.annotation.Resource; + +@Configuration +public class SecurityConfiguration { + + @Resource + private WebProperties webProperties; + + @Bean + public Customizer.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() { + return registry -> { + registry.antMatchers(api("/**")).permitAll(); // 默认 API 都是用户可访问 + }; + } + + private String api(String url) { + return webProperties.getApiPrefix() + url; + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeConfiguration.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeConfiguration.java new file mode 100644 index 0000000..fa74188 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeConfiguration.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.member.framework.sms; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(SmsCodeProperties.class) +public class SmsCodeConfiguration { +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeProperties.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeProperties.java new file mode 100644 index 0000000..542fe2d --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/framework/sms/SmsCodeProperties.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.member.framework.sms; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.time.Duration; +import java.util.Collection; + +@ConfigurationProperties(prefix = "yudao.sms-code") +@Validated +@Data +public class SmsCodeProperties { + + /** + * 过期时间 + */ + @NotNull(message = "过期时间不能为空") + private Duration expireTimes; + /** + * 短信发送频率 + */ + @NotNull(message = "短信发送频率不能为空") + private Duration sendFrequency; + /** + * 每日发送最大数量 + */ + @NotNull(message = "每日发送最大数量不能为空") + private Integer sendMaximumQuantityPerDay; + /** + * 验证码最小值 + */ + @NotNull(message = "验证码最小值不能为空") + private Integer beginCode; + /** + * 验证码最大值 + */ + @NotNull(message = "验证码最大值不能为空") + private Integer endCode; + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/package-info.java new file mode 100644 index 0000000..dabac6a --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java new file mode 100644 index 0000000..a864e1e --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthService.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.member.service.auth; + +import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; +import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; + +import javax.validation.Valid; + +/** + * 用户前台的认证 Service 接口 + * + * 提供用户的账号密码登录、token 的校验等认证相关的功能 + * + * @author 芋道源码 + */ +public interface SysAuthService extends SecurityAuthFrameworkService { + + /** + * 手机 + 密码登录 + * + * @param reqVO 登录信息 + * @param userIp 用户 IP + * @param userAgent 用户 UA + * @return 身份令牌,使用 JWT 方式 + */ + String login(@Valid SysAuthLoginReqVO reqVO, String userIp, String userAgent); + + /** + * 手机 + 验证码登陆 + * + * @param reqVO 登陆信息 + * @param userIp 用户 IP + * @param userAgent 用户 UA + * @return 身份令牌,使用 JWT 方式 + */ + String smsLogin(@Valid SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent); + + + /** + * 社交登录,使用 code 授权码 + * + * @param reqVO 登录信息 + * @param userIp 用户 IP + * @param userAgent 用户 UA + * @return 身份令牌,使用 JWT 方式 + */ + String socialLogin(@Valid MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent); + + /** + * 社交登录,使用 手机号 + 手机验证码 + * + * @param reqVO 登录信息 + * @param userIp 用户 IP + * @param userAgent 用户 UA + * @return 身份令牌,使用 JWT 方式 + */ + String socialLogin2(@Valid MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent); + + /** + * 社交绑定,使用 code 授权码 + * + * @param userId 用户编号 + * @param reqVO 绑定信息 + */ + void socialBind(Long userId, @Valid MbrAuthSocialBindReqVO reqVO); + + /** + * 修改用户密码 + * @param userId 用户id + * @param userReqVO 用户请求实体类 + */ + void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO userReqVO); + + /** + * 忘记密码 + * @param userReqVO 用户请求实体类 + */ + void resetPassword(MbrAuthResetPasswordReqVO userReqVO); +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java new file mode 100644 index 0000000..fd68cff --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceImpl.java @@ -0,0 +1,356 @@ +package cn.iocoder.yudao.module.member.service.auth; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO; +import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginLogTypeEnum; +import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginResultEnum; +import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; +import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; +import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; +import cn.iocoder.yudao.framework.security.core.LoginUser; +import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; +import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; +import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; +import cn.iocoder.yudao.userserver.modules.system.convert.auth.SysAuthConvert; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import com.google.common.annotations.VisibleForTesting; +import lombok.extern.slf4j.Slf4j; +import me.zhyd.oauth.model.AuthUser; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.*; + +/** + * Auth Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Slf4j +public class SysAuthServiceImpl implements SysAuthService { + + private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; + + @Resource + @Lazy // 延迟加载,因为存在相互依赖的问题 + private AuthenticationManager authenticationManager; + + @Resource + private MbrUserService userService; + @Resource + private SysSmsCodeService smsCodeService; + @Resource + private SysLoginLogCoreService loginLogCoreService; + @Resource + private SysUserSessionCoreService userSessionCoreService; + @Resource + private SysSocialCoreService socialService; + + @Resource + private StringRedisTemplate stringRedisTemplate; + @Resource + private PasswordEncoder passwordEncoder; + @Resource + private MbrUserMapper userMapper; + + private static final UserTypeEnum userTypeEnum = UserTypeEnum.MEMBER; + + @Override + public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { + // 获取 username 对应的 SysUserDO + MbrUserDO user = userService.getUserByMobile(mobile); + if (user == null) { + throw new UsernameNotFoundException(mobile); + } + // 创建 LoginUser 对象 + return SysAuthConvert.INSTANCE.convert(user); + } + + @Override + public String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent) { + // 使用手机 + 密码,进行登录。 + LoginUser loginUser = this.login0(reqVO.getMobile(), reqVO.getPassword()); + + // 缓存登录用户到 Redis 中,返回 sessionId 编号 + return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); + } + + @Override + @Transactional + public String smsLogin(SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent) { + // 校验验证码 + smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.LOGIN_BY_SMS.getScene(), + reqVO.getCode(), userIp); + + // 获得获得注册用户 + MbrUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp); + Assert.notNull(user, "获取用户失败,结果为空"); + + // 执行登陆 + this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SMS, SysLoginResultEnum.SUCCESS); + LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); + + // 缓存登录用户到 Redis 中,返回 sessionId 编号 + return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); + } + + @Override + public String socialLogin(MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent) { + // 使用 code 授权码,进行登录 + AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); + org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); + + // 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错 + String unionId = socialService.getAuthUserUnionId(authUser); + List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM); + if (CollUtil.isEmpty(socialUsers)) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_THIRD_LOGIN_NOT_BIND); + } + + // 自动登录 + MbrUserDO user = userService.getUser(socialUsers.get(0).getUserId()); + if (user == null) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + } + this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SOCIAL, SysLoginResultEnum.SUCCESS); + + // 创建 LoginUser 对象 + LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); + + // 绑定社交用户(更新) + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); + + // 缓存登录用户到 Redis 中,返回 sessionId 编号 + return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); + } + + @Override + public String socialLogin2(MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent) { + AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); + org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); + + // 使用手机号、手机验证码登录 + SysAuthSmsLoginReqVO loginReqVO = SysAuthSmsLoginReqVO + .builder() + .mobile(reqVO.getMobile()) + .code(reqVO.getSmsCode()) + .build(); + String sessionId = this.smsLogin(loginReqVO, userIp, userAgent); + LoginUser loginUser = userSessionCoreService.getLoginUser(sessionId); + + // 绑定社交用户(新增) + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); + return sessionId; + } + + @Override + public void socialBind(Long userId, MbrAuthSocialBindReqVO reqVO) { + // 使用 code 授权码,进行登录 + AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); + org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); + + // 绑定社交用户(新增) + socialService.bindSocialUser(userId, reqVO.getType(), authUser, USER_TYPE_ENUM); + } + + private LoginUser login0(String username, String password) { + final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; + // 用户验证 + Authentication authentication; + try { + // 调用 Spring Security 的 AuthenticationManager#authenticate(...) 方法,使用账号密码进行认证 + // 在其内部,会调用到 loadUserByUsername 方法,获取 User 信息 + authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); + } catch (BadCredentialsException badCredentialsException) { + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.BAD_CREDENTIALS); + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_LOGIN_BAD_CREDENTIALS); + } catch (DisabledException disabledException) { + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.USER_DISABLED); + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_LOGIN_USER_DISABLED); + } catch (AuthenticationException authenticationException) { + log.error("[login0][username({}) 发生未知异常]", username, authenticationException); + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.UNKNOWN_ERROR); + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_LOGIN_FAIL_UNKNOWN); + } + // 登录成功的日志 + Assert.notNull(authentication.getPrincipal(), "Principal 不会为空"); + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.SUCCESS); + return (LoginUser) authentication.getPrincipal(); + } + + private void createLoginLog(String mobile, SysLoginLogTypeEnum logTypeEnum, SysLoginResultEnum loginResult) { + // 获得用户 + MbrUserDO user = userService.getUserByMobile(mobile); + // 插入登录日志 + SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); + reqDTO.setLogType(logTypeEnum.getType()); + reqDTO.setTraceId(TracerUtils.getTraceId()); + if (user != null) { + reqDTO.setUserId(user.getId()); + } + reqDTO.setUsername(mobile); + reqDTO.setUserAgent(ServletUtils.getUserAgent()); + reqDTO.setUserIp(getClientIP()); + reqDTO.setResult(loginResult.getResult()); + loginLogCoreService.createLoginLog(reqDTO); + // 更新最后登录时间 + if (user != null && Objects.equals(SysLoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) { + userService.updateUserLogin(user.getId(), getClientIP()); + } + } + + @Override + public LoginUser verifyTokenAndRefresh(String token) { + // 获得 LoginUser + LoginUser loginUser = userSessionCoreService.getLoginUser(token); + if (loginUser == null) { + return null; + } + // 刷新 LoginUser 缓存 + this.refreshLoginUserCache(token, loginUser); + return loginUser; + } + + private void refreshLoginUserCache(String token, LoginUser loginUser) { + // 每 1/3 的 Session 超时时间,刷新 LoginUser 缓存 + if (System.currentTimeMillis() - loginUser.getUpdateTime().getTime() < + userSessionCoreService.getSessionTimeoutMillis() / 3) { + return; + } + + // 重新加载 MbrUserDO 信息 + MbrUserDO user = userService.getUser(loginUser.getId()); + if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.AUTH_TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 + } + + // 刷新 LoginUser 缓存 + userSessionCoreService.refreshUserSession(token, loginUser); + } + + @Override + public LoginUser mockLogin(Long userId) { + // 获取用户编号对应的 MbrUserDO + MbrUserDO user = userService.getUser(userId); + if (user == null) { + throw new UsernameNotFoundException(String.valueOf(userId)); + } + + // 执行登陆 + this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_MOCK, SysLoginResultEnum.SUCCESS); + + // 创建 LoginUser 对象 + return SysAuthConvert.INSTANCE.convert(user); + } + + @Override + public void logout(String token) { + // 查询用户信息 + LoginUser loginUser = userSessionCoreService.getLoginUser(token); + if (loginUser == null) { + return; + } + // 删除 session + userSessionCoreService.deleteUserSession(token); + // 记录登出日志 + this.createLogoutLog(loginUser.getId(), loginUser.getUsername()); + } + + @Override + public void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO reqVO) { + // 检验旧密码 + MbrUserDO userDO = checkOldPassword(userId, reqVO.getOldPassword()); + + // 更新用户密码 + MbrUserDO mbrUserDO = MbrUserDO.builder().build(); + mbrUserDO.setId(userDO.getId()); + mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); + userMapper.updateById(mbrUserDO); + } + + @Override + public void resetPassword(MbrAuthResetPasswordReqVO reqVO) { + // 检验用户是否存在 + MbrUserDO userDO = checkUserIfExists(reqVO.getMobile()); + + // 使用验证码 + smsCodeService.useSmsCode(reqVO.getMobile(),SysSmsSceneEnum.FORGET_MOBILE_BY_SMS.getScene(),reqVO.getCode(),getClientIP()); + + // 更新密码 + MbrUserDO mbrUserDO = MbrUserDO.builder().build(); + mbrUserDO.setId(userDO.getId()); + mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); + userMapper.updateById(mbrUserDO); + } + + /** + * 校验旧密码 + * + * @param id 用户 id + * @param oldPassword 旧密码 + * @return MbrUserDO 用户实体 + */ + @VisibleForTesting + public MbrUserDO checkOldPassword(Long id, String oldPassword) { + MbrUserDO user = userMapper.selectById(id); + if (user == null) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + } + // 参数:未加密密码,编码后的密码 + if (!passwordEncoder.matches(oldPassword,user.getPassword())) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_PASSWORD_FAILED); + } + return user; + } + + public MbrUserDO checkUserIfExists(String mobile) { + MbrUserDO user = userMapper.selectByMobile(mobile); + if (user == null) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + } + return user; + } + + + private void createLogoutLog(Long userId, String username) { + SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); + reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); + reqDTO.setTraceId(TracerUtils.getTraceId()); + reqDTO.setUserId(userId); + reqDTO.setUserType(USER_TYPE_ENUM.getValue()); + reqDTO.setUsername(username); + reqDTO.setUserAgent(ServletUtils.getUserAgent()); + reqDTO.setUserIp(getClientIP()); + reqDTO.setResult(SysLoginResultEnum.SUCCESS.getResult()); + loginLogCoreService.createLoginLog(reqDTO); + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java new file mode 100644 index 0000000..6223e6e --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.service; diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java new file mode 100644 index 0000000..8f0eaf6 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeService.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.member.service.sms; + +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; + +/** + * 短信验证码 Service 接口 + * + * @author 芋道源码 + */ +public interface SysSmsCodeService { + + /** + * 创建短信验证码,并进行发送 + * + * @param mobile 手机号 + * @param scene 发送场景 {@link SysSmsSceneEnum} + * @param createIp 发送 IP + */ + void sendSmsCode(@Mobile String mobile, Integer scene, String createIp); + + /** + * 验证短信验证码,并进行使用 + * 如果正确,则将验证码标记成已使用 + * 如果错误,则抛出 {@link ServiceException} 异常 + * + * @param mobile 手机号 + * @param scene 发送场景 + * @param code 验证码 + * @param usedIp 使用 IP + */ + void useSmsCode(@Mobile String mobile, Integer scene, String code, String usedIp); + + /** + * 根据用户id发送验证码 + * + * @param userId 用户id + */ + void sendSmsCodeLogin(Long userId); + + + /** + * 检查验证码是否有效 + * @param mobile 手机 + * @param code 验证码 + * @param scene 使用场景 + * @return 验证码记录 + */ + SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene); +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java new file mode 100644 index 0000000..43b7a17 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/sms/SysSmsCodeServiceImpl.java @@ -0,0 +1,142 @@ +package cn.iocoder.yudao.module.member.service.sms; + +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms.SysSmsCodeMapper; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.userserver.modules.system.framework.sms.SmsCodeProperties; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Date; + +import static cn.hutool.core.util.RandomUtil.randomInt; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.*; + +/** + * 短信验证码 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class SysSmsCodeServiceImpl implements SysSmsCodeService { + + @Resource + private SmsCodeProperties smsCodeProperties; + + @Resource + private SysSmsCodeMapper smsCodeMapper; + + @Resource + private MbrUserService mbrUserService; + + @Resource + private SysSmsCoreService smsCoreService; + + @Override + public void sendSmsCode(String mobile, Integer scene, String createIp) { + // 创建验证码 + String code = this.createSmsCode(mobile, scene, createIp); + + // 获取发送模板 + String codeTemplate = SysSmsSceneEnum.getCodeByScene(scene); + + // 如果是更换手机号发送验证码,则需要检测手机号是否被注册 + if (SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene().equals(scene)){ + this.checkMobileIsRegister(mobile,scene); + } + + // 发送验证码 + smsCoreService.sendSingleSmsToMember(mobile, null, codeTemplate, + MapUtil.of("code", code)); + } + + public void checkMobileIsRegister(String mobile, Integer scene) { + // 检测手机号是否已被使用 + MbrUserDO userByMobile = mbrUserService.getUserByMobile(mobile); + if (userByMobile != null){ + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_IS_EXISTS); + } + + // 发送短信 + this.sendSmsCode(mobile,scene,getClientIP()); + } + + private String createSmsCode(String mobile, Integer scene, String ip) { + // 校验是否可以发送验证码,不用筛选场景 + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null,null); + if (lastSmsCode != null) { + if (lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。 + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); + } + if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() + < smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁 + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_SEND_TOO_FAST); + } + // TODO 芋艿:提升,每个 IP 每天可发送数量 + // TODO 芋艿:提升,每个 IP 每小时可发送数量 + } + + // 创建验证码记录 + String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1)); + SysSmsCodeDO newSmsCode = SysSmsCodeDO.builder().mobile(mobile).code(code) + .scene(scene).todayIndex(lastSmsCode != null ? lastSmsCode.getTodayIndex() + 1 : 1) + .createIp(ip).used(false).build(); + smsCodeMapper.insert(newSmsCode); + return code; + } + + @Override + public void useSmsCode(String mobile, Integer scene, String code, String usedIp) { + + // 检测验证码是否有效 + SysSmsCodeDO lastSmsCode = this.checkCodeIsExpired(mobile, code, scene); + + // 判断验证码是否已被使用 + if (Boolean.TRUE.equals(lastSmsCode.getUsed())) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_USED); + } + + // 使用验证码 + smsCodeMapper.updateById(SysSmsCodeDO.builder().id(lastSmsCode.getId()) + .used(true).usedTime(new Date()).usedIp(usedIp).build()); + } + + @Override + public void sendSmsCodeLogin(Long userId) { + MbrUserDO user = mbrUserService.getUser(userId); + if (user == null){ + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_NOT_EXISTS); + } + // 发送验证码 + this.sendSmsCode(user.getMobile(),SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), getClientIP()); + } + + @Override + public SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene) { + // 校验验证码 + SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile,code,scene); + + // 若验证码不存在,抛出异常 + if (lastSmsCode == null) { + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_NOT_FOUND); + } + if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() + >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_EXPIRED); + } + + return lastSmsCode; + + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java new file mode 100644 index 0000000..be02945 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserService.java @@ -0,0 +1,81 @@ +package cn.iocoder.yudao.module.member.service.user; + +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; +import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; + +import java.io.InputStream; + +/** + * 前台用户 Service 接口 + * + * @author 芋道源码 + */ +public interface MbrUserService { + + /** + * 通过手机查询用户 + * + * @param mobile 手机 + * @return 用户对象 + */ + MbrUserDO getUserByMobile(String mobile); + + /** + * 基于手机号创建用户。 + * 如果用户已经存在,则直接进行返回 + * + * @param mobile 手机号 + * @param registerIp 注册 IP + * @return 用户对象 + */ + MbrUserDO createUserIfAbsent(@Mobile String mobile, String registerIp); + + /** + * 更新用户的最后登陆信息 + * + * @param id 用户编号 + * @param loginIp 登陆 IP + */ + void updateUserLogin(Long id, String loginIp); + + /** + * 通过用户 ID 查询用户 + * + * @param id 用户ID + * @return 用户对象信息 + */ + MbrUserDO getUser(Long id); + + /** + * 修改用户昵称 + * @param userId 用户id + * @param nickname 用户新昵称 + */ + void updateNickname(Long userId, String nickname); + + /** + * 修改用户头像 + * @param userId 用户id + * @param inputStream 头像文件 + * @return 头像url + */ + String updateAvatar(Long userId, InputStream inputStream); + + /** + * 根据用户id,获取用户头像与昵称 + * + * @param userId 用户id + * @return 用户响应实体类 + */ + MbrUserInfoRespVO getUserInfo(Long userId); + + /** + * 修改手机 + * @param userId 用户id + * @param reqVO 请求实体 + */ + void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO); + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java new file mode 100644 index 0000000..de53135 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/main/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImpl.java @@ -0,0 +1,162 @@ +package cn.iocoder.yudao.module.member.service.user; + +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.IdUtil; +import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService; +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; +import cn.iocoder.yudao.userserver.modules.member.convert.user.UserProfileConvert; +import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; +import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import com.google.common.annotations.VisibleForTesting; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.io.InputStream; +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.USER_NOT_EXISTS; +import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED; + +/** + * User Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Valid +@Slf4j +public class MbrUserServiceImpl implements MbrUserService { + + @Resource + private MbrUserMapper userMapper; + + @Resource + private InfFileCoreService fileCoreService; + + @Resource + private PasswordEncoder passwordEncoder; + + @Resource + private SysSmsCodeService smsCodeService; + + + @Override + public MbrUserDO getUserByMobile(String mobile) { + return userMapper.selectByMobile(mobile); + } + + @Override + public MbrUserDO createUserIfAbsent(String mobile, String registerIp) { + // 用户已经存在 + MbrUserDO user = userMapper.selectByMobile(mobile); + if (user != null) { + return user; + } + // 用户不存在,则进行创建 + return this.createUser(mobile, registerIp); + } + + private MbrUserDO createUser(String mobile, String registerIp) { + // 生成密码 + String password = IdUtil.fastSimpleUUID(); + // 插入用户 + MbrUserDO user = new MbrUserDO(); + user.setMobile(mobile); + user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 + user.setPassword(passwordEncoder.encode(password)); // 加密密码 + user.setRegisterIp(registerIp); + userMapper.insert(user); + return user; + } + + @Override + public void updateUserLogin(Long id, String loginIp) { + userMapper.updateById(new MbrUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); + } + + @Override + public MbrUserDO getUser(Long id) { + return userMapper.selectById(id); + } + + @Override + public void updateNickname(Long userId, String nickname) { + MbrUserDO user = this.checkUserExists(userId); + // 仅当新昵称不等于旧昵称时进行修改 + if (nickname.equals(user.getNickname())){ + return; + } + MbrUserDO userDO = new MbrUserDO(); + userDO.setId(user.getId()); + userDO.setNickname(nickname); + userMapper.updateById(userDO); + } + + @Override + public String updateAvatar(Long userId, InputStream avatarFile) { + this.checkUserExists(userId); + // 创建文件 + String avatar = fileCoreService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile)); + // 更新头像路径 + MbrUserDO userDO = MbrUserDO.builder() + .id(userId) + .avatar(avatar) + .build(); + userMapper.updateById(userDO); + return avatar; + } + + @Override + public MbrUserInfoRespVO getUserInfo(Long userId) { + MbrUserDO user = this.checkUserExists(userId); + // 拼接返回结果 + return UserProfileConvert.INSTANCE.convert(user); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO) { + // 检测用户是否存在 + checkUserExists(userId); + + // 校验旧手机和旧验证码 + SysSmsCodeDO sysSmsCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); + // 判断旧code是否未被使用,如果是,抛出异常 + if (Boolean.FALSE.equals(sysSmsCodeDO.getUsed())){ + throw ServiceExceptionUtil.exception(SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED); + } + + // 使用新验证码 + smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); + + // 更新用户手机 + MbrUserDO userDO = MbrUserDO.builder().id(userId).mobile(reqVO.getMobile()).build(); + userMapper.updateById(userDO); + } + + @VisibleForTesting + public MbrUserDO checkUserExists(Long id) { + if (id == null) { + return null; + } + MbrUserDO user = userMapper.selectById(id); + if (user == null) { + throw exception(USER_NOT_EXISTS); + }else{ + return user; + } + } +} diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java new file mode 100644 index 0000000..ff1c8a7 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/auth/SysAuthServiceTest.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.member.service.auth; + +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; +import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; +import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; +import cn.iocoder.yudao.userserver.BaseDbAndRedisUnitTest; +import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; +import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; +import cn.iocoder.yudao.module.member.controller.app.auth.vo.MbrAuthResetPasswordReqVO; +import cn.iocoder.yudao.module.member.controller.app.auth.vo.MbrAuthUpdatePasswordReqVO; +import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; +import cn.iocoder.yudao.userserver.modules.system.service.auth.impl.SysAuthServiceImpl; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.crypto.password.PasswordEncoder; + +import javax.annotation.Resource; +import java.util.function.Consumer; + +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.hutool.core.util.RandomUtil.randomNumbers; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +// TODO @芋艿:单测的 review,等逻辑都达成一致后 +/** + * {@link SysAuthService} 的单元测试类 + * + * @author 宋天 + */ +@Import({SysAuthServiceImpl.class, YudaoRedisAutoConfiguration.class}) +public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { + + @MockBean + private AuthenticationManager authenticationManager; + @MockBean + private MbrUserService userService; + @MockBean + private SysSmsCodeService smsCodeService; + @MockBean + private SysLoginLogCoreService loginLogCoreService; + @MockBean + private SysUserSessionCoreService userSessionCoreService; + @MockBean + private SysSocialCoreService socialService; + @Resource + private StringRedisTemplate stringRedisTemplate; + @MockBean + private PasswordEncoder passwordEncoder; + @Resource + private MbrUserMapper mbrUserMapper; + @Resource + private SysAuthServiceImpl authService; + + @Test + public void testUpdatePassword_success(){ + // 准备参数 + MbrUserDO userDO = randomMbrUserDO(); + mbrUserMapper.insert(userDO); + + // 新密码 + String newPassword = randomString(); + + // 请求实体 + MbrAuthUpdatePasswordReqVO reqVO = MbrAuthUpdatePasswordReqVO.builder() + .oldPassword(userDO.getPassword()) + .password(newPassword) + .build(); + + // 测试桩 + // 这两个相等是为了返回ture这个结果 + when(passwordEncoder.matches(reqVO.getOldPassword(),reqVO.getOldPassword())).thenReturn(true); + when(passwordEncoder.encode(newPassword)).thenReturn(newPassword); + + // 更新用户密码 + authService.updatePassword(userDO.getId(),reqVO); + assertEquals(mbrUserMapper.selectById(userDO.getId()).getPassword(),newPassword); + } + + @Test + public void testResetPassword_success(){ + // 准备参数 + MbrUserDO userDO = randomMbrUserDO(); + mbrUserMapper.insert(userDO); + + // 随机密码 + String password = randomNumbers(11); + // 随机验证码 + String code = randomNumbers(4); + + // mock + when(passwordEncoder.encode(password)).thenReturn(password); + + // 更新用户密码 + MbrAuthResetPasswordReqVO reqVO = new MbrAuthResetPasswordReqVO(); + reqVO.setMobile(userDO.getMobile()); + reqVO.setPassword(password); + reqVO.setCode(code); + + authService.resetPassword(reqVO); + assertEquals(mbrUserMapper.selectById(userDO.getId()).getPassword(),password); + } + + + // ========== 随机对象 ========== + + @SafeVarargs + private static MbrUserDO randomMbrUserDO(Consumer... consumers) { + Consumer consumer = (o) -> { + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 + o.setPassword(randomString()); + }; + return randomPojo(MbrUserDO.class, ArrayUtils.append(consumer, consumers)); + } + + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java new file mode 100644 index 0000000..6223e6e --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.member.service; diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java new file mode 100644 index 0000000..ecd728e --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/service/user/MbrUserServiceImplTest.java @@ -0,0 +1,152 @@ +package cn.iocoder.yudao.module.member.service.user; + +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService; +import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; +import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; +import cn.iocoder.yudao.userserver.BaseDbAndRedisUnitTest; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; +import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; +import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; +import cn.iocoder.yudao.userserver.modules.member.service.user.impl.MbrUserServiceImpl; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; +import cn.iocoder.yudao.userserver.modules.system.service.auth.impl.SysAuthServiceImpl; +import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.security.crypto.password.PasswordEncoder; + +import javax.annotation.Resource; +import java.io.ByteArrayInputStream; +import java.util.function.Consumer; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; +import static cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +// TODO @芋艿:单测的 review,等逻辑都达成一致后 +/** + * {@link MbrUserServiceImpl} 的单元测试类 + * + * @author 宋天 + */ +@Import({MbrUserServiceImpl.class, YudaoRedisAutoConfiguration.class}) +public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { + + @Resource + private MbrUserServiceImpl mbrUserService; + + @Resource + private StringRedisTemplate stringRedisTemplate; + + @Resource + private MbrUserMapper userMapper; + + @MockBean + private SysAuthServiceImpl authService; + + @MockBean + private InfFileCoreService fileCoreService; + + @MockBean + private PasswordEncoder passwordEncoder; + + @MockBean + private SysSmsCodeService sysSmsCodeService; + + @Test + public void testUpdateNickName_success(){ + // mock 数据 + MbrUserDO userDO = randomMbrUserDO(); + userMapper.insert(userDO); + + // 随机昵称 + String newNickName = randomString(); + + // 调用接口修改昵称 + mbrUserService.updateNickname(userDO.getId(),newNickName); + // 查询新修改后的昵称 + String nickname = mbrUserService.getUser(userDO.getId()).getNickname(); + // 断言 + assertEquals(newNickName,nickname); + } + + @Test + public void testGetUserInfo_success(){ + // mock 数据 + MbrUserDO userDO = randomMbrUserDO(); + userMapper.insert(userDO); + + // 查询用户昵称与头像 + MbrUserInfoRespVO userInfo = mbrUserService.getUserInfo(userDO.getId()); + System.out.println(userInfo); + } + + @Test + public void testUpdateAvatar_success(){ + // mock 数据 + MbrUserDO dbUser = randomMbrUserDO(); + userMapper.insert(dbUser); + + // 准备参数 + Long userId = dbUser.getId(); + byte[] avatarFileBytes = randomBytes(10); + ByteArrayInputStream avatarFile = new ByteArrayInputStream(avatarFileBytes); + // mock 方法 + String avatar = randomString(); + when(fileCoreService.createFile(anyString(), eq(avatarFileBytes))).thenReturn(avatar); + // 调用 + String str = mbrUserService.updateAvatar(userId, avatarFile); + // 断言 + assertEquals(avatar, str); + } + + @Test + public void updateMobile_success(){ + // mock数据 + String oldMobile = randomNumbers(11); + MbrUserDO userDO = randomMbrUserDO(); + userDO.setMobile(oldMobile); + userMapper.insert(userDO); + + + // 旧手机和旧验证码 + SysSmsCodeDO codeDO = new SysSmsCodeDO(); + String oldCode = RandomUtil.randomString(4); + codeDO.setMobile(userDO.getMobile()); + codeDO.setCode(oldCode); + codeDO.setScene(SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); + codeDO.setUsed(Boolean.FALSE); + when(sysSmsCodeService.checkCodeIsExpired(codeDO.getMobile(),codeDO.getCode(),codeDO.getScene())).thenReturn(codeDO); + + // 更新手机号 + String newMobile = randomNumbers(11); + String newCode = randomNumbers(4); + MbrUserUpdateMobileReqVO reqVO = new MbrUserUpdateMobileReqVO(); + reqVO.setMobile(newMobile); + reqVO.setCode(newCode); + reqVO.setOldMobile(oldMobile); + reqVO.setOldCode(oldCode); + mbrUserService.updateMobile(userDO.getId(),reqVO); + + assertEquals(mbrUserService.getUser(userDO.getId()).getMobile(),newMobile); + } + + // ========== 随机对象 ========== + + @SafeVarargs + private static MbrUserDO randomMbrUserDO(Consumer... consumers) { + Consumer consumer = (o) -> { + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 + }; + return randomPojo(MbrUserDO.class, ArrayUtils.append(consumer, consumers)); + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java new file mode 100644 index 0000000..50d19ad --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbAndRedisUnitTest.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.member.test; + +import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; +import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; +import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; +import cn.iocoder.yudao.userserver.config.RedisTestConfiguration; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; +import org.redisson.spring.starter.RedissonAutoConfiguration; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; + +/** + * 依赖内存 DB + Redis 的单元测试 + * + * 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis + * + * @author 芋道源码 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class) +@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 +@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB +public class BaseDbAndRedisUnitTest { + + @Import({ + // DB 配置类 + YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 + DataSourceAutoConfiguration.class, // Spring DB 自动配置类 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 + DruidDataSourceAutoConfigure.class, // Druid 自动配置类 + // MyBatis 配置类 + YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 + MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 + // Redis 配置类 + RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer + RedisAutoConfiguration.class, // Spring Redis 自动配置类 + YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类 + RedissonAutoConfiguration.class, // Redisson 自动高配置类 + }) + public static class Application { + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java new file mode 100644 index 0000000..901d896 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/BaseDbUnitTest.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.member.test; + +import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; +import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; + +/** + * 依赖内存 DB 的单元测试 + * + * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法 + * + * @author 芋道源码 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class) +@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 +@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB +public class BaseDbUnitTest { + + @Import({ + // DB 配置类 + YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 + DataSourceAutoConfiguration.class, // Spring DB 自动配置类 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 + DruidDataSourceAutoConfigure.class, // Druid 自动配置类 + // MyBatis 配置类 + YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 + MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 + }) + public static class Application { + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/RedisTestConfiguration.java b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/RedisTestConfiguration.java new file mode 100644 index 0000000..9983833 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/java/cn/iocoder/yudao/module/member/test/RedisTestConfiguration.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.member.test; + +import com.github.fppt.jedismock.RedisServer; +import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; + +import java.io.IOException; + +@Configuration(proxyBeanMethods = false) +@Lazy(false) // 禁止延迟加载 +@EnableConfigurationProperties(RedisProperties.class) +public class RedisTestConfiguration { + + /** + * 创建模拟的 Redis Server 服务器 + */ + @Bean + public RedisServer redisServer(RedisProperties properties) throws IOException { + RedisServer redisServer = new RedisServer(properties.getPort()); + // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。 + try { + redisServer.start(); + } catch (Exception ignore) {} + return redisServer; + } + +} diff --git a/yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml b/yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml new file mode 100644 index 0000000..d306a7a --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/resources/application-unit-test.yaml @@ -0,0 +1,44 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + schema: classpath:sql/create_tables.sql # MySQL 转 H2 的语句,使用 https://www.jooq.org/translate/ 工具 + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +# Resilience4j 配置项 + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 diff --git a/yudao-module-member/yudao-module-member-impl/src/test/resources/file/erweima.jpg b/yudao-module-member/yudao-module-member-impl/src/test/resources/file/erweima.jpg new file mode 100644 index 0000000..1447283 Binary files /dev/null and b/yudao-module-member/yudao-module-member-impl/src/test/resources/file/erweima.jpg differ diff --git a/yudao-module-member/yudao-module-member-impl/src/test/resources/logback-spring.xml b/yudao-module-member/yudao-module-member-impl/src/test/resources/logback-spring.xml new file mode 100644 index 0000000..daf756b --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/resources/logback-spring.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-member/yudao-module-member-impl/src/test/resources/sql/clean.sql b/yudao-module-member/yudao-module-member-impl/src/test/resources/sql/clean.sql new file mode 100644 index 0000000..bedf8d0 --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/resources/sql/clean.sql @@ -0,0 +1,2 @@ +-- mbr 开头的 DB +DELETE FROM "mbr_user"; \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-impl/src/test/resources/sql/create_tables.sql b/yudao-module-member/yudao-module-member-impl/src/test/resources/sql/create_tables.sql new file mode 100644 index 0000000..c9dfd8c --- /dev/null +++ b/yudao-module-member/yudao-module-member-impl/src/test/resources/sql/create_tables.sql @@ -0,0 +1,33 @@ +-- mbr 开头的 DB +CREATE TABLE IF NOT EXISTS "mbr_user" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号', + "nickname" varchar(30) NOT NULL DEFAULT '' COMMENT '用户昵称', + "avatar" varchar(255) NOT NULL DEFAULT '' COMMENT '头像', + "status" tinyint NOT NULL COMMENT '状态', + "mobile" varchar(11) NOT NULL COMMENT '手机号', + "password" varchar(100) NOT NULL DEFAULT '' COMMENT '密码', + "register_ip" varchar(32) NOT NULL COMMENT '注册 IP', + "login_ip" varchar(50) NULL DEFAULT '' COMMENT '最后登录IP', + "login_date" datetime NULL DEFAULT NULL COMMENT '最后登录时间', + "creator" varchar(64) NULL DEFAULT '' COMMENT '创建者', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + "updater" varchar(64) NULL DEFAULT '' COMMENT '更新者', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + "deleted" bit(1) NOT NULL DEFAULT '0' COMMENT '是否删除', + "tenant_id" bigint not null default '0', + PRIMARY KEY ("id") +) COMMENT '会员表'; + +-- inf 开头的 DB +CREATE TABLE IF NOT EXISTS "inf_file" ( + "id" varchar(188) NOT NULL, + "type" varchar(63) DEFAULT NULL, + "content" blob NOT NULL, + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '文件表'; + diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml new file mode 100644 index 0000000..0040513 --- /dev/null +++ b/yudao-server/pom.xml @@ -0,0 +1,22 @@ + + + + yudao + cn.iocoder.boot + ${revision} + + 4.0.0 + + yudao-server + jar + + ${artifactId} + + 后端 Server 的主项目,通过引入需要 yudao-module-xxx 的依赖, + 从而实现提供 RESTful API 给 yudao-ui-admin、yudao-ui-user 等前端项目。 + 本质上来说,它就是个空壳(容器)! + + + diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/package-info.java deleted file mode 100644 index db25ed2..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 属于整个 yudao-user-server 的 framework 封装 - * - * @author 芋道源码 - */ -package cn.iocoder.yudao.userserver.framework; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/security/SecurityConfiguration.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/security/SecurityConfiguration.java deleted file mode 100644 index 66a0ae7..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/security/SecurityConfiguration.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.userserver.framework.security; - -import cn.iocoder.yudao.framework.web.config.WebProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.Customizer; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; - -import javax.annotation.Resource; - -@Configuration -public class SecurityConfiguration { - - @Resource - private WebProperties webProperties; - - @Bean - public Customizer.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() { - return registry -> { - registry.antMatchers(api("/**")).permitAll(); // 默认 API 都是用户可访问 - }; - } - - private String api(String url) { - return webProperties.getApiPrefix() + url; - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/package-info.java deleted file mode 100644 index 148c73c..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.controller; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.http b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.http deleted file mode 100644 index 26bd55a..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.http +++ /dev/null @@ -1,11 +0,0 @@ -### 请求 /member/user/profile/get 接口 => 没有权限 -GET {{userServerUrl}}/member/user/profile/get -Authorization: Bearer test245 - -### 请求 /member/user/profile/revise-nickname 接口 成功 -PUT {{userServerUrl}}/member/user/profile/update-nickname?nickName=yunai222 -Authorization: Bearer test245 - -### 请求 /member/user/profile/get-user-info 接口 成功 -GET {{userServerUrl}}/member/user/profile/get-user-info?id=245 -Authorization: Bearer test245 diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java deleted file mode 100644 index 8fd7578..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java +++ /dev/null @@ -1,73 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.controller.user; - -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import java.io.IOException; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.FILE_IS_EMPTY; - -@Api(tags = "用户个人中心") -@RestController -@RequestMapping("/member/user/profile") -@Validated -@Slf4j -public class SysUserProfileController { - - @Resource - private MbrUserService userService; - - @PutMapping("/update-nickname") - @ApiOperation("修改用户昵称") - @PreAuthenticated - public CommonResult updateNickname(@RequestParam("nickname") String nickname) { - userService.updateNickname(getLoginUserId(), nickname); - return success(true); - } - - @PutMapping("/update-avatar") - @ApiOperation("修改用户头像") - @PreAuthenticated - public CommonResult updateAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException { - if (file.isEmpty()) { - throw ServiceExceptionUtil.exception(FILE_IS_EMPTY); - } - String avatar = userService.updateAvatar(getLoginUserId(), file.getInputStream()); - return success(avatar); - } - - @GetMapping("/get") - @ApiOperation("获得基本信息") - @PreAuthenticated - public CommonResult getUserInfo() { - return success(userService.getUserInfo(getLoginUserId())); - } - - @PostMapping("/update-mobile") - @ApiOperation(value = "修改用户手机") - @PreAuthenticated - public CommonResult updateMobile(@RequestBody @Valid MbrUserUpdateMobileReqVO reqVO) { - userService.updateMobile(getLoginUserId(), reqVO); - return success(true); - } - -} - diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserInfoRespVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserInfoRespVO.java deleted file mode 100644 index 697c408..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserInfoRespVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.controller.user.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@ApiModel("用户个人信息 Response VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class MbrUserInfoRespVO { - - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") - private String nickname; - - @ApiModelProperty(value = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952") - private String avatar; -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java deleted file mode 100644 index 8593302..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/vo/MbrUserUpdateMobileReqVO.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.controller.user.vo; - -import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Pattern; - -@ApiModel("修改手机 Request VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MbrUserUpdateMobileReqVO { - - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") - @NotEmpty(message = "手机验证码不能为空") - @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") - @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") - private String code; - - @ApiModelProperty(value = "手机号",required = true,example = "15823654487") - @NotBlank(message = "手机号不能为空") - @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") - @Mobile - private String mobile; - - @ApiModelProperty(value = "原手机验证码", required = true, example = "1024") - @NotEmpty(message = "原手机验证码不能为空") - @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") - @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") - private String oldCode; - - @ApiModelProperty(value = "原手机号",required = true,example = "15823654487") - @NotBlank(message = "手机号不能为空") - @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") - @Mobile - private String oldMobile; - - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java deleted file mode 100644 index 5877b74..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 POJO 类的实体转换 - * - * 目前使用 MapStruct 框架 - */ -package cn.iocoder.yudao.userserver.modules.member.convert; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/user/UserProfileConvert.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/user/UserProfileConvert.java deleted file mode 100644 index 6f9d166..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/user/UserProfileConvert.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.convert.user; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface UserProfileConvert { - - UserProfileConvert INSTANCE = Mappers.getMapper(UserProfileConvert.class); - - MbrUserInfoRespVO convert(MbrUserDO bean); - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md deleted file mode 100644 index 8153487..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/dal/mysql/user/MbrUserMapper.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/dal/mysql/user/MbrUserMapper.java deleted file mode 100644 index 6abb5dd..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/dal/mysql/user/MbrUserMapper.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.dal.mysql.user; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -/** - * MbrUserDO Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface MbrUserMapper extends BaseMapperX { - - default MbrUserDO selectByMobile(String mobile) { - return selectOne(MbrUserDO::getMobile, mobile); - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java deleted file mode 100644 index 3794eb0..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * Member 错误码枚举类 - * - * member 系统,使用 1-004-000-000 段 - */ -public interface MbrErrorCodeConstants { - - // ==========用户相关 1004001000============ - ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在"); - - // ==========文件相关 1004002000 =========== - ErrorCode FILE_IS_EMPTY = new ErrorCode(1004002000, "文件为空"); -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/package-info.java deleted file mode 100644 index 2334d44..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * weixin 包下,我们放微信相关业务. - * 例如说:微信公众号、等等 - * ps:微信支付,还是放在 pay 包下 - * - * 缩写:wx - */ -package cn.iocoder.yudao.userserver.modules.member; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/package-info.java deleted file mode 100644 index b12c642..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.service; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java deleted file mode 100644 index e33978b..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java +++ /dev/null @@ -1,81 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.service.user; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; - -import java.io.InputStream; - -/** - * 前台用户 Service 接口 - * - * @author 芋道源码 - */ -public interface MbrUserService { - - /** - * 通过手机查询用户 - * - * @param mobile 手机 - * @return 用户对象 - */ - MbrUserDO getUserByMobile(String mobile); - - /** - * 基于手机号创建用户。 - * 如果用户已经存在,则直接进行返回 - * - * @param mobile 手机号 - * @param registerIp 注册 IP - * @return 用户对象 - */ - MbrUserDO createUserIfAbsent(@Mobile String mobile, String registerIp); - - /** - * 更新用户的最后登陆信息 - * - * @param id 用户编号 - * @param loginIp 登陆 IP - */ - void updateUserLogin(Long id, String loginIp); - - /** - * 通过用户 ID 查询用户 - * - * @param id 用户ID - * @return 用户对象信息 - */ - MbrUserDO getUser(Long id); - - /** - * 修改用户昵称 - * @param userId 用户id - * @param nickname 用户新昵称 - */ - void updateNickname(Long userId, String nickname); - - /** - * 修改用户头像 - * @param userId 用户id - * @param inputStream 头像文件 - * @return 头像url - */ - String updateAvatar(Long userId, InputStream inputStream); - - /** - * 根据用户id,获取用户头像与昵称 - * - * @param userId 用户id - * @return 用户响应实体类 - */ - MbrUserInfoRespVO getUserInfo(Long userId); - - /** - * 修改手机 - * @param userId 用户id - * @param reqVO 请求实体 - */ - void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO); - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java deleted file mode 100644 index ee76906..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java +++ /dev/null @@ -1,161 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.service.user.impl; - -import cn.hutool.core.io.IoUtil; -import cn.hutool.core.util.IdUtil; -import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; -import cn.iocoder.yudao.userserver.modules.member.convert.user.UserProfileConvert; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import com.google.common.annotations.VisibleForTesting; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.io.InputStream; -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.USER_NOT_EXISTS; -import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.USER_SMS_CODE_IS_UNUSED; - -/** - * User Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Valid -@Slf4j -public class MbrUserServiceImpl implements MbrUserService { - - @Resource - private MbrUserMapper userMapper; - - @Resource - private InfFileCoreService fileCoreService; - - @Resource - private PasswordEncoder passwordEncoder; - - @Resource - private SysSmsCodeService smsCodeService; - - - @Override - public MbrUserDO getUserByMobile(String mobile) { - return userMapper.selectByMobile(mobile); - } - - @Override - public MbrUserDO createUserIfAbsent(String mobile, String registerIp) { - // 用户已经存在 - MbrUserDO user = userMapper.selectByMobile(mobile); - if (user != null) { - return user; - } - // 用户不存在,则进行创建 - return this.createUser(mobile, registerIp); - } - - private MbrUserDO createUser(String mobile, String registerIp) { - // 生成密码 - String password = IdUtil.fastSimpleUUID(); - // 插入用户 - MbrUserDO user = new MbrUserDO(); - user.setMobile(mobile); - user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 - user.setPassword(passwordEncoder.encode(password)); // 加密密码 - user.setRegisterIp(registerIp); - userMapper.insert(user); - return user; - } - - @Override - public void updateUserLogin(Long id, String loginIp) { - userMapper.updateById(new MbrUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); - } - - @Override - public MbrUserDO getUser(Long id) { - return userMapper.selectById(id); - } - - @Override - public void updateNickname(Long userId, String nickname) { - MbrUserDO user = this.checkUserExists(userId); - // 仅当新昵称不等于旧昵称时进行修改 - if (nickname.equals(user.getNickname())){ - return; - } - MbrUserDO userDO = new MbrUserDO(); - userDO.setId(user.getId()); - userDO.setNickname(nickname); - userMapper.updateById(userDO); - } - - @Override - public String updateAvatar(Long userId, InputStream avatarFile) { - this.checkUserExists(userId); - // 创建文件 - String avatar = fileCoreService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile)); - // 更新头像路径 - MbrUserDO userDO = MbrUserDO.builder() - .id(userId) - .avatar(avatar) - .build(); - userMapper.updateById(userDO); - return avatar; - } - - @Override - public MbrUserInfoRespVO getUserInfo(Long userId) { - MbrUserDO user = this.checkUserExists(userId); - // 拼接返回结果 - return UserProfileConvert.INSTANCE.convert(user); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateMobile(Long userId, MbrUserUpdateMobileReqVO reqVO) { - // 检测用户是否存在 - checkUserExists(userId); - - // 校验旧手机和旧验证码 - SysSmsCodeDO sysSmsCodeDO = smsCodeService.checkCodeIsExpired(reqVO.getOldMobile(), reqVO.getOldCode(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene()); - // 判断旧code是否未被使用,如果是,抛出异常 - if (Boolean.FALSE.equals(sysSmsCodeDO.getUsed())){ - throw exception(USER_SMS_CODE_IS_UNUSED); - } - - // 使用新验证码 - smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), reqVO.getCode(),getClientIP()); - - // 更新用户手机 - MbrUserDO userDO = MbrUserDO.builder().id(userId).mobile(reqVO.getMobile()).build(); - userMapper.updateById(userDO); - } - - @VisibleForTesting - public MbrUserDO checkUserExists(Long id) { - if (id == null) { - return null; - } - MbrUserDO user = userMapper.selectById(id); - if (user == null) { - throw exception(USER_NOT_EXISTS); - }else{ - return user; - } - } -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http deleted file mode 100644 index c9caded..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.http +++ /dev/null @@ -1,31 +0,0 @@ -### 请求 /login 接口 => 成功 -POST {{userServerUrl}}/login -Content-Type: application/json - -{ - "mobile": "15601691300", - "password": "admin123" -} - -### 请求 /send-sms-code 接口 => 成功 -POST {{userServerUrl}}/send-sms-code -Content-Type: application/json - -{ - "mobile": "15601691399", - "scene": 1 -} - -### 请求 /sms-login 接口 => 成功 -POST {{userServerUrl}}/sms-login -Content-Type: application/json - -{ - "mobile": "15601691301", - "code": 9999 -} - -### 请求 /logout 接口 => 成功 -POST {{userServerUrl}}/logout -Content-Type: application/json -Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66 diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java deleted file mode 100644 index 2c0d493..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java +++ /dev/null @@ -1,130 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth; - -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; -import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -@Api(tags = "认证") -@RestController -@RequestMapping("/") -@Validated -@Slf4j -public class SysAuthController { - - @Resource - private SysAuthService authService; - @Resource - private SysSmsCodeService smsCodeService; - @Resource - private SysSocialCoreService socialService; - - @PostMapping("/login") - @ApiOperation("使用手机 + 密码登录") - public CommonResult login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { - String token = authService.login(reqVO, getClientIP(), getUserAgent()); - // 返回结果 - return success(SysAuthLoginRespVO.builder().token(token).build()); - } - - @PostMapping("/sms-login") - @ApiOperation("使用手机 + 验证码登录") - public CommonResult smsLogin(@RequestBody @Valid SysAuthSmsLoginReqVO reqVO) { - String token = authService.smsLogin(reqVO, getClientIP(), getUserAgent()); - // 返回结果 - return success(SysAuthLoginRespVO.builder().token(token).build()); - } - - @PostMapping("/send-sms-code") - @ApiOperation(value = "发送手机验证码") - public CommonResult sendSmsCode(@RequestBody @Valid SysAuthSendSmsReqVO reqVO) { - smsCodeService.sendSmsCode(reqVO.getMobile(), reqVO.getScene(), getClientIP()); - return success(true); - } - - @GetMapping("/send-sms-code-login") - @ApiOperation(value = "向已登录用户发送验证码",notes = "修改手机时验证原手机号使用") - public CommonResult sendSmsCodeLogin() { - smsCodeService.sendSmsCodeLogin(getLoginUserId()); - return success(true); - } - - @PostMapping("/reset-password") - @ApiOperation(value = "重置密码", notes = "用户忘记密码时使用") - @PreAuthenticated - public CommonResult resetPassword(@RequestBody @Valid MbrAuthResetPasswordReqVO reqVO) { - authService.resetPassword(reqVO); - return success(true); - } - - @PostMapping("/update-password") - @ApiOperation(value = "修改用户密码",notes = "用户修改密码时使用") - @PreAuthenticated - public CommonResult updatePassword(@RequestBody @Valid MbrAuthUpdatePasswordReqVO reqVO) { - authService.updatePassword(getLoginUserId(), reqVO); - return success(true); - } - - - // ========== 社交登录相关 ========== - - @GetMapping("/social-auth-redirect") - @ApiOperation("社交授权的跳转") - @ApiImplicitParams({ - @ApiImplicitParam(name = "type", value = "社交类型", required = true, dataTypeClass = Integer.class), - @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) - }) - public CommonResult socialAuthRedirect(@RequestParam("type") Integer type, - @RequestParam("redirectUri") String redirectUri) { - return CommonResult.success(socialService.getAuthorizeUrl(type, redirectUri)); - } - - - @PostMapping("/social-login") - @ApiOperation("社交登录,使用 code 授权码") - public CommonResult socialLogin(@RequestBody @Valid MbrAuthSocialLoginReqVO reqVO) { - String token = authService.socialLogin(reqVO, getClientIP(), getUserAgent()); - return success(SysAuthLoginRespVO.builder().token(token).build()); - } - - - @PostMapping("/social-login2") - @ApiOperation("社交登录,使用 手机号 + 手机验证码") - public CommonResult socialLogin2(@RequestBody @Valid MbrAuthSocialLogin2ReqVO reqVO) { - String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent()); - return success(SysAuthLoginRespVO.builder().token(token).build()); - } - - @PostMapping("/social-bind") - @ApiOperation("社交绑定,使用 code 授权码") - public CommonResult socialBind(@RequestBody @Valid MbrAuthSocialBindReqVO reqVO) { - authService.socialBind(getLoginUserId(), reqVO); - return CommonResult.success(true); - } - - @DeleteMapping("/social-unbind") - @ApiOperation("取消社交绑定") - public CommonResult socialUnbind(@RequestBody MbrAuthSocialUnbindReqVO reqVO) { - socialService.unbindSocialUser(getLoginUserId(), reqVO.getType(), reqVO.getUnionId(), UserTypeEnum.MEMBER); - return CommonResult.success(true); - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java deleted file mode 100644 index 8160174..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthResetPasswordReqVO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Pattern; - -@ApiModel("重置密码 Request VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MbrAuthResetPasswordReqVO { - - @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") - @NotEmpty(message = "新密码不能为空") - @Length(min = 4, max = 16, message = "密码长度为 4-16 位") - private String password; - - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") - @NotEmpty(message = "手机验证码不能为空") - @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") - @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") - private String code; - - @ApiModelProperty(value = "手机号",required = true,example = "15878962356") - @NotBlank(message = "手机号不能为空") - @Mobile - private String mobile; -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialBindReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialBindReqVO.java deleted file mode 100644 index 767446b..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialBindReqVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -@ApiModel("社交绑定 Request VO,使用 code 授权码") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MbrAuthSocialBindReqVO { - - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") - @InEnum(SysSocialTypeEnum.class) - @NotNull(message = "社交平台的类型不能为空") - private Integer type; - - @ApiModelProperty(value = "授权码", required = true, example = "1024") - @NotEmpty(message = "授权码不能为空") - private String code; - - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") - @NotEmpty(message = "state 不能为空") - private String state; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLogin2ReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLogin2ReqVO.java deleted file mode 100644 index 1da763e..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLogin2ReqVO.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; - -@ApiModel("社交登录 Request VO,使用 code 授权码 + 账号密码") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MbrAuthSocialLogin2ReqVO { - - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") - @InEnum(SysSocialTypeEnum.class) - @NotNull(message = "社交平台的类型不能为空") - private Integer type; - - @ApiModelProperty(value = "授权码", required = true, example = "1024") - @NotEmpty(message = "授权码不能为空") - private String code; - - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") - @NotEmpty(message = "state 不能为空") - private String state; - - @ApiModelProperty(value = "手机号", required = true, example = "15119100000") - @NotEmpty(message = "手机号不能为空") - @Length(min = 11, max = 11, message = "手机号是11位数字") - private String mobile; - - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") - @NotEmpty(message = "手机验证码不能为空") - @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") - @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") - private String smsCode; - - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLoginReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLoginReqVO.java deleted file mode 100644 index cb43023..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialLoginReqVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -@ApiModel("社交登录 Request VO,使用 code 授权码") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MbrAuthSocialLoginReqVO { - - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") - @InEnum(SysSocialTypeEnum.class) - @NotNull(message = "社交平台的类型不能为空") - private Integer type; - - @ApiModelProperty(value = "授权码", required = true, example = "1024") - @NotEmpty(message = "授权码不能为空") - private String code; - - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") - @NotEmpty(message = "state 不能为空") - private String state; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialUnbindReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialUnbindReqVO.java deleted file mode 100644 index 75e3170..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthSocialUnbindReqVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -@ApiModel("取消社交绑定 Request VO,使用 code 授权码") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MbrAuthSocialUnbindReqVO { - - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") - @InEnum(SysSocialTypeEnum.class) - @NotNull(message = "社交平台的类型不能为空") - private Integer type; - - @ApiModelProperty(value = "社交的全局编号", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") - @NotEmpty(message = "社交的全局编号不能为空") - private String unionId; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthUpdatePasswordReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthUpdatePasswordReqVO.java deleted file mode 100644 index b5cc0c7..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/MbrAuthUpdatePasswordReqVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; - -@ApiModel("修改密码 Request VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class MbrAuthUpdatePasswordReqVO { - - @ApiModelProperty(value = "用户旧密码", required = true, example = "123456") - @NotBlank(message = "旧密码不能为空") - @Length(min = 4, max = 16, message = "密码长度为 4-16 位") - private String oldPassword; - - @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") - @NotEmpty(message = "新密码不能为空") - @Length(min = 4, max = 16, message = "密码长度为 4-16 位") - private String password; -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java deleted file mode 100644 index 89f1f50..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthCheckCodeReqVO.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; - -@ApiModel("校验验证码 Request VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class SysAuthCheckCodeReqVO { - - @ApiModelProperty(value = "手机号", example = "15601691234") - @NotBlank(message = "手机号不能为空") - @Mobile - private String mobile; - - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") - @NotBlank(message = "手机验证码不能为空") - @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") - @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") - private String code; - - @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 MbrSmsSceneEnum 枚举") - @NotNull(message = "发送场景不能为空") - @InEnum(SysSmsSceneEnum.class) - private Integer scene; -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginReqVO.java deleted file mode 100644 index 1d51f80..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginReqVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotEmpty; - -@ApiModel("手机 + 密码登录 Request VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class SysAuthLoginReqVO { - - @ApiModelProperty(value = "手机号", required = true, example = "15601691300") - @NotEmpty(message = "手机号不能为空") - @Mobile - private String mobile; - - @ApiModelProperty(value = "密码", required = true, example = "buzhidao") - @NotEmpty(message = "密码不能为空") - @Length(min = 4, max = 16, message = "密码长度为 4-16 位") - private String password; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java deleted file mode 100644 index 95c69c7..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthLoginRespVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@ApiModel("手机密码登录 Response VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class SysAuthLoginRespVO { - - @ApiModelProperty(value = "token", required = true, example = "yudaoyuanma") - private String token; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java deleted file mode 100644 index d8c6c98..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSendSmsReqVO.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.experimental.Accessors; - -import javax.validation.constraints.NotNull; - -@ApiModel("发送手机验证码 Response VO") -@Data -@Accessors(chain = true) -public class SysAuthSendSmsReqVO { - - @ApiModelProperty(value = "手机号", example = "15601691234") - @Mobile - private String mobile; - - @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 MbrSmsSceneEnum 枚举") - @NotNull(message = "发送场景不能为空") - @InEnum(SysSmsSceneEnum.class) - private Integer scene; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java deleted file mode 100644 index a7b36bb..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/vo/SysAuthSmsLoginReqVO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.controller.auth.vo; - -import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.Pattern; - -@ApiModel("手机 + 验证码登录 Request VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class SysAuthSmsLoginReqVO { - - @ApiModelProperty(value = "手机号", required = true, example = "15601691300") - @NotEmpty(message = "手机号不能为空") - @Mobile - private String mobile; - - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") - @NotEmpty(message = "手机验证码不能为空") - @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") - @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") - private String code; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/package-info.java deleted file mode 100644 index aa4f746..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位 - */ -package cn.iocoder.yudao.userserver.modules.system.controller; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/auth/SysAuthConvert.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/auth/SysAuthConvert.java deleted file mode 100644 index f2af812..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/auth/SysAuthConvert.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.convert.auth; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.security.core.LoginUser; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface SysAuthConvert { - - SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class); - - @Mapping(source = "mobile", target = "username") - LoginUser convert0(MbrUserDO bean); - - default LoginUser convert(MbrUserDO bean) { - // 目的,为了设置 UserTypeEnum.MEMBER.getValue() - return convert0(bean).setUserType(UserTypeEnum.MEMBER.getValue()); - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java deleted file mode 100644 index d7da621..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 POJO 类的实体转换 - * - * 目前使用 MapStruct 框架 - */ -package cn.iocoder.yudao.userserver.modules.system.convert; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md deleted file mode 100644 index 8153487..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/package-info.java deleted file mode 100644 index 0c99dcc..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.dal.dataobject; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/sms/SysSmsCodeDO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/sms/SysSmsCodeDO.java deleted file mode 100644 index 8cce25f..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/sms/SysSmsCodeDO.java +++ /dev/null @@ -1,64 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; -import lombok.experimental.Accessors; - -import java.util.Date; - -/** - * 手机验证码 DO - * - * idx_mobile 索引:基于 {@link #mobile} 字段 - * - * @author 芋道源码 - */ -@TableName("sys_sms_code") -@Data -@EqualsAndHashCode(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class SysSmsCodeDO extends BaseDO { - - /** - * 编号 - */ - private Integer id; - /** - * 手机号 - */ - private String mobile; - /** - * 验证码 - */ - private String code; - /** - * 发送场景 - * - * 枚举 {@link SysSmsCodeDO} - */ - private Integer scene; - /** - * 创建 IP - */ - private String createIp; - /** - * 今日发送的第几条 - */ - private Integer todayIndex; - /** - * 是否使用 - */ - private Boolean used; - /** - * 使用时间 - */ - private Date usedTime; - /** - * 使用 IP - */ - private String usedIp; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java deleted file mode 100644 index a1bdead..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.dal.mysql; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java deleted file mode 100644 index 88e1036..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/sms/SysSmsCodeMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import org.apache.ibatis.annotations.Mapper; - - -@Mapper -public interface SysSmsCodeMapper extends BaseMapperX { - - /** - * 获得手机号的最后一个手机验证码 - * - * @param mobile 手机号 - * @param scene 发送场景,选填 - * @param code 验证码 选填 - * @return 手机验证码 - */ - default SysSmsCodeDO selectLastByMobile(String mobile,String code,Integer scene) { - return selectOne(new QueryWrapperX() - .eq("mobile", mobile) - .eqIfPresent("scene", scene) - .eqIfPresent("code", code) - .orderByDesc("id") - .last("LIMIT 1")); - } -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/redis/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/redis/package-info.java deleted file mode 100644 index bb50835..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/redis/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.dal.redis; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java deleted file mode 100644 index 05ae0ed..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/SysErrorCodeConstants.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * System 错误码枚举类 - * - * system 系统,使用 1-005-000-000 段 - */ -public interface SysErrorCodeConstants { - - // ========== AUTH 模块 1005000000 ========== - ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1005000000, "登录失败,账号密码不正确"); - ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1005000001, "登录失败,账号被禁用"); - ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1005000002, "登录失败"); // 登录失败的兜底,未知原因 - ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1005000003, "Token 已经过期"); - ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1005000004, "未绑定账号,需要进行绑定"); - - // ========== SMS CODE 模块 1005001000 ========== - ErrorCode USER_SMS_CODE_NOT_FOUND = new ErrorCode(1005001000, "验证码不存在"); - ErrorCode USER_SMS_CODE_EXPIRED = new ErrorCode(1005001001, "验证码已过期"); - ErrorCode USER_SMS_CODE_USED = new ErrorCode(1005001002, "验证码已使用"); - ErrorCode USER_SMS_CODE_NOT_CORRECT = new ErrorCode(1005001003, "验证码不正确"); - ErrorCode USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1005001004, "超过每日短信发送数量"); - ErrorCode USER_SMS_CODE_SEND_TOO_FAST = new ErrorCode(1005001005, "短信发送过于频率"); - ErrorCode USER_SMS_CODE_IS_EXISTS = new ErrorCode(1005001006, "手机号已被使用"); - ErrorCode USER_SMS_CODE_IS_UNUSED = new ErrorCode(1005001006, "验证码未被使用"); - - // ========== 用户模块 1005002000 ========== - ErrorCode USER_NOT_EXISTS = new ErrorCode(1005002001, "用户不存在"); - ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1005002003, "密码校验失败"); -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java deleted file mode 100644 index 9cea092..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsSceneEnum.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.enums.sms; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 用户短信验证码发送场景的枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum SysSmsSceneEnum implements IntArrayValuable { - - LOGIN_BY_SMS(1,SysSmsTemplateCodeConstants.USER_SMS_LOGIN, "手机号登陆"), - CHANGE_MOBILE_BY_SMS(2,SysSmsTemplateCodeConstants.USER_SMS_UPDATE_MOBILE, "更换手机号"), - FORGET_MOBILE_BY_SMS(3,SysSmsTemplateCodeConstants.USER_SMS_RESET_PASSWORD, "忘记密码"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysSmsSceneEnum::getScene).toArray(); - - /** - * 验证那场景编号 - */ - private final Integer scene; - - /** - * 模版编码 - */ - private final String code; - - /** - * 描述 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - - public static String getCodeByScene(Integer scene){ - for (SysSmsSceneEnum value : values()) { - if (value.getScene().equals(scene)){ - return value.getCode(); - } - } - return null; - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java deleted file mode 100644 index 8a83f75..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/sms/SysSmsTemplateCodeConstants.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.enums.sms; - -/** - * yudao-user-server 使用到的短信模板的 Code 编码的枚举 - * - * @author 芋道源码 - */ -public interface SysSmsTemplateCodeConstants { - - /** - * 前台用户短信登录 - */ - String USER_SMS_LOGIN = "user-sms-login"; - - /** - * 用户忘记密码 - */ - String USER_SMS_RESET_PASSWORD = "user-sms-reset-password"; - - /** - * 用户更新手机号 - */ - String USER_SMS_UPDATE_MOBILE = "user-sms-update-mobile"; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/package-info.java deleted file mode 100644 index cb0def5..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 属于 system 模块的 framework 封装 - * - * @author 芋道源码 - */ -package cn.iocoder.yudao.userserver.modules.system.framework; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeConfiguration.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeConfiguration.java deleted file mode 100644 index a4510ea..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeConfiguration.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.framework.sms; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableConfigurationProperties(SmsCodeProperties.class) -public class SmsCodeConfiguration { -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeProperties.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeProperties.java deleted file mode 100644 index b600c28..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/framework/sms/SmsCodeProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.framework.sms; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.time.Duration; -import java.util.Collection; - -@ConfigurationProperties(prefix = "yudao.sms-code") -@Validated -@Data -public class SmsCodeProperties { - - /** - * 过期时间 - */ - @NotNull(message = "过期时间不能为空") - private Duration expireTimes; - /** - * 短信发送频率 - */ - @NotNull(message = "短信发送频率不能为空") - private Duration sendFrequency; - /** - * 每日发送最大数量 - */ - @NotNull(message = "每日发送最大数量不能为空") - private Integer sendMaximumQuantityPerDay; - /** - * 验证码最小值 - */ - @NotNull(message = "验证码最小值不能为空") - private Integer beginCode; - /** - * 验证码最大值 - */ - @NotNull(message = "验证码最大值不能为空") - private Integer endCode; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/package-info.java deleted file mode 100644 index 89fa9c1..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * system 包下,我们放通用业务,支撑上层的核心业务。 - * 例如说:用户、部门、权限、数据字典等等 - * - * 缩写:sys - */ -package cn.iocoder.yudao.userserver.modules.system; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java deleted file mode 100644 index 0145821..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysAuthService.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.service.auth; - -import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; - -import javax.validation.Valid; - -/** - * 用户前台的认证 Service 接口 - * - * 提供用户的账号密码登录、token 的校验等认证相关的功能 - * - * @author 芋道源码 - */ -public interface SysAuthService extends SecurityAuthFrameworkService { - - /** - * 手机 + 密码登录 - * - * @param reqVO 登录信息 - * @param userIp 用户 IP - * @param userAgent 用户 UA - * @return 身份令牌,使用 JWT 方式 - */ - String login(@Valid SysAuthLoginReqVO reqVO, String userIp, String userAgent); - - /** - * 手机 + 验证码登陆 - * - * @param reqVO 登陆信息 - * @param userIp 用户 IP - * @param userAgent 用户 UA - * @return 身份令牌,使用 JWT 方式 - */ - String smsLogin(@Valid SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent); - - - /** - * 社交登录,使用 code 授权码 - * - * @param reqVO 登录信息 - * @param userIp 用户 IP - * @param userAgent 用户 UA - * @return 身份令牌,使用 JWT 方式 - */ - String socialLogin(@Valid MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent); - - /** - * 社交登录,使用 手机号 + 手机验证码 - * - * @param reqVO 登录信息 - * @param userIp 用户 IP - * @param userAgent 用户 UA - * @return 身份令牌,使用 JWT 方式 - */ - String socialLogin2(@Valid MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent); - - /** - * 社交绑定,使用 code 授权码 - * - * @param userId 用户编号 - * @param reqVO 绑定信息 - */ - void socialBind(Long userId, @Valid MbrAuthSocialBindReqVO reqVO); - - /** - * 修改用户密码 - * @param userId 用户id - * @param userReqVO 用户请求实体类 - */ - void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO userReqVO); - - /** - * 忘记密码 - * @param userReqVO 用户请求实体类 - */ - void resetPassword(MbrAuthResetPasswordReqVO userReqVO); -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java deleted file mode 100644 index 037db64..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ /dev/null @@ -1,355 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.service.auth.impl; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO; -import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginLogTypeEnum; -import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginResultEnum; -import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; -import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; -import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; -import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; -import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; -import cn.iocoder.yudao.userserver.modules.system.convert.auth.SysAuthConvert; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import com.google.common.annotations.VisibleForTesting; -import lombok.extern.slf4j.Slf4j; -import me.zhyd.oauth.model.AuthUser; -import org.springframework.context.annotation.Lazy; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.BadCredentialsException; -import org.springframework.security.authentication.DisabledException; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.*; - -/** - * Auth Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Slf4j -public class SysAuthServiceImpl implements SysAuthService { - - private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; - - @Resource - @Lazy // 延迟加载,因为存在相互依赖的问题 - private AuthenticationManager authenticationManager; - - @Resource - private MbrUserService userService; - @Resource - private SysSmsCodeService smsCodeService; - @Resource - private SysLoginLogCoreService loginLogCoreService; - @Resource - private SysUserSessionCoreService userSessionCoreService; - @Resource - private SysSocialCoreService socialService; - - @Resource - private StringRedisTemplate stringRedisTemplate; - @Resource - private PasswordEncoder passwordEncoder; - @Resource - private MbrUserMapper userMapper; - - private static final UserTypeEnum userTypeEnum = UserTypeEnum.MEMBER; - - @Override - public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { - // 获取 username 对应的 SysUserDO - MbrUserDO user = userService.getUserByMobile(mobile); - if (user == null) { - throw new UsernameNotFoundException(mobile); - } - // 创建 LoginUser 对象 - return SysAuthConvert.INSTANCE.convert(user); - } - - @Override - public String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent) { - // 使用手机 + 密码,进行登录。 - LoginUser loginUser = this.login0(reqVO.getMobile(), reqVO.getPassword()); - - // 缓存登录用户到 Redis 中,返回 sessionId 编号 - return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); - } - - @Override - @Transactional - public String smsLogin(SysAuthSmsLoginReqVO reqVO, String userIp, String userAgent) { - // 校验验证码 - smsCodeService.useSmsCode(reqVO.getMobile(), SysSmsSceneEnum.LOGIN_BY_SMS.getScene(), - reqVO.getCode(), userIp); - - // 获得获得注册用户 - MbrUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp); - Assert.notNull(user, "获取用户失败,结果为空"); - - // 执行登陆 - this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SMS, SysLoginResultEnum.SUCCESS); - LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); - - // 缓存登录用户到 Redis 中,返回 sessionId 编号 - return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); - } - - @Override - public String socialLogin(MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent) { - // 使用 code 授权码,进行登录 - AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); - org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); - - // 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错 - String unionId = socialService.getAuthUserUnionId(authUser); - List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM); - if (CollUtil.isEmpty(socialUsers)) { - throw exception(AUTH_THIRD_LOGIN_NOT_BIND); - } - - // 自动登录 - MbrUserDO user = userService.getUser(socialUsers.get(0).getUserId()); - if (user == null) { - throw exception(USER_NOT_EXISTS); - } - this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_SOCIAL, SysLoginResultEnum.SUCCESS); - - // 创建 LoginUser 对象 - LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); - - // 绑定社交用户(更新) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); - - // 缓存登录用户到 Redis 中,返回 sessionId 编号 - return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); - } - - @Override - public String socialLogin2(MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent) { - AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); - org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); - - // 使用手机号、手机验证码登录 - SysAuthSmsLoginReqVO loginReqVO = SysAuthSmsLoginReqVO - .builder() - .mobile(reqVO.getMobile()) - .code(reqVO.getSmsCode()) - .build(); - String sessionId = this.smsLogin(loginReqVO, userIp, userAgent); - LoginUser loginUser = userSessionCoreService.getLoginUser(sessionId); - - // 绑定社交用户(新增) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); - return sessionId; - } - - @Override - public void socialBind(Long userId, MbrAuthSocialBindReqVO reqVO) { - // 使用 code 授权码,进行登录 - AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); - org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); - - // 绑定社交用户(新增) - socialService.bindSocialUser(userId, reqVO.getType(), authUser, USER_TYPE_ENUM); - } - - private LoginUser login0(String username, String password) { - final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; - // 用户验证 - Authentication authentication; - try { - // 调用 Spring Security 的 AuthenticationManager#authenticate(...) 方法,使用账号密码进行认证 - // 在其内部,会调用到 loadUserByUsername 方法,获取 User 信息 - authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); - } catch (BadCredentialsException badCredentialsException) { - this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.BAD_CREDENTIALS); - throw exception(AUTH_LOGIN_BAD_CREDENTIALS); - } catch (DisabledException disabledException) { - this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.USER_DISABLED); - throw exception(AUTH_LOGIN_USER_DISABLED); - } catch (AuthenticationException authenticationException) { - log.error("[login0][username({}) 发生未知异常]", username, authenticationException); - this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.UNKNOWN_ERROR); - throw exception(AUTH_LOGIN_FAIL_UNKNOWN); - } - // 登录成功的日志 - Assert.notNull(authentication.getPrincipal(), "Principal 不会为空"); - this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.SUCCESS); - return (LoginUser) authentication.getPrincipal(); - } - - private void createLoginLog(String mobile, SysLoginLogTypeEnum logTypeEnum, SysLoginResultEnum loginResult) { - // 获得用户 - MbrUserDO user = userService.getUserByMobile(mobile); - // 插入登录日志 - SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); - reqDTO.setLogType(logTypeEnum.getType()); - reqDTO.setTraceId(TracerUtils.getTraceId()); - if (user != null) { - reqDTO.setUserId(user.getId()); - } - reqDTO.setUsername(mobile); - reqDTO.setUserAgent(ServletUtils.getUserAgent()); - reqDTO.setUserIp(getClientIP()); - reqDTO.setResult(loginResult.getResult()); - loginLogCoreService.createLoginLog(reqDTO); - // 更新最后登录时间 - if (user != null && Objects.equals(SysLoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) { - userService.updateUserLogin(user.getId(), getClientIP()); - } - } - - @Override - public LoginUser verifyTokenAndRefresh(String token) { - // 获得 LoginUser - LoginUser loginUser = userSessionCoreService.getLoginUser(token); - if (loginUser == null) { - return null; - } - // 刷新 LoginUser 缓存 - this.refreshLoginUserCache(token, loginUser); - return loginUser; - } - - private void refreshLoginUserCache(String token, LoginUser loginUser) { - // 每 1/3 的 Session 超时时间,刷新 LoginUser 缓存 - if (System.currentTimeMillis() - loginUser.getUpdateTime().getTime() < - userSessionCoreService.getSessionTimeoutMillis() / 3) { - return; - } - - // 重新加载 MbrUserDO 信息 - MbrUserDO user = userService.getUser(loginUser.getId()); - if (user == null || CommonStatusEnum.DISABLE.getStatus().equals(user.getStatus())) { - throw exception(AUTH_TOKEN_EXPIRED); // 校验 token 时,用户被禁用的情况下,也认为 token 过期,方便前端跳转到登录界面 - } - - // 刷新 LoginUser 缓存 - userSessionCoreService.refreshUserSession(token, loginUser); - } - - @Override - public LoginUser mockLogin(Long userId) { - // 获取用户编号对应的 MbrUserDO - MbrUserDO user = userService.getUser(userId); - if (user == null) { - throw new UsernameNotFoundException(String.valueOf(userId)); - } - - // 执行登陆 - this.createLoginLog(user.getMobile(), SysLoginLogTypeEnum.LOGIN_MOCK, SysLoginResultEnum.SUCCESS); - - // 创建 LoginUser 对象 - return SysAuthConvert.INSTANCE.convert(user); - } - - @Override - public void logout(String token) { - // 查询用户信息 - LoginUser loginUser = userSessionCoreService.getLoginUser(token); - if (loginUser == null) { - return; - } - // 删除 session - userSessionCoreService.deleteUserSession(token); - // 记录登出日志 - this.createLogoutLog(loginUser.getId(), loginUser.getUsername()); - } - - @Override - public void updatePassword(Long userId,MbrAuthUpdatePasswordReqVO reqVO) { - // 检验旧密码 - MbrUserDO userDO = checkOldPassword(userId, reqVO.getOldPassword()); - - // 更新用户密码 - MbrUserDO mbrUserDO = MbrUserDO.builder().build(); - mbrUserDO.setId(userDO.getId()); - mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); - userMapper.updateById(mbrUserDO); - } - - @Override - public void resetPassword(MbrAuthResetPasswordReqVO reqVO) { - // 检验用户是否存在 - MbrUserDO userDO = checkUserIfExists(reqVO.getMobile()); - - // 使用验证码 - smsCodeService.useSmsCode(reqVO.getMobile(),SysSmsSceneEnum.FORGET_MOBILE_BY_SMS.getScene(),reqVO.getCode(),getClientIP()); - - // 更新密码 - MbrUserDO mbrUserDO = MbrUserDO.builder().build(); - mbrUserDO.setId(userDO.getId()); - mbrUserDO.setPassword(passwordEncoder.encode(reqVO.getPassword())); - userMapper.updateById(mbrUserDO); - } - - /** - * 校验旧密码 - * - * @param id 用户 id - * @param oldPassword 旧密码 - * @return MbrUserDO 用户实体 - */ - @VisibleForTesting - public MbrUserDO checkOldPassword(Long id, String oldPassword) { - MbrUserDO user = userMapper.selectById(id); - if (user == null) { - throw exception(USER_NOT_EXISTS); - } - // 参数:未加密密码,编码后的密码 - if (!passwordEncoder.matches(oldPassword,user.getPassword())) { - throw exception(USER_PASSWORD_FAILED); - } - return user; - } - - public MbrUserDO checkUserIfExists(String mobile) { - MbrUserDO user = userMapper.selectByMobile(mobile); - if (user == null) { - throw exception(USER_NOT_EXISTS); - } - return user; - } - - - private void createLogoutLog(Long userId, String username) { - SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); - reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); - reqDTO.setTraceId(TracerUtils.getTraceId()); - reqDTO.setUserId(userId); - reqDTO.setUserType(USER_TYPE_ENUM.getValue()); - reqDTO.setUsername(username); - reqDTO.setUserAgent(ServletUtils.getUserAgent()); - reqDTO.setUserIp(getClientIP()); - reqDTO.setResult(SysLoginResultEnum.SUCCESS.getResult()); - loginLogCoreService.createLoginLog(reqDTO); - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/package-info.java deleted file mode 100644 index d1896cb..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.service; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java deleted file mode 100644 index 281f18c..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/SysSmsCodeService.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.service.sms; - -import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; - -/** - * 短信验证码 Service 接口 - * - * @author 芋道源码 - */ -public interface SysSmsCodeService { - - /** - * 创建短信验证码,并进行发送 - * - * @param mobile 手机号 - * @param scene 发送场景 {@link SysSmsSceneEnum} - * @param createIp 发送 IP - */ - void sendSmsCode(@Mobile String mobile, Integer scene, String createIp); - - /** - * 验证短信验证码,并进行使用 - * 如果正确,则将验证码标记成已使用 - * 如果错误,则抛出 {@link ServiceException} 异常 - * - * @param mobile 手机号 - * @param scene 发送场景 - * @param code 验证码 - * @param usedIp 使用 IP - */ - void useSmsCode(@Mobile String mobile, Integer scene, String code, String usedIp); - - /** - * 根据用户id发送验证码 - * - * @param userId 用户id - */ - void sendSmsCodeLogin(Long userId); - - - /** - * 检查验证码是否有效 - * @param mobile 手机 - * @param code 验证码 - * @param scene 使用场景 - * @return 验证码记录 - */ - SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene); -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java deleted file mode 100644 index 80fc15a..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/sms/impl/SysSmsCodeServiceImpl.java +++ /dev/null @@ -1,141 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.service.sms.impl; - -import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.coreservice.modules.system.service.sms.SysSmsCoreService; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.dal.mysql.sms.SysSmsCodeMapper; -import cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum; -import cn.iocoder.yudao.userserver.modules.system.framework.sms.SmsCodeProperties; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Date; - -import static cn.hutool.core.util.RandomUtil.randomInt; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConstants.*; - -/** - * 短信验证码 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class SysSmsCodeServiceImpl implements SysSmsCodeService { - - @Resource - private SmsCodeProperties smsCodeProperties; - - @Resource - private SysSmsCodeMapper smsCodeMapper; - - @Resource - private MbrUserService mbrUserService; - - @Resource - private SysSmsCoreService smsCoreService; - - @Override - public void sendSmsCode(String mobile, Integer scene, String createIp) { - // 创建验证码 - String code = this.createSmsCode(mobile, scene, createIp); - - // 获取发送模板 - String codeTemplate = SysSmsSceneEnum.getCodeByScene(scene); - - // 如果是更换手机号发送验证码,则需要检测手机号是否被注册 - if (SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene().equals(scene)){ - this.checkMobileIsRegister(mobile,scene); - } - - // 发送验证码 - smsCoreService.sendSingleSmsToMember(mobile, null, codeTemplate, - MapUtil.of("code", code)); - } - - public void checkMobileIsRegister(String mobile, Integer scene) { - // 检测手机号是否已被使用 - MbrUserDO userByMobile = mbrUserService.getUserByMobile(mobile); - if (userByMobile != null){ - throw exception(USER_SMS_CODE_IS_EXISTS); - } - - // 发送短信 - this.sendSmsCode(mobile,scene,getClientIP()); - } - - private String createSmsCode(String mobile, Integer scene, String ip) { - // 校验是否可以发送验证码,不用筛选场景 - SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, null,null); - if (lastSmsCode != null) { - if (lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。 - throw exception(USER_SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); - } - if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() - < smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁 - throw exception(USER_SMS_CODE_SEND_TOO_FAST); - } - // TODO 芋艿:提升,每个 IP 每天可发送数量 - // TODO 芋艿:提升,每个 IP 每小时可发送数量 - } - - // 创建验证码记录 - String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1)); - SysSmsCodeDO newSmsCode = SysSmsCodeDO.builder().mobile(mobile).code(code) - .scene(scene).todayIndex(lastSmsCode != null ? lastSmsCode.getTodayIndex() + 1 : 1) - .createIp(ip).used(false).build(); - smsCodeMapper.insert(newSmsCode); - return code; - } - - @Override - public void useSmsCode(String mobile, Integer scene, String code, String usedIp) { - - // 检测验证码是否有效 - SysSmsCodeDO lastSmsCode = this.checkCodeIsExpired(mobile, code, scene); - - // 判断验证码是否已被使用 - if (Boolean.TRUE.equals(lastSmsCode.getUsed())) { - throw exception(USER_SMS_CODE_USED); - } - - // 使用验证码 - smsCodeMapper.updateById(SysSmsCodeDO.builder().id(lastSmsCode.getId()) - .used(true).usedTime(new Date()).usedIp(usedIp).build()); - } - - @Override - public void sendSmsCodeLogin(Long userId) { - MbrUserDO user = mbrUserService.getUser(userId); - if (user == null){ - throw exception(USER_NOT_EXISTS); - } - // 发送验证码 - this.sendSmsCode(user.getMobile(),SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS.getScene(), getClientIP()); - } - - @Override - public SysSmsCodeDO checkCodeIsExpired(String mobile, String code, Integer scene) { - // 校验验证码 - SysSmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile,code,scene); - - // 若验证码不存在,抛出异常 - if (lastSmsCode == null) { - throw exception(USER_SMS_CODE_NOT_FOUND); - } - if (System.currentTimeMillis() - lastSmsCode.getCreateTime().getTime() - >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 - throw exception(USER_SMS_CODE_EXPIRED); - } - - return lastSmsCode; - - } - -} diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbAndRedisUnitTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbAndRedisUnitTest.java deleted file mode 100644 index 2669ef4..0000000 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbAndRedisUnitTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.userserver; - -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; -import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; -import cn.iocoder.yudao.userserver.config.RedisTestConfiguration; -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; -import org.redisson.spring.starter.RedissonAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.jdbc.Sql; - -/** - * 依赖内存 DB + Redis 的单元测试 - * - * 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis - * - * @author 芋道源码 - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class) -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB -public class BaseDbAndRedisUnitTest { - - @Import({ - // DB 配置类 - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 - DataSourceAutoConfiguration.class, // Spring DB 自动配置类 - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 - DruidDataSourceAutoConfigure.class, // Druid 自动配置类 - // MyBatis 配置类 - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 - // Redis 配置类 - RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer - RedisAutoConfiguration.class, // Spring Redis 自动配置类 - YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类 - RedissonAutoConfiguration.class, // Redisson 自动高配置类 - }) - public static class Application { - } - -} diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbUnitTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbUnitTest.java deleted file mode 100644 index af8d71a..0000000 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/BaseDbUnitTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.userserver; - -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.jdbc.Sql; - -/** - * 依赖内存 DB 的单元测试 - * - * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法 - * - * @author 芋道源码 - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class) -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB -public class BaseDbUnitTest { - - @Import({ - // DB 配置类 - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 - DataSourceAutoConfiguration.class, // Spring DB 自动配置类 - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 - DruidDataSourceAutoConfigure.class, // Druid 自动配置类 - // MyBatis 配置类 - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 - }) - public static class Application { - } - -} diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/config/RedisTestConfiguration.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/config/RedisTestConfiguration.java deleted file mode 100644 index 7164efd..0000000 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/config/RedisTestConfiguration.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.userserver.config; - -import com.github.fppt.jedismock.RedisServer; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; - -import java.io.IOException; - -@Configuration(proxyBeanMethods = false) -@Lazy(false) // 禁止延迟加载 -@EnableConfigurationProperties(RedisProperties.class) -public class RedisTestConfiguration { - - /** - * 创建模拟的 Redis Server 服务器 - */ - @Bean - public RedisServer redisServer(RedisProperties properties) throws IOException { - RedisServer redisServer = new RedisServer(properties.getPort()); - // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。 - try { - redisServer.start(); - } catch (Exception ignore) {} - return redisServer; - } - -} diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java deleted file mode 100644 index 68f4164..0000000 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/member/service/MbrUserServiceImplTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.member.service; - -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService; -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; -import cn.iocoder.yudao.userserver.BaseDbAndRedisUnitTest; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserInfoRespVO; -import cn.iocoder.yudao.userserver.modules.member.controller.user.vo.MbrUserUpdateMobileReqVO; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.impl.MbrUserServiceImpl; -import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.sms.SysSmsCodeDO; -import cn.iocoder.yudao.userserver.modules.system.service.auth.impl.SysAuthServiceImpl; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.security.crypto.password.PasswordEncoder; - -import javax.annotation.Resource; -import java.io.ByteArrayInputStream; -import java.util.function.Consumer; - -import static cn.hutool.core.util.RandomUtil.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; -import static cn.iocoder.yudao.userserver.modules.system.enums.sms.SysSmsSceneEnum.CHANGE_MOBILE_BY_SMS; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.*; - -// TODO @芋艿:单测的 review,等逻辑都达成一致后 -/** - * {@link MbrUserServiceImpl} 的单元测试类 - * - * @author 宋天 - */ -@Import({MbrUserServiceImpl.class, YudaoRedisAutoConfiguration.class}) -public class MbrUserServiceImplTest extends BaseDbAndRedisUnitTest { - - @Resource - private MbrUserServiceImpl mbrUserService; - - @Resource - private StringRedisTemplate stringRedisTemplate; - - @Resource - private MbrUserMapper userMapper; - - @MockBean - private SysAuthServiceImpl authService; - - @MockBean - private InfFileCoreService fileCoreService; - - @MockBean - private PasswordEncoder passwordEncoder; - - @MockBean - private SysSmsCodeService sysSmsCodeService; - - @Test - public void testUpdateNickName_success(){ - // mock 数据 - MbrUserDO userDO = randomMbrUserDO(); - userMapper.insert(userDO); - - // 随机昵称 - String newNickName = randomString(); - - // 调用接口修改昵称 - mbrUserService.updateNickname(userDO.getId(),newNickName); - // 查询新修改后的昵称 - String nickname = mbrUserService.getUser(userDO.getId()).getNickname(); - // 断言 - assertEquals(newNickName,nickname); - } - - @Test - public void testGetUserInfo_success(){ - // mock 数据 - MbrUserDO userDO = randomMbrUserDO(); - userMapper.insert(userDO); - - // 查询用户昵称与头像 - MbrUserInfoRespVO userInfo = mbrUserService.getUserInfo(userDO.getId()); - System.out.println(userInfo); - } - - @Test - public void testUpdateAvatar_success(){ - // mock 数据 - MbrUserDO dbUser = randomMbrUserDO(); - userMapper.insert(dbUser); - - // 准备参数 - Long userId = dbUser.getId(); - byte[] avatarFileBytes = randomBytes(10); - ByteArrayInputStream avatarFile = new ByteArrayInputStream(avatarFileBytes); - // mock 方法 - String avatar = randomString(); - when(fileCoreService.createFile(anyString(), eq(avatarFileBytes))).thenReturn(avatar); - // 调用 - String str = mbrUserService.updateAvatar(userId, avatarFile); - // 断言 - assertEquals(avatar, str); - } - - @Test - public void updateMobile_success(){ - // mock数据 - String oldMobile = randomNumbers(11); - MbrUserDO userDO = randomMbrUserDO(); - userDO.setMobile(oldMobile); - userMapper.insert(userDO); - - - // 旧手机和旧验证码 - SysSmsCodeDO codeDO = new SysSmsCodeDO(); - String oldCode = RandomUtil.randomString(4); - codeDO.setMobile(userDO.getMobile()); - codeDO.setCode(oldCode); - codeDO.setScene(CHANGE_MOBILE_BY_SMS.getScene()); - codeDO.setUsed(Boolean.FALSE); - when(sysSmsCodeService.checkCodeIsExpired(codeDO.getMobile(),codeDO.getCode(),codeDO.getScene())).thenReturn(codeDO); - - // 更新手机号 - String newMobile = randomNumbers(11); - String newCode = randomNumbers(4); - MbrUserUpdateMobileReqVO reqVO = new MbrUserUpdateMobileReqVO(); - reqVO.setMobile(newMobile); - reqVO.setCode(newCode); - reqVO.setOldMobile(oldMobile); - reqVO.setOldCode(oldCode); - mbrUserService.updateMobile(userDO.getId(),reqVO); - - assertEquals(mbrUserService.getUser(userDO.getId()).getMobile(),newMobile); - } - - // ========== 随机对象 ========== - - @SafeVarargs - private static MbrUserDO randomMbrUserDO(Consumer... consumers) { - Consumer consumer = (o) -> { - o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 - }; - return randomPojo(MbrUserDO.class, ArrayUtils.append(consumer, consumers)); - } - -} diff --git a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java b/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java deleted file mode 100644 index 4c8b953..0000000 --- a/yudao-user-server/src/test/java/cn/iocoder/yudao/userserver/modules/system/service/SysAuthServiceTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.service; - -import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO; -import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; -import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; -import cn.iocoder.yudao.userserver.BaseDbAndRedisUnitTest; -import cn.iocoder.yudao.userserver.modules.member.dal.mysql.user.MbrUserMapper; -import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.MbrAuthResetPasswordReqVO; -import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.MbrAuthUpdatePasswordReqVO; -import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService; -import cn.iocoder.yudao.userserver.modules.system.service.auth.impl.SysAuthServiceImpl; -import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.crypto.password.PasswordEncoder; - -import javax.annotation.Resource; -import java.util.function.Consumer; - -import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.hutool.core.util.RandomUtil.randomNumbers; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - -// TODO @芋艿:单测的 review,等逻辑都达成一致后 -/** - * {@link SysAuthService} 的单元测试类 - * - * @author 宋天 - */ -@Import({SysAuthServiceImpl.class, YudaoRedisAutoConfiguration.class}) -public class SysAuthServiceTest extends BaseDbAndRedisUnitTest { - - @MockBean - private AuthenticationManager authenticationManager; - @MockBean - private MbrUserService userService; - @MockBean - private SysSmsCodeService smsCodeService; - @MockBean - private SysLoginLogCoreService loginLogCoreService; - @MockBean - private SysUserSessionCoreService userSessionCoreService; - @MockBean - private SysSocialCoreService socialService; - @Resource - private StringRedisTemplate stringRedisTemplate; - @MockBean - private PasswordEncoder passwordEncoder; - @Resource - private MbrUserMapper mbrUserMapper; - @Resource - private SysAuthServiceImpl authService; - - @Test - public void testUpdatePassword_success(){ - // 准备参数 - MbrUserDO userDO = randomMbrUserDO(); - mbrUserMapper.insert(userDO); - - // 新密码 - String newPassword = randomString(); - - // 请求实体 - MbrAuthUpdatePasswordReqVO reqVO = MbrAuthUpdatePasswordReqVO.builder() - .oldPassword(userDO.getPassword()) - .password(newPassword) - .build(); - - // 测试桩 - // 这两个相等是为了返回ture这个结果 - when(passwordEncoder.matches(reqVO.getOldPassword(),reqVO.getOldPassword())).thenReturn(true); - when(passwordEncoder.encode(newPassword)).thenReturn(newPassword); - - // 更新用户密码 - authService.updatePassword(userDO.getId(),reqVO); - assertEquals(mbrUserMapper.selectById(userDO.getId()).getPassword(),newPassword); - } - - @Test - public void testResetPassword_success(){ - // 准备参数 - MbrUserDO userDO = randomMbrUserDO(); - mbrUserMapper.insert(userDO); - - // 随机密码 - String password = randomNumbers(11); - // 随机验证码 - String code = randomNumbers(4); - - // mock - when(passwordEncoder.encode(password)).thenReturn(password); - - // 更新用户密码 - MbrAuthResetPasswordReqVO reqVO = new MbrAuthResetPasswordReqVO(); - reqVO.setMobile(userDO.getMobile()); - reqVO.setPassword(password); - reqVO.setCode(code); - - authService.resetPassword(reqVO); - assertEquals(mbrUserMapper.selectById(userDO.getId()).getPassword(),password); - } - - - // ========== 随机对象 ========== - - @SafeVarargs - private static MbrUserDO randomMbrUserDO(Consumer... consumers) { - Consumer consumer = (o) -> { - o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 - o.setPassword(randomString()); - }; - return randomPojo(MbrUserDO.class, ArrayUtils.append(consumer, consumers)); - } - - -} diff --git a/yudao-user-server/src/test/resources/application-unit-test.yaml b/yudao-user-server/src/test/resources/application-unit-test.yaml deleted file mode 100644 index d306a7a..0000000 --- a/yudao-user-server/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,44 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - schema: classpath:sql/create_tables.sql # MySQL 转 H2 的语句,使用 https://www.jooq.org/translate/ 工具 - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - -# Resilience4j 配置项 - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 diff --git a/yudao-user-server/src/test/resources/file/erweima.jpg b/yudao-user-server/src/test/resources/file/erweima.jpg deleted file mode 100644 index 1447283..0000000 Binary files a/yudao-user-server/src/test/resources/file/erweima.jpg and /dev/null differ diff --git a/yudao-user-server/src/test/resources/logback-spring.xml b/yudao-user-server/src/test/resources/logback-spring.xml deleted file mode 100644 index daf756b..0000000 --- a/yudao-user-server/src/test/resources/logback-spring.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/yudao-user-server/src/test/resources/sql/clean.sql b/yudao-user-server/src/test/resources/sql/clean.sql deleted file mode 100644 index bedf8d0..0000000 --- a/yudao-user-server/src/test/resources/sql/clean.sql +++ /dev/null @@ -1,2 +0,0 @@ --- mbr 开头的 DB -DELETE FROM "mbr_user"; \ No newline at end of file diff --git a/yudao-user-server/src/test/resources/sql/create_tables.sql b/yudao-user-server/src/test/resources/sql/create_tables.sql deleted file mode 100644 index c9dfd8c..0000000 --- a/yudao-user-server/src/test/resources/sql/create_tables.sql +++ /dev/null @@ -1,33 +0,0 @@ --- mbr 开头的 DB -CREATE TABLE IF NOT EXISTS "mbr_user" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号', - "nickname" varchar(30) NOT NULL DEFAULT '' COMMENT '用户昵称', - "avatar" varchar(255) NOT NULL DEFAULT '' COMMENT '头像', - "status" tinyint NOT NULL COMMENT '状态', - "mobile" varchar(11) NOT NULL COMMENT '手机号', - "password" varchar(100) NOT NULL DEFAULT '' COMMENT '密码', - "register_ip" varchar(32) NOT NULL COMMENT '注册 IP', - "login_ip" varchar(50) NULL DEFAULT '' COMMENT '最后登录IP', - "login_date" datetime NULL DEFAULT NULL COMMENT '最后登录时间', - "creator" varchar(64) NULL DEFAULT '' COMMENT '创建者', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - "updater" varchar(64) NULL DEFAULT '' COMMENT '更新者', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - "deleted" bit(1) NOT NULL DEFAULT '0' COMMENT '是否删除', - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") -) COMMENT '会员表'; - --- inf 开头的 DB -CREATE TABLE IF NOT EXISTS "inf_file" ( - "id" varchar(188) NOT NULL, - "type" varchar(63) DEFAULT NULL, - "content" blob NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '文件表'; - -- libgit2 0.21.4