mitao
2024-08-24 403fbe8fa8d3df96d692ad41ffa1c300b0db5493
APP端登录模块接口
1 文件已复制
4 文件已重命名
56个文件已修改
24个文件已删除
49个文件已添加
3840 ■■■■■ 已修改文件
code-generator/pom.xml 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/DataUpdateHandlerConfig.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/HttpConfig.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/MybatisPlusConfig.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysUser.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/SysUserFallbackFactory.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/feignClient/SysUserClient.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppCaptchaBody.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppVerifyCellPhoneBody.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppWXLoginBody.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppleLoginUser.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyAddSysUserDto.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanySysUserReq.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyUserListVo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/LoginUser.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/SysUserRoleDTO.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAdd.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAddDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/WXLoginUser.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/factory/RemoteAppUserFallbackFactory.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/feign/RemoteAppUserService.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/controller/TokenController.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/form/AppChangePwdBody.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/form/AppLoginBody.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/form/AppRegisterBody.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/form/VerifyResultVO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/util/HuaWeiSMSUtil.java 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/config/MybatisPlusConfig.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/CacheConstants.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/Constants.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/SecurityConstants.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/ServiceNameConstants.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AppUserStatusEnum.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ApproveConfigEnum.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditStateEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditTypeEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarColorEnum.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarStateEnum.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ConfigEnum.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractStateEnum.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractTypeEnum.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/DisabledEnum.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/HandoverStateEnum.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ImportTypeEnum.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/InsureTypeEnum.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ListingStatusEnum.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PurchaseStateEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnCarTypeEnum.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnStateEnum.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/TreeLevelEnum.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/WarrantyStateEnum.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseModel.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/EnableCustomConfig.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/JacksonConfig.java 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/LocalDateTimeSerializerConfig.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/handler/MyMetaObjectHandler.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/service/TokenService.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/SwaggerProvider.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/pom.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/pom.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/controller/SysFileController.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/utils/ObsUploadUtil.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/pom.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/pom.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/HomeBackgroundMusicController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/HomeBackgroundMusicUserController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/HomeBackgroundMusic.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/HomeBackgroundMusicUser.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/HomeBackgroundMusicMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/HomeBackgroundMusicUserMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/HomeBackgroundMusicUserService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/HomeBackgroundMusicUserServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/HomeBackgroundMusicMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/HomeBackgroundMusicUserMapper.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/pom.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderPaymentRecordService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/client/PublicController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/TreeLevelSetting.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/UserLevelSetting.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/ContentSettingVO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/BannerService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/CommonQuestionService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ContentSettingService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/CustomConfigService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/HotWordsService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/PublicService.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/TreeLevelSettingService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/UserLevelSettingService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/VersionService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/VipSettingService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/BannerServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/CommonQuestionServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/ContentSettingServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/CustomConfigServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/HotWordsServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/TreeLevelSettingServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/UserLevelSettingServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/VersionServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/VipSettingServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/TreeLevelSettingMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/UserLevelSettingMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/pom.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserQuestionController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/inner/InnerAppUserController.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserBankController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserCourseController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserEnergyRecordController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserMeditationController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTagController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTreeController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWalletRecordController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWithdrawController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeRedemptionRecordController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtTagController.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserQuestion.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserTree.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/Tag.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserQuestionMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserQuestionService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserQuestionServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserServiceImpl.java 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserQuestionMapper.xml 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserTreeMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
code-generator/pom.xml
New file
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan</artifactId>
    <version>3.6.2</version>
  </parent>
  <artifactId>code-generator</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity-engine-core -->
    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-engine-core</artifactId>
      <version>2.3</version>
    </dependency>
    <!-- Mysql Connector -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-generator</artifactId>
      <version>3.4.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-common-core</artifactId>
    </dependency>
  </dependencies>
</project>
pom.xml
@@ -238,10 +238,7 @@
        <module>xinquan-modules</module>
        <module>xinquan-api</module>
        <module>xinquan-common</module>
        <module>xinquan-modules/xinquan-user</module>
        <module>xinquan-modules/xinquan-course</module>
        <module>xinquan-modules/xinquan-meditation</module>
        <module>xinquan-modules/xinquan-order</module>
        <module>code-generator</module>
    </modules>
    <packaging>pom</packaging>
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java
@@ -8,7 +8,7 @@
 * @author mitao
 * @date 2024/8/21
 */
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.COURSE, fallbackFactory = RemoteCourseFallbackFactory.class)
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.COURSE_SERVICE, fallbackFactory = RemoteCourseFallbackFactory.class)
public interface RemoteCourseService {
}
xinquan-api/xinquan-api-course/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +0,0 @@
com.xinquan.course.api.factory.RemoteCourseFallbackFactory
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/DataUpdateHandlerConfig.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/HttpConfig.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/MybatisPlusConfig.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysUser.java
@@ -1,6 +1,7 @@
package com.xinquan.system.api.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.common.core.annotation.Excel.Type;
@@ -28,7 +29,7 @@
    /** 用户ID */
    @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
    @TableField("user_id")
    @TableId("user_id")
    private Long userId;
    /** 部门ID */
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/SysUserFallbackFactory.java
@@ -4,11 +4,9 @@
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.feignClient.SysUserClient;
import com.xinquan.system.api.model.*;
import java.util.List;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class SysUserFallbackFactory implements FallbackFactory<SysUserClient> {
    @Override
@@ -48,11 +46,6 @@
            @Override
            public R<List<SysUser>> queryUserByPhoneList(List<String> phoneList) {
                return R.fail("通过手机号集合查询用户失败:" + cause.getMessage());
            }
            @Override
            public R<Boolean> addUserRole(List<SysUserRoleDTO> dtoList) {
                return R.fail("默认批量添加修理厂失败:" + cause.getMessage());
            }
            @Override
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/feignClient/SysUserClient.java
@@ -5,7 +5,6 @@
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.factory.SysUserFallbackFactory;
import com.xinquan.system.api.model.SysUserRoleDTO;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@@ -52,14 +51,6 @@
     */
    @PostMapping("/user/queryUserByPhoneList")
    R<List<SysUser>>  queryUserByPhoneList(@RequestBody List<String> phoneList);
    /**
     * 默认批量添加修理厂
     * @param dtoList
     * @return
     */
    @PostMapping("/user/addUserRole")
    R<Boolean>  addUserRole(@RequestBody List<SysUserRoleDTO> dtoList);
    /**
     * 通过手机号查询用户
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppCaptchaBody.java
New file
@@ -0,0 +1,26 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/8/22
 */
@Data
@ApiModel(value = "APP端验证码对象", description = "APP端验证码对象")
public class AppCaptchaBody implements Serializable {
    private static final long serialVersionUID = 6079425494597881288L;
    @ApiModelProperty(value = "手机号")
    @NotBlank(message = "手机号不能为空")
    private String cellPhone;
    @ApiModelProperty("验证码")
    @NotBlank(message = "验证码不能为空")
    private String captcha;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppVerifyCellPhoneBody.java
New file
@@ -0,0 +1,28 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @author mitao
 * @date 2024/8/23
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "APP端验证手机号对象", description = "APP端验证手机号对象")
public class AppVerifyCellPhoneBody extends AppCaptchaBody {
    private static final long serialVersionUID = -6119279151800382508L;
    @NotBlank(message = "微信openid或苹果appleId不能为空")
    @ApiModelProperty(value = "微信openid或苹果appleId")
    private String wxOrAppleId;
    @NotNull(message = "登录类型不能为空")
    @ApiModelProperty(value = "登录类型 1=微信 2=苹果")
    private Integer loginType;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppWXLoginBody.java
New file
@@ -0,0 +1,49 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
/**
 * 用户登录对象
 *
 * @author ruoyi
 */
@Data
@ApiModel("APP用户微信登录对象")
public class AppWXLoginBody implements Serializable {
    private static final long serialVersionUID = 2440885532660952359L;
    /**
     * 微信openId
     */
    @ApiModelProperty(value = "微信openId")
    @NotBlank(message = "微信openId不能为空")
    private String wxOpenId;
    /**
     * 用户昵称
     */
    @ApiModelProperty(value = "用户昵称")
    @NotBlank(message = "用户昵称不能为空")
    private String nickname;
    /**
     * 用户头像
     */
    @ApiModelProperty(value = "用户头像")
    @NotBlank(message = "用户头像不能为空")
    private String headImgUrl;
    /**
     * 用户头像
     */
    @ApiModelProperty(value = "用户性别")
    @NotNull(message = "用户性别不能为空")
    private Integer sex;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/AppleLoginUser.java
New file
@@ -0,0 +1,18 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * 用户信息
 *
 * @author ruoyi
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "苹果登录用户信息")
public class AppleLoginUser extends WXLoginUser {
    private static final long serialVersionUID = 6891070491318038281L;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyAddSysUserDto.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanySysUserReq.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyUserListVo.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/LoginUser.java
@@ -1,14 +1,17 @@
package com.xinquan.system.api.model;
import com.xinquan.system.api.domain.SysUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Set;
import com.xinquan.system.api.domain.SysUser;
/**
 * 用户信息
 *
 * @author ruoyi
 */
@ApiModel(value = "登录用户信息")
public class LoginUser implements Serializable
{
    private static final long serialVersionUID = 1L;
@@ -16,46 +19,55 @@
    /**
     * 用户唯一标识
     */
    @ApiModelProperty(value = "用户唯一标识")
    private String token;
    /**
     * 用户名id
     * 用户id
     */
    @ApiModelProperty(value = "用户id")
    private Long userid;
    /**
     * 用户名
     */
    @ApiModelProperty(value = "用户名")
    private String username;
    /**
     * 登录时间
     */
    @ApiModelProperty(value = "登录时间")
    private Long loginTime;
    /**
     * 过期时间
     */
    @ApiModelProperty(value = "过期时间")
    private Long expireTime;
    /**
     * 登录IP地址
     */
    @ApiModelProperty(value = "登录IP地址")
    private String ipaddr;
    /**
     * 权限列表
     */
    @ApiModelProperty(value = "权限列表")
    private Set<String> permissions;
    /**
     * 角色列表
     */
    @ApiModelProperty(value = "角色列表")
    private Set<String> roles;
    /**
     * 用户信息
     */
    @ApiModelProperty(value = "用户信息")
    private SysUser sysUser;
    public String getToken()
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/SysUserRoleDTO.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAdd.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAddDto.java
File was deleted
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/WXLoginUser.java
New file
@@ -0,0 +1,68 @@
package com.xinquan.system.api.model;
import com.xinquan.system.api.domain.SysUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.Data;
/**
 * 用户信息
 *
 * @author ruoyi
 */
@Data
@ApiModel(value = "微信登录用户信息")
public class WXLoginUser implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 用户唯一标识
     */
    @ApiModelProperty(value = "APP用户id")
    private Long token;
    /**
     * 用户id
     */
    @ApiModelProperty(value = "用户id")
    private Long userid;
    /**
     * 用户名
     */
    @ApiModelProperty(value = "用户名")
    private String username;
    /**
     * 登录时间
     */
    @ApiModelProperty(value = "登录时间")
    private Long loginTime;
    /**
     * 过期时间
     */
    @ApiModelProperty(value = "过期时间")
    private Long expireTime;
    /**
     * 登录IP地址
     */
    @ApiModelProperty(value = "登录IP地址")
    private String ipaddr;
    @ApiModelProperty(value = "绑定手机号状态 1=是 2=否")
    private Integer bindStatus = 2;
    @ApiModelProperty(value = "用户手机")
    private String cellPhone;
    /**
     * 系统用户信息
     */
    @ApiModelProperty(value = "系统用户信息")
    private SysUser sysUser;
}
xinquan-api/xinquan-api-user/pom.xml
@@ -27,5 +27,12 @@
        </exclusion>
      </exclusions>
    </dependency>
    <!--system feign模块-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-api-system</artifactId>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/factory/RemoteAppUserFallbackFactory.java
@@ -1,6 +1,12 @@
package com.xinquan.user.api.factory;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.model.AppleLoginUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
@@ -28,6 +34,26 @@
            public R<Boolean> registerAppUser(AppUserDTO appUserDTO, String source) {
                return R.fail("APP用户注册失败。");
            }
            @Override
            public R<WXLoginUser> wxLogin(AppWXLoginBody body, String inner) {
                return R.fail("APP用户微信登录失败。");
            }
            @Override
            public R<AppleLoginUser> appleLogin(String appleId, String source) {
                return R.fail("APP用户苹果登录失败。");
            }
            @Override
            public R<LoginUser> appCaptchaLogin(AppCaptchaBody body, String source) {
                return R.fail("APP用户验证码登录失败。");
            }
            @Override
            public R<WXLoginUser> verifyCellPhone(AppVerifyCellPhoneBody body, String source) {
                return R.fail("APP用户微信苹果登录验证手机号失败。");
            }
        };
    }
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/feign/RemoteAppUserService.java
@@ -3,6 +3,12 @@
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.model.AppleLoginUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.factory.RemoteAppUserFallbackFactory;
@@ -10,16 +16,17 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * @author mitao
 * @date 2024/8/21
 */
@FeignClient(contextId = "remoteAppUserService", value = ServiceNameConstants.APP_USER, fallbackFactory = RemoteAppUserFallbackFactory.class)
@FeignClient(contextId = "remoteAppUserService", value = ServiceNameConstants.APP_USER_SERVICE, fallbackFactory = RemoteAppUserFallbackFactory.class)
public interface RemoteAppUserService {
    /**
     * 获取用户信息
     * 获取未注销的用户信息
     *
     * @param dto
     * @param source
@@ -30,7 +37,7 @@
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * app用户注册
     * APP用户注册
     *
     * @param appUserDTO
     * @param source
@@ -39,4 +46,48 @@
    @PostMapping("/inner/app-user/registerAppUser")
    R<Boolean> registerAppUser(@RequestBody AppUserDTO appUserDTO,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * APP微信登录
     *
     * @param body
     * @param source
     * @return
     */
    @PostMapping("/inner/app-user/wxLogin")
    R<WXLoginUser> wxLogin(@RequestBody AppWXLoginBody body,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * APP苹果登录
     *
     * @param appleId
     * @param source
     * @return
     */
    @PostMapping("/inner/app-user/appleLogin")
    R<AppleLoginUser> appleLogin(@RequestParam("appleId") String appleId,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * 验证码登录
     *
     * @param body
     * @param source
     * @return
     */
    @PostMapping("/inner/app-user/captchaLogin")
    R<LoginUser> appCaptchaLogin(@RequestBody AppCaptchaBody body,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * 微信苹果登录验证手机号码操作
     *
     * @param body
     * @param source
     * @return
     */
    @PostMapping("/inner/app-user/verifyCellPhone")
    R<WXLoginUser> verifyCellPhone(@RequestBody AppVerifyCellPhoneBody body,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
xinquan-auth/src/main/java/com/xinquan/auth/controller/TokenController.java
@@ -1,8 +1,11 @@
package com.xinquan.auth.controller;
import com.xinquan.auth.form.AppChangePwdBody;
import com.xinquan.auth.form.AppLoginBody;
import com.xinquan.auth.form.AppRegisterBody;
import com.xinquan.auth.form.LoginBody;
import com.xinquan.auth.form.RegisterBody;
import com.xinquan.auth.form.VerifyResultVO;
import com.xinquan.auth.service.SysLoginService;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.JwtUtils;
@@ -13,7 +16,12 @@
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.feignClient.SysUserClient;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.model.AppleLoginUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
@@ -23,6 +31,7 @@
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -52,11 +61,15 @@
     * @param cellPhone 手机号码
     * @return
     */
    @GetMapping("/app/send-captcha-code")
    @GetMapping("/app/sendCaptchaCode")
    @ApiOperation(value = "发送验证码",tags = {"APP端"})
    @ApiImplicitParams({@ApiImplicitParam(name = "cellPhone",value = "手机号码",required = true,dataType = "String",paramType = "query")})
    public R<?> sendCaptchaCode(@RequestParam("cellPhone") String cellPhone) {
        sysLoginService.sendCaptchaCode(cellPhone);
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cellPhone", value = "手机号码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型 1=注册 2=验证码登录 3=找回密码 4=第三方登录后验证手机", required = true, dataType = "Integer", paramType = "query")})
    public R<?> sendCaptchaCode(
            @RequestParam(value = "cellPhone", required = true) String cellPhone,
            @RequestParam("type") Integer type) {
        sysLoginService.sendCaptchaCode(cellPhone, type);
        return R.ok();
    }
@@ -67,13 +80,110 @@
     */
    @ApiOperation(value = "注册账户",tags = {"APP端"})
    @PostMapping("/app/register")
    public R<?> appRegister(@RequestBody AppRegisterBody appRegisterBody)
    public R<?> appRegister(@Validated @RequestBody AppRegisterBody appRegisterBody)
    {
        // 用户注册
        sysLoginService.appRegister(appRegisterBody);
        return R.ok();
    }
    /**
     * 账号密码登录
     *
     * @param body
     * @return
     */
    @ApiOperation(value = "账号密码登录", tags = {"APP端"})
    @PostMapping("/app/login")
    public R<?> appLogin(@Validated @RequestBody AppLoginBody body) {
        LoginUser userInfo = sysLoginService.appLogin(body);
        return R.ok(tokenService.createToken(userInfo));
    }
    /**
     * 验证码登录
     *
     * @param body
     * @return
     */
    @ApiOperation(value = "验证码登录", tags = {"APP端"})
    @PostMapping("/app/captchaLogin")
    public R<?> appCaptchaLogin(@Validated @RequestBody AppCaptchaBody body) {
        LoginUser userInfo = sysLoginService.appCaptchaLogin(body);
        return R.ok(tokenService.createToken(userInfo));
    }
    /**
     * 验证手机号
     *
     * @param body
     * @return
     */
    @ApiOperation(value = "忘记密码-验证手机号", tags = {"APP端"})
    @PostMapping("/app/verifyPhone")
    public R<VerifyResultVO> verifyPhone(@Validated @RequestBody AppCaptchaBody body) {
        return R.ok(sysLoginService.verifyPhone(body));
    }
    /**
     * 设置新密码
     *
     * @param body
     * @return
     */
    @ApiOperation(value = "设置新密码", tags = {"APP端"})
    @PostMapping("/app/changePassword")
    public R<?> changePassword(@Validated @RequestBody AppChangePwdBody body) {
        sysLoginService.changePassword(body);
        return R.ok();
    }
    /**
     * APP微信登录
     *
     * @param body
     * @return
     */
    @ApiOperation(value = "微信登录", tags = {"APP端"})
    @PostMapping("/app/wxLogin")
    public R<?> thirdLogin(@Validated @RequestBody AppWXLoginBody body) {
        WXLoginUser wxLoginUser = sysLoginService.wxLogin(body);
        return R.ok(tokenService.createToken4WXLoginUser(wxLoginUser));
    }
    /**
     * 苹果登录
     *
     * @param appleId
     * @return
     */
    @ApiOperation(value = "苹果登录", tags = {"APP端"})
    @PostMapping("/app/appleLogin")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appleId", value = "苹果ID", required = true, dataType = "String", paramType = "query")})
    public R<?> appleLogin(@RequestParam(value = "appleId", required = true) String appleId) {
        AppleLoginUser appleLoginUser = sysLoginService.appleLogin(appleId);
        return R.ok(tokenService.createToken4WXLoginUser(appleLoginUser));
    }
    /**
     * 微信苹果登录-验证手机号
     *
     * @param body
     * @return
     */
    @ApiOperation(value = "微信苹果登录-验证手机号", tags = {"APP端"})
    @PostMapping("/app/verifyCellPhone")
    public R<?> verifyCellPhone(@Validated @RequestBody AppVerifyCellPhoneBody body) {
        return R.ok(tokenService.createToken4WXLoginUser(sysLoginService.verifyCellPhone(body)));
    }
    /**
     * 管理后台登录
     *
     * @param form
     * @return
     */
    @ApiOperation(value = "管理后台登录",tags = {"管理后台"})
    @PostMapping("login")
    public R<?> login(@RequestBody LoginBody form)
xinquan-auth/src/main/java/com/xinquan/auth/form/AppChangePwdBody.java
New file
@@ -0,0 +1,29 @@
package com.xinquan.auth.form;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * 用户登录对象
 *
 * @author ruoyi
 */
@Data
@ApiModel("APP用户修改密码对象")
@EqualsAndHashCode(callSuper = true)
public class AppChangePwdBody extends AppLoginBody implements Serializable {
    private static final long serialVersionUID = 2440885532660952359L;
    /**
     * 用户密码
     */
    @ApiModelProperty(value = "密码修改秘钥")
    @NotBlank(message = "密码修改秘钥不能为空")
    private String secret;
}
xinquan-auth/src/main/java/com/xinquan/auth/form/AppLoginBody.java
New file
@@ -0,0 +1,34 @@
package com.xinquan.auth.form;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.Data;
/**
 * 用户登录对象
 *
 * @author ruoyi
 */
@Data
@ApiModel("APP用户登录对象")
public class AppLoginBody implements Serializable {
    private static final long serialVersionUID = 2440885532660952359L;
    /**
     * 手机号
     */
    @ApiModelProperty(value = "手机号")
    @NotBlank(message = "手机号不能为空")
    private String cellPhone;
    /**
     * 用户密码
     */
    @ApiModelProperty(value = "用户密码")
    @NotBlank(message = "密码不能为空")
    private String password;
}
xinquan-auth/src/main/java/com/xinquan/auth/form/AppRegisterBody.java
@@ -1,10 +1,12 @@
package com.xinquan.auth.form;
import com.xinquan.system.api.model.AppCaptchaBody;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * 用户注册对象
@@ -12,23 +14,16 @@
 * @author ruoyi
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "APP端注册对象", description = "APP端注册对象")
public class AppRegisterBody implements Serializable
public class AppRegisterBody extends AppCaptchaBody implements Serializable
{
    private static final long serialVersionUID = 438348119520198682L;
    @ApiModelProperty(value = "电话号码")
    @NotBlank(message = "电话号码不能为空")
    private String cellPhone;
    @ApiModelProperty(value = "用户密码")
    @NotBlank(message = "用户密码不能为空")
    private String password;
    @ApiModelProperty("验证码")
    @NotBlank(message = "验证码不能为空")
    private String verifyCode;
    @ApiModelProperty("邀请人id")
    private Long inviteUserId;
xinquan-auth/src/main/java/com/xinquan/auth/form/VerifyResultVO.java
New file
@@ -0,0 +1,23 @@
package com.xinquan.auth.form;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/8/22
 */
@Data
@ApiModel("手机号验证结果")
public class VerifyResultVO implements Serializable {
    private static final long serialVersionUID = -1642557986917707324L;
    @ApiModelProperty("密码修改秘钥")
    private String secret;
    @ApiModelProperty("是否验证成功")
    private Boolean successFlag;
}
xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java
@@ -2,12 +2,17 @@
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.xinquan.auth.form.AppChangePwdBody;
import com.xinquan.auth.form.AppLoginBody;
import com.xinquan.auth.form.AppRegisterBody;
import com.xinquan.auth.form.VerifyResultVO;
import com.xinquan.auth.util.HuaWeiSMSUtil;
import com.xinquan.common.core.constant.CacheConstants;
import com.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.UserConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.enums.AppUserStatusEnum;
import com.xinquan.common.core.enums.UserStatus;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.core.text.Convert;
@@ -17,7 +22,13 @@
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.feignClient.SysUserClient;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.model.AppleLoginUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
@@ -25,6 +36,8 @@
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -53,6 +66,8 @@
    @Autowired
    private RemoteAppUserService remoteAppUserService;
    @Autowired
    private SysUserClient sysUserClient;
    /**
     * 登录
     */
@@ -163,7 +178,8 @@
        String cellPhone = appRegisterBody.getCellPhone();
        String password = appRegisterBody.getPassword();
        //验证码校验
        if (!verifyCode(cellPhone, appRegisterBody.getVerifyCode()))
        if (!verifyCaptcha(cellPhone, appRegisterBody.getCaptcha(),
                CacheConstants.APP_REGISTER_CAPTCHA_CODE_PREFIX))
        {
            throw new ServiceException("验证码错误");
        }
@@ -211,14 +227,14 @@
    /**
     * 校验验证码
     * @param cellPhone 手机号
     * @param verifyCode 验证码
     * @param captcha 验证码
     * @return true/false
     */
    private boolean verifyCode(String cellPhone, String verifyCode) {
        if (StringUtils.isNotBlank(cellPhone) && StringUtils.isNotBlank(verifyCode)) {
            String key = CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone;
    private boolean verifyCaptcha(String cellPhone, String captcha, String keyPrefix) {
        if (StringUtils.isNotBlank(cellPhone) && StringUtils.isNotBlank(captcha)) {
            String key = keyPrefix + cellPhone;
            String code = redisService.getCacheObject(key);
            if (StringUtils.isNotBlank(code) && code.equals(verifyCode)) {
            if (StringUtils.isNotBlank(code) && code.equals(captcha)) {
                redisService.deleteObject(key);
                return true;
            }
@@ -227,25 +243,228 @@
    }
    /**
     * 发送验证码
     * @param cellPhone 手机号码
     * 根据类型获取对象的验证码key
     *
     * @param type
     * @return
     */
    public void sendCaptchaCode(String cellPhone) {
        Boolean result = redisService.hasKey(
                CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone);
    private String getCaptchaCodeByTypePrefix(Integer type) {
        switch (type) {
            case 1:
                return CacheConstants.APP_REGISTER_CAPTCHA_CODE_PREFIX;
            case 2:
                return CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX;
            case 3:
                return CacheConstants.APP_PASSWORD_CAPTCHA_CODE_PREFIX;
            case 4:
                return CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX;
            default:
                return "";
        }
    }
    /**
     * 发送验证码
     *
     * @param cellPhone 手机号码
     * @param type
     */
    public void sendCaptchaCode(String cellPhone, Integer type) {
        String key = getCaptchaCodeByTypePrefix(type);
        Boolean result = redisService.hasKey(key + cellPhone);
        if (result) {
            throw new ServiceException("请勿重复发送验证码");
        }
        String code = RandomUtil.randomNumbers(6);
        try {
            //TODO 发送短信
            log.info("发送验证码成功,手机号:{} 验证码:{}", cellPhone,code);
            log.info("发送验证码成功,手机号:{} 验证码:{}", cellPhone, code);
            // TODO 修改sender参数及templateId
            HuaWeiSMSUtil.sendSms("[\"" + code + "\"]", cellPhone, "8823121426646",
                    "cf1707ec44694627b1b483b0277e12fd");
        } catch (Exception e) {
            log.error("发送短信失败", e);
            throw new ServiceException("验证码发送失败");
        }
        //将验证码放入redis
        redisService.setCacheObject(CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone, code, 5L,
        redisService.setCacheObject(key + cellPhone, code, 5L,
                TimeUnit.MINUTES);
    }
    /**
     * APP账号密码登录
     *
     * @param body
     * @return
     */
    public LoginUser appLogin(AppLoginBody body) {
        // IP黑名单校验
        String blackStr = Convert.toStr(
                redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
            recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL,
                    "很遗憾,访问IP已被列入系统黑名单");
            throw new ServiceException("很遗憾,访问IP已被列入系统黑名单");
        }
        // 查询用户信息
        AppUser appUser = remoteAppUserService.getUserByCondition(
                AppUserDTO.builder().cellPhone(body.getCellPhone()).build(),
                SecurityConstants.INNER).getData();
        if (StringUtils.isNull(appUser)) {
            recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL,
                    "登录用户不存在");
            throw new ServiceException("登录用户:" + body.getCellPhone() + " 不存在");
        }
        // 1:正常 2:冻结 3:注销
        if (appUser.getUserStatus().equals(AppUserStatusEnum.FROZEN.getCode())) {
            recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL,
                    "账号已冻结");
            throw new ServiceException("账号已冻结");
        }
        if (appUser.getUserStatus().equals(AppUserStatusEnum.LOGOUT.getCode())) {
            recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL,
                    "账号已注销");
            throw new ServiceException("账号已注销");
        }
        // 查询系统用户信息
        SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
        if (StringUtils.isNull(sysUser)) {
            recordLogService.recordLogininfor(body.getCellPhone(), Constants.LOGIN_FAIL,
                    "登录用户不存在");
            throw new ServiceException("登录用户:" + body.getCellPhone() + " 不存在");
        }
        // 校验账号密码
        passwordService.validate(sysUser, body.getPassword());
        LoginUser userInfo = new LoginUser();
        userInfo.setSysUser(sysUser);
        recordLogService.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS,
                "登录成功");
        return userInfo;
    }
    /**
     * APP微信登录
     *
     * @param body
     * @return
     */
    public WXLoginUser wxLogin(AppWXLoginBody body) {
        // 通过wxOpenId查询APP用户信息
        R<WXLoginUser> userResult = remoteAppUserService.wxLogin(body, SecurityConstants.INNER);
        if (R.FAIL == userResult.getCode()) {
            throw new ServiceException(userResult.getMsg());
        }
        return userResult.getData();
    }
    /**
     * 苹果登录
     *
     * @param appleId 苹果id
     * @return
     */
    public AppleLoginUser appleLogin(String appleId) {
        R<AppleLoginUser> userResult = remoteAppUserService.appleLogin(appleId,
                SecurityConstants.INNER);
        if (R.FAIL == userResult.getCode()) {
            throw new ServiceException(userResult.getMsg());
        }
        return userResult.getData();
    }
    /**
     * 验证手机号
     *
     * @param body
     * @return
     */
    public VerifyResultVO verifyPhone(AppCaptchaBody body) {
        VerifyResultVO verifyResultVO = new VerifyResultVO();
        boolean b = verifyCaptcha(body.getCellPhone(), body.getCaptcha(),
                CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX);
        verifyResultVO.setSuccessFlag(b);
        if (b) {
            // 验证成功,删除验证码
            redisService.deleteObject(
                    CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX + body.getCellPhone());
            verifyResultVO.setSecret(IdUtil.randomUUID());
            redisService.setCacheObject(
                    CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone(),
                    verifyResultVO.getSecret(), 10L, TimeUnit.MINUTES);
        }
        return verifyResultVO;
    }
    public void changePassword(AppChangePwdBody body) {
        Object baseSecret = redisService.getCacheObject(
                CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone());
        if (Objects.isNull(baseSecret)) {
            throw new ServiceException("密码修改秘钥已失效,请重新校验手机号获取");
        }
        if (!body.getSecret().equals(baseSecret.toString())) {
            throw new ServiceException("密码修改秘钥不正确");
        }
        // 校验密码,密码至少8个字符,不能全是字母或者数字
        String regex = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$\n";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(body.getPassword());
        if (!matcher.matches()) {
            throw new ServiceException("密码至少8个字符,不能全是字母或者数字");
        }
        // 根据手机号查询用户
        AppUser appUser = remoteAppUserService.getUserByCondition(
                AppUserDTO.builder().cellPhone(body.getCellPhone()).build(),
                SecurityConstants.INNER).getData();
        if (Objects.isNull(appUser)) {
            throw new ServiceException("用户不存在或已注销");
        }
        // 查询系统用户
        SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
        if (Objects.isNull(sysUser)) {
            throw new ServiceException("用户不存在或已注销");
        }
        // 修改密码
        sysUser.setPassword(SecurityUtils.encryptPassword(body.getPassword()));
        sysUserClient.updateUser(sysUser);
        redisService.deleteObject(CacheConstants.APP_PASSWORD_SECRET_PREFIX + body.getCellPhone());
    }
    /**
     * 验证码登录
     *
     * @param body
     * @return
     */
    public LoginUser appCaptchaLogin(AppCaptchaBody body) {
        // 校验验证码
        if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(),
                CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX)) {
            throw new ServiceException("验证码不正确");
        }
        R<LoginUser> loginUserR = remoteAppUserService.appCaptchaLogin(body,
                SecurityConstants.INNER);
        if (R.FAIL == loginUserR.getCode()) {
            throw new ServiceException(loginUserR.getMsg());
        }
        return loginUserR.getData();
    }
    public WXLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) {
        String captcha = redisService.getCacheObject(
                CacheConstants.APP_VERIFY_CAPTCHA_CODE_PREFIX + body.getCellPhone());
        if (Objects.isNull(captcha)) {
            throw new ServiceException("验证码已失效,请重新获取");
        }
        // 校验验证码
        if (!verifyCaptcha(body.getCellPhone(), body.getCaptcha(),
                CacheConstants.APP_LOGIN_CAPTCHA_CODE_PREFIX)) {
            throw new ServiceException("验证码不正确");
        }
        // 更新用户系统用户信息
        R<WXLoginUser> result = remoteAppUserService.verifyCellPhone(body, SecurityConstants.INNER);
        if (R.FAIL == result.getCode()) {
            throw new ServiceException(result.getMsg());
        }
        return result.getData();
    }
}
xinquan-auth/src/main/java/com/xinquan/auth/util/HuaWeiSMSUtil.java
New file
@@ -0,0 +1,189 @@
package com.xinquan.auth.util;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
// 如果JDK版本是1.8,可使用原生Base64类
public class HuaWeiSMSUtil {
    // 无需修改,用于格式化鉴权头域,给"X-WSSE"参数赋值
    private static final String WSSE_HEADER_FORMAT = "UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"";
    // 无需修改,用于格式化鉴权头域,给"Authorization"参数赋值
    private static final String AUTH_HEADER_VALUE = "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"";
    public static void main(String[] args) throws Exception {
        sendSms("[\"" + 12356 + "\"]", "18283820718", "8823121426646",
                "cf1707ec44694627b1b483b0277e12fd");
//        sendSms("[\"17623778642\",\"蓉A-7823\"]","17623778642","8819122535459","6c848255000c4619833ab690e393f906");
//        sendSms("[\"17623778642\",\"蓉A-7823\",\"2019/12/27\",\"14:00\"]","17623778642","8819122535459","bb13d00d11e043659001a89c72d54cab");
    }
    /**
     * 调用短信
     *
     * @param code       入参
     * @param phone      接收短信手机号
     * @param sender     国内短信签名通道号或国际/港澳台短信通道号
     * @param templateId 模板ID
     * @throws Exception
     */
    public static void sendSms(String code, String phone, String sender, String templateId)
            throws Exception {
        // TODO 必填,请参考"开发准备"获取如下数据,替换为实际值
        String url = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1"; // APP接入地址+接口访问URI
        String appKey = "tTMBH29Tm6tKKHf882JXob82P1rb"; // APP_Key
        String appSecret = "Ob02q15WAgDZRwW9kDlVPklBSdfR"; // APP_Secret
        // 条件必填,国内短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
        // 国际/港澳台短信不用关注该参数
        String signature = null; // 签名名称
        // 必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔
        String receiver = "+86" + phone; // 短信接收人号码
        // 选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
        String statusCallBack = "";
        /**
         * 选填,使用无变量模板时请赋空值 String templateParas = "";
         * 单变量模板示例:模板内容为"您的验证码是${NUM_6}"时,templateParas可填写为"[\"369751\"]"
         * 双变量模板示例:模板内容为"您有${NUM_2}件快递请到${TXT_20}领取"时,templateParas可填写为"[\"3\",\"人民公园正门\"]"
         * ${DATE}${TIME}变量不允许取值为空,${TXT_20}变量可以使用英文空格或点号替代空值,${NUM_6}变量可以使用0替代空值
         * 查看更多模板和变量规范:产品介绍>模板和变量规范
         */
        String templateParas = code; // 模板变量
        // 请求Body,不携带签名名称时,signature请填null
        String body = buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack,
                signature);
        if (null == body || body.isEmpty()) {
            System.out.println("body is null.");
            return;
        }
        // 请求Headers中的X-WSSE参数值
        String wsseHeader = buildWsseHeader(appKey, appSecret);
        if (null == wsseHeader || wsseHeader.isEmpty()) {
            System.out.println("wsse header is null.");
            return;
        }
        // 如果JDK版本低于1.8,可使用如下代码
        // 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
        // CloseableHttpClient client = HttpClients.custom()
        //        .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
        //            @Override
        //            public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        //                return true;
        //            }
        //        }).build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
        // 如果JDK版本是1.8,可使用如下代码
        // 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
        CloseableHttpClient client = HttpClients.custom()
                .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null,
                        (x509CertChain, authType) -> true).build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
        HttpResponse response = client.execute(RequestBuilder.create("POST")// 请求方法POST
                .setUri(url)
                .addHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded")
                .addHeader(HttpHeaders.AUTHORIZATION, AUTH_HEADER_VALUE)
                .addHeader("X-WSSE", wsseHeader)
                .setEntity(new StringEntity(body)).build());
        System.out.println(response.toString()); // 打印响应头域信息
        System.out.println(EntityUtils.toString(response.getEntity())); // 打印响应消息实体
    }
    /**
     * 构造请求Body体
     *
     * @param sender
     * @param receiver
     * @param templateId
     * @param templateParas
     * @param statusCallbackUrl
     * @param signature         | 签名名称,使用国内短信通用模板时填写
     * @return
     */
    static String buildRequestBody(String sender, String receiver, String templateId,
            String templateParas,
            String statusCallbackUrl, String signature) {
        if (null == sender || null == receiver || null == templateId || sender.isEmpty()
                || receiver.isEmpty()
                || templateId.isEmpty()) {
            System.out.println("buildRequestBody(): sender, receiver or templateId is null.");
            return null;
        }
        List<NameValuePair> keyValues = new ArrayList<NameValuePair>();
        keyValues.add(new BasicNameValuePair("from", sender));
        keyValues.add(new BasicNameValuePair("to", receiver));
        keyValues.add(new BasicNameValuePair("templateId", templateId));
        if (null != templateParas && !templateParas.isEmpty()) {
            keyValues.add(new BasicNameValuePair("templateParas", templateParas));
        }
        if (null != statusCallbackUrl && !statusCallbackUrl.isEmpty()) {
            keyValues.add(new BasicNameValuePair("statusCallback", statusCallbackUrl));
        }
        if (null != signature && !signature.isEmpty()) {
            keyValues.add(new BasicNameValuePair("signature", signature));
        }
        return URLEncodedUtils.format(keyValues, Charset.forName("UTF-8"));
    }
    /**
     * 构造X-WSSE参数值
     *
     * @param appKey
     * @param appSecret
     * @return
     */
    static String buildWsseHeader(String appKey, String appSecret) {
        if (null == appKey || null == appSecret || appKey.isEmpty() || appSecret.isEmpty()) {
            System.out.println("buildWsseHeader(): appKey or appSecret is null.");
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        String time = sdf.format(new Date()); // Created
        String nonce = UUID.randomUUID().toString().replace("-", ""); // Nonce
        byte[] passwordDigest = DigestUtils.sha256(nonce + time + appSecret);
        String hexDigest = Hex.encodeHexString(passwordDigest);
        // 如果JDK版本是1.8,请加载原生Base64类,并使用如下代码
        String passwordDigestBase64Str = Base64.getEncoder()
                .encodeToString(hexDigest.getBytes()); // PasswordDigest
        // 如果JDK版本低于1.8,请加载三方库提供Base64类,并使用如下代码
        // String passwordDigestBase64Str = Base64.encodeBase64String(hexDigest.getBytes(Charset.forName("utf-8"))); //PasswordDigest
        // 若passwordDigestBase64Str中包含换行符,请执行如下代码进行修正
        // passwordDigestBase64Str = passwordDigestBase64Str.replaceAll("[\\s*\t\n\r]", "");
        return String.format(WSSE_HEADER_FORMAT, appKey, passwordDigestBase64Str, nonce, time);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/config/MybatisPlusConfig.java
New file
@@ -0,0 +1,58 @@
package com.xinquan.common.core.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
 * Mybatis Plus 配置
 *
 * @author ruoyi
 */
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(paginationInnerInterceptor());
        // 乐观锁插件
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
        // 阻断插件
        interceptor.addInnerInterceptor(blockAttackInnerInterceptor());
        return interceptor;
    }
    /**
     * 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
     */
    public PaginationInnerInterceptor paginationInnerInterceptor() {
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        // 设置数据库类型为mysql
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        paginationInnerInterceptor.setMaxLimit(-1L);
        return paginationInnerInterceptor;
    }
    /**
     * 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
     */
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
        return new OptimisticLockerInnerInterceptor();
    }
    /**
     * 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
     */
    public BlockAttackInnerInterceptor blockAttackInnerInterceptor() {
        return new BlockAttackInnerInterceptor();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/CacheConstants.java
@@ -56,5 +56,26 @@
     * 登录IP黑名单 cache key
     */
    public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList";
    public static final String APP_CAPTCHA_CODE_PREFIX = "app_captcha_code:";
    /**
     * APP注册验证码 redis key
     */
    public static final String APP_REGISTER_CAPTCHA_CODE_PREFIX = "app_register_captcha_code:";
    /**
     * APP登录验证码 redis key
     */
    public static final String APP_LOGIN_CAPTCHA_CODE_PREFIX = "app_login_captcha_code:";
    /**
     * APP修改密码验证码 redis key
     */
    public static final String APP_PASSWORD_CAPTCHA_CODE_PREFIX = "app_password_captcha_code:";
    /**
     * APP第三方登录手机号校验验证码 redis key
     */
    public static final String APP_VERIFY_CAPTCHA_CODE_PREFIX = "app_verify_captcha_code:";
    /**
     * APP第三方登录手机号校验验证码修改密码秘钥 redis key
     */
    public static final String APP_PASSWORD_SECRET_PREFIX = "app_password_secret:";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/Constants.java
@@ -133,4 +133,8 @@
     */
    public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
            "org.springframework", "org.apache", "com.xinquan.common.core.utils.file" };
    /**
     * 默认密码
     */
    public static final String DEFAULT_PASSWORD = "123456";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/SecurityConstants.java
@@ -18,6 +18,11 @@
    public static final String DETAILS_USERNAME = "username";
    /**
     * 登录端
     */
    public static final String LOGIN_FROM = "login_from";
    /**
     * 授权信息字段
     */
    public static final String AUTHORIZATION_HEADER = "Authorization";
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/ServiceNameConstants.java
@@ -24,15 +24,19 @@
    /**
     * 课程服务的serviceid
     */
    public static final String COURSE = "xinquan-course";
    public static final String COURSE_SERVICE = "xinquan-course";
    /**
     * 车辆服务的serviceid
     * 用户服务的serviceid
     */
    public static final String APP_USER = "xinquan-user";
    public static final String APP_USER_SERVICE = "xinquan-user";
    /**
     * 车辆合同的serviceid
     * 冥想服务的serviceid
     */
    public static final String CONTRACT_SERVICE = "xinquan-contract";
    public static final String MEDITATION_SERVICE = "xinquan-meditation";
    /**
     * 订单服务
     */
    public static final String ORDER_SERVICE = "xinquan-order";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AppUserStatusEnum.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum AppUserStatusEnum {
    NORMAL(1, "正常"),
    FROZEN(2, "冻结"),
    LOGOUT(3, "注销");
    private final Integer code;
    private final String desc;
    public static AppUserStatusEnum getEnumByCode(Integer code) {
        for (AppUserStatusEnum e : AppUserStatusEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ApproveConfigEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditStateEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditTypeEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarColorEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarStateEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ConfigEnum.java
New file
@@ -0,0 +1,63 @@
package com.xinquan.common.core.enums;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
/**
 * @ClassName ConfigEnum
 * @Description TODO
 * @Author jqs
 * @Date 2023/6/6 10:35
 * @Version 1.0
 */
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
@Getter
public enum ConfigEnum {
    PLATFORM_SERVICE_PHONE("PLATFORM_SERVICE_PHONE", 1, "客服电话"),
    PLATFORM_SERVICE_CODE("PLATFORM_SERVICE_CODE", 1, "客服二维码"),
    SHOP_EMERGENCY_DEGREE("SHOP_EMERGENCY_DEGREE", 3, "合作商任务紧急程度"),
    SHOP_FOLLOW_TYPE("SHOP_FOLLOW_TYPE", 3, "合作商跟进类型"),
    SHOP_CUSTOM_STATUS("SHOP_CUSTOM_STATUS", 3, "合作商状态"),
    SHOP_SOURCE_CHANNEL("SHOP_SOURCE_CHANNEL", 3, "来源渠道"),
    SHARE_INTEGRAL("SHARE_INTEGRAL", 2, "分享小程序可获得积分"),
    SUGGEST_PLATFORM_INTEGRAL("SUGGEST_PLATFORM_INTEGRAL", 2, "平台建议可获得积分"),
    SIGN_IN_INTEGRAL("SIGN_IN_INTEGRAL", 2, "每日签到可获得积分"),
    SUGGEST_SHOP_INTEGRAL("SUGGEST_SHOP_INTEGRAL", 2, "门店建议可获得积分"),
    ORDER_AUTO_CANCEL_TIME("ORDER_AUTO_CANCEL_TIME", 2, "C端订单自动取消时间"),
    PAY_MONEY_INTEGRAL("PAY_MONEY_INTEGRAL", 2, "购物满1元可获得积分"),
    MEMBER_SOURCE_CHANNEL("MEMBER_SOURCE_CHANNEL", 4, "会员来源"),
    MEMBER_CHARACTER("MEMBER_CHARACTER", 4, "会员性格"),
    MEMBER_LEVEL("MEMBER_LEVEL", 4, "会员等级"),
    MEMBER_TYPE("MEMBER_TYPE", 4, "会员类型"),
    NURSE_PROBLEM("NURSE_PROBLEM", 4, "调理问题"),
    HOME_STYLE("HOME_STYLE", 2, "首页风格"),
    HOME_SLOGAN("HOME_SLOGAN", 1, "首页广告语"),
    HOME_LOGO("HOME_LOGO", 1, "首页logo"),
    SHOP_COMMON_PROPORTION("SHOP_COMMON_PROPORTION", 3, "商户统一分成");
    private final String key;
    private final Integer keyType;
    private final String keyName;
    private static final Map<String, ConfigEnum> valueMap = new HashMap<>();
    static {
        for (ConfigEnum configEnum : ConfigEnum.values()) {
            valueMap.put(configEnum.keyName, configEnum);
        }
    }
    ConfigEnum(String key, Integer keyType, String keyName) {
        this.key = key;
        this.keyType = keyType;
        this.keyName = keyName;
    }
    public static ConfigEnum getByKeyName(String keyName) {
        return valueMap.get(keyName);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractStateEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractTypeEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/DisabledEnum.java
@@ -8,15 +8,15 @@
 * @Description
 * @date 2022-06-08 16:55
 */
@Getter
public enum DisabledEnum {
    NO(0, "否"),
    YES(1, "是");
    @Getter
    YES(1, "是"),
    NO(2, "否");
    private String desc;
    @Getter
    private int code;
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/HandoverStateEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ImportTypeEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/InsureTypeEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ListingStatusEnum.java
New file
@@ -0,0 +1,39 @@
package com.xinquan.common.core.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ListingStatusEnum {
    /*上架状态 0=上架中 1=已下架*/
    ON_SHELVES(0, "上架中"),
    REMOVED_FROM_THE_SHELF(1, "已下架");
    @EnumValue
    private final int code;
    @JsonValue
    private final String desc;
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static ListingStatusEnum fromCode(Integer code) {
        ListingStatusEnum[] resultTypes = ListingStatusEnum.values();
        for (ListingStatusEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PurchaseStateEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnCarTypeEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnStateEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/TreeLevelEnum.java
New file
@@ -0,0 +1,32 @@
package com.xinquan.common.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TreeLevelEnum {
    SEED(1, "种子", 0),
    SPROUTING(2, "发芽", 1000),
    SEEDLING(3, "幼苗", 2000),
    SMALL_SAPLINGS(4, "小树苗", 3000),
    MEDIUM_SIZED_SAPLINGS(5, "中等树苗", 4000),
    SMALL_TREE(5, "小树", 6000),
    MEDIUM_TREE(6, "中树", 8000),
    BIG_TREE(7, "大树", 10000),
    MATURE_TREE(8, "成熟的大树", 12000),
    TOWERING_TREES(8, "参天大树", 14400);
    private final Integer code;
    private final String desc;
    private final Integer growthValue;
    public static TreeLevelEnum getEnumByCode(Integer code) {
        for (TreeLevelEnum e : TreeLevelEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/WarrantyStateEnum.java
File was deleted
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseModel.java
@@ -3,7 +3,6 @@
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.time.LocalDateTime;
@@ -19,24 +18,24 @@
    /** 创建者 */
    @ApiModelProperty(value = "记录创建人,前端忽略")
    @TableField(value = "createBy", fill = FieldFill.INSERT)
    @TableField(value = "create_by", fill = FieldFill.INSERT)
    private String createBy;
    /** 创建时间 */
    @ApiModelProperty(value = "记录创建时间,前端忽略")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(value = "createTime", fill = FieldFill.INSERT)
    // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /** 更新者 */
    @ApiModelProperty(value = "记录修改人,前端忽略")
    @TableField(value = "updateBy", fill = FieldFill.INSERT_UPDATE)
    @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
    private String updateBy;
    /** 更新时间 */
    @ApiModelProperty(value = "记录修改时间,前端忽略")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE)
    // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    /** 是否删除 0未删除 1已删除 */
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/EnableCustomConfig.java
@@ -1,5 +1,7 @@
package com.xinquan.common.security.annotation;
import com.xinquan.common.security.config.ApplicationConfig;
import com.xinquan.common.security.feign.FeignAutoConfiguration;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@@ -10,8 +12,6 @@
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableAsync;
import com.xinquan.common.security.config.ApplicationConfig;
import com.xinquan.common.security.feign.FeignAutoConfiguration;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/JacksonConfig.java
@@ -1,33 +1,37 @@
package com.xinquan.common.security.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import java.math.BigInteger;
import java.time.format.DateTimeFormatter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
/**
 * Jackson配置
 */
@Configuration
@ConditionalOnClass(ObjectMapper.class)
public class JacksonConfig {
    @SuppressWarnings("deprecation")
    private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    private static final String DATE_PATTERN = "yyyy-MM-dd";
    @Bean
    public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
        final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        final ObjectMapper objectMapper = builder.build();
        SimpleModule simpleModule = new SimpleModule();
        // Long 转为 String 防止 js 丢失精度
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        // 忽略 transient 关键词属性
        objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
        return new MappingJackson2HttpMessageConverter(objectMapper);
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return jacksonObjectMapperBuilder -> {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(
                    DATE_TIME_PATTERN);
            jacksonObjectMapperBuilder.timeZone("GMT+8");
            jacksonObjectMapperBuilder.serializers(new LocalDateTimeSerializer(dateTimeFormatter));
            jacksonObjectMapperBuilder.deserializers(
                    new LocalDateTimeDeserializer(dateTimeFormatter));
            // long -> string
            jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
            jacksonObjectMapperBuilder.serializerByType(BigInteger.class,
                    ToStringSerializer.instance);
        };
    }
}
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/LocalDateTimeSerializerConfig.java
File was deleted
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/handler/MyMetaObjectHandler.java
New file
@@ -0,0 +1,44 @@
package com.xinquan.common.security.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.xinquan.common.security.utils.SecurityUtils;
import java.time.LocalDateTime;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
/**
 * 自动填充处理类
 *
 * @author mitao
 * @date 2024-05-16
 */
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        // 获取当前登录用户
        Long userId = SecurityUtils.getUserId();
        fillValue("createBy", userId.toString(), metaObject);
        fillValue("createTime", LocalDateTime.now(), metaObject);
    }
    @Override
    public void updateFill(MetaObject metaObject) {
        // 获取当前登录用户
        Long userId = SecurityUtils.getUserId();
        fillValue("updateBy", userId.toString(), metaObject);
        fillValue("updateTime", LocalDateTime.now(), metaObject);
    }
    private void fillValue(String fieldName, Object data, MetaObject metaObject) {
        if (metaObject.hasSetter(fieldName)) {
            // 值为空时设置默认值
            Object sidObj = getFieldValByName(fieldName, metaObject);
            if (sidObj == null || "updateBy".equals(fieldName) || "updateTime".equals(fieldName)) {
                setFieldValByName(fieldName, data, metaObject);
            }
        }
    }
}
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/service/TokenService.java
@@ -1,11 +1,5 @@
package com.xinquan.common.security.service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xinquan.common.core.constant.CacheConstants;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.utils.JwtUtils;
@@ -16,6 +10,13 @@
import com.xinquan.common.redis.service.RedisService;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
 * token验证处理
@@ -166,4 +167,36 @@
    {
        return ACCESS_TOKEN + token;
    }
    public Map<String, Object> createToken4WXLoginUser(WXLoginUser wxLoginUser) {
        LoginUser loginUser = new LoginUser();
        // Jwt存储信息
        Map<String, Object> claimsMap = new HashMap<String, Object>();
        // 接口返回信息
        Map<String, Object> rspMap = new HashMap<String, Object>();
        // 用户为空只返回openid
        rspMap.put("cellPhone", "");
        rspMap.put("access_token", "");
        if (wxLoginUser.getSysUser() != null) {
            loginUser.setSysUser(wxLoginUser.getSysUser());
            String token = IdUtils.fastUUID();
            Long userId = loginUser.getSysUser().getUserId();
            String userName = loginUser.getSysUser().getUserName();
            loginUser.setToken(token);
            loginUser.setUserid(userId);
            loginUser.setIpaddr(IpUtils.getIpAddr());
            refreshToken(loginUser);
            claimsMap.put(SecurityConstants.USER_KEY, token);
            claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
            claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
            if (StringUtils.isNotBlank(wxLoginUser.getCellPhone())) {
                rspMap.put("cellPhone", wxLoginUser.getCellPhone());
            } else {
                rspMap.put("cellPhone", "");
            }
            rspMap.put("access_token", JwtUtils.createToken(claimsMap));
            rspMap.put("expires_in", expireTime);
        }
        return rspMap;
    }
}
xinquan-common/xinquan-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -3,5 +3,5 @@
com.xinquan.common.security.aspect.PreAuthorizeAspect
com.xinquan.common.security.aspect.InnerAuthAspect
com.xinquan.common.security.handler.GlobalExceptionHandler
com.xinquan.common.security.handler.MyMetaObjectHandler
com.xinquan.common.security.config.JacksonConfig
com.xinquan.common.security.config.LocalDateTimeSerializerConfig
xinquan-gateway/src/main/java/com/xinquan/gateway/config/SwaggerProvider.java
@@ -56,6 +56,10 @@
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName()))
                        // .filter(predicateDefinition -> !"xinquan-auth".equalsIgnoreCase(routeDefinition.getId()))
                        .filter(predicateDefinition -> !"xinquan-gen".equalsIgnoreCase(
                                routeDefinition.getId()))
                        .filter(predicateDefinition -> !"xinquan-job".equalsIgnoreCase(
                                routeDefinition.getId()))
                        .forEach(predicateDefinition -> resourceList
                                .add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs()
                                        .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL)))));
xinquan-modules/pom.xml
@@ -13,6 +13,11 @@
        <module>xinquan-gen</module>
        <module>xinquan-job</module>
        <module>xinquan-file</module>
        <module>xinquan-user</module>
        <module>xinquan-meditation</module>
        <module>xinquan-course</module>
        <module>xinquan-order</module>
    </modules>
    <artifactId>xinquan-modules</artifactId>
xinquan-modules/xinquan-course/pom.xml
@@ -5,12 +5,11 @@
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan</artifactId>
    <artifactId>xinquan-modules</artifactId>
    <version>3.6.2</version>
    <relativePath>../../pom.xml</relativePath>
  </parent>
  <artifactId>xinquan-course</artifactId>
  <artifactId>xinquan-modules-course</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
@@ -19,13 +18,6 @@
  </properties>
  <dependencies>
    <!--system feign模块-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-api-system</artifactId>
      <scope>compile</scope>
    </dependency>
    <!--user feign模块-->
    <dependency>
xinquan-modules/xinquan-file/pom.xml
@@ -65,7 +65,18 @@
            <groupId>com.xinquan</groupId>
            <artifactId>xinquan-common-swagger</artifactId>
        </dependency>
        <!--华为云OBS-->
        <dependency>
            <groupId>com.huaweicloud</groupId>
            <artifactId>esdk-obs-java</artifactId>
            <version>3.19.5</version>
            <exclusions>
                <exclusion>
                    <artifactId>okio</artifactId>
                    <groupId>com.squareup.okio</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/controller/SysFileController.java
@@ -1,15 +1,17 @@
package com.xinquan.file.controller;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.file.FileUtils;
import com.xinquan.file.service.ISysFileService;
import com.xinquan.file.utils.ObsUploadUtil;
import com.xinquan.system.api.domain.SysFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.file.FileUtils;
import com.xinquan.file.service.ISysFileService;
import com.xinquan.system.api.domain.SysFile;
/**
 * 文件请求处理
@@ -45,4 +47,22 @@
            return R.fail(e.getMessage());
        }
    }
    /**
     * 文件上传请求
     */
    @PostMapping("obs-upload")
    public R<String> uploadOSS(@RequestPart("file") MultipartFile file) {
        try {
            // 上传并返回访问地址
            String fileName = file.getOriginalFilename();
            String prefix = fileName.substring(fileName.lastIndexOf("."));
            long fileSize = file.getSize();
            String url = ObsUploadUtil.obsUpload(file);
            return R.ok(url);
        } catch (Exception e) {
            log.error("上传文件失败", e);
            return R.fail(e.getMessage());
        }
    }
}
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/utils/ObsUploadUtil.java
New file
@@ -0,0 +1,77 @@
package com.xinquan.file.utils;
import com.obs.services.ObsClient;
import com.obs.services.model.ObjectMetadata;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import org.springframework.web.multipart.MultipartFile;
public class ObsUploadUtil {
    // OBS图片访问域名 TODO 修改正式参数
    public static String endPoint = "obs.cn-southwest-2.myhuaweicloud.com";
    public static String accessKeyId = "IZB26ZHC7C5MWIOH1TGE";
    public static String accessKeySecret = "y5PXhFMDOHiPH0nnQMz4gkvA63oqKAC621zXzOPk";
    public static String bucketName = "mimishejiao";
    public static String oss_domain = "https://mimishejiao.obs.cn-southwest-2.myhuaweicloud.com/";
    // 创建ObsClient实例
    public static ObsClient obsClient = new ObsClient(accessKeyId, accessKeySecret, endPoint);
    public static String obsUpload(MultipartFile file)
            throws IOException {
        String fileName = "";
        if (file != null && !"".equals(file.getOriginalFilename())
                && file.getOriginalFilename() != null) {
            InputStream content = file.getInputStream();// 获得指定文件的输入流
            ObjectMetadata meta = new ObjectMetadata();// 创建上传Object的Metadata
            meta.setContentLength(file.getSize());  // 必须设置ContentLength
            String originalFilename = file.getOriginalFilename();
            fileName =
                    UUID.randomUUID().toString().replaceAll("-", "") + originalFilename.subSequence(
                            originalFilename.lastIndexOf("."), originalFilename.length());
            obsClient.putObject(bucketName, "xinquan/" + fileName, content, meta);// 上传Object.
            if (fileName != null && !"".equals(fileName)) {
                System.out.println(fileName);
                fileName = oss_domain + "admin/" + fileName;
            }
        }
        return fileName;
    }
    /**
     * 删除某个Object
     *
     * @param bucketUrl
     * @return
     */
    public static boolean deleteObject(String bucketUrl) {
        try {
            bucketUrl = bucketUrl.replace(oss_domain + "admin/", "");
            // 删除Object.
            obsClient.deleteObject(bucketName, bucketUrl);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            // ossClient.shutdown();
        }
        return true;
    }
//     public static void createBucket(String bucketName)
//     {
//         //初始化 OSSClient
////          ossClient = new OssClient(endPoint, accessKeyId, accessKeySecret);
//
//         // 新建一个Bucket
//         Bucket bucket = ossClient.createBucket(bucketName);
//         System.out.println(bucket.getName());
//         System.out.println(bucket.getCreationDate());
//     }
//
//     public static void main(String[] args) {
//         OssUploadUtil.createBucket("ssfdfsd");
//    }
}
xinquan-modules/xinquan-gen/pom.xml
@@ -88,25 +88,6 @@
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity-engine-core -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
xinquan-modules/xinquan-meditation/pom.xml
@@ -5,12 +5,11 @@
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan</artifactId>
    <artifactId>xinquan-modules</artifactId>
    <version>3.6.2</version>
    <relativePath>../../pom.xml</relativePath>
  </parent>
  <artifactId>xinquan-meditation</artifactId>
  <artifactId>xinquan-modules-meditation</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
@@ -19,13 +18,6 @@
  </properties>
  <dependencies>
    <!--system feign模块-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-api-system</artifactId>
      <scope>compile</scope>
    </dependency>
    <!--user feign模块-->
    <dependency>
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/HomeBackgroundMusicController.java
File was renamed from xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/HomeBackgroundMusicController.java
@@ -1,8 +1,7 @@
package com.xinquan.system.controller;
package com.xinquan.meditation.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/HomeBackgroundMusicUserController.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.meditation.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 首页背景音乐用户关系表         前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@RestController
@RequestMapping("/meditation/home-background-music-user")
public class HomeBackgroundMusicUserController {
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/HomeBackgroundMusic.java
File was renamed from xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/HomeBackgroundMusic.java
@@ -1,10 +1,10 @@
package com.xinquan.system.domain;
package com.xinquan.meditation.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -27,7 +27,7 @@
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "首页背景音乐id")
    @TableId(value = "id", type = IdType.AUTO)
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "背景图片")
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/HomeBackgroundMusicUser.java
New file
@@ -0,0 +1,42 @@
package com.xinquan.meditation.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 * 首页背景音乐用户关系表
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_home_background_music_user")
@ApiModel(value = "HomeBackgroundMusicUser对象", description = "首页背景音乐用户关系表")
public class HomeBackgroundMusicUser extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "首页背景音乐用户关系id")
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "用户id")
    @TableField("app_user_id")
    private Long appUserId;
    @ApiModelProperty(value = "首页音频id")
    @TableField("home_background_music_id")
    private Long homeBackgroundMusicId;
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/HomeBackgroundMusicMapper.java
File was renamed from xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/HomeBackgroundMusicMapper.java
@@ -1,7 +1,7 @@
package com.xinquan.system.mapper;
package com.xinquan.meditation.mapper;
import com.xinquan.system.domain.HomeBackgroundMusic;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xinquan.meditation.domain.HomeBackgroundMusic;
/**
 * <p>
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/HomeBackgroundMusicUserMapper.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.meditation.mapper;
import com.xinquan.meditation.domain.HomeBackgroundMusicUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * <p>
 * 首页背景音乐用户关系表         Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface HomeBackgroundMusicUserMapper extends BaseMapper<HomeBackgroundMusicUser> {
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/HomeBackgroundMusicUserService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.meditation.service;
import com.xinquan.meditation.domain.HomeBackgroundMusicUser;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 首页背景音乐用户关系表         服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface HomeBackgroundMusicUserService extends IService<HomeBackgroundMusicUser> {
}
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/HomeBackgroundMusicUserServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.meditation.service.impl;
import com.xinquan.meditation.domain.HomeBackgroundMusicUser;
import com.xinquan.meditation.mapper.HomeBackgroundMusicUserMapper;
import com.xinquan.meditation.service.HomeBackgroundMusicUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 首页背景音乐用户关系表         服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class HomeBackgroundMusicUserServiceImpl extends ServiceImpl<HomeBackgroundMusicUserMapper, HomeBackgroundMusicUser> implements HomeBackgroundMusicUserService {
}
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/HomeBackgroundMusicMapper.xml
File was renamed from xinquan-modules/xinquan-system/src/main/resources/mapper/system/HomeBackgroundMusicMapper.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinquan.system.mapper.HomeBackgroundMusicMapper">
<mapper namespace="com.xinquan.meditation.mapper.HomeBackgroundMusicMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.system.domain.HomeBackgroundMusic">
    <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.HomeBackgroundMusic">
        <id column="id" property="id" />
        <result column="del_flag" property="delFlag" />
        <result column="create_by" property="createBy" />
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/HomeBackgroundMusicUserMapper.xml
New file
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinquan.meditation.mapper.HomeBackgroundMusicUserMapper">
  <!-- 通用查询映射结果 -->
  <resultMap id="BaseResultMap" type="com.xinquan.meditation.domain.HomeBackgroundMusicUser">
    <id column="id" property="id"/>
    <result column="app_user_id" property="appUserId"/>
    <result column="home_background_music_id" property="homeBackgroundMusicId"/>
  </resultMap>
  <!-- 通用查询结果列 -->
  <sql id="Base_Column_List">
    id, app_user_id, home_background_music_id
  </sql>
</mapper>
xinquan-modules/xinquan-order/pom.xml
@@ -5,12 +5,11 @@
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan</artifactId>
    <artifactId>xinquan-modules</artifactId>
    <version>3.6.2</version>
    <relativePath>../../pom.xml</relativePath>
  </parent>
  <artifactId>xinquan-order</artifactId>
  <artifactId>xinquan-modules-order</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
@@ -19,13 +18,6 @@
  </properties>
  <dependencies>
    <!--system feign模块-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-api-system</artifactId>
      <scope>compile</scope>
    </dependency>
    <!--user feign模块-->
    <dependency>
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderPaymentRecordService.java
@@ -1,7 +1,7 @@
package com.xinquan.order.service;
import com.xinquan.order.domain.OrderPaymentRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.order.domain.OrderPaymentRecord;
/**
 * <p>
xinquan-modules/xinquan-system/pom.xml
@@ -143,6 +143,11 @@
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/client/PublicController.java
New file
@@ -0,0 +1,38 @@
package com.xinquan.system.controller.client;
import com.xinquan.common.core.web.domain.AjaxResult;
import com.xinquan.system.service.PublicService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author mitao
 * @date 2024/8/23
 */
@Slf4j
@Api(tags = {"公共接口"})
@RestController
@RequestMapping("/public")
@RequiredArgsConstructor
public class PublicController {
    private final PublicService publicService;
    @ApiOperation(value = "获取用户协议、隐私协议、关于心泉、新手冥想指南、课程/冥想音频购买协议")
    @GetMapping("/getContent")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "key", value = "用户内容 1=用户协议 2=隐私协议 3=关于心泉 4=新手冥想指南 5=课程/冥想音频购买协议",
                    required = true, type = "Integer", paramType = "query")})
    public AjaxResult getContent(
            @RequestParam(value = "key", required = true) Integer key) {
        return AjaxResult.success(publicService.getContent(key));
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/TreeLevelSetting.java
@@ -1,10 +1,10 @@
package com.xinquan.system.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -30,6 +30,10 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "树苗等级类型 1=种子 2=发芽 3=幼苗 4=小树苗 5=中等树苗 6=小树 7=中树 8=大树 9=成熟的大树 10=参天大树")
    @TableField("tree_level_type")
    private Integer treeLevelType;
    @ApiModelProperty(value = "树苗阶段")
    @TableField("level_name")
    private String levelName;
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/UserLevelSetting.java
@@ -1,10 +1,10 @@
package com.xinquan.system.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -30,9 +30,9 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "树苗设置id")
    @TableField("tree_level_setting_id")
    private Integer treeLevelSettingId;
    @ApiModelProperty(value = "树苗等级类型 1=种子 2=发芽 3=幼苗 4=小树苗 5=中等树苗 6=小树 7=中树 8=大树 9=成熟的大树 10=参天大树")
    @TableField("tree_level_type")
    private Integer treeLevelType;
    @ApiModelProperty(value = "等级图标")
    @TableField("level_icon")
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/ContentSettingVO.java
New file
@@ -0,0 +1,23 @@
package com.xinquan.system.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.Data;
@Data
@ApiModel(value = "ContentSettingVO对象", description = "内容设置视图对象")
public class ContentSettingVO implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "内容id")
    private Long id;
    @ApiModelProperty(value = "内容类型 1=用户协议 2=隐私协议 3=关于心泉 4= 新手冥想指南 5=课程/冥想音频购买协议")
    private Integer contentType;
    @ApiModelProperty(value = "内容")
    private String content;
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/BannerService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.Banner;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 用户信息表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface BannerService extends IService<Banner> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/CommonQuestionService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.CommonQuestion;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 常见问题表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface CommonQuestionService extends IService<CommonQuestion> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ContentSettingService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.ContentSetting;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 内容设置表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface ContentSettingService extends IService<ContentSetting> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/CustomConfigService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.CustomConfig;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 系统配置 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface CustomConfigService extends IService<CustomConfig> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/HotWordsService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.HotWords;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 热词表     服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface HotWordsService extends IService<HotWords> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/PublicService.java
New file
@@ -0,0 +1,34 @@
package com.xinquan.system.service;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.system.domain.ContentSetting;
import com.xinquan.system.domain.vo.ContentSettingVO;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * @author mitao
 * @date 2024/8/23
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PublicService {
    private final ContentSettingService contentSettingService;
    /**
     * 根据key获取内容
     *
     * @param key
     * @return
     */
    public ContentSettingVO getContent(Integer key) {
        Optional<ContentSetting> contentSetting = contentSettingService.lambdaQuery()
                .eq(ContentSetting::getContentType, key).oneOpt();
        return contentSetting.map(setting -> BeanUtils.copyBean(setting, ContentSettingVO.class))
                .orElse(null);
    }
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/TreeLevelSettingService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.TreeLevelSetting;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 树苗音频表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface TreeLevelSettingService extends IService<TreeLevelSetting> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/UserLevelSettingService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.UserLevelSetting;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 用户等级表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface UserLevelSettingService extends IService<UserLevelSetting> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/VersionService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.Version;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 版本表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface VersionService extends IService<Version> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/VipSettingService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.service;
import com.xinquan.system.domain.VipSetting;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 会员设置表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
public interface VipSettingService extends IService<VipSetting> {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/BannerServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.Banner;
import com.xinquan.system.mapper.BannerMapper;
import com.xinquan.system.service.BannerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class BannerServiceImpl extends ServiceImpl<BannerMapper, Banner> implements BannerService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/CommonQuestionServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.CommonQuestion;
import com.xinquan.system.mapper.CommonQuestionMapper;
import com.xinquan.system.service.CommonQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 常见问题表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class CommonQuestionServiceImpl extends ServiceImpl<CommonQuestionMapper, CommonQuestion> implements CommonQuestionService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/ContentSettingServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.ContentSetting;
import com.xinquan.system.mapper.ContentSettingMapper;
import com.xinquan.system.service.ContentSettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 内容设置表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class ContentSettingServiceImpl extends ServiceImpl<ContentSettingMapper, ContentSetting> implements ContentSettingService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/CustomConfigServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.CustomConfig;
import com.xinquan.system.mapper.CustomConfigMapper;
import com.xinquan.system.service.CustomConfigService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 系统配置 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class CustomConfigServiceImpl extends ServiceImpl<CustomConfigMapper, CustomConfig> implements CustomConfigService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/HotWordsServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.HotWords;
import com.xinquan.system.mapper.HotWordsMapper;
import com.xinquan.system.service.HotWordsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 热词表     服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class HotWordsServiceImpl extends ServiceImpl<HotWordsMapper, HotWords> implements HotWordsService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/TreeLevelSettingServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.TreeLevelSetting;
import com.xinquan.system.mapper.TreeLevelSettingMapper;
import com.xinquan.system.service.TreeLevelSettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 树苗音频表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class TreeLevelSettingServiceImpl extends ServiceImpl<TreeLevelSettingMapper, TreeLevelSetting> implements TreeLevelSettingService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/UserLevelSettingServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.UserLevelSetting;
import com.xinquan.system.mapper.UserLevelSettingMapper;
import com.xinquan.system.service.UserLevelSettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 用户等级表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class UserLevelSettingServiceImpl extends ServiceImpl<UserLevelSettingMapper, UserLevelSetting> implements UserLevelSettingService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/VersionServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.Version;
import com.xinquan.system.mapper.VersionMapper;
import com.xinquan.system.service.VersionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 版本表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class VersionServiceImpl extends ServiceImpl<VersionMapper, Version> implements VersionService {
}
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/VipSettingServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.system.service.impl;
import com.xinquan.system.domain.VipSetting;
import com.xinquan.system.mapper.VipSettingMapper;
import com.xinquan.system.service.VipSettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 会员设置表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-23
 */
@Service
public class VipSettingServiceImpl extends ServiceImpl<VipSettingMapper, VipSetting> implements VipSettingService {
}
xinquan-modules/xinquan-system/src/main/resources/mapper/system/TreeLevelSettingMapper.xml
@@ -10,6 +10,7 @@
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="tree_level_type" property="treeLevelType"/>
        <result column="level_name" property="levelName" />
        <result column="growth_value" property="growthValue" />
        <result column="grow_up_music" property="growUpMusic" />
xinquan-modules/xinquan-system/src/main/resources/mapper/system/UserLevelSettingMapper.xml
@@ -10,7 +10,7 @@
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="tree_level_setting_id" property="treeLevelSettingId" />
        <result column="tree_level_type" property="treeLevelType"/>
        <result column="level_icon" property="levelIcon" />
        <result column="level_name" property="levelName" />
        <result column="growth_value" property="growthValue" />
xinquan-modules/xinquan-user/pom.xml
@@ -5,12 +5,11 @@
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan</artifactId>
    <artifactId>xinquan-modules</artifactId>
    <version>3.6.2</version>
    <relativePath>../../pom.xml</relativePath>
  </parent>
  <artifactId>xinquan-user</artifactId>
  <artifactId>xinquan-modules-user</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
@@ -19,12 +18,6 @@
  </properties>
  <dependencies>
    <!--system feign模块-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-api-system</artifactId>
      <scope>compile</scope>
    </dependency>
    <!--user feign模块-->
    <dependency>
@@ -117,6 +110,7 @@
    <!-- 引入Druid依赖,阿里巴巴所提供的数据源 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>${druid.version}</version>
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserQuestionController.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.user.controller.client;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 用户计划引导页问题记录表 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-08-24
 */
@RestController
@RequestMapping("/client/user/app-user-question")
public class ClientAppUserQuestionController {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/inner/InnerAppUserController.java
@@ -2,14 +2,22 @@
import com.xinquan.common.core.domain.R;
import com.xinquan.common.security.annotation.InnerAuth;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.model.AppleLoginUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.service.AppUserService;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -31,17 +39,67 @@
     */
    @InnerAuth
    @PostMapping("/getUserByCondition")
    R<AppUser> getUserByCondition(@RequestBody AppUserDTO dto){
    R<Optional<AppUser>> getUserByCondition(@RequestBody AppUserDTO dto) {
        return R.ok(appUserService.getUserByCondition(dto));
    }
    /**
     * app用户注册
     * APP用户注册
     * @param appUserDTO
     * @return
     */
    @InnerAuth
    @PostMapping("/registerAppUser")
    R<Boolean> registerAppUser(@RequestBody AppUserDTO appUserDTO){
        return R.ok(appUserService.registerAppUser(appUserDTO));
    }
    /**
     * APP微信登录
     *
     * @param body
     * @return
     */
    @InnerAuth
    @PostMapping("/wxLogin")
    R<WXLoginUser> wxLogin(@RequestBody AppWXLoginBody body) {
        return R.ok(appUserService.wxLogin(body));
    }
    /**
     * APP苹果登录
     *
     * @param appleId
     * @param source
     * @return
     */
    @InnerAuth
    @PostMapping("/appleLogin")
    R<AppleLoginUser> appleLogin(@RequestParam("appleId") String appleId) {
        return R.ok(appUserService.appleLogin(appleId));
    }
    /**
     * 验证码登录
     *
     * @param body
     * @return
     */
    @InnerAuth
    @PostMapping("/captchaLogin")
    R<LoginUser> appCaptchaLogin(@RequestBody AppCaptchaBody body) {
        return R.ok(appUserService.appCaptchaLogin(body));
    }
    /**
     * 微信苹果登录验证手机号码操作
     *
     * @param body
     * @return
     */
    @InnerAuth
    @PostMapping("/verifyCellPhone")
    R<WXLoginUser> verifyCellPhone(@RequestBody AppVerifyCellPhoneBody body) {
        return R.ok(appUserService.verifyCellPhone(body));
    }
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserBankController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserCourseController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserEnergyRecordController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserMeditationController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTagController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTreeController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWalletRecordController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWithdrawController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeRedemptionRecordController.java
@@ -1,8 +1,7 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtTagController.java
@@ -1,8 +1,9 @@
package com.xinquan.controller;
package com.xinquan.user.controller.management;
import com.xinquan.user.service.TagService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -13,9 +14,29 @@
 * @author mitao
 * @since 2024-08-21
 */
@Api(value = "管理后台接口", tags = "管理后台接口")
@RestController
@RequestMapping("/mgt/tag")
@RequiredArgsConstructor
public class MgtTagController {
    private final TagService tagService;
/*    @ApiOperation(value = "添加用户标签")
    @PostMapping("save")
    public AjaxResult save(@RequestBody Tag tag) {
        tagService.save(tag);
        return AjaxResult.success();
    }
    @ApiOperation(value = "获取用户标签")
    @GetMapping("/{id}")
    @ApiParam(value = "标签id")
    public AjaxResult save(@PathVariable("id") Long id) {
        Tag byId = tagService.getById(id);
        return AjaxResult.success(byId);
    }*/
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserQuestion.java
New file
@@ -0,0 +1,41 @@
package com.xinquan.user.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 * 用户计划引导页问题记录表
 * </p>
 *
 * @author mitao
 * @since 2024-08-24
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_app_user_question")
@ApiModel(value="AppUserQuestion对象", description="用户计划引导页问题记录表")
public class AppUserQuestion extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "用户计划引导问题记录表")
    @TableId("id")
    private Long id;
    @ApiModelProperty(value = "1:您是否内心纠结敏感多疑?2:您是否辗转反侧彻夜难眠?3:您是否情绪失控暴躁易怒?4:您是否沉迷情感倍受伤害?5:您是否人生迷茫踌躇彷徨?6:其它补充说明")
    @TableField("type")
    private Integer type;
    @ApiModelProperty(value = "回答 1:是2:否3:偶尔有")
    @TableField("answer")
    private Integer answer;
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserTree.java
@@ -1,10 +1,10 @@
package com.xinquan.user.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -34,9 +34,9 @@
    @TableField("app_user_id")
    private Long appUserId;
    @ApiModelProperty(value = "树苗等级id")
    @TableField("tree_level_id")
    private Integer treeLevelId;
    @ApiModelProperty(value = "树苗等级类型 1=种子 2=发芽 3=幼苗 4=小树苗 5=中等树苗 6=小树 7=中树 8=大树 9=成熟的大树 10=参天大树")
    @TableField("tree_level_type")
    private Integer treeLevelType;
    @ApiModelProperty(value = "成长值")
    @TableField("growth_value")
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/Tag.java
@@ -34,5 +34,4 @@
    @TableField("tag_name")
    private String tagName;
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserQuestionMapper.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.user.mapper;
import com.xinquan.user.domain.AppUserQuestion;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * <p>
 * 用户计划引导页问题记录表 Mapper 接口
 * </p>
 *
 * @author mitao
 * @since 2024-08-24
 */
public interface AppUserQuestionMapper extends BaseMapper<AppUserQuestion> {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserQuestionService.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.user.service;
import com.xinquan.user.domain.AppUserQuestion;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 用户计划引导页问题记录表 服务类
 * </p>
 *
 * @author mitao
 * @since 2024-08-24
 */
public interface AppUserQuestionService extends IService<AppUserQuestion> {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserService.java
@@ -1,8 +1,15 @@
package com.xinquan.user.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.model.AppleLoginUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import java.util.Optional;
/**
 * <p>
@@ -15,14 +22,49 @@
public interface AppUserService extends IService<AppUser> {
    /**
     * 获取用户信息
     *
     * @param dto
     * @return
     */
    AppUser getUserByCondition(AppUserDTO dto);
    Optional<AppUser> getUserByCondition(AppUserDTO dto);
    /**
     * app用户注册
     * @param appUserDTO
     * @return
     */
    Boolean registerAppUser(AppUserDTO appUserDTO);
    /**
     * APP微信登录
     *
     * @param body
     * @return
     */
    WXLoginUser wxLogin(AppWXLoginBody body);
    /**
     * 苹果登录
     *
     * @param appleId
     * @param source
     * @return
     */
    AppleLoginUser appleLogin(String appleId);
    /**
     * 验证码登录
     *
     * @param body
     * @return
     */
    LoginUser appCaptchaLogin(AppCaptchaBody body);
    /**
     * 微信苹果登录验证手机号码操作
     *
     * @param body
     * @return
     */
    WXLoginUser verifyCellPhone(AppVerifyCellPhoneBody body);
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserQuestionServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.xinquan.user.service.impl;
import com.xinquan.user.domain.AppUserQuestion;
import com.xinquan.user.mapper.AppUserQuestionMapper;
import com.xinquan.user.service.AppUserQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 用户计划引导页问题记录表 服务实现类
 * </p>
 *
 * @author mitao
 * @since 2024-08-24
 */
@Service
public class AppUserQuestionServiceImpl extends ServiceImpl<AppUserQuestionMapper, AppUserQuestion> implements AppUserQuestionService {
}
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserServiceImpl.java
@@ -1,13 +1,39 @@
package com.xinquan.user.service.impl;
import cn.hutool.core.util.IdUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.enums.AppUserStatusEnum;
import com.xinquan.common.core.enums.DisabledEnum;
import com.xinquan.common.core.enums.TreeLevelEnum;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.core.utils.page.BeanUtils;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.feignClient.SysUserClient;
import com.xinquan.system.api.model.AppCaptchaBody;
import com.xinquan.system.api.model.AppVerifyCellPhoneBody;
import com.xinquan.system.api.model.AppWXLoginBody;
import com.xinquan.system.api.model.AppleLoginUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.system.api.model.WXLoginUser;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.domain.AppUserTree;
import com.xinquan.user.mapper.AppUserMapper;
import com.xinquan.user.service.AppUserService;
import com.xinquan.user.service.AppUserTreeService;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * <p>
@@ -18,20 +44,28 @@
 * @since 2024-08-21
 */
@Service
@RequiredArgsConstructor
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements AppUserService {
    private final SysUserClient sysUserClient;
    private final RemoteUserService remoteUserService;
    private final AppUserTreeService appUserTreeService;
    /**
     * 获取用户信息
     *
     * @param dto
     * @return
     */
    @Override
    public AppUser getUserByCondition(AppUserDTO dto) {
        return  this.lambdaQuery()
    public Optional<AppUser> getUserByCondition(AppUserDTO dto) {
        return this.lambdaQuery()
                .eq(Objects.nonNull(dto.getId()), AppUser::getId, dto.getId())
                .eq(StringUtils.isNotBlank(dto.getAppleId()), AppUser::getAppleId, dto.getAppleId())
                .eq(StringUtils.isNotBlank(dto.getCellPhone()), AppUser::getCellPhone,
                        dto.getCellPhone())
                .eq(StringUtils.isNotBlank(dto.getWxOpenId()), AppUser::getWxOpenId,
                        dto.getWxOpenId()).oneOpt().orElse(null);
                        dto.getWxOpenId())
                .ne(AppUser::getUserStatus, AppUserStatusEnum.LOGOUT.getCode()).oneOpt();
    }
    /**
@@ -44,4 +78,266 @@
        AppUser appUser = BeanUtils.copyBean(appUserDTO, AppUser.class);
        return this.save(appUser);
    }
    /**
     * APP微信登录
     *
     * @param body
     * @return
     */
    @Override
    public WXLoginUser wxLogin(AppWXLoginBody body) {
        WXLoginUser wxLoginUser = new WXLoginUser();
        Optional<AppUser> optionalAppUser = this.getUserByCondition(
                AppUserDTO.builder().wxOpenId(body.getWxOpenId()).build());
        // 存在账户,查询关联系统用户
        if (optionalAppUser.isPresent()) {
            AppUser appUser = optionalAppUser.get();
            SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
            wxLoginUser.setSysUser(sysUser);
            if (Objects.nonNull(sysUser.getUserName())) {
                wxLoginUser.setBindStatus(1);
                wxLoginUser.setCellPhone(appUser.getCellPhone());
            }
        } else {
            // 不存在账户,创建账户
            // 注册用户信息
            SysUser sysUser = new SysUser();
            sysUser.setNickName(body.getNickname());
            sysUser.setAvatar(body.getHeadImgUrl());
            R<SysUser> registerResult = remoteUserService.registerAppUserInfo(sysUser,
                    SecurityConstants.INNER);
            if (registerResult.getCode() == Constants.FAIL) {
                throw new ServiceException(registerResult.getMsg());
            }
            SysUser sysUserRes = registerResult.getData();
            AppUser appUser = new AppUser();
            appUser.setUserId(sysUserRes.getUserId());
            appUser.setWxOpenId(body.getWxOpenId());
            appUser.setNickname(body.getNickname());
            appUser.setAvatar(body.getHeadImgUrl());
            appUser.setGender(body.getSex());
            appUser.setBalance(BigDecimal.ZERO);
            appUser.setSanskritFlag(DisabledEnum.NO.getCode());
            appUser.setBalance(BigDecimal.ZERO);
            appUser.setIncome(BigDecimal.ZERO);
            appUser.setTotalEnergyValue(0);
            appUser.setRegisterTime(LocalDateTime.now());
            appUser.setLevelSettingId(TreeLevelEnum.SEED.getCode());
            this.save(appUser);
            // 初始化用户树苗
            initUserTree(appUser.getId());
            wxLoginUser.setSysUser(null);
            wxLoginUser.setBindStatus(DisabledEnum.NO.getCode());
        }
        return wxLoginUser;
    }
    @Override
    public AppleLoginUser appleLogin(String appleId) {
        AppleLoginUser appleLoginUser = new AppleLoginUser();
        Optional<AppUser> optionalAppUser = this.getUserByCondition(
                AppUserDTO.builder().appleId(appleId).build());
        // 存在账户,查询关联系统用户
        if (optionalAppUser.isPresent()) {
            AppUser appUser = optionalAppUser.get();
            SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
            appleLoginUser.setSysUser(sysUser);
            if (Objects.nonNull(sysUser.getUserName())) {
                appleLoginUser.setBindStatus(1);
                appleLoginUser.setCellPhone(appUser.getCellPhone());
            }
        } else {
            // 不存在账户,创建账户
            // 注册用户信息
            SysUser sysUser = new SysUser();
            String nickname = "用户" + IdUtil.fastSimpleUUID().substring(0, 6);
            sysUser.setNickName(nickname);
            sysUser.setAvatar("qwer");
            R<SysUser> registerResult = remoteUserService.registerAppUserInfo(sysUser,
                    SecurityConstants.INNER);
            if (registerResult.getCode() == Constants.FAIL) {
                throw new ServiceException(registerResult.getMsg());
            }
            SysUser sysUserRes = registerResult.getData();
            AppUser appUser = new AppUser();
            appUser.setUserId(sysUserRes.getUserId());
            appUser.setNickname(nickname);
            appUser.setAvatar("qwer"); // TODO 待完善默认头像
            appUser.setBalance(BigDecimal.ZERO);
            appUser.setSanskritFlag(DisabledEnum.NO.getCode());
            appUser.setBalance(BigDecimal.ZERO);
            appUser.setIncome(BigDecimal.ZERO);
            appUser.setTotalEnergyValue(0);
            appUser.setRegisterTime(LocalDateTime.now());
            appUser.setLevelSettingId(TreeLevelEnum.SEED.getCode());
            this.save(appUser);
            // 初始化用户树苗
            initUserTree(appUser.getId());
            appleLoginUser.setSysUser(null);
            appleLoginUser.setBindStatus(DisabledEnum.NO.getCode());
        }
        return appleLoginUser;
    }
    /**
     * 验证码登录
     *
     * @param body
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoginUser appCaptchaLogin(AppCaptchaBody body) {
        LoginUser loginUser = new LoginUser();
        Optional<AppUser> optionalAppUser = this.getUserByCondition(
                AppUserDTO.builder().cellPhone(body.getCellPhone()).build());
        if (optionalAppUser.isPresent()) {
            AppUser appUser = optionalAppUser.get();
            SysUser sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
            loginUser.setSysUser(sysUser);
        } else {
            // 注册用户信息
            SysUser sysUser = new SysUser();
            String nickname = "用户" + IdUtil.fastSimpleUUID().substring(0, 6);
            sysUser.setNickName(nickname);
            sysUser.setAvatar("qwer");
            sysUser.setUserName(body.getCellPhone());
            // 设置默认密码123456
            sysUser.setPassword(SecurityUtils.encryptPassword(Constants.DEFAULT_PASSWORD));
            R<SysUser> registerResult = remoteUserService.registerAppUserInfo(sysUser,
                    SecurityConstants.INNER);
            if (registerResult.getCode() == Constants.FAIL) {
                throw new ServiceException(registerResult.getMsg());
            }
            SysUser sysUserRes = registerResult.getData();
            AppUser appUser = new AppUser();
            appUser.setUserId(sysUserRes.getUserId());
            appUser.setNickname(nickname);
            appUser.setCellPhone(body.getCellPhone());
            appUser.setAvatar("qwer"); // TODO 待完善默认头像
            appUser.setBalance(BigDecimal.ZERO);
            appUser.setSanskritFlag(DisabledEnum.NO.getCode());
            appUser.setBalance(BigDecimal.ZERO);
            appUser.setIncome(BigDecimal.ZERO);
            appUser.setTotalEnergyValue(0);
            appUser.setRegisterTime(LocalDateTime.now());
            appUser.setLevelSettingId(TreeLevelEnum.SEED.getCode());
            this.save(appUser);
            // 初始化用户树苗
            initUserTree(appUser.getId());
        }
        return loginUser;
    }
    /**
     * 初始化用户树苗
     *
     * @param appUserId 用户id
     */
    private void initUserTree(Long appUserId) {
        AppUserTree appUserTree = new AppUserTree();
        appUserTree.setAppUserId(appUserId);
        appUserTree.setTreeLevelType(TreeLevelEnum.SEED.getCode());
        appUserTree.setGrowthValue(0);
        appUserTree.setSowAgain(2);
        appUserTree.setCurrentEnergyValue(0);
        appUserTreeService.save(appUserTree);
    }
    /**
     * 微信苹果登录验证手机号码操作
     *
     * @param body
     * @return
     */
    @Override
    public WXLoginUser verifyCellPhone(AppVerifyCellPhoneBody body) {
        Integer loginType = body.getLoginType();
        String wxOrAppleId = body.getWxOrAppleId();
        SysUser sysUser;
        AppUser appUser;
        // 先通过手机号查询用户,如果用户先使用手机号码登录过,那么就已经存在这个手机号码的用户了。
        Optional<AppUser> baseOptionalAppUser = this.getUserByCondition(
                AppUserDTO.builder().cellPhone(body.getCellPhone()).build());
        // 如果存在 更新wxOpenId 或appleId
        if (baseOptionalAppUser.isPresent()) {
            appUser = baseOptionalAppUser.get();
            if (loginType.equals(1)) {
                appUser.setWxOpenId(wxOrAppleId);
            } else {
                appUser.setAppleId(wxOrAppleId);
            }
            // 查询系统用户
            sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
            if (Objects.isNull(sysUser)) {
                throw new ServiceException("系统用户不存在");
            }
        } else {
            Optional<AppUser> userOptional = getAppUserByThirdId(loginType, wxOrAppleId);
            if (loginType.equals(1)) {
                // 微信登录
                handleUserNotPresent(userOptional, "该用户不存在,请重新进行微信授权登录");
            } else {
                // 苹果登录
                handleUserNotPresent(userOptional, "该用户不存在,请重新进行苹果授权登录");
            }
            appUser = userOptional.get();
            appUser.setCellPhone(body.getCellPhone());
            // 更新系统用户
            sysUser = sysUserClient.getSysUser(appUser.getUserId()).getData();
            if (Objects.isNull(sysUser)) {
                throw new ServiceException("系统用户不存在");
            }
            sysUser.setUserName(body.getCellPhone());
            sysUser.setPassword(
                    SecurityUtils.encryptPassword(Constants.DEFAULT_PASSWORD)); // 默认密码为123456
            sysUser.setPhonenumber(body.getCellPhone());
            sysUserClient.updateSysUser(sysUser);
        }
        // 更新用户信息
        this.updateById(appUser);
        if (loginType.equals(1)) {
            // 微信登录
            WXLoginUser wxLoginUser = new WXLoginUser();
            wxLoginUser.setBindStatus(1);
            wxLoginUser.setCellPhone(body.getCellPhone());
            wxLoginUser.setSysUser(sysUser);
            return wxLoginUser;
        } else {
            // 苹果登录
            AppleLoginUser appleLoginUser = new AppleLoginUser();
            appleLoginUser.setBindStatus(1);
            appleLoginUser.setCellPhone(body.getCellPhone());
            appleLoginUser.setSysUser(sysUser);
            return appleLoginUser;
        }
    }
    // 定义一个方法来处理用户不存在的情况
    private void handleUserNotPresent(Optional<AppUser> userOptional, String errorMessage) {
        if (!userOptional.isPresent()) {
            throw new ServiceException(errorMessage);
        }
    }
    /**
     * 根据第三方id获取未注销用户
     *
     * @param loginType   登录类型 1=微信 2=苹果
     * @param wxOrAppleId 微信openid或苹果appleId
     * @return Optional<AppUser>
     */
    private Optional<AppUser> getAppUserByThirdId(Integer loginType, String wxOrAppleId) {
        return this.lambdaQuery()
                .eq(loginType.equals(1), AppUser::getWxOpenId, wxOrAppleId)
                .eq(loginType.equals(2), AppUser::getAppleId, wxOrAppleId)
                .ne(AppUser::getUserStatus, AppUserStatusEnum.LOGOUT)
                .oneOpt();
    }
}
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserQuestionMapper.xml
copy from xinquan-modules/xinquan-system/src/main/resources/mapper/system/HomeBackgroundMusicMapper.xml copy to xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserQuestionMapper.xml
File was copied from xinquan-modules/xinquan-system/src/main/resources/mapper/system/HomeBackgroundMusicMapper.xml
@@ -1,18 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinquan.system.mapper.HomeBackgroundMusicMapper">
<mapper namespace="com.xinquan.user.mapper.AppUserQuestionMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.xinquan.system.domain.HomeBackgroundMusic">
    <resultMap id="BaseResultMap" type="com.xinquan.user.domain.AppUserQuestion">
        <id column="id" property="id" />
        <result column="del_flag" property="delFlag" />
        <result column="create_by" property="createBy" />
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="image_url" property="imageUrl" />
        <result column="audio_file" property="audioFile" />
        <result column="sort_num" property="sortNum" />
        <result column="type" property="type" />
        <result column="answer" property="answer" />
    </resultMap>
    <!-- 通用查询结果列 -->
@@ -22,7 +21,7 @@
        create_time,
        update_by,
        update_time,
        id, image_url, audio_file, sort_num
        id, type, answer
    </sql>
</mapper>
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserTreeMapper.xml
@@ -11,7 +11,7 @@
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="app_user_id" property="appUserId" />
        <result column="tree_level_id" property="treeLevelId" />
        <result column="tree_level_type" property="treeLevelType"/>
        <result column="growth_value" property="growthValue" />
        <result column="current_energy_value" property="currentEnergyValue" />
        <result column="sow_again" property="sowAgain" />