From 0a0b63e4805936df661d4247d90e4479992e762c Mon Sep 17 00:00:00 2001 From: wangyu <727842003@qq.com> Date: Fri, 31 Dec 2021 10:37:12 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=AE=9E=E7=8E=B0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90=E7=BB=86=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/authorized/AuthorizedQo.java | 5 +- .../authorized/AuthorizedUserDetails.java | 11 ++- .../framework/domain/po/Department.java | 5 ++ .../com/flyfish/framework/domain/po/Role.java | 19 +++++ .../controller/DepartmentController.java | 3 +- .../framework/domain/AdminUserDetails.java | 11 +-- .../framework/service/DepartmentService.java | 6 +- .../service/UserDetailsConverter.java | 85 ++++++++++++++++--- 8 files changed, 119 insertions(+), 26 deletions(-) diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java index 4123e4d..0fe76fb 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedQo.java @@ -8,6 +8,7 @@ import lombok.Setter; import java.util.Collections; import java.util.List; +import java.util.Set; /** * 带鉴权的查询实体,主要以部门隔绝 @@ -23,11 +24,11 @@ public abstract class AuthorizedQo extends NameLikeQ * * @return 结果 */ - public List getAuthorizedIds() { + public Set getAuthorizedIds() { if (user instanceof AuthorizedUserDetails) { return ((AuthorizedUserDetails) user).getAuthorityCodes(); } - return Collections.singletonList(Department.PUBLIC); + return Collections.singleton(Department.PUBLIC); } @Override diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java index 25cfe9b..d4c4b9f 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedUserDetails.java @@ -1,6 +1,6 @@ package com.flyfish.framework.domain.authorized; -import java.util.List; +import java.util.Set; /** * 支持授权的用户详情 @@ -14,5 +14,12 @@ public interface AuthorizedUserDetails { * * @return 结果 */ - List getAuthorityCodes(); + Set getAuthorityCodes(); + + /** + * 获取可见部门 + * + * @return 结果 + */ + Set getVisibleDeparts(); } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Department.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Department.java index 7f258c1..363db63 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Department.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Department.java @@ -19,6 +19,11 @@ public class Department extends TreeDomain { public static final String PUBLIC = "public"; + /** + * 部门的完整名称 + */ + private String fullName; + /** * 默认选中 */ diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Role.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Role.java index d2bc503..ca2a85c 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Role.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/po/Role.java @@ -1,6 +1,7 @@ package com.flyfish.framework.domain.po; import com.flyfish.framework.domain.base.AuditDomain; +import com.flyfish.framework.enums.NamedEnum; import com.flyfish.framework.enums.RoleType; import lombok.*; import org.springframework.data.mongodb.core.mapping.DBRef; @@ -46,4 +47,22 @@ public class Role extends AuditDomain { */ @DBRef private List permissions; + + /** + * 角色拥有的数据权限 + */ + private List authorities; + + /** + * 数据规则权限 + */ + @AllArgsConstructor + @Getter + public enum Authority implements NamedEnum { + + ADMIN("拥有完全控制权限"), VIEW("查看本部门"), EDIT("编辑本部门"), + VIEW_CHILDREN("查看所有下级"), EDIT_CHILDREN("编辑所有下级"); + + private final String name; + } } diff --git a/flyfish-user/src/main/java/com/flyfish/framework/controller/DepartmentController.java b/flyfish-user/src/main/java/com/flyfish/framework/controller/DepartmentController.java index 5331e63..1d8defa 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/controller/DepartmentController.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/controller/DepartmentController.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; +import java.util.ArrayList; import java.util.List; /** @@ -32,7 +33,7 @@ public class DepartmentController extends ReactiveTreeController { AdminUserDetails details = (AdminUserDetails) detail; - return reactiveService.getByIds(details.getAuthorityCodes()).collectList(); + return reactiveService.getByIds(new ArrayList<>(details.getVisibleDeparts())).collectList(); }) .map(this::makeTree) .map(Result::accept); diff --git a/flyfish-user/src/main/java/com/flyfish/framework/domain/AdminUserDetails.java b/flyfish-user/src/main/java/com/flyfish/framework/domain/AdminUserDetails.java index c42181f..65371c5 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/domain/AdminUserDetails.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/domain/AdminUserDetails.java @@ -19,10 +19,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.List; +import java.util.*; /** * 客户端用户详情 @@ -105,7 +102,11 @@ public class AdminUserDetails implements UserDetails, IUser, AuthorizedUserDetai /** * 权限code列表 */ - private List authorityCodes; + private Set authorityCodes; + /** + * 可见的部门codes + */ + private Set visibleDeparts; /** * 判断是否是管理员 diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java b/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java index 93705b8..daa1b5f 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/DepartmentService.java @@ -10,6 +10,8 @@ import reactor.core.publisher.Mono; import javax.annotation.Resource; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** * 部门服务 @@ -27,9 +29,9 @@ public class DepartmentService extends BaseReactiveServiceImpl { * * @return 结果 */ - public Mono> getSubCodes(List parents) { + public Mono> getSubCodes(Set parents) { Query query = Query.query(Criteria.where("parentIds").in(parents)); query.fields().include("_id"); - return reactiveMongoOperations.find(query, Department.class).map(Department::getId).collectList(); + return reactiveMongoOperations.find(query, Department.class).map(Department::getId).collect(Collectors.toSet()); } } diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/UserDetailsConverter.java b/flyfish-user/src/main/java/com/flyfish/framework/service/UserDetailsConverter.java index 738f360..b6933fb 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/service/UserDetailsConverter.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/UserDetailsConverter.java @@ -3,17 +3,20 @@ package com.flyfish.framework.service; import com.flyfish.framework.domain.AdminUserDetails; import com.flyfish.framework.domain.base.IUser; import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.domain.po.Role; import com.flyfish.framework.enums.UserType; import com.flyfish.framework.utils.CopyUtils; import lombok.RequiredArgsConstructor; import lombok.val; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.ListUtils; +import org.apache.commons.collections4.SetUtils; +import org.apache.commons.lang3.BooleanUtils; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; -import java.util.Collections; +import java.util.*; import java.util.stream.Collectors; @Service @@ -31,22 +34,76 @@ public class UserDetailsConverter { public Mono mapToUserDetails(IUser user) { AdminUserDetails userDetail = new AdminUserDetails(); CopyUtils.copyProps(user, userDetail); - userDetail.setAuthorityCodes(Collections.singletonList(Department.PUBLIC)); + userDetail.setAuthorityCodes(Collections.singleton(Department.PUBLIC)); if (user.getType() == UserType.SUPER_ADMIN) { userDetail.setAuthorityCodes(null); - } - if (CollectionUtils.isNotEmpty(user.getDepartments())) { - val departs = user.getDepartments().stream().map(Department::getId) - .collect(Collectors.toList()); - userDetail.setAuthorityCodes(ListUtils.union(departs, userDetail.getAuthorityCodes())); - return departmentService.getSubCodes(departs) - .map(codes -> { - if (CollectionUtils.isNotEmpty(codes)) { - userDetail.setAuthorityCodes(ListUtils.union(codes, userDetail.getAuthorityCodes())); - } - return userDetail; - }); + } else if (CollectionUtils.isNotEmpty(user.getDepartments())) { + return judgeDeparts(user, userDetail); } return Mono.just(userDetail); } + + /** + * 判断部门包含关系,默认看不到本部门的数据却可以看到子部门的 + * + * @param user 用户信息 + * @param userDetails 用户详情 + */ + private Mono judgeDeparts(IUser user, AdminUserDetails userDetails) { + // 整合数据权限 + Set authorities = user.getRoles().stream().reduce(new HashSet<>(), (result, item) -> { + // 管理员拥有完全控制权限 + if (BooleanUtils.isTrue(item.getAdmin())) { + result.add(Role.Authority.ADMIN); + } + result.addAll(item.getAuthorities()); + return result; + }, (a, b) -> a); + // 根据权限组装查询条件 + Set departs = mergeDeparts(user.getDepartments()); + // 查询所有子部门id + return departmentService.getSubCodes(departs) + .map(codes -> { + // 取出权限,便于判定 + boolean admin = authorities.contains(Role.Authority.ADMIN); + boolean view = authorities.contains(Role.Authority.VIEW); + boolean viewChildren = authorities.contains(Role.Authority.VIEW_CHILDREN); + // 全部 + Set all = new HashSet<>(); + // 拥有查看本部门的权限 + if (admin || view) { + all.addAll(departs); + } + // 拥有查看所有下级的权限 + if (admin || viewChildren) { + all.addAll(codes); + } + // 最终设置权限 + if (CollectionUtils.isNotEmpty(all)) { + userDetails.setAuthorityCodes(SetUtils.union(all, userDetails.getAuthorityCodes())); + } + userDetails.setVisibleDeparts(SetUtils.union(codes, departs)); + return userDetails; + }); + + } + + /** + * 合并部门,有包含关系的部门将被合并 + * + * @param departments 部门 + * @return 结果 + */ + private Set mergeDeparts(List departments) { + Set departs = departments.stream().map(Department::getId) + .collect(Collectors.toSet()); + List removing = new ArrayList<>(); + for (Department department : departments) { + if (CollectionUtils.containsAny(department.getParentIds(), departs)) { + removing.add(department.getId()); + } + } + removing.forEach(departs::remove); + return departs; + } }