Эх сурвалжийг харах

Merge branch 'dev/2024/0529/update-app-Y' of feifan/mall-backend-app into master

修改登录系统
Yangzw 9 сар өмнө
parent
commit
b54a858e1e
18 өөрчлөгдсөн 174 нэмэгдсэн , 21 устгасан
  1. 1 0
      feifan-module-member/feifan-module-member-api/src/main/java/cn/newfeifan/mall/module/member/enums/ErrorCodeConstants.java
  2. 8 3
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/AppAuthController.java
  3. 4 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java
  4. 16 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthMemberUserRespVO.java
  5. 18 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthSelectUsernameLoginReqVO.java
  6. 0 10
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java
  7. 21 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthSocialRegisterReqVO.java
  8. 1 1
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/SocialLoginValidateSmsCodeReqVO.java
  9. 5 1
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthService.java
  10. 49 1
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthServiceImpl.java
  11. 2 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserService.java
  12. 5 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserServiceImpl.java
  13. 8 0
      feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/api/social/SocialUserApi.java
  14. 6 0
      feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/api/social/dto/SocialUserRespDTO.java
  15. 5 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/api/social/SocialUserApiImpl.java
  16. 4 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/social/SocialUserBindMapper.java
  17. 8 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserService.java
  18. 13 5
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserServiceImpl.java

+ 1 - 0
feifan-module-member/feifan-module-member-api/src/main/java/cn/newfeifan/mall/module/member/enums/ErrorCodeConstants.java

@@ -19,6 +19,7 @@ public interface ErrorCodeConstants {
     ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_004_003_000, "登录失败,用户名或密码不正确");
     ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_004_003_001, "登录失败,账号被禁用");
     ErrorCode AUTH_SOCIAL_USER_NOT_FOUND = new ErrorCode(1_004_003_005, "登录失败,解析不到三方登录信息");
+    ErrorCode AUTH_SOCIAL_USER_BIND_USER_NOT_FOUND = new ErrorCode(1_004_003_006, "登录失败,查询不到此用户");
     ErrorCode AUTH_MOBILE_USED = new ErrorCode(1_004_003_007, "手机号已经被使用");
 
     // ========== 用户收件地址 1-004-004-000 ==========

+ 8 - 3
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/AppAuthController.java

@@ -102,8 +102,7 @@ public class AppAuthController {
     @Operation(summary = "社交快捷登录-校验手机验证码")
     public CommonResult<AppAuthLoginRespVO> socialLoginValidateSmsCode(@RequestBody @Validated SocialLoginValidateSmsCodeReqVO requestVO) {
         authService.validateSmsCode(getLoginUserId(), requestVO.getReqVO());
-        AppAuthSocialLoginReqVO loginReqVO = requestVO.getLoginReqVO();
-        return success(authService.socialLogin(loginReqVO, requestVO.getReqVO().getMobile(), false, true));
+        return success(authService.socialRegister(requestVO.getRegisterReqVO(), requestVO.getReqVO().getMobile(), false, true));
     }
 
     // ========== 社交登录相关 ==========
@@ -122,7 +121,13 @@ public class AppAuthController {
     @PostMapping("/social-login")
     @Operation(summary = "社交快捷登录,使用 code 授权码", description = "适合未登录的用户,但是社交账号已绑定用户")
     public CommonResult<AppAuthLoginRespVO> socialLogin(@RequestBody @Valid AppAuthSocialLoginReqVO reqVO) {
-        return success(authService.socialLogin(reqVO, null, true, false));
+        return success(authService.socialLogin(reqVO));
+    }
+
+    @PostMapping("/select-username-login")
+    @Operation(summary = "选择用户名登录")
+    public CommonResult<AppAuthLoginRespVO> selectUsernameLogin(@RequestBody @Valid AppAuthSelectUsernameLoginReqVO reqVO) {
+        return success(authService.selectUsernameLogin(reqVO));
     }
 
     @PostMapping("/weixin-mini-app-login")

+ 4 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java

@@ -7,6 +7,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "用户 APP - 登录 Response VO")
 @Data
@@ -27,6 +28,9 @@ public class AppAuthLoginRespVO {
     @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime expiresTime;
 
+    @Schema(description = "当前微信绑定的账号集合")
+    private List<AppAuthMemberUserRespVO> socialUsers;
+
     /**
      * 仅社交登录、社交绑定时会返回
      *

+ 16 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthMemberUserRespVO.java

@@ -0,0 +1,16 @@
+package cn.newfeifan.mall.module.member.controller.app.auth.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+@Schema(description = "用户 APP - 微信下的用户 Response VO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AppAuthMemberUserRespVO {
+    @Schema(description = "用户名", example = "张三")
+    private String username;
+    @Schema(description = "头像", example = "https://www.iocoder.cn/xxx.jpg")
+    private String avatar;
+}

+ 18 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthSelectUsernameLoginReqVO.java

@@ -0,0 +1,18 @@
+package cn.newfeifan.mall.module.member.controller.app.auth.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@Schema(description = "用户 APP - 用户微信登录后可以选择微信绑定的账号登录")
+public class AppAuthSelectUsernameLoginReqVO {
+    @Schema(description = "openId", requiredMode = Schema.RequiredMode.REQUIRED, example = "nice")
+    @NotNull(message = "openId不能为空")
+    private String openId;
+
+    @Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "nice")
+    @NotNull(message = "用户名不能为空")
+    private String username;
+}

+ 0 - 10
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java

@@ -30,14 +30,4 @@ public class AppAuthSocialLoginReqVO {
     @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62")
     @NotEmpty(message = "state 不能为空")
     private String state;
-
-    @Schema(description = "分享链接ID 没有可以不传")
-    private String linkId;
-
-    public Long getLinkId() {
-        if (linkId == null) {
-            return null;
-        }
-        return Long.parseLong(linkId,16);
-    }
 }

+ 21 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/AppAuthSocialRegisterReqVO.java

@@ -0,0 +1,21 @@
+package cn.newfeifan.mall.module.member.controller.app.auth.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class AppAuthSocialRegisterReqVO  extends AppAuthSocialLoginReqVO{
+    @Schema(description = "分享链接ID")
+    @NotNull(message = "只能通过分享注册")
+    private String linkId;
+
+    public Long getLinkId() {
+        if (linkId == null) {
+            return null;
+        }
+        return Long.parseLong(linkId,16);
+    }
+
+}

+ 1 - 1
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/vo/SocialLoginValidateSmsCodeReqVO.java

@@ -20,6 +20,6 @@ public class SocialLoginValidateSmsCodeReqVO {
      * 该字段包含了社交登录所需的请求参数。
      */
     @Valid
-    private AppAuthSocialLoginReqVO loginReqVO;
+    private AppAuthSocialRegisterReqVO registerReqVO;
 
 }

+ 5 - 1
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthService.java

@@ -43,7 +43,7 @@ public interface MemberAuthService {
      * @param phone 用户手机号
      * @return 登录结果
      */
-    AppAuthLoginRespVO socialLogin(@Valid AppAuthSocialLoginReqVO reqVO, String phone, Boolean isFirst, Boolean isRegister);
+    AppAuthLoginRespVO socialRegister(@Valid AppAuthSocialRegisterReqVO reqVO, String phone, Boolean isFirst, Boolean isRegister);
 
     /**
      * 微信小程序的一键登录
@@ -93,4 +93,8 @@ public interface MemberAuthService {
      * @return 登录结果
      */
     AppAuthLoginRespVO smsRegister(AppAuthSmsRegisterReqVO reqVO);
+
+    AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO);
+
+    AppAuthLoginRespVO selectUsernameLogin(AppAuthSelectUsernameLoginReqVO reqVO);
 }

+ 49 - 1
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthServiceImpl.java

@@ -33,7 +33,9 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.newfeifan.mall.framework.common.util.servlet.ServletUtils.getClientIP;
@@ -103,7 +105,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
 
     @Override
     @Transactional
-    public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO, String phone, Boolean isFirst, Boolean isRegister) {
+    public AppAuthLoginRespVO socialRegister(AppAuthSocialRegisterReqVO reqVO, String phone, Boolean isFirst, Boolean isRegister) {
 
 
         // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
@@ -143,6 +145,52 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, socialUser.getOpenid());
     }
 
+    @Override
+    public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) {
+        // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
+        SocialUserRespDTO socialUser = socialUserApi.getSocialUserByCode(UserTypeEnum.MEMBER.getValue(), reqVO.getType(),
+                reqVO.getCode(), reqVO.getState(), true, false);
+        if (socialUser == null) {
+            throw exception(AUTH_SOCIAL_USER_NOT_FOUND);
+        }
+
+        //如果同一个微信绑定了多个用户就返回用户集 供用户选择登录
+        if(socialUser.getUserIds().size() != 1){
+            List<MemberUserDO> users = userService.getUserList(socialUser.getUserIds());
+            List<AppAuthMemberUserRespVO> memberUserRespVOS = users.stream().map(user -> AppAuthMemberUserRespVO
+                    .builder()
+                    .username(user.getUsername())
+                    .avatar(user.getAvatar())
+                    .build())
+                    .collect(Collectors.toList());
+            return AppAuthLoginRespVO.builder().socialUsers(memberUserRespVOS).build();
+        }else{
+            //如果只有一个账号那就直接登录
+            socialUser.setUserId(socialUser.getUserIds().get(0));
+        }
+
+        MemberUserDO user = userService.getUser(socialUser.getUserId());
+        if (user == null) {
+            throw exception(USER_NOT_EXISTS);
+        }
+
+        // 创建 Token 令牌,记录登录日志
+        return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, socialUser.getOpenid());
+    }
+
+    @Override
+    public AppAuthLoginRespVO selectUsernameLogin(AppAuthSelectUsernameLoginReqVO reqVO) {
+        MemberUserDO user = userService.selectByUsername(reqVO.getUsername());
+
+        //如果微信绑定的账号中没有此账号那就返回报错
+        Boolean flag = socialUserApi.wxIsBindByUserId(reqVO.getOpenId(), user.getId());
+        if(!flag){
+            throw exception(AUTH_SOCIAL_USER_BIND_USER_NOT_FOUND);
+        }
+
+        return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, reqVO.getOpenId());
+    }
+
     @Override
     public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) {
         // 获得对应的手机号信息

+ 2 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserService.java

@@ -212,4 +212,6 @@ public interface MemberUserService {
      * @return 数量
      */
     Long getUserCountByMobile(String mobile);
+
+    MemberUserDO selectByUsername(String username);
 }

+ 5 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserServiceImpl.java

@@ -362,4 +362,9 @@ public class MemberUserServiceImpl implements MemberUserService {
         return memberUserMapper.selectCount(MemberUserDO::getMobile,mobile);
     }
 
+    @Override
+    public MemberUserDO selectByUsername(String username) {
+        return memberUserMapper.selectOne(MemberUserDO::getUsername,username);
+    }
+
 }

+ 8 - 0
feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/api/social/SocialUserApi.java

@@ -52,4 +52,12 @@ public interface SocialUserApi {
      */
     SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst, Boolean isRegister);
 
+    /**
+     * 判断微信是否绑定此账号
+     * @param openId openId
+     * @param userId 用户编号
+     * @return 是否
+     */
+    Boolean wxIsBindByUserId(String openId,Long userId);
+
 }

+ 6 - 0
feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/api/social/dto/SocialUserRespDTO.java

@@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.List;
+
 /**
  * 社交用户 Response DTO
  *
@@ -31,5 +33,9 @@ public class SocialUserRespDTO {
      * 关联的用户编号
      */
     private Long userId;
+    /**
+     * 关联的用户编号
+     */
+    private List<Long> userIds;
 
 }

+ 5 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/api/social/SocialUserApiImpl.java

@@ -42,4 +42,9 @@ public class SocialUserApiImpl implements SocialUserApi {
        return socialUserService.getSocialUserByCode(userType, socialType, code, state, isFirst, isRegister);
     }
 
+    @Override
+    public Boolean wxIsBindByUserId(String openId, Long userId) {
+        return socialUserService.wxIsBindByUserId(openId,userId);
+    }
+
 }

+ 4 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/social/SocialUserBindMapper.java

@@ -27,6 +27,10 @@ public interface SocialUserBindMapper extends BaseMapperX<SocialUserBindDO> {
         return selectOne(SocialUserBindDO::getUserType, userType,
                 SocialUserBindDO::getSocialUserId, socialUserId);
     }
+    default List<SocialUserBindDO> selectsByUserTypeAndSocialUserId(Integer userType, Long socialUserId) {
+        return selectList(SocialUserBindDO::getUserType, userType,
+                SocialUserBindDO::getSocialUserId, socialUserId);
+    }
 
     default List<SocialUserBindDO> selectListByUserIdAndUserType(Long userId, Integer userType) {
         return selectList(new LambdaQueryWrapperX<SocialUserBindDO>()

+ 8 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserService.java

@@ -100,4 +100,12 @@ public interface SocialUserService {
     PageResult<SocialUserDO> getSocialUserPage(SocialUserPageReqVO pageReqVO);
 
     String getOpenIdByUserId(Long userId);
+
+    /**
+     * 判断微信是否绑定此账号
+     * @param openId
+     * @param userId
+     * @return
+     */
+    Boolean wxIsBindByUserId(String openId, Long userId);
 }

+ 13 - 5
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserServiceImpl.java

@@ -26,6 +26,7 @@ import javax.validation.constraints.NotNull;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.convertSet;
@@ -110,7 +111,7 @@ public class SocialUserServiceImpl implements SocialUserService {
         SocialUserDO socialUser = socialUserMapper.selectById(socialUserBind.getSocialUserId());
         Assert.notNull(socialUser, "社交用户不能为空");
         return new SocialUserRespDTO(socialUser.getOpenid(), socialUser.getNickname(), socialUser.getAvatar(),
-                socialUserBind.getUserId());
+                socialUserBind.getUserId(),null);
     }
 
     @Override
@@ -123,7 +124,7 @@ public class SocialUserServiceImpl implements SocialUserService {
         SocialUserBindDO socialUserBind = socialUserBindMapper.selectByUserTypeAndSocialUserId(userType,
                 socialUser.getId());
         return new SocialUserRespDTO(socialUser.getOpenid(), socialUser.getNickname(), socialUser.getAvatar(),
-                socialUserBind != null ? socialUserBind.getUserId() : null);
+                socialUserBind != null ? socialUserBind.getUserId() : null,null);
     }
 
     @Override
@@ -132,11 +133,12 @@ public class SocialUserServiceImpl implements SocialUserService {
         SocialUserDO socialUser = authSocialUser(socialType, userType, code, state, isFirst, isRegister);
         Assert.notNull(socialUser, "社交用户不能为空");
 
-        // 获得绑定用户
-        SocialUserBindDO socialUserBind = socialUserBindMapper.selectByUserTypeAndSocialUserId(userType,
+        // 获得绑定用户
+        List<SocialUserBindDO> socialUserBindDOS = socialUserBindMapper.selectsByUserTypeAndSocialUserId(userType,
                 socialUser.getId());
+        List<Long> userIds = socialUserBindDOS.stream().map(SocialUserBindDO::getUserId).collect(Collectors.toList());
         return new SocialUserRespDTO(socialUser.getOpenid(), socialUser.getNickname(), socialUser.getAvatar(),
-                socialUserBind != null ? socialUserBind.getUserId() : null);
+                 null,userIds);
     }
 
     public SocialUserDO authSocialUser(Integer socialType, Integer userType, String code, String state) {
@@ -233,4 +235,10 @@ public class SocialUserServiceImpl implements SocialUserService {
         return socialUserMapper.getOpenIdByUserId(userId);
     }
 
+    @Override
+    public Boolean wxIsBindByUserId(String openId, Long userId) {
+        SocialUserDO socialUserDO = socialUserMapper.selectOne(SocialUserDO::getOpenid, openId);
+        return socialUserBindMapper.selectOne(SocialUserBindDO::getSocialUserId,socialUserDO.getId(),SocialUserBindDO::getUserId,userId) != null;
+    }
+
 }