Bladeren bron

更新首次登录注册

Yangzw 11 maanden geleden
bovenliggende
commit
b20e1ff3f1

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

@@ -93,11 +93,11 @@ public class AppAuthController {
 
     @PostMapping("/social-login-validate-sms-code")
     @Operation(summary = "社交快捷登录-校验手机验证码")
-    public CommonResult<AppAuthLoginRespVO> socialLoginValidateSmsCode( @RequestBody @Validated SocialLoginValidateSmsCodeReqVO requestVO) {
+    public CommonResult<AppAuthLoginRespVO> socialLoginValidateSmsCode(@RequestBody @Validated SocialLoginValidateSmsCodeReqVO requestVO) {
         authService.validateSmsCode(getLoginUserId(), requestVO.getReqVO());
         AppAuthSocialLoginReqVO loginReqVO = requestVO.getLoginReqVO();
         String code = requestVO.getReqVO().getCode();
-        return success(authService.socialLogin(loginReqVO, code, false));
+        return success(authService.socialLogin(loginReqVO, code, false, true));
     }
 
     // ========== 社交登录相关 ==========
@@ -116,7 +116,7 @@ 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));
+        return success(authService.socialLogin(reqVO, null, true, false));
     }
 
     @PostMapping("/weixin-mini-app-login")

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

@@ -6,7 +6,7 @@ import javax.validation.Valid;
 
 /**
  * 会员的认证 Service 接口
- *
+ * <p>
  * 提供用户的账号密码登录、token 的校验等认证相关的功能
  *
  * @author 非繁源码
@@ -31,7 +31,7 @@ public interface MemberAuthService {
     /**
      * 手机 + 验证码登陆
      *
-     * @param reqVO    登陆信息
+     * @param reqVO 登陆信息
      * @return 登录结果
      */
     AppAuthLoginRespVO smsLogin(@Valid AppAuthSmsLoginReqVO reqVO);
@@ -43,16 +43,7 @@ public interface MemberAuthService {
      * @param phone 用户手机号
      * @return 登录结果
      */
-    AppAuthLoginRespVO socialLogin(@Valid AppAuthSocialLoginReqVO reqVO, String phone, Boolean isFirst);
-
-    /**
-     * 首次社交登录,自动注册账号
-     *
-     * @param reqVO 登录信息
-     * @param phone 手机号
-     * @return 登录结果
-     */
-    AppAuthLoginRespVO smsCodeLogin(AppAuthSocialLoginReqVO reqVO, String phone);
+    AppAuthLoginRespVO socialLogin(@Valid AppAuthSocialLoginReqVO reqVO, String phone, Boolean isFirst, Boolean isRegister);
 
     /**
      * 微信小程序的一键登录
@@ -65,7 +56,7 @@ public interface MemberAuthService {
     /**
      * 获得社交认证 URL
      *
-     * @param type 社交平台类型
+     * @param type        社交平台类型
      * @param redirectUri 跳转地址
      * @return 认证 URL
      */
@@ -75,7 +66,7 @@ public interface MemberAuthService {
      * 给用户发送短信验证码
      *
      * @param userId 用户编号
-     * @param reqVO 发送信息
+     * @param reqVO  发送信息
      */
     void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO);
 
@@ -83,7 +74,7 @@ public interface MemberAuthService {
      * 校验短信验证码是否正确
      *
      * @param userId 用户编号
-     * @param reqVO 校验信息
+     * @param reqVO  校验信息
      */
     void validateSmsCode(Long userId, AppAuthSmsValidateReqVO reqVO);
 

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

@@ -102,10 +102,12 @@ public class MemberAuthServiceImpl implements MemberAuthService {
 
     @Override
     @Transactional
-    public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO, String phone, Boolean isFirst) {
+    public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO, String phone, Boolean isFirst, Boolean isRegister) {
+
+
         // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
         SocialUserRespDTO socialUser = socialUserApi.getSocialUserByCode(UserTypeEnum.MEMBER.getValue(), reqVO.getType(),
-                reqVO.getCode(), reqVO.getState(), isFirst);
+                reqVO.getCode(), reqVO.getState(), isFirst, isRegister);
         if (socialUser == null) {
             throw exception(AUTH_SOCIAL_USER_NOT_FOUND);
         }
@@ -123,10 +125,10 @@ public class MemberAuthServiceImpl implements MemberAuthService {
                 user = userService.getUserByMobile(phone);
                 if (user == null) {
                     //加入手机号
-                    user = userService.createUser(phone,socialUser.getNickname(), socialUser.getAvatar(), getClientIP(), getTerminal());
+                    user = userService.createUser(phone, socialUser.getNickname(), socialUser.getAvatar(), getClientIP(), getTerminal());
                 }
             } else {
-                user = userService.createUser(null,socialUser.getNickname(), socialUser.getAvatar(), getClientIP(), getTerminal());
+                user = userService.createUser(null, socialUser.getNickname(), socialUser.getAvatar(), getClientIP(), getTerminal());
             }
 
             socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),
@@ -140,17 +142,6 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, socialUser.getOpenid());
     }
 
-    @Override
-    @Transactional
-    public AppAuthLoginRespVO smsCodeLogin(AppAuthSocialLoginReqVO reqVO, String phone) {
-//        SocialUserRespDTO socialUser = socialUserApi.getFirstSocialUserByCode(UserTypeEnum.MEMBER.getValue(), reqVO.getType(),
-//                reqVO.getCode(), reqVO.getState());
-//        if (socialUser == null) {
-//            throw exception(AUTH_SOCIAL_USER_NOT_FOUND);
-//        }
-        return socialLogin(reqVO, phone, false);
-    }
-
     @Override
     public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) {
         // 获得对应的手机号信息

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

@@ -32,8 +32,8 @@ public interface SocialUserApi {
     /**
      * 获得社交用户,基于 userId
      *
-     * @param userType 用户类型
-     * @param userId 用户编号
+     * @param userType   用户类型
+     * @param userId     用户编号
      * @param socialType 社交平台的类型
      * @return 社交用户
      */
@@ -41,15 +41,15 @@ public interface SocialUserApi {
 
     /**
      * 获得社交用户
-     *
+     * <p>
      * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常
      *
-     * @param userType 用户类型
+     * @param userType   用户类型
      * @param socialType 社交平台的类型
-     * @param code 授权码
-     * @param state state
+     * @param code       授权码
+     * @param state      state
      * @return 社交用户
      */
-    SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst);
+    SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst, Boolean isRegister);
 
 }

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

@@ -13,6 +13,7 @@ public interface ErrorCodeConstants {
     ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_002_000_000, "登录失败,账号密码不正确");
     ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_002_000_001, "登录失败,账号被禁用");
     ErrorCode AUTH_LOGIN_USER_IS_FIRST = new ErrorCode(1_002_000_002, "第一次登录请输入手机号校验");
+    ErrorCode AUTH_LOGIN_USER_ERROR_CODE = new ErrorCode(1_002_000_002, "code校验失败");
     ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1_002_000_004, "验证码不正确,原因:{}");
     ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1_002_000_005, "未绑定账号,需要进行绑定");
     ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1_002_000_006, "Token 已经过期");

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

@@ -38,8 +38,8 @@ public class SocialUserApiImpl implements SocialUserApi {
     }
 
     @Override
-    public SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst) {
-       return socialUserService.getSocialUserByCode(userType, socialType, code, state, isFirst);
+    public SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst,Boolean isRegister) {
+       return socialUserService.getSocialUserByCode(userType, socialType, code, state, isFirst, isRegister);
     }
 
 }

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

@@ -38,18 +38,18 @@ public interface SocialUserService {
     /**
      * 取消绑定社交用户
      *
-     * @param userId 用户编号
-     * @param userType 全局用户类型
+     * @param userId     用户编号
+     * @param userType   全局用户类型
      * @param socialType 社交平台的类型 {@link SocialTypeEnum}
-     * @param openid 社交平台的 openid
+     * @param openid     社交平台的 openid
      */
     void unbindSocialUser(Long userId, Integer userType, Integer socialType, String openid);
 
     /**
      * 获得社交用户,基于 userId
      *
-     * @param userType 用户类型
-     * @param userId 用户编号
+     * @param userType   用户类型
+     * @param userId     用户编号
      * @param socialType 社交平台的类型
      * @return 社交用户
      */
@@ -57,29 +57,29 @@ public interface SocialUserService {
 
     /**
      * 获得社交用户
-     *
+     * <p>
      * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常
      *
-     * @param userType 用户类型
+     * @param userType   用户类型
      * @param socialType 社交平台的类型
-     * @param code 授权码
-     * @param state state
+     * @param code       授权码
+     * @param state      state
      * @return 社交用户
      */
     SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state);
 
     /**
      * 获得社交用户
-     *
+     * <p>
      * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常
      *
-     * @param userType 用户类型
+     * @param userType   用户类型
      * @param socialType 社交平台的类型
-     * @param code 授权码
-     * @param state state
+     * @param code       授权码
+     * @param state      state
      * @return 社交用户
      */
-    SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst);
+    SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst, Boolean isRegister);
 
     // ==================== 社交用户 CRUD ====================
 

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

@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.newfeifan.mall.framework.common.exception.ServiceException;
 import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.framework.common.util.json.JsonUtils;
 import cn.newfeifan.mall.module.system.api.social.dto.SocialUserBindReqDTO;
 import cn.newfeifan.mall.module.system.api.social.dto.SocialUserRespDTO;
 import cn.newfeifan.mall.module.system.controller.admin.socail.vo.user.SocialUserPageReqVO;
@@ -12,8 +13,10 @@ import cn.newfeifan.mall.module.system.dal.dataobject.social.SocialUserDO;
 import cn.newfeifan.mall.module.system.dal.mysql.social.SocialUserBindMapper;
 import cn.newfeifan.mall.module.system.dal.mysql.social.SocialUserMapper;
 import cn.newfeifan.mall.module.system.enums.social.SocialTypeEnum;
+import com.alibaba.fastjson.JSONObject;
 import com.xingyuv.jushauth.model.AuthUser;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -22,6 +25,7 @@ import javax.annotation.Resource;
 import javax.validation.constraints.NotNull;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.convertSet;
@@ -46,6 +50,9 @@ public class SocialUserServiceImpl implements SocialUserService {
     @Resource
     private SocialClientService socialClientService;
 
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
     @Override
     public List<SocialUserDO> getSocialUserList(Long userId, Integer userType) {
         // 获得绑定
@@ -118,10 +125,11 @@ public class SocialUserServiceImpl implements SocialUserService {
         return new SocialUserRespDTO(socialUser.getOpenid(), socialUser.getNickname(), socialUser.getAvatar(),
                 socialUserBind != null ? socialUserBind.getUserId() : null);
     }
+
     @Override
-    public SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst) {
+    public SocialUserRespDTO getSocialUserByCode(Integer userType, Integer socialType, String code, String state, Boolean isFirst, Boolean isRegister) {
         // 获得社交用户
-        SocialUserDO socialUser = authSocialUser(socialType, userType, code, state,isFirst);
+        SocialUserDO socialUser = authSocialUser(socialType, userType, code, state, isFirst, isRegister);
         Assert.notNull(socialUser, "社交用户不能为空");
 
         // 获得绑定用户
@@ -132,7 +140,7 @@ public class SocialUserServiceImpl implements SocialUserService {
     }
 
     public SocialUserDO authSocialUser(Integer socialType, Integer userType, String code, String state) {
-        return this.authSocialUser(socialType, userType, code, state, false);
+        return this.authSocialUser(socialType, userType, code, state, false, false);
     }
 
     /**
@@ -140,13 +148,13 @@ public class SocialUserServiceImpl implements SocialUserService {
      * 如果授权失败,则会抛出 {@link ServiceException} 异常
      *
      * @param socialType 社交平台的类型 {@link SocialTypeEnum}
-     * @param userType 用户类型
-     * @param code     授权码
-     * @param state    state
+     * @param userType   用户类型
+     * @param code       授权码
+     * @param state      state
      * @return 授权用户
      */
     @NotNull
-    public SocialUserDO authSocialUser(Integer socialType, Integer userType, String code, String state, boolean isFirst) {
+    public SocialUserDO authSocialUser(Integer socialType, Integer userType, String code, String state, Boolean isFirst, Boolean isRegister) {
         // 优先从 DB 中获取,因为 code 有且可以使用一次。
         // 在社交登录时,当未绑定 User 时,需要绑定登录,此时需要 code 使用两次
         SocialUserDO socialUser = socialUserMapper.selectByTypeAndCodeAnState(socialType, code, state);
@@ -154,13 +162,22 @@ public class SocialUserServiceImpl implements SocialUserService {
             return socialUser;
         }
 
-        // 请求获取
-        AuthUser authUser = socialClientService.getAuthUser(socialType, userType, code, state);
+        AuthUser authUser;
+
+        if (isRegister) {
+            //如果已经走过首次登录,则从缓存里面拿取code
+            authUser = getAuthUser(code);
+        } else {
+            // 请求获取
+            authUser =socialClientService.getAuthUser(socialType, userType, code, state);
+        }
         Assert.notNull(authUser, "三方用户不能为空");
 
         // 保存到 DB 中
         socialUser = socialUserMapper.selectByTypeAndOpenid(socialType, authUser.getUuid());
         if (isFirst && socialUser == null) {
+            //首次登录就将code缓存到redis中
+            stringRedisTemplate.opsForValue().set("auth_user:" + code, JsonUtils.toJsonString(authUser) , 60 * 10 , TimeUnit.SECONDS);
             throw exception(AUTH_LOGIN_USER_IS_FIRST);
         }
         if (socialUser == null) {
@@ -178,6 +195,27 @@ public class SocialUserServiceImpl implements SocialUserService {
     }
 
 
+    /**
+     * 根据代码获取认证用户信息。
+     *
+     * @param code 用户认证的唯一标识符。
+     * @return AuthUser 对象,如果找不到则返回null。
+     */
+    private AuthUser getAuthUser(String code) {
+        if (code == null || code.trim().isEmpty()) {
+            // 处理边界条件:无效的code
+            return null;
+        }
+        String json = stringRedisTemplate.opsForValue().get("auth_user:" + code);
+        if (json != null) {
+            // 假设存在一个方法从JSON字符串中安全地解析AuthUser对象
+            return JSONObject.parseObject(json,AuthUser.class);
+        }
+
+        throw exception(AUTH_LOGIN_USER_ERROR_CODE);
+    }
+
+
     // ==================== 社交用户 CRUD ====================
 
     @Override