diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/AuthController.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/AuthController.java index 06358c2..a1154b4 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/AuthController.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/AuthController.java @@ -7,7 +7,6 @@ import com.viewsh.framework.common.enums.UserTypeEnum; import com.viewsh.framework.common.pojo.CommonResult; import com.viewsh.framework.security.config.SecurityProperties; import com.viewsh.framework.security.core.util.SecurityFrameworkUtils; -import com.viewsh.module.infra.api.file.FileApi; import com.viewsh.module.system.controller.admin.auth.vo.*; import com.viewsh.module.system.convert.auth.AuthConvert; import com.viewsh.module.system.dal.dataobject.permission.MenuDO; @@ -62,8 +61,6 @@ public class AuthController { @Resource private SecurityProperties securityProperties; - @Resource - private FileApi fileApi; @PostMapping("/login") @PermitAll @@ -115,12 +112,7 @@ public class AuthController { menuList = menuService.filterDisableMenus(menuList); // 2. 拼接结果返回 - AuthPermissionInfoRespVO respVO = AuthConvert.INSTANCE.convert(user, roles, menuList); - // 私有桶:对头像 URL 生成预签名访问地址 - if (respVO.getUser() != null && StrUtil.isNotEmpty(respVO.getUser().getAvatar())) { - respVO.getUser().setAvatar(fileApi.presignGetUrl(respVO.getUser().getAvatar(), null).getCheckedData()); - } - return success(respVO); + return success(AuthConvert.INSTANCE.convert(user, roles, menuList)); } @PostMapping("/register") diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java index 250c210..c3935a7 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java @@ -1,102 +1,104 @@ -package com.viewsh.module.system.controller.admin.auth.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; -import java.util.Set; - -@Schema(description = "管理后台 - 登录用户的权限信息 Response VO,额外包括用户信息和角色列表") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class AuthPermissionInfoRespVO { - - @Schema(description = "用户信息", requiredMode = Schema.RequiredMode.REQUIRED) - private UserVO user; - - @Schema(description = "角色标识数组", requiredMode = Schema.RequiredMode.REQUIRED) - private Set roles; - - @Schema(description = "操作权限数组", requiredMode = Schema.RequiredMode.REQUIRED) - private Set permissions; - - @Schema(description = "菜单树", requiredMode = Schema.RequiredMode.REQUIRED) - private List menus; - - @Schema(description = "用户信息 VO") - @Data - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class UserVO { - - @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long id; - - @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码") - private String nickname; - - @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.jpg") - private String avatar; - - @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") - private Long deptId; - - @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "viewsh") - private String username; - - @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") - private String email; - - } - - @Schema(description = "管理后台 - 登录用户的菜单信息 Response VO") - @Data - @NoArgsConstructor - @AllArgsConstructor - @Builder - public static class MenuVO { - - @Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") - private Long id; - - @Schema(description = "父菜单 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long parentId; - - @Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") - private String name; - - @Schema(description = "路由地址,仅菜单类型为菜单或者目录时,才需要传", example = "post") - private String path; - - @Schema(description = "组件路径,仅菜单类型为菜单时,才需要传", example = "system/post/index") - private String component; - - @Schema(description = "组件名", example = "SystemUser") - private String componentName; - - @Schema(description = "菜单图标,仅菜单类型为菜单或者目录时,才需要传", example = "/menu/list") - private String icon; - - @Schema(description = "是否可见", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") - private Boolean visible; - - @Schema(description = "是否缓存", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") - private Boolean keepAlive; - - @Schema(description = "是否总是显示", example = "false") - private Boolean alwaysShow; - - /** - * 子路由 - */ - private List children; - - } - -} +package com.viewsh.module.system.controller.admin.auth.vo; + +import com.viewsh.framework.web.core.presign.annotation.OssPresignUrl; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; + +@Schema(description = "管理后台 - 登录用户的权限信息 Response VO,额外包括用户信息和角色列表") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AuthPermissionInfoRespVO { + + @Schema(description = "用户信息", requiredMode = Schema.RequiredMode.REQUIRED) + private UserVO user; + + @Schema(description = "角色标识数组", requiredMode = Schema.RequiredMode.REQUIRED) + private Set roles; + + @Schema(description = "操作权限数组", requiredMode = Schema.RequiredMode.REQUIRED) + private Set permissions; + + @Schema(description = "菜单树", requiredMode = Schema.RequiredMode.REQUIRED) + private List menus; + + @Schema(description = "用户信息 VO") + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + public static class UserVO { + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码") + private String nickname; + + @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.jpg") + @OssPresignUrl + private String avatar; + + @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") + private Long deptId; + + @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "viewsh") + private String username; + + @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") + private String email; + + } + + @Schema(description = "管理后台 - 登录用户的菜单信息 Response VO") + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + public static class MenuVO { + + @Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") + private Long id; + + @Schema(description = "父菜单 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long parentId; + + @Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") + private String name; + + @Schema(description = "路由地址,仅菜单类型为菜单或者目录时,才需要传", example = "post") + private String path; + + @Schema(description = "组件路径,仅菜单类型为菜单时,才需要传", example = "system/post/index") + private String component; + + @Schema(description = "组件名", example = "SystemUser") + private String componentName; + + @Schema(description = "菜单图标,仅菜单类型为菜单或者目录时,才需要传", example = "/menu/list") + private String icon; + + @Schema(description = "是否可见", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") + private Boolean visible; + + @Schema(description = "是否缓存", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") + private Boolean keepAlive; + + @Schema(description = "是否总是显示", example = "false") + private Boolean alwaysShow; + + /** + * 子路由 + */ + private List children; + + } + +} diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/OAuth2UserController.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/OAuth2UserController.java index 8ce3afb..ee7190e 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/OAuth2UserController.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/OAuth2UserController.java @@ -1,10 +1,8 @@ package com.viewsh.module.system.controller.admin.oauth2; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; import com.viewsh.framework.common.pojo.CommonResult; import com.viewsh.framework.common.util.object.BeanUtils; -import com.viewsh.module.infra.api.file.FileApi; import com.viewsh.module.system.controller.admin.oauth2.vo.user.OAuth2UserInfoRespVO; import com.viewsh.module.system.controller.admin.oauth2.vo.user.OAuth2UserUpdateReqVO; import com.viewsh.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; @@ -49,8 +47,6 @@ public class OAuth2UserController { private DeptService deptService; @Resource private PostService postService; - @Resource - private FileApi fileApi; @GetMapping("/get") @Operation(summary = "获得用户基本信息") @@ -69,10 +65,6 @@ public class OAuth2UserController { List posts = postService.getPostList(user.getPostIds()); resp.setPosts(BeanUtils.toBean(posts, OAuth2UserInfoRespVO.Post.class)); } - // 私有桶:对头像 URL 生成预签名访问地址 - if (StrUtil.isNotEmpty(resp.getAvatar())) { - resp.setAvatar(fileApi.presignGetUrl(resp.getAvatar(), null).getCheckedData()); - } return success(resp); } diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java index dc36cb0..c9ce52b 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java @@ -1,70 +1,72 @@ -package com.viewsh.module.system.controller.admin.oauth2.vo.user; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -@Schema(description = "管理后台 - OAuth2 获得用户基本信息 Response VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class OAuth2UserInfoRespVO { - - @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long id; - - @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") - private String username; - - @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") - private String nickname; - - @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") - private String email; - @Schema(description = "手机号码", example = "15601691300") - private String mobile; - - @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") - private Integer sex; - - @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") - private String avatar; - - /** - * 所在部门 - */ - private Dept dept; - - /** - * 所属岗位数组 - */ - private List posts; - - @Schema(description = "部门") - @Data - public static class Dept { - - @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long id; - - @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部") - private String name; - - } - - @Schema(description = "岗位") - @Data - public static class Post { - - @Schema(description = "岗位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long id; - - @Schema(description = "岗位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "开发") - private String name; - - } - -} +package com.viewsh.module.system.controller.admin.oauth2.vo.user; + +import com.viewsh.framework.web.core.presign.annotation.OssPresignUrl; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Schema(description = "管理后台 - OAuth2 获得用户基本信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OAuth2UserInfoRespVO { + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + private String username; + + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") + private String nickname; + + @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") + private String email; + @Schema(description = "手机号码", example = "15601691300") + private String mobile; + + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") + private Integer sex; + + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") + @OssPresignUrl + private String avatar; + + /** + * 所在部门 + */ + private Dept dept; + + /** + * 所属岗位数组 + */ + private List posts; + + @Schema(description = "部门") + @Data + public static class Dept { + + @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部") + private String name; + + } + + @Schema(description = "岗位") + @Data + public static class Post { + + @Schema(description = "岗位编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "岗位名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "开发") + private String name; + + } + +} diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserController.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserController.java index ad69ce3..d040c8e 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserController.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserController.java @@ -1,14 +1,12 @@ package com.viewsh.module.system.controller.admin.user; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; import com.viewsh.framework.apilog.core.annotation.ApiAccessLog; import com.viewsh.framework.common.enums.CommonStatusEnum; import com.viewsh.framework.common.pojo.CommonResult; import com.viewsh.framework.common.pojo.PageParam; import com.viewsh.framework.common.pojo.PageResult; import com.viewsh.framework.excel.core.util.ExcelUtils; -import com.viewsh.module.infra.api.file.FileApi; import com.viewsh.module.system.controller.admin.user.vo.user.*; import com.viewsh.module.system.convert.user.UserConvert; import com.viewsh.module.system.dal.dataobject.dept.DeptDO; @@ -47,8 +45,6 @@ public class UserController { private AdminUserService userService; @Resource private DeptService deptService; - @Resource - private FileApi fileApi; @PostMapping("/create") @Operation(summary = "新增用户") @@ -113,12 +109,6 @@ public class UserController { Map deptMap = deptService.getDeptMap( convertList(pageResult.getList(), AdminUserDO::getDeptId)); List userList = UserConvert.INSTANCE.convertList(pageResult.getList(), deptMap); - // 私有桶:对头像 URL 生成预签名访问地址 - userList.forEach(vo -> { - if (StrUtil.isNotEmpty(vo.getAvatar())) { - vo.setAvatar(fileApi.presignGetUrl(vo.getAvatar(), null).getCheckedData()); - } - }); return success(new PageResult<>(userList, pageResult.getTotal())); } @@ -143,12 +133,7 @@ public class UserController { } // 拼接数据 DeptDO dept = deptService.getDept(user.getDeptId()); - UserRespVO respVO = UserConvert.INSTANCE.convert(user, dept); - // 私有桶:对头像 URL 生成预签名访问地址 - if (StrUtil.isNotEmpty(respVO.getAvatar())) { - respVO.setAvatar(fileApi.presignGetUrl(respVO.getAvatar(), null).getCheckedData()); - } - return success(respVO); + return success(UserConvert.INSTANCE.convert(user, dept)); } @GetMapping("/export-excel") diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserProfileController.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserProfileController.java index 9069887..37f43ca 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserProfileController.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/UserProfileController.java @@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil; import com.viewsh.framework.common.pojo.CommonResult; import com.viewsh.framework.common.util.http.HttpUtils; import com.viewsh.framework.datapermission.core.annotation.DataPermission; -import com.viewsh.module.infra.api.file.FileApi; import com.viewsh.module.system.controller.admin.user.vo.profile.UserProfileRespVO; import com.viewsh.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO; import com.viewsh.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; @@ -49,8 +48,6 @@ public class UserProfileController { private PermissionService permissionService; @Resource private RoleService roleService; - @Resource - private FileApi fileApi; @GetMapping("/get") @Operation(summary = "获得登录用户信息") @@ -64,12 +61,7 @@ public class UserProfileController { DeptDO dept = user.getDeptId() != null ? deptService.getDept(user.getDeptId()) : null; // 获得岗位信息 List posts = CollUtil.isNotEmpty(user.getPostIds()) ? postService.getPostList(user.getPostIds()) : null; - UserProfileRespVO respVO = UserConvert.INSTANCE.convert(user, userRoles, dept, posts); - // 私有桶:对头像 URL 生成预签名访问地址 - if (StrUtil.isNotEmpty(respVO.getAvatar())) { - respVO.setAvatar(fileApi.presignGetUrl(respVO.getAvatar(), null).getCheckedData()); - } - return success(respVO); + return success(UserConvert.INSTANCE.convert(user, userRoles, dept, posts)); } @PutMapping("/update") diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java index 4478c94..49cfca2 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java @@ -1,59 +1,61 @@ -package com.viewsh.module.system.controller.admin.user.vo.profile; - -import com.viewsh.module.system.controller.admin.dept.vo.dept.DeptSimpleRespVO; -import com.viewsh.module.system.controller.admin.dept.vo.post.PostSimpleRespVO; -import com.viewsh.module.system.controller.admin.permission.vo.role.RoleSimpleRespVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.List; - -@Data -@Schema(description = "管理后台 - 用户个人中心信息 Response VO") -public class UserProfileRespVO { - - @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Long id; - - @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "viewsh") - private String username; - - @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") - private String nickname; - - @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") - private String email; - - @Schema(description = "手机号码", example = "15601691300") - private String mobile; - - @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") - private Integer sex; - - @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") - private String avatar; - - @Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1") - private String loginIp; - - @Schema(description = "最后登录时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") - private LocalDateTime loginDate; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") - private LocalDateTime createTime; - - /** - * 所属角色 - */ - private List roles; - /** - * 所在部门 - */ - private DeptSimpleRespVO dept; - /** - * 所属岗位数组 - */ - private List posts; - -} +package com.viewsh.module.system.controller.admin.user.vo.profile; + +import com.viewsh.framework.web.core.presign.annotation.OssPresignUrl; +import com.viewsh.module.system.controller.admin.dept.vo.dept.DeptSimpleRespVO; +import com.viewsh.module.system.controller.admin.dept.vo.post.PostSimpleRespVO; +import com.viewsh.module.system.controller.admin.permission.vo.role.RoleSimpleRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +@Schema(description = "管理后台 - 用户个人中心信息 Response VO") +public class UserProfileRespVO { + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "viewsh") + private String username; + + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + private String nickname; + + @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") + private String email; + + @Schema(description = "手机号码", example = "15601691300") + private String mobile; + + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") + private Integer sex; + + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") + @OssPresignUrl + private String avatar; + + @Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1") + private String loginIp; + + @Schema(description = "最后登录时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") + private LocalDateTime loginDate; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") + private LocalDateTime createTime; + + /** + * 所属角色 + */ + private List roles; + /** + * 所在部门 + */ + private DeptSimpleRespVO dept; + /** + * 所属岗位数组 + */ + private List posts; + +} diff --git a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/user/UserRespVO.java b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/user/UserRespVO.java index dedcafb..e39bb0d 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/user/UserRespVO.java +++ b/viewsh-module-system/viewsh-module-system-server/src/main/java/com/viewsh/module/system/controller/admin/user/vo/user/UserRespVO.java @@ -1,75 +1,77 @@ -package com.viewsh.module.system.controller.admin.user.vo.user; - -import com.viewsh.framework.excel.core.annotations.DictFormat; -import com.viewsh.framework.excel.core.convert.DictConvert; -import com.viewsh.module.system.enums.DictTypeConstants; -import cn.idev.excel.annotation.ExcelIgnoreUnannotated; -import cn.idev.excel.annotation.ExcelProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.Set; - -@Schema(description = "管理后台 - 用户信息 Response VO") -@Data -@ExcelIgnoreUnannotated -public class UserRespVO{ - - @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @ExcelProperty("用户编号") - private Long id; - - @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "viewsh") - @ExcelProperty("用户名称") - private String username; - - @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") - @ExcelProperty("用户昵称") - private String nickname; - - @Schema(description = "备注", example = "我是一个用户") - private String remark; - - @Schema(description = "部门ID", example = "我是一个用户") - private Long deptId; - @Schema(description = "部门名称", example = "IT 部") - @ExcelProperty("部门名称") - private String deptName; - - @Schema(description = "岗位编号数组", example = "1") - private Set postIds; - - @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") - @ExcelProperty("用户邮箱") - private String email; - - @Schema(description = "手机号码", example = "15601691300") - @ExcelProperty("手机号码") - private String mobile; - - @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") - @ExcelProperty(value = "用户性别", converter = DictConvert.class) - @DictFormat(DictTypeConstants.USER_SEX) - private Integer sex; - - @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") - private String avatar; - - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @ExcelProperty(value = "帐号状态", converter = DictConvert.class) - @DictFormat(DictTypeConstants.COMMON_STATUS) - private Integer status; - - @Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1") - @ExcelProperty("最后登录IP") - private String loginIp; - - @Schema(description = "最后登录时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") - @ExcelProperty("最后登录时间") - private LocalDateTime loginDate; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") - private LocalDateTime createTime; - -} +package com.viewsh.module.system.controller.admin.user.vo.user; + +import com.viewsh.framework.excel.core.annotations.DictFormat; +import com.viewsh.framework.excel.core.convert.DictConvert; +import com.viewsh.framework.web.core.presign.annotation.OssPresignUrl; +import com.viewsh.module.system.enums.DictTypeConstants; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Set; + +@Schema(description = "管理后台 - 用户信息 Response VO") +@Data +@ExcelIgnoreUnannotated +public class UserRespVO{ + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("用户编号") + private Long id; + + @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "viewsh") + @ExcelProperty("用户名称") + private String username; + + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + @ExcelProperty("用户昵称") + private String nickname; + + @Schema(description = "备注", example = "我是一个用户") + private String remark; + + @Schema(description = "部门ID", example = "我是一个用户") + private Long deptId; + @Schema(description = "部门名称", example = "IT 部") + @ExcelProperty("部门名称") + private String deptName; + + @Schema(description = "岗位编号数组", example = "1") + private Set postIds; + + @Schema(description = "用户邮箱", example = "viewsh@iocoder.cn") + @ExcelProperty("用户邮箱") + private String email; + + @Schema(description = "手机号码", example = "15601691300") + @ExcelProperty("手机号码") + private String mobile; + + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") + @ExcelProperty(value = "用户性别", converter = DictConvert.class) + @DictFormat(DictTypeConstants.USER_SEX) + private Integer sex; + + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") + @OssPresignUrl + private String avatar; + + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty(value = "帐号状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.COMMON_STATUS) + private Integer status; + + @Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1") + @ExcelProperty("最后登录IP") + private String loginIp; + + @Schema(description = "最后登录时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") + @ExcelProperty("最后登录时间") + private LocalDateTime loginDate; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式") + private LocalDateTime createTime; + +} diff --git a/viewsh-module-system/viewsh-module-system-server/src/test/java/com/viewsh/module/system/service/social/SocialUserServiceImplTest.java b/viewsh-module-system/viewsh-module-system-server/src/test/java/com/viewsh/module/system/service/social/SocialUserServiceImplTest.java index ac00f09..ecc9b1d 100644 --- a/viewsh-module-system/viewsh-module-system-server/src/test/java/com/viewsh/module/system/service/social/SocialUserServiceImplTest.java +++ b/viewsh-module-system/viewsh-module-system-server/src/test/java/com/viewsh/module/system/service/social/SocialUserServiceImplTest.java @@ -1,288 +1,291 @@ -package com.viewsh.module.system.service.social; - -import com.viewsh.framework.common.enums.UserTypeEnum; -import com.viewsh.framework.common.pojo.PageResult; -import com.viewsh.framework.test.core.ut.BaseDbUnitTest; -import com.viewsh.module.system.api.social.dto.SocialUserBindReqDTO; -import com.viewsh.module.system.api.social.dto.SocialUserRespDTO; -import com.viewsh.module.system.controller.admin.socail.vo.user.SocialUserPageReqVO; -import com.viewsh.module.system.dal.dataobject.social.SocialUserBindDO; -import com.viewsh.module.system.dal.dataobject.social.SocialUserDO; -import com.viewsh.module.system.dal.mysql.social.SocialUserBindMapper; -import com.viewsh.module.system.dal.mysql.social.SocialUserMapper; -import com.viewsh.module.system.enums.social.SocialTypeEnum; -import jakarta.annotation.Resource; -import me.zhyd.oauth.model.AuthUser; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.bean.override.mockito.MockitoBean; - -import java.util.List; - -import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.hutool.core.util.RandomUtil.randomLong; -import static com.viewsh.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; -import static com.viewsh.framework.common.util.date.LocalDateTimeUtils.buildTime; -import static com.viewsh.framework.common.util.json.JsonUtils.toJsonString; -import static com.viewsh.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static com.viewsh.framework.test.core.util.AssertUtils.assertPojoEquals; -import static com.viewsh.framework.test.core.util.AssertUtils.assertServiceException; -import static com.viewsh.framework.test.core.util.RandomUtils.randomPojo; -import static com.viewsh.framework.test.core.util.RandomUtils.randomString; -import static com.viewsh.module.system.enums.ErrorCodeConstants.SOCIAL_USER_NOT_FOUND; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.when; - -/** - * {@link SocialUserServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(SocialUserServiceImpl.class) -public class SocialUserServiceImplTest extends BaseDbUnitTest { - - @Resource - private SocialUserServiceImpl socialUserService; - - @Resource - private SocialUserMapper socialUserMapper; - @Resource - private SocialUserBindMapper socialUserBindMapper; - - @MockitoBean - private SocialClientService socialClientService; - - @Test - public void testGetSocialUserList() { - Long userId = 1L; - Integer userType = UserTypeEnum.ADMIN.getValue(); - // mock 获得社交用户 - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType()); - socialUserMapper.insert(socialUser); // 可被查到 - socialUserMapper.insert(randomPojo(SocialUserDO.class)); // 不可被查到 - // mock 获得绑定 - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到 - .setUserId(userId).setUserType(userType).setSocialType(SocialTypeEnum.GITEE.getType()) - .setSocialUserId(socialUser.getId())); - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到 - .setUserId(2L).setUserType(userType).setSocialType(SocialTypeEnum.DINGTALK.getType())); - - // 调用 - List result = socialUserService.getSocialUserList(userId, userType); - // 断言 - assertEquals(1, result.size()); - assertPojoEquals(socialUser, result.get(0)); - } - - @Test - public void testBindSocialUser() { - // 准备参数 - SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO() - .setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) - .setSocialType(SocialTypeEnum.GITEE.getType()).setCode("test_code").setState("test_state"); - // mock 数据:获得社交用户 - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(reqDTO.getSocialType()) - .setCode(reqDTO.getCode()).setState(reqDTO.getState()); - socialUserMapper.insert(socialUser); - // mock 数据:用户可能之前已经绑定过该社交类型 - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) - .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(-1L)); - // mock 数据:社交用户可能之前绑定过别的用户 - socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserType(UserTypeEnum.ADMIN.getValue()) - .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); - - // 调用 - String openid = socialUserService.bindSocialUser(reqDTO); - // 断言 - List socialUserBinds = socialUserBindMapper.selectList(); - assertEquals(1, socialUserBinds.size()); - assertEquals(socialUser.getOpenid(), openid); - } - - @Test - public void testUnbindSocialUser_success() { - // 准备参数 - Long userId = 1L; - Integer userType = UserTypeEnum.ADMIN.getValue(); - Integer type = SocialTypeEnum.GITEE.getType(); - String openid = "test_openid"; - // mock 数据:社交用户 - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setOpenid(openid); - socialUserMapper.insert(socialUser); - // mock 数据:社交绑定关系 - SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType) - .setUserId(userId).setSocialType(type); - socialUserBindMapper.insert(socialUserBind); - - // 调用 - socialUserService.unbindSocialUser(userId, userType, type, openid); - // 断言 - assertEquals(0, socialUserBindMapper.selectCount(null).intValue()); - } - - @Test - public void testUnbindSocialUser_notFound() { - // 调用,并断言 - assertServiceException( - () -> socialUserService.unbindSocialUser(randomLong(), UserTypeEnum.ADMIN.getValue(), - SocialTypeEnum.GITEE.getType(), "test_openid"), - SOCIAL_USER_NOT_FOUND); - } - - @Test - public void testGetSocialUser() { - // 准备参数 - Integer userType = UserTypeEnum.ADMIN.getValue(); - Integer type = SocialTypeEnum.GITEE.getType(); - String code = "tudou"; - String state = "yuanma"; - // mock 社交用户 - SocialUserDO socialUserDO = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); - socialUserMapper.insert(socialUserDO); - // mock 社交用户的绑定 - Long userId = randomLong(); - SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) - .setSocialType(type).setSocialUserId(socialUserDO.getId()); - socialUserBindMapper.insert(socialUserBind); - - // 调用 - SocialUserRespDTO socialUser = socialUserService.getSocialUserByCode(userType, type, code, state); - // 断言 - assertEquals(userId, socialUser.getUserId()); - assertEquals(socialUserDO.getOpenid(), socialUser.getOpenid()); - } - - @Test - public void testAuthSocialUser_exists() { - // 准备参数 - Integer socialType = SocialTypeEnum.GITEE.getType(); - Integer userType = randomEle(SocialTypeEnum.values()).getType(); - String code = "tudou"; - String state = "yuanma"; - // mock 方法 - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(socialType).setCode(code).setState(state); - socialUserMapper.insert(socialUser); - - // 调用 - SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); - // 断言 - assertPojoEquals(socialUser, result); - } - - @Test - public void testAuthSocialUser_notNull() { - // mock 数据 - SocialUserDO socialUser = randomPojo(SocialUserDO.class, - o -> o.setType(SocialTypeEnum.GITEE.getType()).setCode("tudou").setState("yuanma")); - socialUserMapper.insert(socialUser); - // 准备参数 - Integer socialType = SocialTypeEnum.GITEE.getType(); - Integer userType = randomEle(SocialTypeEnum.values()).getType(); - String code = "tudou"; - String state = "yuanma"; - - // 调用 - SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); - // 断言 - assertPojoEquals(socialUser, result); - } - - @Test - public void testAuthSocialUser_insert() { - // 准备参数 - Integer socialType = SocialTypeEnum.GITEE.getType(); - Integer userType = randomEle(SocialTypeEnum.values()).getType(); - String code = "tudou"; - String state = "yuanma"; - // mock 方法 - AuthUser authUser = randomPojo(AuthUser.class); - when(socialClientService.getAuthUser(eq(socialType), eq(userType), eq(code), eq(state))).thenReturn(authUser); - - // 调用 - SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); - // 断言 - assertBindSocialUser(socialType, result, authUser); - assertEquals(code, result.getCode()); - assertEquals(state, result.getState()); - } - - @Test - public void testAuthSocialUser_update() { - // 准备参数 - Integer socialType = SocialTypeEnum.GITEE.getType(); - Integer userType = randomEle(SocialTypeEnum.values()).getType(); - String code = "tudou"; - String state = "yuanma"; - // mock 数据 - socialUserMapper.insert(randomPojo(SocialUserDO.class).setType(socialType).setOpenid("test_openid")); - // mock 方法 - AuthUser authUser = randomPojo(AuthUser.class); - when(socialClientService.getAuthUser(eq(socialType), eq(userType), eq(code), eq(state))).thenReturn(authUser); - - // 调用 - SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); - // 断言 - assertBindSocialUser(socialType, result, authUser); - 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()); - } - - @Test - public void testGetSocialUser_id() { - // mock 数据 - SocialUserDO socialUserDO = randomPojo(SocialUserDO.class); - socialUserMapper.insert(socialUserDO); - // 参数准备 - Long id = socialUserDO.getId(); - - // 调用 - SocialUserDO dbSocialUserDO = socialUserService.getSocialUser(id); - // 断言 - assertPojoEquals(socialUserDO, dbSocialUserDO); - } - - @Test - public void testGetSocialUserPage() { - // mock 数据 - SocialUserDO dbSocialUser = randomPojo(SocialUserDO.class, o -> { // 等会查询到 - o.setType(SocialTypeEnum.GITEE.getType()); - o.setNickname("芋艿"); - o.setOpenid("viewshyuanma"); - o.setCreateTime(buildTime(2020, 1, 15)); - }); - socialUserMapper.insert(dbSocialUser); - // 测试 type 不匹配 - socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setType(SocialTypeEnum.DINGTALK.getType()))); - // 测试 nickname 不匹配 - socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setNickname(randomString()))); - // 测试 openid 不匹配 - socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setOpenid("java"))); - // 测试 createTime 不匹配 - socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setCreateTime(buildTime(2020, 1, 21)))); - // 准备参数 - SocialUserPageReqVO reqVO = new SocialUserPageReqVO(); - reqVO.setType(SocialTypeEnum.GITEE.getType()); - reqVO.setNickname("芋"); - reqVO.setOpenid("viewsh"); - reqVO.setCreateTime(buildBetweenTime(2020, 1, 10, 2020, 1, 20)); - - // 调用 - PageResult pageResult = socialUserService.getSocialUserPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbSocialUser, pageResult.getList().get(0)); - } - -} +package com.viewsh.module.system.service.social; + +import com.viewsh.framework.common.enums.UserTypeEnum; +import com.viewsh.framework.common.pojo.PageResult; +import com.viewsh.framework.test.core.ut.BaseDbUnitTest; +import com.viewsh.module.system.api.social.dto.SocialUserBindReqDTO; +import com.viewsh.module.system.api.social.dto.SocialUserRespDTO; +import com.viewsh.module.system.controller.admin.socail.vo.user.SocialUserPageReqVO; +import com.viewsh.module.system.controller.admin.socail.vo.user.SocialUserRespVO; +import com.viewsh.module.system.dal.dataobject.social.SocialUserBindDO; +import com.viewsh.module.system.dal.dataobject.social.SocialUserDO; +import com.viewsh.module.system.dal.mysql.social.SocialUserBindMapper; +import com.viewsh.module.system.dal.mysql.social.SocialUserMapper; +import com.viewsh.module.system.enums.social.SocialTypeEnum; +import jakarta.annotation.Resource; +import me.zhyd.oauth.model.AuthUser; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +import java.util.List; + +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.hutool.core.util.RandomUtil.randomLong; +import static com.viewsh.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static com.viewsh.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static com.viewsh.framework.common.util.json.JsonUtils.toJsonString; +import static com.viewsh.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static com.viewsh.framework.test.core.util.AssertUtils.assertPojoEquals; +import static com.viewsh.framework.test.core.util.AssertUtils.assertServiceException; +import static com.viewsh.framework.test.core.util.RandomUtils.randomPojo; +import static com.viewsh.framework.test.core.util.RandomUtils.randomString; +import static com.viewsh.module.system.enums.ErrorCodeConstants.SOCIAL_USER_NOT_FOUND; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.when; + +/** + * {@link SocialUserServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(SocialUserServiceImpl.class) +public class SocialUserServiceImplTest extends BaseDbUnitTest { + + @Resource + private SocialUserServiceImpl socialUserService; + + @Resource + private SocialUserMapper socialUserMapper; + @Resource + private SocialUserBindMapper socialUserBindMapper; + + @MockitoBean + private SocialClientService socialClientService; + + @Test + public void testGetSocialUserBindList() { + Long userId = 1L; + Integer userType = UserTypeEnum.ADMIN.getValue(); + // mock 获得社交用户 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(SocialTypeEnum.GITEE.getType()); + socialUserMapper.insert(socialUser); // 可被查到 + socialUserMapper.insert(randomPojo(SocialUserDO.class)); // 不可被查到 + // mock 获得绑定 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 可被查询到 + .setUserId(userId).setUserType(userType).setSocialType(SocialTypeEnum.GITEE.getType()) + .setSocialUserId(socialUser.getId())); + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class) // 不可被查询到 + .setUserId(2L).setUserType(userType).setSocialType(SocialTypeEnum.DINGTALK.getType())); + + // 调用 + List result = socialUserService.getSocialUserBindList(userId, userType); + // 断言 + assertEquals(1, result.size()); + assertEquals(socialUser.getId(), result.get(0).getId()); + assertEquals(socialUser.getType(), result.get(0).getType()); + assertEquals(socialUser.getOpenid(), result.get(0).getOpenid()); + } + + @Test + public void testBindSocialUser() { + // 准备参数 + SocialUserBindReqDTO reqDTO = new SocialUserBindReqDTO() + .setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) + .setSocialType(SocialTypeEnum.GITEE.getType()).setCode("test_code").setState("test_state"); + // mock 数据:获得社交用户 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(reqDTO.getSocialType()) + .setCode(reqDTO.getCode()).setState(reqDTO.getState()); + socialUserMapper.insert(socialUser); + // mock 数据:用户可能之前已经绑定过该社交类型 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserId(1L).setUserType(UserTypeEnum.ADMIN.getValue()) + .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(-1L)); + // mock 数据:社交用户可能之前绑定过别的用户 + socialUserBindMapper.insert(randomPojo(SocialUserBindDO.class).setUserType(UserTypeEnum.ADMIN.getValue()) + .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); + + // 调用 + String openid = socialUserService.bindSocialUser(reqDTO); + // 断言 + List socialUserBinds = socialUserBindMapper.selectList(); + assertEquals(1, socialUserBinds.size()); + assertEquals(socialUser.getOpenid(), openid); + } + + @Test + public void testUnbindSocialUser_success() { + // 准备参数 + Long userId = 1L; + Integer userType = UserTypeEnum.ADMIN.getValue(); + Integer type = SocialTypeEnum.GITEE.getType(); + String openid = "test_openid"; + // mock 数据:社交用户 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setOpenid(openid); + socialUserMapper.insert(socialUser); + // mock 数据:社交绑定关系 + SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType) + .setUserId(userId).setSocialType(type); + socialUserBindMapper.insert(socialUserBind); + + // 调用 + socialUserService.unbindSocialUser(userId, userType, type, openid); + // 断言 + assertEquals(0, socialUserBindMapper.selectCount(null).intValue()); + } + + @Test + public void testUnbindSocialUser_notFound() { + // 调用,并断言 + assertServiceException( + () -> socialUserService.unbindSocialUser(randomLong(), UserTypeEnum.ADMIN.getValue(), + SocialTypeEnum.GITEE.getType(), "test_openid"), + SOCIAL_USER_NOT_FOUND); + } + + @Test + public void testGetSocialUser() { + // 准备参数 + Integer userType = UserTypeEnum.ADMIN.getValue(); + Integer type = SocialTypeEnum.GITEE.getType(); + String code = "tudou"; + String state = "yuanma"; + // mock 社交用户 + SocialUserDO socialUserDO = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); + socialUserMapper.insert(socialUserDO); + // mock 社交用户的绑定 + Long userId = randomLong(); + SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) + .setSocialType(type).setSocialUserId(socialUserDO.getId()); + socialUserBindMapper.insert(socialUserBind); + + // 调用 + SocialUserRespDTO socialUser = socialUserService.getSocialUserByCode(userType, type, code, state); + // 断言 + assertEquals(userId, socialUser.getUserId()); + assertEquals(socialUserDO.getOpenid(), socialUser.getOpenid()); + } + + @Test + public void testAuthSocialUser_exists() { + // 准备参数 + Integer socialType = SocialTypeEnum.GITEE.getType(); + Integer userType = randomEle(SocialTypeEnum.values()).getType(); + String code = "tudou"; + String state = "yuanma"; + // mock 方法 + SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(socialType).setCode(code).setState(state); + socialUserMapper.insert(socialUser); + + // 调用 + SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); + // 断言 + assertPojoEquals(socialUser, result); + } + + @Test + public void testAuthSocialUser_notNull() { + // mock 数据 + SocialUserDO socialUser = randomPojo(SocialUserDO.class, + o -> o.setType(SocialTypeEnum.GITEE.getType()).setCode("tudou").setState("yuanma")); + socialUserMapper.insert(socialUser); + // 准备参数 + Integer socialType = SocialTypeEnum.GITEE.getType(); + Integer userType = randomEle(SocialTypeEnum.values()).getType(); + String code = "tudou"; + String state = "yuanma"; + + // 调用 + SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); + // 断言 + assertPojoEquals(socialUser, result); + } + + @Test + public void testAuthSocialUser_insert() { + // 准备参数 + Integer socialType = SocialTypeEnum.GITEE.getType(); + Integer userType = randomEle(SocialTypeEnum.values()).getType(); + String code = "tudou"; + String state = "yuanma"; + // mock 方法 + AuthUser authUser = randomPojo(AuthUser.class); + when(socialClientService.getAuthUser(eq(socialType), eq(userType), eq(code), eq(state))).thenReturn(authUser); + + // 调用 + SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); + // 断言 + assertBindSocialUser(socialType, result, authUser); + assertEquals(code, result.getCode()); + assertEquals(state, result.getState()); + } + + @Test + public void testAuthSocialUser_update() { + // 准备参数 + Integer socialType = SocialTypeEnum.GITEE.getType(); + Integer userType = randomEle(SocialTypeEnum.values()).getType(); + String code = "tudou"; + String state = "yuanma"; + // mock 数据 + socialUserMapper.insert(randomPojo(SocialUserDO.class).setType(socialType).setOpenid("test_openid")); + // mock 方法 + AuthUser authUser = randomPojo(AuthUser.class); + when(socialClientService.getAuthUser(eq(socialType), eq(userType), eq(code), eq(state))).thenReturn(authUser); + + // 调用 + SocialUserDO result = socialUserService.authSocialUser(socialType, userType, code, state); + // 断言 + assertBindSocialUser(socialType, result, authUser); + 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()); + } + + @Test + public void testGetSocialUser_id() { + // mock 数据 + SocialUserDO socialUserDO = randomPojo(SocialUserDO.class); + socialUserMapper.insert(socialUserDO); + // 参数准备 + Long id = socialUserDO.getId(); + + // 调用 + SocialUserDO dbSocialUserDO = socialUserService.getSocialUser(id); + // 断言 + assertPojoEquals(socialUserDO, dbSocialUserDO); + } + + @Test + public void testGetSocialUserPage() { + // mock 数据 + SocialUserDO dbSocialUser = randomPojo(SocialUserDO.class, o -> { // 等会查询到 + o.setType(SocialTypeEnum.GITEE.getType()); + o.setNickname("芋艿"); + o.setOpenid("viewshyuanma"); + o.setCreateTime(buildTime(2020, 1, 15)); + }); + socialUserMapper.insert(dbSocialUser); + // 测试 type 不匹配 + socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setType(SocialTypeEnum.DINGTALK.getType()))); + // 测试 nickname 不匹配 + socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setNickname(randomString()))); + // 测试 openid 不匹配 + socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setOpenid("java"))); + // 测试 createTime 不匹配 + socialUserMapper.insert(cloneIgnoreId(dbSocialUser, o -> o.setCreateTime(buildTime(2020, 1, 21)))); + // 准备参数 + SocialUserPageReqVO reqVO = new SocialUserPageReqVO(); + reqVO.setType(SocialTypeEnum.GITEE.getType()); + reqVO.setNickname("芋"); + reqVO.setOpenid("viewsh"); + reqVO.setCreateTime(buildBetweenTime(2020, 1, 10, 2020, 1, 20)); + + // 调用 + PageResult pageResult = socialUserService.getSocialUserPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbSocialUser, pageResult.getList().get(0)); + } + +}