Commit 89df5b3cf619e98cf4a4fb98d5bd140f2b644eb3

Authored by YunaiV
1 parent 705a5ff6

临时提交,暂时不考虑 unionId,简化模型

yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java
1 1 package cn.iocoder.yudao.module.system.enums.social;
2 2  
3   -import cn.hutool.core.collection.ListUtil;
4 3 import cn.hutool.core.util.ArrayUtil;
5 4 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
6 5 import lombok.AllArgsConstructor;
7 6 import lombok.Getter;
8 7  
9 8 import java.util.Arrays;
10   -import java.util.List;
  9 +import java.util.Collection;
  10 +import java.util.Set;
  11 +import java.util.stream.Collectors;
11 12  
12 13 /**
13 14 * 社交平台的类型枚举
... ... @@ -77,4 +78,11 @@ public enum SocialTypeEnum implements IntArrayValuable {
77 78 return ArrayUtil.firstMatch(o -> o.getType().equals(type), values());
78 79 }
79 80  
  81 + public static Set<Integer> getTypes(Collection<Integer> platforms) {
  82 + return Arrays.stream(values())
  83 + .filter(socialTypeEnum -> platforms.contains(socialTypeEnum.getPlatform()))
  84 + .map(SocialTypeEnum::getType)
  85 + .collect(Collectors.toSet());
  86 + }
  87 +
80 88 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserDO.java
... ... @@ -43,13 +43,6 @@ public class SocialUserDO extends BaseDO {
43 43 */
44 44 private String token;
45 45 /**
46   - * 社交的全局编号
47   - *
48   - * 例如说,微信平台的 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html
49   - * 如果没有 unionId 的平台,直接使用 openid 作为该字段的值
50   - */
51   - private String unionId;
52   - /**
53 46 * 原始 Token 数据,一般是 JSON 格式
54 47 */
55 48 private String rawTokenInfo;
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java
... ... @@ -5,14 +5,21 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5 5 import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
6 6 import org.apache.ibatis.annotations.Mapper;
7 7  
  8 +import java.util.List;
  9 +
8 10 @Mapper
9 11 public interface SocialUserBindMapper extends BaseMapperX<SocialUserBindDO> {
10 12  
11   - default void deleteByUserTypeAndUserIdAndPlatformAndUnionId(Integer userType, Long userId,
12   - Integer platform, String unionId) {
  13 + default void deleteByUserTypeAndUserIdAndUnionId(Integer userType, Long userId, Integer platform) {
13 14 delete(new LambdaQueryWrapperX<SocialUserBindDO>()
14 15 .eq(SocialUserBindDO::getUserType, userType)
15 16 .eq(SocialUserBindDO::getUserId, userId)
  17 + .eq(SocialUserBindDO::getPlatform, platform));
  18 + }
  19 +
  20 + default void deleteByUserTypeAndPlatformAndUnionId(Integer userType, Integer platform, String unionId) {
  21 + delete(new LambdaQueryWrapperX<SocialUserBindDO>()
  22 + .eq(SocialUserBindDO::getUserType, userType)
16 23 .eq(SocialUserBindDO::getPlatform, platform)
17 24 .eq(SocialUserBindDO::getUnionId, unionId));
18 25 }
... ... @@ -25,4 +32,10 @@ public interface SocialUserBindMapper extends BaseMapperX&lt;SocialUserBindDO&gt; {
25 32 .eq(SocialUserBindDO::getUnionId, unionId));
26 33 }
27 34  
  35 + default List<SocialUserBindDO> selectListByUserIdAndUserType(Long userId, Integer userType) {
  36 + return selectList(new LambdaQueryWrapperX<SocialUserBindDO>()
  37 + .eq(SocialUserBindDO::getUserId, userId)
  38 + .eq(SocialUserBindDO::getUserType, userType));
  39 + }
  40 +
28 41 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserMapper.java
... ... @@ -25,8 +25,10 @@ public interface SocialUserMapper extends BaseMapperX&lt;SocialUserDO&gt; {
25 25 .eq(SocialUserDO::getCode, openid));
26 26 }
27 27  
28   - default List<SocialUserDO> selectListByUserId(Integer userType, Long userId) {
29   - return selectList(new QueryWrapper<SocialUserDO>().eq("user_type", userType).eq("user_id", userId));
  28 + default List<SocialUserDO> selectListByUnionIdAndType(Collection<String> unionIds, Collection<Integer> types) {
  29 + return selectList(new LambdaQueryWrapper<SocialUserDO>()
  30 + .in(SocialUserDO::getUnionId, unionIds)
  31 + .in(SocialUserDO::getType, types));
30 32 }
31 33  
32 34 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
1 1 package cn.iocoder.yudao.module.system.service.social;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.lang.Assert;
4 5 import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 7 import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
6 8 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
7 9 import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
... ... @@ -21,7 +23,9 @@ import org.springframework.transaction.annotation.Transactional;
21 23 import org.springframework.validation.annotation.Validated;
22 24  
23 25 import javax.annotation.Resource;
  26 +import java.util.Collections;
24 27 import java.util.List;
  28 +import java.util.Set;
25 29  
26 30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27 31 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
... ... @@ -64,20 +68,18 @@ public class SocialUserServiceImpl implements SocialUserService {
64 68 }
65 69  
66 70 // 请求获取
67   - AuthUser authUser = getAuthUser(type, buildAuthCallback(code, state));
68   - if (authUser == null) {
69   - throw exception(SOCIAL_USER_NOT_FOUND);
70   - }
  71 + AuthUser authUser = getAuthUser(type, code, state);
  72 + Assert.notNull(authUser, "三方用户不能为空");
71 73  
72 74 // 保存到 DB 中
73 75 socialUser = socialUserMapper.selectByTypeAndOpenid(type, authUser.getUuid());
74 76 if (socialUser == null) {
75 77 socialUser = new SocialUserDO();
76 78 }
77   - socialUser.setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken())))
  79 + socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询
  80 + .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken())))
78 81 .setUnionId(StrUtil.blankToDefault(authUser.getToken().getUnionId(), authUser.getUuid())) // unionId 识别多个用户
79   - .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo()))
80   - .setCode(code).setState(state); // 需要保存 code + state 字段,保证后续可查询
  82 + .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo()));
81 83 if (socialUser.getId() == null) {
82 84 socialUserMapper.insert(socialUser);
83 85 } else {
... ... @@ -88,7 +90,15 @@ public class SocialUserServiceImpl implements SocialUserService {
88 90  
89 91 @Override
90 92 public List<SocialUserDO> getSocialUserList(Long userId, Integer userType) {
91   - return socialUserMapper.selectListByUserId(userType, userId);
  93 + // 获得绑定
  94 + List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectListByUserIdAndUserType(userId, userType);
  95 + if (CollUtil.isEmpty(socialUserBinds)) {
  96 + return Collections.emptyList();
  97 + }
  98 + // 获得社交用户
  99 + Set<Integer> platforms = CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getPlatform);
  100 + return socialUserMapper.selectListByUnionIdAndType(CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getUnionId),
  101 + SocialTypeEnum.getTypes(platforms));
92 102 }
93 103  
94 104 @Override
... ... @@ -98,13 +108,19 @@ public class SocialUserServiceImpl implements SocialUserService {
98 108 SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState());
99 109 Assert.notNull(socialUser, "社交用户不能为空");
100 110  
  111 + // 如果 unionId 之前被绑定过,需要进行解绑
  112 + Integer platform = SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform();
  113 + socialUserBindMapper.deleteByUserTypeAndPlatformAndUnionId(reqDTO.getUserType(), platform,
  114 + socialUser.getUnionId());
  115 +
101 116 // 如果 userId 之前绑定过该 type 的其它账号,需要进行解绑
102   - socialUserBindMapper.deleteByUserTypeAndUserIdAndPlatformAndUnionId(reqDTO.getUserType(), reqDTO.getUserId(),
103   - SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(), socialUser.getUnionId());
  117 + socialUserBindMapper.deleteByUserTypeAndUserIdAndUnionId(reqDTO.getUserType(), reqDTO.getUserId(),
  118 + socialUser.getUnionId());
104 119  
105 120 // 绑定当前登录的社交用户
106   - SocialUserBindDO socialUserBind = SocialUserBindDO.builder().userId(reqDTO.getUserId()).userType(reqDTO.getUserType())
107   - .unionId(socialUser.getUnionId()).build();
  121 + SocialUserBindDO socialUserBind = SocialUserBindDO.builder()
  122 + .userId(reqDTO.getUserId()).userType(reqDTO.getUserType())
  123 + .platform(platform).unionId(socialUser.getUnionId()).build();
108 124 socialUserBindMapper.insert(socialUserBind);
109 125 }
110 126  
... ... @@ -140,22 +156,20 @@ public class SocialUserServiceImpl implements SocialUserService {
140 156 * 请求社交平台,获得授权的用户
141 157 *
142 158 * @param type 社交平台的类型
143   - * @param authCallback 授权回调
  159 + * @param code 授权码
  160 + * @param state 授权 state
144 161 * @return 授权的用户
145 162 */
146   - private AuthUser getAuthUser(Integer type, AuthCallback authCallback) {
  163 + private AuthUser getAuthUser(Integer type, String code, String state) {
147 164 AuthRequest authRequest = authRequestFactory.get(SocialTypeEnum.valueOfType(type).getSource());
  165 + AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build();
148 166 AuthResponse<?> authResponse = authRequest.login(authCallback);
149   - log.info("[getAuthUser0][请求社交平台 type({}) request({}) response({})]", type, toJsonString(authCallback),
150   - toJsonString(authResponse));
  167 + log.info("[getAuthUser][请求社交平台 type({}) request({}) response({})]", type,
  168 + toJsonString(authCallback), toJsonString(authResponse));
151 169 if (!authResponse.ok()) {
152 170 throw exception(SOCIAL_USER_AUTH_FAILURE, authResponse.getMsg());
153 171 }
154 172 return (AuthUser) authResponse.getData();
155 173 }
156 174  
157   - private static AuthCallback buildAuthCallback(String code, String state) {
158   - return AuthCallback.builder().code(code).state(state).build();
159   - }
160   -
161 175 }
... ...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java
1 1 package cn.iocoder.yudao.module.system.service.social;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  4 +import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
  5 +import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
  6 +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
  7 +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
  9 +import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
3 10 import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper;
4 11 import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
  12 +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
5 13 import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
6 14 import com.xkcoding.justauth.AuthRequestFactory;
  15 +import me.zhyd.oauth.enums.AuthResponseStatus;
  16 +import me.zhyd.oauth.model.AuthCallback;
  17 +import me.zhyd.oauth.model.AuthResponse;
  18 +import me.zhyd.oauth.model.AuthUser;
7 19 import me.zhyd.oauth.request.AuthRequest;
8 20 import me.zhyd.oauth.utils.AuthStateUtils;
9 21 import org.junit.jupiter.api.Test;
  22 +import org.junit.jupiter.api.function.Executable;
10 23 import org.mockito.MockedStatic;
11 24 import org.springframework.boot.test.mock.mockito.MockBean;
12 25 import org.springframework.context.annotation.Import;
13 26  
14 27 import javax.annotation.Resource;
15 28  
16   -import static cn.hutool.core.util.RandomUtil.randomEle;
17   -import static cn.hutool.core.util.RandomUtil.randomString;
  29 +import java.util.List;
  30 +
  31 +import static cn.hutool.core.util.RandomUtil.*;
  32 +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
  33 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  34 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
18 35 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  36 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_AUTH_FAILURE;
  37 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_NOT_FOUND;
19 38 import static org.junit.jupiter.api.Assertions.assertEquals;
20 39 import static org.mockito.Mockito.*;
21 40  
... ... @@ -27,6 +46,8 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest {
27 46  
28 47 @Resource
29 48 private SocialUserMapper socialUserMapper;
  49 + @Resource
  50 + private SocialUserBindMapper socialUserBindMapper;
30 51  
31 52 @MockBean
32 53 private AuthRequestFactory authRequestFactory;
... ... @@ -35,7 +56,7 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest {
35 56 public void testGetAuthorizeUrl() {
36 57 try (MockedStatic<AuthStateUtils> authStateUtilsMock = mockStatic(AuthStateUtils.class)) {
37 58 // 准备参数
38   - Integer type = 31;
  59 + Integer type = SocialTypeEnum.WECHAT_MP.getType();
39 60 String redirectUri = "sss";
40 61 // mock 获得对应的 AuthRequest 实现
41 62 AuthRequest authRequest = mock(AuthRequest.class);
... ... @@ -51,25 +72,138 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest {
51 72 }
52 73 }
53 74  
54   -// /**
55   -// * 情况一,创建 SocialUserDO 的情况
56   -// */
57   -// @Test
58   -// public void testBindSocialUser_create() {
59   -// // mock 数据
60   -// // 准备参数
61   -// Long userId = randomLongId();
62   -// Integer type = randomEle(SocialTypeEnum.values()).getType();
63   -// AuthUser authUser = randomPojo(AuthUser.class);
64   -// // mock 方法
65   -//
66   -// // 调用
67   -// socialService.bindSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, authUser);
68   -// // 断言
69   -// List<SocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId);
70   -// assertEquals(1, socialUsers.size());
71   -// assertBindSocialUser(socialUsers.get(0), authUser, userId, type);
72   -// }
  75 + @Test
  76 + public void testAuthSocialUser_exists() {
  77 + // 准备参数
  78 + Integer type = SocialTypeEnum.GITEE.getType();
  79 + String code = "tudou";
  80 + String state = "yuanma";
  81 + // mock 方法
  82 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state);
  83 + socialUserMapper.insert(socialUser);
  84 +
  85 + // 调用
  86 + SocialUserDO result = socialUserService.authSocialUser(type, code, state);
  87 + // 断言
  88 + assertPojoEquals(socialUser, result);
  89 + }
  90 +
  91 + @Test
  92 + public void testAuthSocialUser_authFailure() {
  93 + // 准备参数
  94 + Integer type = SocialTypeEnum.GITEE.getType();
  95 + // mock 方法
  96 + AuthRequest authRequest = mock(AuthRequest.class);
  97 + when(authRequestFactory.get(anyString())).thenReturn(authRequest);
  98 + AuthResponse<?> authResponse = new AuthResponse<>(0, "模拟失败", null);
  99 + when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse);
  100 +
  101 + // 调用并断言
  102 + assertServiceException(
  103 + () -> socialUserService.authSocialUser(type, randomString(10), randomString(10)),
  104 + SOCIAL_USER_AUTH_FAILURE, "模拟失败");
  105 + }
  106 +
  107 + @Test
  108 + public void testAuthSocialUser_insert() {
  109 + // 准备参数
  110 + Integer type = SocialTypeEnum.GITEE.getType();
  111 + String code = "tudou";
  112 + String state = "yuanma";
  113 + // mock 方法
  114 + AuthRequest authRequest = mock(AuthRequest.class);
  115 + when(authRequestFactory.get(eq(SocialTypeEnum.GITEE.getSource()))).thenReturn(authRequest);
  116 + AuthUser authUser = randomPojo(AuthUser.class);
  117 + AuthResponse<AuthUser> authResponse = new AuthResponse<>(AuthResponseStatus.SUCCESS.getCode(), null, authUser);
  118 + when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse);
  119 +
  120 + // 调用
  121 + SocialUserDO result = socialUserService.authSocialUser(type, code, state);
  122 + // 断言
  123 + assertBindSocialUser(type, result, authResponse.getData());
  124 + assertEquals(code, result.getCode());
  125 + assertEquals(state, result.getState());
  126 + }
  127 +
  128 + @Test
  129 + public void testAuthSocialUser_update() {
  130 + // 准备参数
  131 + Integer type = SocialTypeEnum.GITEE.getType();
  132 + String code = "tudou";
  133 + String state = "yuanma";
  134 + // mock 数据
  135 + socialUserMapper.insert(randomPojo(SocialUserDO.class).setType(type).setOpenid("test_openid"));
  136 + // mock 方法
  137 + AuthRequest authRequest = mock(AuthRequest.class);
  138 + when(authRequestFactory.get(eq(SocialTypeEnum.GITEE.getSource()))).thenReturn(authRequest);
  139 + AuthUser authUser = randomPojo(AuthUser.class);
  140 + authUser.getToken().setOpenId("test_openid");
  141 + AuthResponse<AuthUser> authResponse = new AuthResponse<>(AuthResponseStatus.SUCCESS.getCode(), null, authUser);
  142 + when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse);
  143 +
  144 + // 调用
  145 + SocialUserDO result = socialUserService.authSocialUser(type, code, state);
  146 + // 断言
  147 + assertBindSocialUser(type, result, authResponse.getData());
  148 + assertEquals(code, result.getCode());
  149 + assertEquals(state, result.getState());
  150 + }
  151 +
  152 + private void assertBindSocialUser(Integer type, SocialUserDO socialUser, AuthUser authUser) {
  153 + assertEquals(authUser.getToken().getAccessToken(), socialUser.getToken());
  154 + assertEquals(toJsonString(authUser.getToken()), socialUser.getRawTokenInfo());
  155 + assertEquals(authUser.getNickname(), socialUser.getNickname());
  156 + assertEquals(authUser.getAvatar(), socialUser.getAvatar());
  157 + assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo());
  158 + assertEquals(type, socialUser.getType());
  159 + assertEquals(authUser.getUuid(), socialUser.getOpenid());
  160 + assertEquals(authUser.getToken().getUnionId(), socialUser.getUnionId());
  161 + }
  162 +
  163 + @Test
  164 + public void testGetSocialUserList() {
  165 + Long userId = 1L;
  166 + Integer userType = UserTypeEnum.ADMIN.getValue();
  167 + // mock 获得绑定
  168 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到
  169 + .setUserId(userId).setUserType(userType).setPlatform(SocialTypeEnum.GITEE.getPlatform())
  170 + .setUnionId("test_unionId"));
  171 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到
  172 + .setUserId(2L).setUserType(userType).setPlatform(SocialTypeEnum.DINGTALK.getPlatform()));
  173 + // mock 获得社交用户
  174 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType())
  175 + .setUnionId("test_unionId");
  176 + socialUserMapper.insert(socialUser); // 可被查到
  177 + socialUserMapper.insert(randomPojo(SocialUserDO.class)); // 不可被查到
  178 +
  179 + // 调用
  180 + List<SocialUserDO> result = socialUserService.getSocialUserList(userId, userType);
  181 + // 断言
  182 + assertEquals(1, result.size());
  183 + assertPojoEquals(socialUser, result.get(0));
  184 + }
  185 +
  186 + @Test
  187 + public void testBindSocialUser_create() {
  188 + // 准备参数
  189 + SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO()
  190 + .setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue())
  191 + .setType(SocialTypeEnum.GITEE.getType()).setCode("test_code").setState("test_state");
  192 + // mock 数据:获得社交用户
  193 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(reqDTO.getType())
  194 + .setCode(reqDTO.getCode()).setState(reqDTO.getState()).setUnionId("test_unionId");
  195 + socialUserMapper.insert(socialUser);
  196 + // mock 数据:解绑其它账号
  197 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue())
  198 + .setPlatform(SocialTypeEnum.GITEE.getPlatform()).setUnionId("test_delete_unionId"));
  199 +
  200 + // 调用
  201 + socialUserService.bindSocialUser(reqDTO);
  202 + // 断言
  203 + List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList();
  204 + assertEquals(1, socialUserBinds.size());
  205 +
  206 + }
73 207 //
74 208 // /**
75 209 // * 情况二,更新 SocialUserDO 的情况
... ... @@ -119,20 +253,7 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest {
119 253 // List<SocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId);
120 254 // assertEquals(1, socialUsers.size());
121 255 // }
122   -//
123   -// private void assertBindSocialUser(SocialUserDO socialUser, AuthUser authUser, Long userId,
124   -// Integer type) {
125   -// assertEquals(authUser.getToken().getAccessToken(), socialUser.getToken());
126   -// assertEquals(toJsonString(authUser.getToken()), socialUser.getRawTokenInfo());
127   -// assertEquals(authUser.getNickname(), socialUser.getNickname());
128   -// assertEquals(authUser.getAvatar(), socialUser.getAvatar());
129   -// assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo());
130   -// assertEquals(userId, socialUser.getUserId());
131   -// assertEquals(UserTypeEnum.ADMIN.getValue(), socialUser.getUserType());
132   -// assertEquals(type, socialUser.getType());
133   -// assertEquals(authUser.getUuid(), socialUser.getOpenid());
134   -// assertEquals(socialService.getAuthUserUnionId(authUser), socialUser.getUnionId());
135   -// }
  256 +
136 257 //
137 258 // /**
138 259 // * 情况一,如果新老的 unionId 是一致的,无需解绑
... ...
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql
... ... @@ -15,6 +15,7 @@ DELETE FROM &quot;system_sms_template&quot;;
15 15 DELETE FROM "system_sms_log";
16 16 DELETE FROM "system_error_code";
17 17 DELETE FROM "system_social_user";
  18 +DELETE FROM "system_social_user_bind";
18 19 DELETE FROM "system_tenant";
19 20 DELETE FROM "system_tenant_package";
20 21 DELETE FROM "system_sensitive_word";
... ...
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
... ... @@ -378,16 +378,16 @@ CREATE TABLE IF NOT EXISTS &quot;system_error_code&quot; (
378 378  
379 379 CREATE TABLE IF NOT EXISTS "system_social_user" (
380 380 "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
381   - "user_id" bigint NOT NULL,
382   - "user_type" tinyint NOT NULL DEFAULT '0',
383 381 "type" tinyint NOT NULL,
384   - "openid" varchar(32) NOT NULL,
  382 + "openid" varchar(64) NOT NULL,
385 383 "token" varchar(256) DEFAULT NULL,
386   - "union_id" varchar(32) NOT NULL,
  384 + "union_id" varchar(64) NOT NULL,
387 385 "raw_token_info" varchar(1024) NOT NULL,
388 386 "nickname" varchar(32) NOT NULL,
389 387 "avatar" varchar(255) DEFAULT NULL,
390 388 "raw_user_info" varchar(1024) NOT NULL,
  389 + "code" varchar(64) NOT NULL,
  390 + "state" varchar(64),
391 391 "creator" varchar(64) DEFAULT '',
392 392 "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
393 393 "updater" varchar(64) DEFAULT '',
... ... @@ -396,6 +396,20 @@ CREATE TABLE IF NOT EXISTS &quot;system_social_user&quot; (
396 396 PRIMARY KEY ("id")
397 397 ) COMMENT '社交用户';
398 398  
  399 +CREATE TABLE IF NOT EXISTS "system_social_user_bind" (
  400 + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  401 + "user_id" bigint NOT NULL,
  402 + "user_type" tinyint NOT NULL DEFAULT '0',
  403 + "platform" tinyint NOT NULL,
  404 + "union_id" varchar(64) NOT NULL,
  405 + "creator" varchar(64) DEFAULT '',
  406 + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  407 + "updater" varchar(64) DEFAULT '',
  408 + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  409 + "deleted" bit NOT NULL DEFAULT FALSE,
  410 + PRIMARY KEY ("id")
  411 +) COMMENT '社交用户的绑定';
  412 +
399 413 CREATE TABLE IF NOT EXISTS "system_tenant" (
400 414 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
401 415 "name" varchar(63) NOT NULL,
... ...