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