diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java index 67fca5ff3..81b4e47e9 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java @@ -1,13 +1,14 @@ package cn.iocoder.yudao.module.system.enums.social; -import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ArrayUtil; import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.AllArgsConstructor; import lombok.Getter; import java.util.Arrays; -import java.util.List; +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; /** * 社交平台的类型枚举 @@ -77,4 +78,11 @@ public enum SocialTypeEnum implements IntArrayValuable { return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); } + public static Set getTypes(Collection platforms) { + return Arrays.stream(values()) + .filter(socialTypeEnum -> platforms.contains(socialTypeEnum.getPlatform())) + .map(SocialTypeEnum::getType) + .collect(Collectors.toSet()); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserDO.java index 069536dca..7d9babf57 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserDO.java @@ -42,13 +42,6 @@ public class SocialUserDO extends BaseDO { * 社交 token */ private String token; - /** - * 社交的全局编号 - * - * 例如说,微信平台的 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html - * 如果没有 unionId 的平台,直接使用 openid 作为该字段的值 - */ - private String unionId; /** * 原始 Token 数据,一般是 JSON 格式 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java index 0b245e0bd..016a7fcf8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java +++ b/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; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + @Mapper public interface SocialUserBindMapper extends BaseMapperX { - default void deleteByUserTypeAndUserIdAndPlatformAndUnionId(Integer userType, Long userId, - Integer platform, String unionId) { + default void deleteByUserTypeAndUserIdAndUnionId(Integer userType, Long userId, Integer platform) { delete(new LambdaQueryWrapperX() .eq(SocialUserBindDO::getUserType, userType) .eq(SocialUserBindDO::getUserId, userId) + .eq(SocialUserBindDO::getPlatform, platform)); + } + + default void deleteByUserTypeAndPlatformAndUnionId(Integer userType, Integer platform, String unionId) { + delete(new LambdaQueryWrapperX() + .eq(SocialUserBindDO::getUserType, userType) .eq(SocialUserBindDO::getPlatform, platform) .eq(SocialUserBindDO::getUnionId, unionId)); } @@ -25,4 +32,10 @@ public interface SocialUserBindMapper extends BaseMapperX { .eq(SocialUserBindDO::getUnionId, unionId)); } + default List selectListByUserIdAndUserType(Long userId, Integer userType) { + return selectList(new LambdaQueryWrapperX() + .eq(SocialUserBindDO::getUserId, userId) + .eq(SocialUserBindDO::getUserType, userType)); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserMapper.java index aa5a623de..4c1d854a7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserMapper.java +++ b/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 { .eq(SocialUserDO::getCode, openid)); } - default List selectListByUserId(Integer userType, Long userId) { - return selectList(new QueryWrapper().eq("user_type", userType).eq("user_id", userId)); + default List selectListByUnionIdAndType(Collection unionIds, Collection types) { + return selectList(new LambdaQueryWrapper() + .in(SocialUserDO::getUnionId, unionIds) + .in(SocialUserDO::getType, types)); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java index 711e21871..dd4dc0f5a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.system.service.social; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.http.HttpUtils; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; @@ -21,7 +23,9 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.util.Collections; import java.util.List; +import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; @@ -64,20 +68,18 @@ public class SocialUserServiceImpl implements SocialUserService { } // 请求获取 - AuthUser authUser = getAuthUser(type, buildAuthCallback(code, state)); - if (authUser == null) { - throw exception(SOCIAL_USER_NOT_FOUND); - } + AuthUser authUser = getAuthUser(type, code, state); + Assert.notNull(authUser, "三方用户不能为空"); // 保存到 DB 中 socialUser = socialUserMapper.selectByTypeAndOpenid(type, authUser.getUuid()); if (socialUser == null) { socialUser = new SocialUserDO(); } - socialUser.setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken()))) + socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询 + .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken()))) .setUnionId(StrUtil.blankToDefault(authUser.getToken().getUnionId(), authUser.getUuid())) // unionId 识别多个用户 - .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo())) - .setCode(code).setState(state); // 需要保存 code + state 字段,保证后续可查询 + .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo())); if (socialUser.getId() == null) { socialUserMapper.insert(socialUser); } else { @@ -88,7 +90,15 @@ public class SocialUserServiceImpl implements SocialUserService { @Override public List getSocialUserList(Long userId, Integer userType) { - return socialUserMapper.selectListByUserId(userType, userId); + // 获得绑定 + List socialUserBinds = socialUserBindMapper.selectListByUserIdAndUserType(userId, userType); + if (CollUtil.isEmpty(socialUserBinds)) { + return Collections.emptyList(); + } + // 获得社交用户 + Set platforms = CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getPlatform); + return socialUserMapper.selectListByUnionIdAndType(CollectionUtils.convertSet(socialUserBinds, SocialUserBindDO::getUnionId), + SocialTypeEnum.getTypes(platforms)); } @Override @@ -98,13 +108,19 @@ public class SocialUserServiceImpl implements SocialUserService { SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); Assert.notNull(socialUser, "社交用户不能为空"); + // 如果 unionId 之前被绑定过,需要进行解绑 + Integer platform = SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(); + socialUserBindMapper.deleteByUserTypeAndPlatformAndUnionId(reqDTO.getUserType(), platform, + socialUser.getUnionId()); + // 如果 userId 之前绑定过该 type 的其它账号,需要进行解绑 - socialUserBindMapper.deleteByUserTypeAndUserIdAndPlatformAndUnionId(reqDTO.getUserType(), reqDTO.getUserId(), - SocialTypeEnum.valueOfType(socialUser.getType()).getPlatform(), socialUser.getUnionId()); + socialUserBindMapper.deleteByUserTypeAndUserIdAndUnionId(reqDTO.getUserType(), reqDTO.getUserId(), + socialUser.getUnionId()); // 绑定当前登录的社交用户 - SocialUserBindDO socialUserBind = SocialUserBindDO.builder().userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) - .unionId(socialUser.getUnionId()).build(); + SocialUserBindDO socialUserBind = SocialUserBindDO.builder() + .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) + .platform(platform).unionId(socialUser.getUnionId()).build(); socialUserBindMapper.insert(socialUserBind); } @@ -140,22 +156,20 @@ public class SocialUserServiceImpl implements SocialUserService { * 请求社交平台,获得授权的用户 * * @param type 社交平台的类型 - * @param authCallback 授权回调 + * @param code 授权码 + * @param state 授权 state * @return 授权的用户 */ - private AuthUser getAuthUser(Integer type, AuthCallback authCallback) { + private AuthUser getAuthUser(Integer type, String code, String state) { AuthRequest authRequest = authRequestFactory.get(SocialTypeEnum.valueOfType(type).getSource()); + AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build(); AuthResponse authResponse = authRequest.login(authCallback); - log.info("[getAuthUser0][请求社交平台 type({}) request({}) response({})]", type, toJsonString(authCallback), - toJsonString(authResponse)); + log.info("[getAuthUser][请求社交平台 type({}) request({}) response({})]", type, + toJsonString(authCallback), toJsonString(authResponse)); if (!authResponse.ok()) { throw exception(SOCIAL_USER_AUTH_FAILURE, authResponse.getMsg()); } return (AuthUser) authResponse.getData(); } - private static AuthCallback buildAuthCallback(String code, String state) { - return AuthCallback.builder().code(code).state(state).build(); - } - } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java index 909424074..b7302173d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java @@ -1,21 +1,40 @@ package cn.iocoder.yudao.module.system.service.social; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.test.core.util.AssertUtils; +import cn.iocoder.yudao.framework.test.core.util.RandomUtils; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; +import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper; import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import com.baomidou.mybatisplus.core.toolkit.PluginUtils; import com.xkcoding.justauth.AuthRequestFactory; +import me.zhyd.oauth.enums.AuthResponseStatus; +import me.zhyd.oauth.model.AuthCallback; +import me.zhyd.oauth.model.AuthResponse; +import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.request.AuthRequest; import me.zhyd.oauth.utils.AuthStateUtils; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; import org.mockito.MockedStatic; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.hutool.core.util.RandomUtil.randomString; +import java.util.List; + +import static cn.hutool.core.util.RandomUtil.*; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_AUTH_FAILURE; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_NOT_FOUND; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; @@ -27,6 +46,8 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { @Resource private SocialUserMapper socialUserMapper; + @Resource + private SocialUserBindMapper socialUserBindMapper; @MockBean private AuthRequestFactory authRequestFactory; @@ -35,7 +56,7 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { public void testGetAuthorizeUrl() { try (MockedStatic authStateUtilsMock = mockStatic(AuthStateUtils.class)) { // 准备参数 - Integer type = 31; + Integer type = SocialTypeEnum.WECHAT_MP.getType(); String redirectUri = "sss"; // mock 获得对应的 AuthRequest 实现 AuthRequest authRequest = mock(AuthRequest.class); @@ -51,25 +72,138 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { } } -// /** -// * 情况一,创建 SocialUserDO 的情况 -// */ -// @Test -// public void testBindSocialUser_create() { -// // mock 数据 -// // 准备参数 -// Long userId = randomLongId(); -// Integer type = randomEle(SocialTypeEnum.values()).getType(); -// AuthUser authUser = randomPojo(AuthUser.class); -// // mock 方法 -// -// // 调用 -// socialService.bindSocialUser(userId, UserTypeEnum.ADMIN.getValue(), type, authUser); -// // 断言 -// List socialUsers = socialUserMapper.selectList("user_id", userId); -// assertEquals(1, socialUsers.size()); -// assertBindSocialUser(socialUsers.get(0), authUser, userId, type); -// } + @Test + public void testAuthSocialUser_exists() { + // 准备参数 + Integer type = SocialTypeEnum.GITEE.getType(); + String code = "tudou"; + String state = "yuanma"; + // mock 方法 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); + socialUserMapper.insert(socialUser); + + // 调用 + SocialUserDO result = socialUserService.authSocialUser(type, code, state); + // 断言 + assertPojoEquals(socialUser, result); + } + + @Test + public void testAuthSocialUser_authFailure() { + // 准备参数 + Integer type = SocialTypeEnum.GITEE.getType(); + // mock 方法 + AuthRequest authRequest = mock(AuthRequest.class); + when(authRequestFactory.get(anyString())).thenReturn(authRequest); + AuthResponse authResponse = new AuthResponse<>(0, "模拟失败", null); + when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse); + + // 调用并断言 + assertServiceException( + () -> socialUserService.authSocialUser(type, randomString(10), randomString(10)), + SOCIAL_USER_AUTH_FAILURE, "模拟失败"); + } + + @Test + public void testAuthSocialUser_insert() { + // 准备参数 + Integer type = SocialTypeEnum.GITEE.getType(); + String code = "tudou"; + String state = "yuanma"; + // mock 方法 + AuthRequest authRequest = mock(AuthRequest.class); + when(authRequestFactory.get(eq(SocialTypeEnum.GITEE.getSource()))).thenReturn(authRequest); + AuthUser authUser = randomPojo(AuthUser.class); + AuthResponse authResponse = new AuthResponse<>(AuthResponseStatus.SUCCESS.getCode(), null, authUser); + when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse); + + // 调用 + SocialUserDO result = socialUserService.authSocialUser(type, code, state); + // 断言 + assertBindSocialUser(type, result, authResponse.getData()); + assertEquals(code, result.getCode()); + assertEquals(state, result.getState()); + } + + @Test + public void testAuthSocialUser_update() { + // 准备参数 + Integer type = SocialTypeEnum.GITEE.getType(); + String code = "tudou"; + String state = "yuanma"; + // mock 数据 + socialUserMapper.insert(randomPojo(SocialUserDO.class).setType(type).setOpenid("test_openid")); + // mock 方法 + AuthRequest authRequest = mock(AuthRequest.class); + when(authRequestFactory.get(eq(SocialTypeEnum.GITEE.getSource()))).thenReturn(authRequest); + AuthUser authUser = randomPojo(AuthUser.class); + authUser.getToken().setOpenId("test_openid"); + AuthResponse authResponse = new AuthResponse<>(AuthResponseStatus.SUCCESS.getCode(), null, authUser); + when(authRequest.login(any(AuthCallback.class))).thenReturn(authResponse); + + // 调用 + SocialUserDO result = socialUserService.authSocialUser(type, code, state); + // 断言 + assertBindSocialUser(type, result, authResponse.getData()); + assertEquals(code, result.getCode()); + assertEquals(state, result.getState()); + } + + private void assertBindSocialUser(Integer type, SocialUserDO socialUser, AuthUser authUser) { + assertEquals(authUser.getToken().getAccessToken(), socialUser.getToken()); + assertEquals(toJsonString(authUser.getToken()), socialUser.getRawTokenInfo()); + assertEquals(authUser.getNickname(), socialUser.getNickname()); + assertEquals(authUser.getAvatar(), socialUser.getAvatar()); + assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo()); + assertEquals(type, socialUser.getType()); + assertEquals(authUser.getUuid(), socialUser.getOpenid()); + assertEquals(authUser.getToken().getUnionId(), socialUser.getUnionId()); + } + + @Test + public void testGetSocialUserList() { + Long userId = 1L; + Integer userType = UserTypeEnum.ADMIN.getValue(); + // mock 获得绑定 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到 + .setUserId(userId).setUserType(userType).setPlatform(SocialTypeEnum.GITEE.getPlatform()) + .setUnionId("test_unionId")); + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到 + .setUserId(2L).setUserType(userType).setPlatform(SocialTypeEnum.DINGTALK.getPlatform())); + // mock 获得社交用户 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType()) + .setUnionId("test_unionId"); + socialUserMapper.insert(socialUser); // 可被查到 + socialUserMapper.insert(randomPojo(SocialUserDO.class)); // 不可被查到 + + // 调用 + List result = socialUserService.getSocialUserList(userId, userType); + // 断言 + assertEquals(1, result.size()); + assertPojoEquals(socialUser, result.get(0)); + } + + @Test + public void testBindSocialUser_create() { + // 准备参数 + SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO() + .setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) + .setType(SocialTypeEnum.GITEE.getType()).setCode("test_code").setState("test_state"); + // mock 数据:获得社交用户 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(reqDTO.getType()) + .setCode(reqDTO.getCode()).setState(reqDTO.getState()).setUnionId("test_unionId"); + socialUserMapper.insert(socialUser); + // mock 数据:解绑其它账号 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) + .setPlatform(SocialTypeEnum.GITEE.getPlatform()).setUnionId("test_delete_unionId")); + + // 调用 + socialUserService.bindSocialUser(reqDTO); + // 断言 + List socialUserBinds = socialUserBindMapper.selectList(); + assertEquals(1, socialUserBinds.size()); + + } // // /** // * 情况二,更新 SocialUserDO 的情况 @@ -119,20 +253,7 @@ public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { // List socialUsers = socialUserMapper.selectList("user_id", userId); // assertEquals(1, socialUsers.size()); // } -// -// private void assertBindSocialUser(SocialUserDO socialUser, AuthUser authUser, Long userId, -// Integer type) { -// assertEquals(authUser.getToken().getAccessToken(), socialUser.getToken()); -// assertEquals(toJsonString(authUser.getToken()), socialUser.getRawTokenInfo()); -// assertEquals(authUser.getNickname(), socialUser.getNickname()); -// assertEquals(authUser.getAvatar(), socialUser.getAvatar()); -// assertEquals(toJsonString(authUser.getRawUserInfo()), socialUser.getRawUserInfo()); -// assertEquals(userId, socialUser.getUserId()); -// assertEquals(UserTypeEnum.ADMIN.getValue(), socialUser.getUserType()); -// assertEquals(type, socialUser.getType()); -// assertEquals(authUser.getUuid(), socialUser.getOpenid()); -// assertEquals(socialService.getAuthUserUnionId(authUser), socialUser.getUnionId()); -// } + // // /** // * 情况一,如果新老的 unionId 是一致的,无需解绑 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql index 6f0e9d384..1a3cdce8f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql @@ -15,6 +15,7 @@ DELETE FROM "system_sms_template"; DELETE FROM "system_sms_log"; DELETE FROM "system_error_code"; DELETE FROM "system_social_user"; +DELETE FROM "system_social_user_bind"; DELETE FROM "system_tenant"; DELETE FROM "system_tenant_package"; DELETE FROM "system_sensitive_word"; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql index ae59b7ab0..9f88f8b5b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql @@ -378,16 +378,16 @@ CREATE TABLE IF NOT EXISTS "system_error_code" ( CREATE TABLE IF NOT EXISTS "system_social_user" ( "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" tinyint NOT NULL DEFAULT '0', "type" tinyint NOT NULL, - "openid" varchar(32) NOT NULL, + "openid" varchar(64) NOT NULL, "token" varchar(256) DEFAULT NULL, - "union_id" varchar(32) NOT NULL, + "union_id" varchar(64) NOT NULL, "raw_token_info" varchar(1024) NOT NULL, "nickname" varchar(32) NOT NULL, "avatar" varchar(255) DEFAULT NULL, "raw_user_info" varchar(1024) NOT NULL, + "code" varchar(64) NOT NULL, + "state" varchar(64), "creator" varchar(64) DEFAULT '', "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, "updater" varchar(64) DEFAULT '', @@ -396,6 +396,20 @@ CREATE TABLE IF NOT EXISTS "system_social_user" ( PRIMARY KEY ("id") ) COMMENT '社交用户'; +CREATE TABLE IF NOT EXISTS "system_social_user_bind" ( + "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "user_id" bigint NOT NULL, + "user_type" tinyint NOT NULL DEFAULT '0', + "platform" tinyint NOT NULL, + "union_id" varchar(64) NOT NULL, + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '社交用户的绑定'; + CREATE TABLE IF NOT EXISTS "system_tenant" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "name" varchar(63) NOT NULL,