| 
					
				 | 
			
			
				@@ -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 
			 |