From 0d6df43c9c948aafc77258c508f6ce6ea668364c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 5 Oct 2021 23:47:37 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BC=98=E5=8C=96=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E7=99=BB=E9=99=86=E7=9A=84=E4=BB=A3=E7=A0=81=202.=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20redis=20=E5=AD=98=E5=82=A8=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/auth/SysAuthController.java | 19 +-- .../controller/user/vo/user/AuthUser.java | 7 - .../system/convert/auth/SysAuthConvert.java | 4 - .../{user => social}/SysSocialUserDO.java | 3 +- .../dal/mysql/social/SysSocialUserMapper.java | 24 +++ .../mysql/social/SysSysUserSocialMapper.java | 11 -- .../dal/mysql/social/SysUserSocialMapper.java | 11 -- .../dal/mysql/user/SysSocialUserMapper.java | 18 --- .../dal/redis/SysRedisKeyConstants.java | 8 +- .../SysSocialAuthUserRedisDAO.java} | 10 +- .../system/enums/SysErrorCodeConstants.java | 4 +- .../system/enums/user/SysSocialTypeEnum.java | 13 +- .../service/auth/impl/SysAuthServiceImpl.java | 114 ++------------ .../service/social/SysSocialService.java | 63 ++++++++ .../social/impl/SysSocialServiceImpl.java | 147 ++++++++++++++++++ .../user/{ => impl}/SysUserServiceImpl.java | 20 ++- .../src/main/resources/application-local.yaml | 4 +- .../auth/SysUserSessionServiceImplTest.java | 2 +- .../service/user/SysUserServiceImplTest.java | 1 + 19 files changed, 294 insertions(+), 189 deletions(-) delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/vo/user/AuthUser.java rename yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/{user => social}/SysSocialUserDO.java (94%) create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSocialUserMapper.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSysUserSocialMapper.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysUserSocialMapper.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/user/SysSocialUserMapper.java rename yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/{auth/SysAuthSocialUserRedisDAO.java => social/SysSocialAuthUserRedisDAO.java} (79%) create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialService.java create mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/impl/SysSocialServiceImpl.java rename yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/{ => impl}/SysUserServiceImpl.java (96%) diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java index 7862ac04b..4750d6264 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysSocialTypeEnum; import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysAuthService; import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService; +import cn.iocoder.yudao.adminserver.modules.system.service.social.SysSocialService; import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -56,9 +57,8 @@ public class SysAuthController { private SysRoleService roleService; @Resource private SysPermissionService permissionService; - @Resource - private AuthRequestFactory authRequestFactory; + private SysSocialService socialService; @PostMapping("/login") @ApiOperation("使用账号密码登录") @@ -110,12 +110,7 @@ public class SysAuthController { }) public CommonResult socialLoginRedirect(@RequestParam("type") Integer type, @RequestParam("redirectUri") String redirectUri) { - // 获得对应的 AuthRequest 实现 - AuthRequest authRequest = authRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); - // 生成跳转地址 - String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); - authorizeUri = HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); - return CommonResult.success(authorizeUri); + return CommonResult.success(socialService.getAuthorizeUrl(type, redirectUri)); } @PostMapping("/social-login") @@ -136,12 +131,4 @@ public class SysAuthController { return success(SysAuthLoginRespVO.builder().token(token).build()); } - @RequestMapping("/{type}/callback") - public AuthResponse login(@PathVariable String type, AuthCallback callback) { - AuthRequest authRequest = authRequestFactory.get(type); - AuthResponse response = authRequest.login(callback); - log.info("【response】= {}", JSONUtil.toJsonStr(response)); - return response; - } - } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/vo/user/AuthUser.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/vo/user/AuthUser.java deleted file mode 100644 index 3d1c7680e..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/vo/user/AuthUser.java +++ /dev/null @@ -1,7 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.system.controller.user.vo.user; - -/** - * @author weir - */ -public class AuthUser { -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/SysAuthConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/SysAuthConvert.java index 225f21b9a..65d79a898 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/SysAuthConvert.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/auth/SysAuthConvert.java @@ -43,10 +43,6 @@ public interface SysAuthConvert { LoginUser convert(SysUserProfileUpdatePasswordReqVO reqVO); - AuthCallback convert(SysAuthSocialLoginReqVO bean); - - AuthCallback convert(SysAuthSocialLogin2ReqVO bean); - /** * 将菜单列表,构建成菜单树 * diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/user/SysSocialUserDO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/social/SysSocialUserDO.java similarity index 94% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/user/SysSocialUserDO.java rename to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/social/SysSocialUserDO.java index 66c3043a9..cde686983 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/user/SysSocialUserDO.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/social/SysSocialUserDO.java @@ -1,5 +1,6 @@ -package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user; +package cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social; +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.TableId; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSocialUserMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSocialUserMapper.java new file mode 100644 index 000000000..9c00b2136 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSocialUserMapper.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social; + +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysSocialUserDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface SysSocialUserMapper extends BaseMapperX { + + default List selectListByTypeAndUnionId(Integer userType, Collection types, String unionId) { + return selectList(new QueryWrapper().eq("user_type", userType) + .in("type", types).eq("union_id", unionId)); + } + + default List selectListByTypeAndUserId(Integer userType, Collection types, Long userId) { + return selectList(new QueryWrapper().eq("user_type", userType) + .in("type", types).eq("user_id", userId)); + } + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSysUserSocialMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSysUserSocialMapper.java deleted file mode 100644 index f06d408f3..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysSysUserSocialMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social; - -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysSocialUserDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface SysSysUserSocialMapper extends BaseMapperX { - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysUserSocialMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysUserSocialMapper.java deleted file mode 100644 index 85bed3e36..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/social/SysUserSocialMapper.java +++ /dev/null @@ -1,11 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social; - -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysSocialUserDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface SysUserSocialMapper extends BaseMapperX { - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/user/SysSocialUserMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/user/SysSocialUserMapper.java deleted file mode 100644 index 55e9b723f..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/user/SysSocialUserMapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.system.dal.mysql.user; - -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysSocialUserDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -@Mapper -public interface SysSocialUserMapper extends BaseMapperX { - - default List selectListByTypeAndUnionId(Integer userType, Integer type, String unionId) { - return selectList(new QueryWrapper().eq("user_type", userType) - .eq("type", type).eq("union_id", unionId)); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/SysRedisKeyConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/SysRedisKeyConstants.java index 2012ec3a9..f43e29b0d 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/SysRedisKeyConstants.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/SysRedisKeyConstants.java @@ -23,8 +23,12 @@ public interface SysRedisKeyConstants { "captcha_code:%s", // 参数为 uuid STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); - RedisKeyDefine AUTH_SOCIAL_USER = new RedisKeyDefine("认证的社交用户", - "auth_social_user:%d:%s", // 参数为 type,code + RedisKeyDefine SOCIAL_AUTH_USER = new RedisKeyDefine("社交的授权用户", + "social_auth_user:%d:%s", // 参数为 type,code STRING, AuthUser.class, Duration.ofDays(1)); + RedisKeyDefine SOCIAL_AUTH_STATE = new RedisKeyDefine("社交的 state", + "social_auth_state:%s", // 参数为 state + STRING, String.class, Duration.ofHours(24)); // 值为 state + } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/auth/SysAuthSocialUserRedisDAO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/social/SysSocialAuthUserRedisDAO.java similarity index 79% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/auth/SysAuthSocialUserRedisDAO.java rename to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/social/SysSocialAuthUserRedisDAO.java index 945bc65fc..d5e84e62d 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/auth/SysAuthSocialUserRedisDAO.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/redis/social/SysSocialAuthUserRedisDAO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.adminserver.modules.system.dal.redis.auth; +package cn.iocoder.yudao.adminserver.modules.system.dal.redis.social; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import me.zhyd.oauth.model.AuthCallback; @@ -8,7 +8,7 @@ import org.springframework.stereotype.Repository; import javax.annotation.Resource; -import static cn.iocoder.yudao.adminserver.modules.system.dal.redis.SysRedisKeyConstants.AUTH_SOCIAL_USER; +import static cn.iocoder.yudao.adminserver.modules.system.dal.redis.SysRedisKeyConstants.SOCIAL_AUTH_USER; /** * 社交 {@link me.zhyd.oauth.model.AuthUser} 的 RedisDAO @@ -16,7 +16,7 @@ import static cn.iocoder.yudao.adminserver.modules.system.dal.redis.SysRedisKeyC * @author 芋道源码 */ @Repository -public class SysAuthSocialUserRedisDAO { +public class SysSocialAuthUserRedisDAO { @Resource private StringRedisTemplate stringRedisTemplate; @@ -28,11 +28,11 @@ public class SysAuthSocialUserRedisDAO { public void set(Integer type, AuthCallback authCallback, AuthUser authUser) { String redisKey = formatKey(type, authCallback.getCode()); - stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(authUser), AUTH_SOCIAL_USER.getTimeout()); + stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(authUser), SOCIAL_AUTH_USER.getTimeout()); } private static String formatKey(Integer type, String code) { - return String.format(AUTH_SOCIAL_USER.getKeyTemplate(), type, code); + return String.format(SOCIAL_AUTH_USER.getKeyTemplate(), type, code); } } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java index 487ae1309..ad4598615 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java @@ -17,7 +17,6 @@ public interface SysErrorCodeConstants { ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在"); ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确"); ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定"); - ErrorCode AUTH_THIRD_OAUTH_FAILURE = new ErrorCode(1002000006, "社交授权失败,原因是:{}"); // ========== TOKEN 模块 1002001000 ========== ErrorCode TOKEN_EXPIRED = new ErrorCode(1002001000, "Token 已经过期"); @@ -98,4 +97,7 @@ public interface SysErrorCodeConstants { ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002013000, "错误码不存在"); ErrorCode ERROR_CODE_DUPLICATE = new ErrorCode(1002013001, "已经存在编码为【{}】的错误码"); + // ========== 社交模块 1002014000 ========== + ErrorCode SOCIAL_AUTH_FAILURE = new ErrorCode(1002014000, "社交授权失败,原因是:{}"); + } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/user/SysSocialTypeEnum.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/user/SysSocialTypeEnum.java index 510428dff..f1415a0fe 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/user/SysSocialTypeEnum.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/user/SysSocialTypeEnum.java @@ -1,14 +1,16 @@ package cn.iocoder.yudao.adminserver.modules.system.enums.user; +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; /** - * 社交用户的类型枚举 + * 社交平台的类型枚举 * * @author 芋道源码 */ @@ -23,6 +25,8 @@ public enum SysSocialTypeEnum implements IntArrayValuable { public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SysSocialTypeEnum::getType).toArray(); + public static final List WECHAT_ALL = ListUtil.toList(WECHAT_ENTERPRISE.type); + /** * 类型 */ @@ -41,4 +45,11 @@ public enum SysSocialTypeEnum implements IntArrayValuable { return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); } + public static List getRelationTypes(Integer type) { + if (WECHAT_ALL.contains(type)) { + return WECHAT_ALL; + } + return ListUtil.toList(type); + } + } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 9b26a8ace..955d33e5d 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -1,17 +1,13 @@ package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthSocialLogin2ReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthSocialLoginReqVO; -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysSocialUserDO; -import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.user.SysSocialUserMapper; -import cn.iocoder.yudao.adminserver.modules.system.dal.redis.auth.SysAuthSocialUserRedisDAO; -import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysSocialTypeEnum; +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysSocialUserDO; +import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social.SysSocialUserMapper; +import cn.iocoder.yudao.adminserver.modules.system.service.social.SysSocialService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; @@ -27,12 +23,8 @@ import cn.iocoder.yudao.adminserver.modules.system.service.logger.SysLoginLogSer import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; -import com.xkcoding.justauth.AuthRequestFactory; import lombok.extern.slf4j.Slf4j; -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 org.springframework.context.annotation.Lazy; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -47,7 +39,6 @@ import org.springframework.util.Assert; import javax.annotation.Resource; import java.util.List; -import java.util.Objects; import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -77,15 +68,12 @@ public class SysAuthServiceImpl implements SysAuthService { private SysLoginLogService loginLogService; @Resource private SysUserSessionService userSessionService; - @Resource - private SysAuthSocialUserRedisDAO authSocialUserRedisDAO; + private SysSocialService socialService; + @Resource private SysSocialUserMapper socialUserMapper; - @Resource - private AuthRequestFactory authRequestFactory; - @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 获取 username 对应的 SysUserDO @@ -189,13 +177,12 @@ public class SysAuthServiceImpl implements SysAuthService { @Override public String socialLogin(SysAuthSocialLoginReqVO reqVO, String userIp, String userAgent) { // 使用 code 授权码,进行登陆 - AuthCallback authCallback = SysAuthConvert.INSTANCE.convert(reqVO); - AuthUser authUser = this.obtainAuthUserFromCache(reqVO.getType(), authCallback); + AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); + Assert.notNull(authUser, "授权用户不为空"); // 如果未绑定 SysSocialUserDO 用户,则无法自动登陆,进行报错 - String unionId = getAuthUserUnionId(authUser); - List socialUsers = socialUserMapper.selectListByTypeAndUnionId(UserTypeEnum.ADMIN.getValue(), - reqVO.getType(), unionId); + String unionId = socialService.getAuthUserUnionId(authUser); + List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId); if (CollUtil.isEmpty(socialUsers)) { throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } @@ -209,8 +196,8 @@ public class SysAuthServiceImpl implements SysAuthService { // TODO 芋艿:需要改造下,增加各种登陆方式 loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 - // 保存社交用户 - this.saveSocialUser(reqVO.getType(), socialUsers, loginUser.getId(), authUser); + // 绑定社交用户(更新) + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser); // 缓存登陆用户到 Redis 中,返回 sessionId 编号 return userSessionService.createUserSession(loginUser, userIp, userAgent); @@ -219,91 +206,20 @@ public class SysAuthServiceImpl implements SysAuthService { @Override public String socialLogin2(SysAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent) { // 使用 code 授权码,进行登陆 - AuthCallback authCallback = SysAuthConvert.INSTANCE.convert(reqVO); - AuthUser authUser = this.obtainAuthUserFromCache(reqVO.getType(), authCallback); - - // 查询社交对应的 SysSocialUserDO 用户 - String unionId = getAuthUserUnionId(authUser); - List socialUsers = socialUserMapper.selectListByTypeAndUnionId(UserTypeEnum.ADMIN.getValue(), - reqVO.getType(), unionId); + AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState()); + Assert.notNull(authUser, "授权用户不为空"); // 使用账号密码,进行登陆。 LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword()); // TODO 芋艿:需要改造下,增加各种登陆方式 loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 - // 保存社交用户 - this.saveSocialUser(reqVO.getType(), socialUsers, loginUser.getId(), authUser); + // 绑定社交用户(新增) + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser); // 缓存登陆用户到 Redis 中,返回 sessionId 编号 return userSessionService.createUserSession(loginUser, userIp, userAgent); } - private static String getAuthUserUnionId(AuthUser authUser) { - return StrUtil.blankToDefault(authUser.getToken().getUnionId(), authUser.getUuid()); - } - - private AuthUser obtainAuthUserFromCache(Integer type, AuthCallback authCallback) { - // 从缓存中获取 - AuthUser authUser = authSocialUserRedisDAO.get(type, authCallback); - if (authUser != null) { - return authUser; - } - - // 请求获取 - authUser = this.obtainAuthUser(type, authCallback); - authSocialUserRedisDAO.set(type, authCallback, authUser); - return authUser; - } - - private AuthUser obtainAuthUser(Integer type, AuthCallback authCallback) { - AuthRequest authRequest = authRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); - AuthResponse authResponse = authRequest.login(authCallback); - log.info("[obtainAuthUser][请求社交平台 type({}) request({}) response({})]", type, JsonUtils.toJsonString(authCallback), - JsonUtils.toJsonString(authResponse)); - if (!authResponse.ok()) { - throw exception(AUTH_THIRD_OAUTH_FAILURE, authResponse.getMsg()); - } - return (AuthUser) authResponse.getData(); - } - - /** - * 保存社交用户 - * - * @param socialUsers 已存在的社交用户列表 - * @param userId 绑定的用户编号 - * @param authUser 需要保存的社交用户信息 - */ - private void saveSocialUser(Integer type, List socialUsers, Long userId, AuthUser authUser) { - // 逻辑一:如果 socialUsers 指定的 userId 改变,需要进行更新 - // 例如说,一个微信 unionId 对应了多个社交账号,结果其中有个关联了新的 userId,则其它也要跟着修改 - // 考虑到 socialUsers 一般比较少,直接 for 循环更新即可 - socialUsers.forEach(socialUser -> { - if (Objects.equals(socialUser.getUserId(), userId)) { - return; - } - socialUserMapper.updateById(new SysSocialUserDO().setUserId(socialUser.getUserId()).setUserId(userId)); - }); - - // 逻辑二:如果 authUser 不存在于 socialUsers 中,则进行新增;否则,进行更新 - SysSocialUserDO saveSocialUser = CollUtil.findOneByField(socialUsers, "openid", authUser.getUuid()); - if (saveSocialUser == null) { - saveSocialUser = new SysSocialUserDO(); - saveSocialUser.setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()); - saveSocialUser.setType(type).setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()) - .setUnionId(getAuthUserUnionId(authUser)).setRawTokenInfo(JsonUtils.toJsonString(authUser.getToken())); - saveSocialUser.setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()) - .setRawUserInfo(JsonUtils.toJsonString(authUser.getRawUserInfo())); - socialUserMapper.insert(saveSocialUser); - } else { - saveSocialUser = new SysSocialUserDO().setId(saveSocialUser.getId()); - saveSocialUser.setToken(authUser.getToken().getAccessToken()).setUnionId(getAuthUserUnionId(authUser)) - .setRawTokenInfo(JsonUtils.toJsonString(authUser.getToken())); - saveSocialUser.setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()) - .setRawUserInfo(JsonUtils.toJsonString(authUser.getRawUserInfo())); - socialUserMapper.updateById(saveSocialUser); - } - } - @Override public void logout(String token) { // 查询用户信息 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialService.java new file mode 100644 index 000000000..fdbc0dc28 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialService.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.adminserver.modules.system.service.social; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysSocialUserDO; +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysSocialTypeEnum; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import me.zhyd.oauth.model.AuthUser; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 社交 Service 接口,例如说社交平台的授权登录 + * + * @author 芋道源码 + */ +public interface SysSocialService { + + /** + * 获得社交平台的授权 URL + * + * @param type 社交平台的类型 {@link SysSocialTypeEnum} + * @param redirectUri 重定向 URL + * @return 社交平台的授权 URL + */ + String getAuthorizeUrl(Integer type, String redirectUri); + + /** + * 获得授权的用户 + * 如果授权失败,则会抛出 {@link ServiceException} 异常 + * + * @param type 社交平台的类型 {@link SysSocialTypeEnum} + * @param code 授权码 + * @param state state + * @return 授权用户 + */ + @NotNull + AuthUser getAuthUser(Integer type, String code, String state); + + default String getAuthUserUnionId(AuthUser authUser) { + return StrUtil.blankToDefault(authUser.getToken().getUnionId(), authUser.getUuid()); + } + + /** + * 获得 unionId 对应的某个社交平台的“所有”社交用户 + * 注意,这里的“所有”,指的是类似【微信】平台,包括了小程序、公众号、PC 网站,他们的 unionId 是一致的 + * + * @param type 社交平台的类型 {@link SysSocialTypeEnum} + * @param unionId 社交平台的 unionId + * @return 社交用户列表 + */ + List getAllSocialUserList(Integer type, String unionId); + + /** + * 绑定社交用户 + * + * @param userId 用户编号 + * @param type 社交平台的类型 {@link SysSocialTypeEnum} + * @param authUser 授权用户 + */ + void bindSocialUser(Long userId, Integer type, AuthUser authUser); + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/impl/SysSocialServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/impl/SysSocialServiceImpl.java new file mode 100644 index 000000000..d250fdd8a --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/social/impl/SysSocialServiceImpl.java @@ -0,0 +1,147 @@ +package cn.iocoder.yudao.adminserver.modules.system.service.social.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysSocialUserDO; +import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social.SysSocialUserMapper; +import cn.iocoder.yudao.adminserver.modules.system.dal.redis.social.SysSocialAuthUserRedisDAO; +import cn.iocoder.yudao.adminserver.modules.system.enums.user.SysSocialTypeEnum; +import cn.iocoder.yudao.adminserver.modules.system.service.social.SysSocialService; +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; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import com.xkcoding.justauth.AuthRequestFactory; +import lombok.extern.slf4j.Slf4j; +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.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants.SOCIAL_AUTH_FAILURE; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; + +/** + * 社交 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Valid +@Slf4j +public class SysSocialServiceImpl implements SysSocialService { + + @Resource + private AuthRequestFactory authRequestFactory; + + @Resource + private SysSocialAuthUserRedisDAO authSocialUserRedisDAO; + + @Resource + private SysSocialUserMapper socialUserMapper; + + @Override + public String getAuthorizeUrl(Integer type, String redirectUri) { + // 获得对应的 AuthRequest 实现 + AuthRequest authRequest = authRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); + // 生成跳转地址 + String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); + return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); + } + + @Override + public AuthUser getAuthUser(Integer type, String code, String state) { + AuthCallback authCallback = buildAuthCallback(code, state); + // 从缓存中获取 + AuthUser authUser = authSocialUserRedisDAO.get(type, authCallback); + if (authUser != null) { + return authUser; + } + + // 请求获取 + authUser = this.getAuthUser0(type, authCallback); + // 缓存。原因是 code 有且可以使用一次。在社交登录时,当未绑定 User 时,需要绑定登陆,此时需要 code 使用两次 + authSocialUserRedisDAO.set(type, authCallback, authUser); + return authUser; + } + + @Override + public List getAllSocialUserList(Integer type, String unionId) { + List types = SysSocialTypeEnum.getRelationTypes(type); + return socialUserMapper.selectListByTypeAndUnionId(UserTypeEnum.ADMIN.getValue(), types, unionId); + } + + @Override + public void bindSocialUser(Long userId, Integer type, AuthUser authUser) { + // 获得 unionId 对应的 SysSocialUserDO 列表 + String unionId = getAuthUserUnionId(authUser); + List socialUsers = this.getAllSocialUserList(type, unionId); + + // 逻辑一:如果 userId 之前绑定过该 type 的其它账号,需要进行解绑 + List types = SysSocialTypeEnum.getRelationTypes(type); + List oldSocialUsers = socialUserMapper.selectListByTypeAndUserId(UserTypeEnum.ADMIN.getValue(), + types, userId); + if (CollUtil.isNotEmpty(oldSocialUsers) && !Objects.equals(unionId, oldSocialUsers.get(0).getUnionId())) { + socialUserMapper.deleteBatchIds(CollectionUtils.convertSet(oldSocialUsers, SysSocialUserDO::getId)); + } + + // 逻辑二:如果 socialUsers 指定的 userId 改变,需要进行更新 + // 例如说,一个微信 unionId 对应了多个社交账号,结果其中有个关联了新的 userId,则其它也要跟着修改 + // 考虑到 socialUsers 一般比较少,直接 for 循环更新即可 + socialUsers.forEach(socialUser -> { + if (Objects.equals(socialUser.getUserId(), userId)) { + return; + } + socialUserMapper.updateById(new SysSocialUserDO().setUserId(socialUser.getUserId()).setUserId(userId)); + }); + + // 逻辑三:如果 authUser 不存在于 socialUsers 中,则进行新增;否则,进行更新 + SysSocialUserDO saveSocialUser = CollUtil.findOneByField(socialUsers, "openid", authUser.getUuid()); + if (saveSocialUser == null) { + saveSocialUser = new SysSocialUserDO(); + saveSocialUser.setUserId(userId).setUserType(UserTypeEnum.ADMIN.getValue()); + saveSocialUser.setType(type).setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()) + .setUnionId(unionId).setRawTokenInfo(JsonUtils.toJsonString(authUser.getToken())); + saveSocialUser.setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()) + .setRawUserInfo(JsonUtils.toJsonString(authUser.getRawUserInfo())); + socialUserMapper.insert(saveSocialUser); + } else { + saveSocialUser = new SysSocialUserDO().setId(saveSocialUser.getId()); + saveSocialUser.setToken(authUser.getToken().getAccessToken()) + .setRawTokenInfo(JsonUtils.toJsonString(authUser.getToken())); + saveSocialUser.setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()) + .setRawUserInfo(JsonUtils.toJsonString(authUser.getRawUserInfo())); + socialUserMapper.updateById(saveSocialUser); + } + } + + /** + * 请求社交平台,获得授权的用户 + * + * @param type 社交平台的类型 + * @param authCallback 授权回调 + * @return 授权的用户 + */ + private AuthUser getAuthUser0(Integer type, AuthCallback authCallback) { + AuthRequest authRequest = authRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); + AuthResponse authResponse = authRequest.login(authCallback); + log.info("[getAuthUser0][请求社交平台 type({}) request({}) response({})]", type, JsonUtils.toJsonString(authCallback), + JsonUtils.toJsonString(authResponse)); + if (!authResponse.ok()) { + throw exception(SOCIAL_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-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java similarity index 96% rename from yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImpl.java rename to yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java index ef26b0778..01a70f9bf 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.adminserver.modules.system.service.user; +package cn.iocoder.yudao.adminserver.modules.system.service.user.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.IoUtil; @@ -12,11 +12,11 @@ import cn.iocoder.yudao.adminserver.modules.system.convert.user.SysUserConvert; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysPostDO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; -import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.social.SysUserSocialMapper; import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.user.SysUserMapper; import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService; import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysPostService; import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; +import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -49,8 +49,6 @@ public class SysUserServiceImpl implements SysUserService { @Resource private SysUserMapper userMapper; - @Resource - private SysUserSocialMapper userSocialMapper; @Resource private SysDeptService deptService; @@ -218,7 +216,7 @@ public class SysUserServiceImpl implements SysUserService { } @VisibleForTesting - void checkUserExists(Long id) { + public void checkUserExists(Long id) { if (id == null) { return; } @@ -229,7 +227,7 @@ public class SysUserServiceImpl implements SysUserService { } @VisibleForTesting - void checkUsernameUnique(Long id, String username) { + public void checkUsernameUnique(Long id, String username) { if (StrUtil.isBlank(username)) { return; } @@ -247,7 +245,7 @@ public class SysUserServiceImpl implements SysUserService { } @VisibleForTesting - void checkEmailUnique(Long id, String email) { + public void checkEmailUnique(Long id, String email) { if (StrUtil.isBlank(email)) { return; } @@ -265,7 +263,7 @@ public class SysUserServiceImpl implements SysUserService { } @VisibleForTesting - void checkMobileUnique(Long id, String mobile) { + public void checkMobileUnique(Long id, String mobile) { if (StrUtil.isBlank(mobile)) { return; } @@ -283,7 +281,7 @@ public class SysUserServiceImpl implements SysUserService { } @VisibleForTesting - void checkDeptEnable(Long deptId) { + public void checkDeptEnable(Long deptId) { if (deptId == null) { // 允许不选择 return; } @@ -297,7 +295,7 @@ public class SysUserServiceImpl implements SysUserService { } @VisibleForTesting - void checkPostEnable(Set postIds) { + public void checkPostEnable(Set postIds) { if (CollUtil.isEmpty(postIds)) { // 允许不选择 return; } @@ -324,7 +322,7 @@ public class SysUserServiceImpl implements SysUserService { * @param oldPassword 旧密码 */ @VisibleForTesting - void checkOldPassword(Long id, String oldPassword) { + public void checkOldPassword(Long id, String oldPassword) { SysUserDO user = userMapper.selectById(id); if (user == null) { throw exception(USER_NOT_EXISTS); diff --git a/yudao-admin-server/src/main/resources/application-local.yaml b/yudao-admin-server/src/main/resources/application-local.yaml index 873335c43..1968aba06 100644 --- a/yudao-admin-server/src/main/resources/application-local.yaml +++ b/yudao-admin-server/src/main/resources/application-local.yaml @@ -185,4 +185,6 @@ justauth: agent-id: 1000004 ignore-check-redirect-uri: true cache: - type: default + type: REDIS + prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: + timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionServiceImplTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionServiceImplTest.java index 026b23d67..740460ec9 100644 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionServiceImplTest.java +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionServiceImplTest.java @@ -41,7 +41,7 @@ import cn.iocoder.yudao.adminserver.modules.system.enums.common.SysSexEnum; import cn.iocoder.yudao.adminserver.modules.system.service.auth.impl.SysUserSessionServiceImpl; import cn.iocoder.yudao.adminserver.modules.system.service.dept.impl.SysDeptServiceImpl; import cn.iocoder.yudao.adminserver.modules.system.service.logger.impl.SysLoginLogServiceImpl; -import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserServiceImpl; +import cn.iocoder.yudao.adminserver.modules.system.service.user.impl.SysUserServiceImpl; import cn.iocoder.yudao.framework.test.core.util.AssertUtils; import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java index 95833e076..2e9ed80b4 100644 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.system.service.user; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.adminserver.BaseDbUnitTest; +import cn.iocoder.yudao.adminserver.modules.system.service.user.impl.SysUserServiceImpl; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.adminserver.modules.infra.service.file.InfFileService;