mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 04:08:43 +08:00 
			
		
		
		
	Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
Conflicts: yudao-core-service/pom.xml yudao-dependencies/pom.xml yudao-framework/pom.xml
This commit is contained in:
		@@ -101,12 +101,6 @@
 | 
			
		||||
            <artifactId>guava</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <!-- 三方云服务相关 -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>com.xkcoding.justauth</groupId>
 | 
			
		||||
            <artifactId>justauth-spring-boot-starter</artifactId>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
    </dependencies>
 | 
			
		||||
 | 
			
		||||
</project>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.coreservice.modules.system.compent.justauth;
 | 
			
		||||
 | 
			
		||||
import me.zhyd.oauth.config.AuthSource;
 | 
			
		||||
 | 
			
		||||
public enum AuthExtendSource implements AuthSource {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 微信小程序授权登录
 | 
			
		||||
     */
 | 
			
		||||
    WECHAT_MINI_PROGRAM{
 | 
			
		||||
        @Override
 | 
			
		||||
        public String authorize() {
 | 
			
		||||
            // https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
 | 
			
		||||
            throw new UnsupportedOperationException("不支持获取授权url, 请使用小程序内置函数wx.login()登录获取code");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String accessToken() {
 | 
			
		||||
            // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
 | 
			
		||||
            // 获取openid, unionid , session_key
 | 
			
		||||
            return "https://api.weixin.qq.com/sns/jscode2session";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String userInfo() {
 | 
			
		||||
            //https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html
 | 
			
		||||
            throw new UnsupportedOperationException("不支持获取用户信息url, 请使用小程序内置函数wx.getUserProfile()获取用户信息");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.coreservice.modules.system.compent.justauth;
 | 
			
		||||
 | 
			
		||||
import lombok.*;
 | 
			
		||||
import me.zhyd.oauth.model.AuthToken;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * TODO @timfruit:类注释
 | 
			
		||||
 * @author timfruit
 | 
			
		||||
 * @date 2021-10-29
 | 
			
		||||
 */
 | 
			
		||||
@Getter
 | 
			
		||||
@Setter
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
public class AuthExtendToken extends AuthToken {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 微信小程序 会话密钥
 | 
			
		||||
     */
 | 
			
		||||
    private String miniSessionKey;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,90 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.coreservice.modules.system.compent.justauth;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import me.zhyd.oauth.cache.AuthStateCache;
 | 
			
		||||
import me.zhyd.oauth.config.AuthConfig;
 | 
			
		||||
import me.zhyd.oauth.exception.AuthException;
 | 
			
		||||
import me.zhyd.oauth.model.AuthCallback;
 | 
			
		||||
import me.zhyd.oauth.model.AuthToken;
 | 
			
		||||
import me.zhyd.oauth.model.AuthUser;
 | 
			
		||||
import me.zhyd.oauth.request.AuthDefaultRequest;
 | 
			
		||||
import me.zhyd.oauth.utils.HttpUtils;
 | 
			
		||||
import me.zhyd.oauth.utils.UrlBuilder;
 | 
			
		||||
 | 
			
		||||
// TODO @timfruit:新建一个 yudao-spring-boot-starter-biz-social 包,把这个拓展拿进去哈。另外,可以思考下。
 | 
			
		||||
// 1. application-local.yaml 的配置里,justauth.extend.enum-class 能否不配置,而是自动配置好
 | 
			
		||||
// 2. application-local.yaml 的配置里,justauth.extend.extend.config.WECHAT_MINI_PROGRAM 有办法和 justauth.type.WECHAT_MP 持平
 | 
			
		||||
/**
 | 
			
		||||
 * 微信小程序登陆
 | 
			
		||||
 *
 | 
			
		||||
 * @author timfruit
 | 
			
		||||
 * @date 2021-10-29
 | 
			
		||||
 */
 | 
			
		||||
public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest {
 | 
			
		||||
 | 
			
		||||
    public AuthWeChatMiniProgramRequest(AuthConfig config) {
 | 
			
		||||
        super(config, AuthExtendSource.WECHAT_MINI_PROGRAM);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public AuthWeChatMiniProgramRequest(AuthConfig config, AuthStateCache authStateCache) {
 | 
			
		||||
        super(config, AuthExtendSource.WECHAT_MINI_PROGRAM, authStateCache);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected AuthToken getAccessToken(AuthCallback authCallback) {
 | 
			
		||||
        // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
 | 
			
		||||
        String response = new HttpUtils(config.getHttpConfig()).get(accessTokenUrl(authCallback.getCode()));
 | 
			
		||||
        JSONObject accessTokenObject = JSONObject.parseObject(response); // TODO @timfruit:使用 JsonUtils,项目尽量避免直接使用某个 json 库
 | 
			
		||||
 | 
			
		||||
        this.checkResponse(accessTokenObject);
 | 
			
		||||
 | 
			
		||||
        AuthExtendToken token = new AuthExtendToken();
 | 
			
		||||
        token.setMiniSessionKey(accessTokenObject.getString("session_key"));
 | 
			
		||||
        token.setOpenId(accessTokenObject.getString("openid"));
 | 
			
		||||
        token.setUnionId(accessTokenObject.getString("unionid"));
 | 
			
		||||
        return token;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected AuthUser getUserInfo(AuthToken authToken) {
 | 
			
		||||
        // https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserProfile.html
 | 
			
		||||
        // 如果需要用户信息,需要在小程序调用函数后传给后端
 | 
			
		||||
        return AuthUser.builder()
 | 
			
		||||
                .uuid(authToken.getOpenId())
 | 
			
		||||
                //TODO 是使用默认值,还是有小程序获取用户信息 和 code 一起传过来
 | 
			
		||||
                .nickname("")
 | 
			
		||||
                .avatar("")
 | 
			
		||||
                .token(authToken)
 | 
			
		||||
                .source(source.toString())
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 检查响应内容是否正确
 | 
			
		||||
     *
 | 
			
		||||
     * @param object 请求响应内容
 | 
			
		||||
     */
 | 
			
		||||
    private void checkResponse(JSONObject object) {
 | 
			
		||||
        int code = object.getIntValue("errcode");
 | 
			
		||||
        if(code != 0){ // TODO @timfruit:if (code != 0) { ,注意空格
 | 
			
		||||
            throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg"));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 返回获取 accessToken 的 url
 | 
			
		||||
     *
 | 
			
		||||
     * @param code 授权码
 | 
			
		||||
     * @return 返回获取 accessToken 的 url
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected String accessTokenUrl(String code) {
 | 
			
		||||
        return UrlBuilder.fromBaseUrl(source.accessToken())
 | 
			
		||||
                .queryParam("appid", config.getClientId())
 | 
			
		||||
                .queryParam("secret", config.getClientSecret())
 | 
			
		||||
                .queryParam("js_code", code)
 | 
			
		||||
                .queryParam("grant_type", "authorization_code")
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -8,9 +8,8 @@ import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
// TODO @timfruit:SysSocialUserCoreMapper 改名,方便区分
 | 
			
		||||
@Mapper
 | 
			
		||||
public interface SysSocialUserMapper extends BaseMapperX<SysSocialUserDO> {
 | 
			
		||||
public interface SysSocialUserCoreMapper extends BaseMapperX<SysSocialUserDO> {
 | 
			
		||||
 | 
			
		||||
    default List<SysSocialUserDO> selectListByTypeAndUnionId(Integer userType, Collection<Integer> types, String unionId) {
 | 
			
		||||
        return selectList(new QueryWrapper<SysSocialUserDO>().eq("user_type", userType)
 | 
			
		||||
@@ -10,9 +10,8 @@ import javax.annotation.Resource;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.coreservice.modules.system.dal.redis.SysRedisKeyCoreConstants.SOCIAL_AUTH_USER;
 | 
			
		||||
 | 
			
		||||
// TODO @timfruit,这里的 AuthUser 还是保留全路径,主要想体现出来,不是自己定义的
 | 
			
		||||
/**
 | 
			
		||||
 * 社交 {@link AuthUser} 的 RedisDAO
 | 
			
		||||
 * 社交 {@link me.zhyd.oauth.model.AuthUser} 的 RedisDAO
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,7 @@ import java.util.List;
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
// TODO @timfruit:SysSocialCoreService 改名,方便区分
 | 
			
		||||
public interface SysSocialService {
 | 
			
		||||
public interface SysSocialCoreService {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获得社交平台的授权 URL
 | 
			
		||||
@@ -50,6 +49,7 @@ public interface SysSocialService {
 | 
			
		||||
     * @param type 社交平台的类型 {@link SysSocialTypeEnum}
 | 
			
		||||
     * @param unionId 社交平台的 unionId
 | 
			
		||||
     * @return 社交用户列表
 | 
			
		||||
     * @param userTypeEnum 全局用户类型
 | 
			
		||||
     */
 | 
			
		||||
    List<SysSocialUserDO> getAllSocialUserList(Integer type, String unionId, UserTypeEnum userTypeEnum);
 | 
			
		||||
 | 
			
		||||
@@ -58,6 +58,7 @@ public interface SysSocialService {
 | 
			
		||||
     *
 | 
			
		||||
     * @param userId 用户编号
 | 
			
		||||
     * @return 社交用户列表
 | 
			
		||||
     * @param userTypeEnum 全局用户类型
 | 
			
		||||
     */
 | 
			
		||||
    List<SysSocialUserDO> getSocialUserList(Long userId, UserTypeEnum userTypeEnum);
 | 
			
		||||
 | 
			
		||||
@@ -67,6 +68,7 @@ public interface SysSocialService {
 | 
			
		||||
     * @param userId 用户编号
 | 
			
		||||
     * @param type 社交平台的类型 {@link SysSocialTypeEnum}
 | 
			
		||||
     * @param authUser 授权用户
 | 
			
		||||
     * @param userTypeEnum 全局用户类型
 | 
			
		||||
     */
 | 
			
		||||
    void bindSocialUser(Long userId, Integer type, AuthUser authUser, UserTypeEnum userTypeEnum);
 | 
			
		||||
 | 
			
		||||
@@ -76,8 +78,8 @@ public interface SysSocialService {
 | 
			
		||||
     * @param userId 用户编号
 | 
			
		||||
     * @param type 社交平台的类型 {@link SysSocialTypeEnum}
 | 
			
		||||
     * @param unionId 社交平台的 unionId
 | 
			
		||||
     * @param userTypeEnum 全局用户类型
 | 
			
		||||
     */
 | 
			
		||||
    void unbindSocialUser(Long userId, Integer type, String unionId,UserTypeEnum userTypeEnum);
 | 
			
		||||
    // TODO @timfruit:逗号后面要有空格;缺少了 @userTypeEnum 的注释,都补充下哈。
 | 
			
		||||
    void unbindSocialUser(Long userId, Integer type, String unionId, UserTypeEnum userTypeEnum);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -2,10 +2,10 @@ package cn.iocoder.yudao.coreservice.modules.system.service.social.impl;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.collection.CollUtil;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.mysql.social.SysSocialUserMapper;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.mysql.social.SysSocialUserCoreMapper;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.redis.social.SysSocialAuthUserRedisDAO;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
 | 
			
		||||
@@ -38,7 +38,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
 | 
			
		||||
@Service
 | 
			
		||||
@Validated
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class SysSocialServiceImpl implements SysSocialService {
 | 
			
		||||
public class SysSocialCoreServiceImpl implements SysSocialCoreService {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private AuthRequestFactory authRequestFactory;
 | 
			
		||||
@@ -47,7 +47,7 @@ public class SysSocialServiceImpl implements SysSocialService {
 | 
			
		||||
    private SysSocialAuthUserRedisDAO authSocialUserRedisDAO;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private SysSocialUserMapper socialUserMapper;
 | 
			
		||||
    private SysSocialUserCoreMapper socialUserMapper;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getAuthorizeUrl(Integer type, String redirectUri) {
 | 
			
		||||
@@ -0,0 +1,171 @@
 | 
			
		||||
package cn.iocoder.yudao.coreservice.modules.system.service.social;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.coreservice.BaseDbAndRedisUnitTest;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.mysql.social.SysSocialUserCoreMapper;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.dal.redis.social.SysSocialAuthUserRedisDAO;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.coreservice.modules.system.service.social.impl.SysSocialCoreServiceImpl;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 | 
			
		||||
import com.xkcoding.justauth.AuthRequestFactory;
 | 
			
		||||
import me.zhyd.oauth.model.AuthUser;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
import org.springframework.boot.test.mock.mockito.MockBean;
 | 
			
		||||
import org.springframework.context.annotation.Import;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static cn.hutool.core.util.RandomUtil.randomEle;
 | 
			
		||||
import static cn.hutool.core.util.RandomUtil.randomString;
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
 | 
			
		||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
 | 
			
		||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
 | 
			
		||||
import static org.junit.jupiter.api.Assertions.assertEquals;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link SysSocialCoreServiceImpl} 的单元测试类
 | 
			
		||||
 *
 | 
			
		||||
 * @author 芋道源码
 | 
			
		||||
 */
 | 
			
		||||
@Import({SysSocialCoreServiceImpl.class, SysSocialAuthUserRedisDAO.class})
 | 
			
		||||
public class SysSocialCoreServiceTest extends BaseDbAndRedisUnitTest {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private SysSocialCoreServiceImpl socialService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private SysSocialUserCoreMapper socialUserMapper;
 | 
			
		||||
 | 
			
		||||
    @MockBean
 | 
			
		||||
    private AuthRequestFactory authRequestFactory;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 情况一,创建 SysSocialUserDO 的情况
 | 
			
		||||
     */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testBindSocialUser_create() {
 | 
			
		||||
        // mock 数据
 | 
			
		||||
        // 准备参数
 | 
			
		||||
        Long userId = randomLongId();
 | 
			
		||||
        Integer type = randomEle(SysSocialTypeEnum.values()).getType();
 | 
			
		||||
        AuthUser authUser = randomPojo(AuthUser.class);
 | 
			
		||||
        // mock 方法
 | 
			
		||||
 | 
			
		||||
        // 调用
 | 
			
		||||
        socialService.bindSocialUser(userId, type, authUser, UserTypeEnum.ADMIN);
 | 
			
		||||
        // 断言
 | 
			
		||||
        List<SysSocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId);
 | 
			
		||||
        assertEquals(1, socialUsers.size());
 | 
			
		||||
        assertBindSocialUser(socialUsers.get(0), authUser, userId, type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 情况二,更新 SysSocialUserDO 的情况
 | 
			
		||||
     */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testBindSocialUser_update() {
 | 
			
		||||
        // mock 数据
 | 
			
		||||
        SysSocialUserDO dbSocialUser = randomPojo(SysSocialUserDO.class, socialUserDO -> {
 | 
			
		||||
            socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue());
 | 
			
		||||
            socialUserDO.setType(randomEle(SysSocialTypeEnum.values()).getType());
 | 
			
		||||
        });
 | 
			
		||||
        socialUserMapper.insert(dbSocialUser);
 | 
			
		||||
        // 准备参数
 | 
			
		||||
        Long userId = dbSocialUser.getUserId();
 | 
			
		||||
        Integer type = dbSocialUser.getType();
 | 
			
		||||
        AuthUser authUser = randomPojo(AuthUser.class);
 | 
			
		||||
        // mock 方法
 | 
			
		||||
 | 
			
		||||
        // 调用
 | 
			
		||||
        socialService.bindSocialUser(userId, type, authUser, UserTypeEnum.ADMIN);
 | 
			
		||||
        // 断言
 | 
			
		||||
        List<SysSocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId);
 | 
			
		||||
        assertEquals(1, socialUsers.size());
 | 
			
		||||
        assertBindSocialUser(socialUsers.get(0), authUser, userId, type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 情况一和二都存在的,逻辑二的场景
 | 
			
		||||
     */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testBindSocialUser_userId() {
 | 
			
		||||
        // mock 数据
 | 
			
		||||
        SysSocialUserDO dbSocialUser = randomPojo(SysSocialUserDO.class, socialUserDO -> {
 | 
			
		||||
            socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue());
 | 
			
		||||
            socialUserDO.setType(randomEle(SysSocialTypeEnum.values()).getType());
 | 
			
		||||
        });
 | 
			
		||||
        socialUserMapper.insert(dbSocialUser);
 | 
			
		||||
        // 准备参数
 | 
			
		||||
        Long userId = randomLongId();
 | 
			
		||||
        Integer type = dbSocialUser.getType();
 | 
			
		||||
        AuthUser authUser = randomPojo(AuthUser.class);
 | 
			
		||||
        // mock 方法
 | 
			
		||||
 | 
			
		||||
        // 调用
 | 
			
		||||
        socialService.bindSocialUser(userId, type, authUser, UserTypeEnum.ADMIN);
 | 
			
		||||
        // 断言
 | 
			
		||||
        List<SysSocialUserDO> socialUsers = socialUserMapper.selectList("user_id", userId);
 | 
			
		||||
        assertEquals(1, socialUsers.size());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void assertBindSocialUser(SysSocialUserDO 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 是一致的,无需解绑
 | 
			
		||||
     */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testUnbindOldSocialUser_no() {
 | 
			
		||||
        // mock 数据
 | 
			
		||||
        SysSocialUserDO oldSocialUser = randomPojo(SysSocialUserDO.class, socialUserDO -> {
 | 
			
		||||
            socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue());
 | 
			
		||||
            socialUserDO.setType(randomEle(SysSocialTypeEnum.values()).getType());
 | 
			
		||||
        });
 | 
			
		||||
        socialUserMapper.insert(oldSocialUser);
 | 
			
		||||
        // 准备参数
 | 
			
		||||
        Long userId = oldSocialUser.getUserId();
 | 
			
		||||
        Integer type = oldSocialUser.getType();
 | 
			
		||||
        String newUnionId = oldSocialUser.getUnionId();
 | 
			
		||||
 | 
			
		||||
        // 调用
 | 
			
		||||
        socialService.unbindOldSocialUser(userId, type, newUnionId, UserTypeEnum.ADMIN);
 | 
			
		||||
        // 断言
 | 
			
		||||
        assertEquals(1L, socialUserMapper.selectCount(null).longValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 情况二,如果新老的 unionId 不一致的,需解绑
 | 
			
		||||
     */
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testUnbindOldSocialUser_yes() {
 | 
			
		||||
        // mock 数据
 | 
			
		||||
        SysSocialUserDO oldSocialUser = randomPojo(SysSocialUserDO.class, socialUserDO -> {
 | 
			
		||||
            socialUserDO.setUserType(UserTypeEnum.ADMIN.getValue());
 | 
			
		||||
            socialUserDO.setType(randomEle(SysSocialTypeEnum.values()).getType());
 | 
			
		||||
        });
 | 
			
		||||
        socialUserMapper.insert(oldSocialUser);
 | 
			
		||||
        // 准备参数
 | 
			
		||||
        Long userId = oldSocialUser.getUserId();
 | 
			
		||||
        Integer type = oldSocialUser.getType();
 | 
			
		||||
        String newUnionId = randomString(10);
 | 
			
		||||
 | 
			
		||||
        // 调用
 | 
			
		||||
        socialService.unbindOldSocialUser(userId, type, newUnionId, UserTypeEnum.ADMIN);
 | 
			
		||||
        // 断言
 | 
			
		||||
        assertEquals(0L, socialUserMapper.selectCount(null).longValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -8,3 +8,4 @@ DELETE FROM "sys_user_session";
 | 
			
		||||
DELETE FROM "sys_dict_data";
 | 
			
		||||
DELETE FROM "sys_sms_template";
 | 
			
		||||
DELETE FROM "sys_sms_log";
 | 
			
		||||
DELETE FROM "sys_social_user";
 | 
			
		||||
 
 | 
			
		||||
@@ -177,3 +177,23 @@ CREATE TABLE IF NOT EXISTS `sys_login_log` (
 | 
			
		||||
    "tenant_id" bigint not null default  '0',
 | 
			
		||||
    PRIMARY KEY (`id`)
 | 
			
		||||
) COMMENT ='系统访问记录';
 | 
			
		||||
 | 
			
		||||
CREATE TABLE IF NOT EXISTS "sys_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,
 | 
			
		||||
    "token" varchar(256) DEFAULT NULL,
 | 
			
		||||
    "union_id" varchar(32) 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,
 | 
			
		||||
    "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 '社交用户';
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user