From 38f90de29235d2fd35b3923a77146f3eb3a12920 Mon Sep 17 00:00:00 2001 From: wangyu <727842003@qq.com> Date: Mon, 3 Jan 2022 01:19:44 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=AE=8C=E6=95=B4=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=9D=83=E9=99=90=E9=9A=94=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/builder/CriteriaBuilder.java | 57 +++++++++--- .../context/ReactiveUserContext.java | 23 +++++ .../domain/authorized/AuthorizedDomain.java | 4 + .../domain/authorized/AuthorizedQo.java | 21 ++++- .../domain/authorized/AuthorizedVo.java | 16 ++++ .../flyfish/framework/domain/base/BaseQo.java | 2 +- .../flyfish/framework/domain/base/Domain.java | 3 +- .../impl/DefaultReactiveRepositoryImpl.java | 4 +- .../flyfish/framework/utils/DepartUtils.java | 88 +++++++++++++++++++ .../config/audit/RoleBeanPoster.java | 33 +++++++ .../controller/DepartmentController.java | 14 ++- .../framework/service/DepartmentService.java | 43 +++++++++ .../service/UserDetailsConverter.java | 44 ++++------ .../framework/service/UserService.java | 26 ++++++ .../reactive/ReactiveTreeController.java | 3 +- .../utils/ReactiveRedisOperations.java | 10 +++ 16 files changed, 341 insertions(+), 50 deletions(-) create mode 100644 flyfish-data/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java create mode 100644 flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java create mode 100644 flyfish-data/src/main/java/com/flyfish/framework/utils/DepartUtils.java create mode 100644 flyfish-user/src/main/java/com/flyfish/framework/config/audit/RoleBeanPoster.java diff --git a/flyfish-data/src/main/java/com/flyfish/framework/builder/CriteriaBuilder.java b/flyfish-data/src/main/java/com/flyfish/framework/builder/CriteriaBuilder.java index 7337af0..eaca67e 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/builder/CriteriaBuilder.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/builder/CriteriaBuilder.java @@ -3,19 +3,22 @@ package com.flyfish.framework.builder; import com.flyfish.framework.context.DateContext; import com.flyfish.framework.domain.base.Domain; import com.flyfish.framework.domain.base.Qo; +import com.mongodb.BasicDBList; import lombok.Getter; import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.ClassUtils; import org.bson.types.ObjectId; import org.springframework.beans.BeanUtils; import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.function.BiFunction; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -25,12 +28,11 @@ import java.util.stream.Collectors; */ public final class CriteriaBuilder { + private final Map> functionMap = new HashMap<>(); + private final Map keyMapper = new HashMap<>(); + private final List> criterias = new ArrayList<>(); private Qo qo; - private Map> functionMap = new HashMap<>(); - - private Map keyMapper = new HashMap<>(); - /** * 构造器,接受一个qo * @@ -44,6 +46,20 @@ public final class CriteriaBuilder { return builder; } + /** + * 创建criteria列表 + * + * @param criteria 多个查询 + * @return 结果 + */ + public static BasicDBList createCriteriaList(Criteria... criteria) { + BasicDBList bsonList = new BasicDBList(); + for (Criteria c : criteria) { + bsonList.add(c.getCriteriaObject()); + } + return bsonList; + } + /** * 添加策略 * @@ -81,6 +97,17 @@ public final class CriteriaBuilder { return this; } + /** + * 添加自定义条件 + * + * @param function 函数 + * @return 结果 + */ + public CriteriaBuilder with(Supplier function) { + this.criterias.add(function); + return this; + } + /** * 批量导入规则 * @@ -94,11 +121,11 @@ public final class CriteriaBuilder { } public Criteria build() { - if (!CollectionUtils.isEmpty(functionMap)) { + if (!MapUtils.isEmpty(functionMap)) { // 键集合 Set keySet = functionMap.keySet(); // 建立查询器 - Criteria[] criteria = Arrays.stream(BeanUtils.getPropertyDescriptors(qo.getClass())) + List criteria = Arrays.stream(BeanUtils.getPropertyDescriptors(qo.getClass())) .filter(propertyDescriptor -> keySet.contains(propertyDescriptor.getName())) .map(propertyDescriptor -> { try { @@ -117,7 +144,13 @@ public final class CriteriaBuilder { return null; }) .filter(Objects::nonNull) - .toArray(Criteria[]::new); + .collect(Collectors.toList()); + // 添加自定义criteria + if (CollectionUtils.isNotEmpty(criterias)) { + for (Supplier builder : criterias) { + criteria.add(builder.get()); + } + } return combine(criteria); } return null; @@ -165,12 +198,12 @@ public final class CriteriaBuilder { * @param criteria 结果 * @return 返回 */ - private Criteria combine(Criteria[] criteria) { - if (criteria.length == 0) { + private Criteria combine(List criteria) { + if (criteria.size() == 0) { return new Criteria(); } - if (criteria.length == 1) { - return criteria[0]; + if (criteria.size() == 1) { + return criteria.get(0); } return new Criteria().andOperator(criteria); } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java b/flyfish-data/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java new file mode 100644 index 0000000..c16fa37 --- /dev/null +++ b/flyfish-data/src/main/java/com/flyfish/framework/context/ReactiveUserContext.java @@ -0,0 +1,23 @@ +package com.flyfish.framework.context; + +import com.flyfish.framework.domain.base.IUser; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; +import reactor.core.publisher.Mono; + +/** + * 异步的用户上下文 + * + * @author wangyu + */ +public class ReactiveUserContext { + + /** + * 当前用户 + * + * @return 结果 + */ + public static Mono currentUser() { + return ReactiveSecurityContextHolder.getContext() + .map(ctx -> (IUser) ctx.getAuthentication().getPrincipal()); + } +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java index 40af6f3..d966992 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedDomain.java @@ -15,4 +15,8 @@ public abstract class AuthorizedDomain extends AuditDomain { // 作用域id,一般是部门。用户存储时插入 @Property(readonly = true) private String authorizeId; + + // 是否已发布,已发布的内容,谁都不能修改 + @Property(readonly = true) + private Boolean published = false; } 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 0fe76fb..4227709 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 @@ -3,11 +3,12 @@ package com.flyfish.framework.domain.authorized; import com.flyfish.framework.builder.CriteriaBuilder; import com.flyfish.framework.domain.base.NameLikeQo; import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.enums.UserType; import lombok.Getter; import lombok.Setter; +import org.springframework.data.mongodb.core.query.Criteria; import java.util.Collections; -import java.util.List; import java.util.Set; /** @@ -19,12 +20,15 @@ import java.util.Set; @Setter public abstract class AuthorizedQo extends NameLikeQo { + // 是否已发布 + private Boolean published; + /** * 获取可见的权限ids * * @return 结果 */ - public Set getAuthorizedIds() { + private Set authorizeIds() { if (user instanceof AuthorizedUserDetails) { return ((AuthorizedUserDetails) user).getAuthorityCodes(); } @@ -33,6 +37,17 @@ public abstract class AuthorizedQo extends NameLikeQ @Override public CriteriaBuilder criteriaBuilder() { - return super.criteriaBuilder().with("authorizedIds", "authorizeId", CriteriaBuilder.Builders.IN); + if (user.getType() == UserType.SUPER_ADMIN) { + return super.criteriaBuilder().with("published"); + } + return super.criteriaBuilder() + .with(() -> Criteria.where("$or").is( + CriteriaBuilder.createCriteriaList( + Criteria.where("authorizeId").in(authorizeIds()), + Criteria.where("creatorId").is(user.getId()) + .and("authorizeId").in(((AuthorizedUserDetails) user).getVisibleDeparts()) + ) + )) + .with("published"); } } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java new file mode 100644 index 0000000..d90515c --- /dev/null +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/authorized/AuthorizedVo.java @@ -0,0 +1,16 @@ +package com.flyfish.framework.domain.authorized; + +import com.flyfish.framework.domain.base.Vo; +import lombok.Data; + +/** + * 授权的vo,需要返回权限标识 + * + * @param 泛型 + */ +@Data +public abstract class AuthorizedVo implements Vo { + + // 是否是只读数据 + protected Boolean readonly; +} diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/BaseQo.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/base/BaseQo.java index f315c00..4a562ab 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/BaseQo.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/base/BaseQo.java @@ -130,6 +130,6 @@ public class BaseQo implements Qo { @Override public Sort sorts() { - return Sort.by(Sort.Order.desc("createTime")); + return Sort.by(Sort.Order.desc("modifyTime")); } } diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Domain.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Domain.java index b860b29..a18f5a7 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Domain.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/base/Domain.java @@ -3,7 +3,6 @@ package com.flyfish.framework.domain.base; import com.fasterxml.jackson.annotation.JsonIgnore; import com.flyfish.framework.annotations.Generation; import com.flyfish.framework.annotations.Property; -import com.flyfish.framework.domain.po.User; import lombok.Getter; import lombok.Setter; import org.springframework.data.annotation.Id; @@ -51,7 +50,7 @@ public abstract class Domain implements Po, Named, Serializable { @Transient @JsonIgnore @Property(readonly = true) - private User currentUser; + private IUser currentUser; @Override public int hashCode() { diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java index 171fc0e..c4975fa 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java @@ -83,7 +83,8 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) .flatMapMany(querying -> mongoOperations.find(querying, entityInformation.getJavaType(), - entityInformation.getCollectionName())); + entityInformation.getCollectionName())) + .doOnNext(t -> t.setCurrentUser(query.getUser())); } /** @@ -117,6 +118,7 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact return Mono.justOrEmpty(QueryBuildUtils.getQuery(query)) .flatMap(querying -> mongoOperations.find(querying.with(pageable), entityInformation.getJavaType(), entityInformation.getCollectionName()) + .doOnNext(t -> t.setCurrentUser(query.getUser())) .collectList() .flatMap(list -> ReactivePageableExecutionUtils.getPage(list, pageable, this.count(query)))) .defaultIfEmpty(Page.empty()); diff --git a/flyfish-data/src/main/java/com/flyfish/framework/utils/DepartUtils.java b/flyfish-data/src/main/java/com/flyfish/framework/utils/DepartUtils.java new file mode 100644 index 0000000..825c2fb --- /dev/null +++ b/flyfish-data/src/main/java/com/flyfish/framework/utils/DepartUtils.java @@ -0,0 +1,88 @@ +package com.flyfish.framework.utils; + +import com.flyfish.framework.domain.authorized.AuthorizedDomain; +import com.flyfish.framework.domain.authorized.AuthorizedVo; +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 org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.data.util.CastUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 部门工具类 + * + * @author wangyu + */ +public final class DepartUtils { + + /** + * 合并部门,有包含关系的部门将被合并 + * + * @param departments 部门 + * @return 结果 + */ + public static Set mergeDeparts(List departments) { + if (CollectionUtils.isEmpty(departments)) { + return Collections.emptySet(); + } + 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; + } + + /** + * 包装权限,必须调用 + * + * @param item 内容 + * @return 结果 + */ + public static T wrapAuthority(T item, AuthorizedDomain po) { + if (item instanceof AuthorizedVo) { + AuthorizedVo vo = CastUtils.cast(item); + // 已发布的内容,谁都不能修改 + if (BooleanUtils.isTrue(po.getPublished())) { + vo.setReadonly(true); + } else { + vo.setReadonly(false); + // 获取当前用户 + IUser user = po.getCurrentUser(); + if (user.getType() != UserType.SUPER_ADMIN) { + // 用户所属部门 + Set userDeparts = DepartUtils.mergeDeparts(user.getDepartments()); + // 实体归属部门 + String currentDepart = po.getAuthorizeId(); + // 用户权限合集 + Set authorities = user.getRoles().stream() + .flatMap(role -> null == role.getAuthorities() ? Stream.empty() : role.getAuthorities().stream()) + .collect(Collectors.toSet()); + // 取出权限,便于判定 + boolean admin = authorities.contains(Role.Authority.ADMIN); + boolean edit = authorities.contains(Role.Authority.EDIT); + boolean editChildren = authorities.contains(Role.Authority.EDIT_CHILDREN); + // 开始判定只读情况,管理员权限或者创建者,均具有读写权限 + if (!admin && !po.getCreatorId().equals(user.getId())) { + vo.setReadonly(!edit && userDeparts.contains(currentDepart) || + !editChildren && !userDeparts.contains(currentDepart)); + } + } + } + } + return item; + } +} diff --git a/flyfish-user/src/main/java/com/flyfish/framework/config/audit/RoleBeanPoster.java b/flyfish-user/src/main/java/com/flyfish/framework/config/audit/RoleBeanPoster.java new file mode 100644 index 0000000..ad278bf --- /dev/null +++ b/flyfish-user/src/main/java/com/flyfish/framework/config/audit/RoleBeanPoster.java @@ -0,0 +1,33 @@ +package com.flyfish.framework.config.audit; + +import com.flyfish.framework.auditor.ReactiveBeanPoster; +import com.flyfish.framework.domain.po.Role; +import com.flyfish.framework.service.UserDetailsConverter; +import com.flyfish.framework.utils.ReactiveRedisOperations; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +/** + * 角色bean后置处理 + * + * @author wangyu + */ +@Component +@RequiredArgsConstructor +public class RoleBeanPoster implements ReactiveBeanPoster { + + private final ReactiveRedisOperations reactiveRedisOperations; + private final UserDetailsConverter userDetailsConverter; + + /** + * 对入库的实体进行审查,并执行额外功能 + * + * @param data 原数据 + */ + @Override + public Mono post(Role data) { + // 更新缓存 + return reactiveRedisOperations.del(reactiveRedisOperations.getKeys("user-*")).thenReturn(data); + } +} 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 1d8defa..b4be09b 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 @@ -5,11 +5,14 @@ import com.flyfish.framework.controller.reactive.ReactiveTreeController; import com.flyfish.framework.domain.AdminUserDetails; import com.flyfish.framework.domain.DepartmentQo; import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.enums.UserType; import com.flyfish.framework.utils.UserUtils; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.ArrayList; @@ -31,10 +34,17 @@ public class DepartmentController extends ReactiveTreeController>> getAuthorizedTree() { return ReactiveSecurityContextHolder.getContext() .map(UserUtils::extractUserDetails) - .flatMap(detail -> { + .flatMapMany(detail -> { AdminUserDetails details = (AdminUserDetails) detail; - return reactiveService.getByIds(new ArrayList<>(details.getVisibleDeparts())).collectList(); + if (details.getType() == UserType.SUPER_ADMIN) { + return reactiveService.getAll(); + } + if (CollectionUtils.isNotEmpty(details.getVisibleDeparts())) { + return reactiveService.getByIds(new ArrayList<>(details.getVisibleDeparts())); + } + return Flux.empty(); }) + .collectList() .map(this::makeTree) .map(Result::accept); } 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 daa1b5f..43a47a5 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 @@ -1,11 +1,19 @@ package com.flyfish.framework.service; +import com.flyfish.framework.domain.AdminUserDetails; +import com.flyfish.framework.domain.DepartmentQo; +import com.flyfish.framework.domain.authorized.AuthorizedUserDetails; +import com.flyfish.framework.domain.base.Qo; import com.flyfish.framework.domain.po.Department; +import com.flyfish.framework.enums.UserType; import com.flyfish.framework.service.impl.BaseReactiveServiceImpl; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import javax.annotation.Resource; @@ -34,4 +42,39 @@ public class DepartmentService extends BaseReactiveServiceImpl { query.fields().include("_id"); return reactiveMongoOperations.find(query, Department.class).map(Department::getId).collect(Collectors.toSet()); } + + /** + * 查询列表 + * + * @param query 查询 + * @return 结果 + */ + @Override + public Flux getList(Qo query) { + if (query instanceof DepartmentQo) { + DepartmentQo qo = (DepartmentQo) query; + // 如果是非管理员 + if (qo.getUser().getType() != UserType.SUPER_ADMIN) { + // 使用列表内的部门作为条件 + AdminUserDetails userDetails = (AdminUserDetails) query.getUser(); + // 查询根节点下的节点 + if (Department.ROOT.equals(qo.getParentId())) { + qo.setParentId(null); + qo.setIds(userDetails.getVisibleDeparts()); + // 不递归,指定深度,保证单层 + if (BooleanUtils.isNotTrue(qo.getRecursive())) { + // 指定深度 + int maxDepth = userDetails.getDepartments().stream().max((a, b) -> a.getDepth() - b.getDepth()) + .map(Department::getDepth) + .orElse(0); + qo.setDepth(maxDepth); + } + } + if (null == qo.getParentId() && CollectionUtils.isEmpty(qo.getParentIds())) { + qo.setIds(userDetails.getVisibleDeparts()); + } + } + } + return super.getList(query); + } } 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 b6933fb..e0cbf44 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 @@ -6,18 +6,16 @@ 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 com.flyfish.framework.utils.DepartUtils; 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.*; import java.util.stream.Collectors; +import java.util.stream.Stream; @Service @RequiredArgsConstructor @@ -51,16 +49,11 @@ public class UserDetailsConverter { */ 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 authorities = user.getRoles().stream() + .flatMap(role -> null == role.getAuthorities() ? Stream.empty() : role.getAuthorities().stream()) + .collect(Collectors.toSet()); // 根据权限组装查询条件 - Set departs = mergeDeparts(user.getDepartments()); + Set departs = DepartUtils.mergeDeparts(user.getDepartments()); // 查询所有子部门id return departmentService.getSubCodes(departs) .map(codes -> { @@ -80,30 +73,25 @@ public class UserDetailsConverter { } // 最终设置权限 if (CollectionUtils.isNotEmpty(all)) { - userDetails.setAuthorityCodes(SetUtils.union(all, userDetails.getAuthorityCodes())); + userDetails.setAuthorityCodes(union(all, userDetails.getAuthorityCodes())); } - userDetails.setVisibleDeparts(SetUtils.union(codes, departs)); + userDetails.setVisibleDeparts(union(codes, departs)); return userDetails; }); } /** - * 合并部门,有包含关系的部门将被合并 + * 链接两个set * - * @param departments 部门 + * @param a 第一个 + * @param b 第二个 * @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; + private Set union(Set a, Set b) { + Set result = new HashSet<>(); + result.addAll(a); + result.addAll(b); + return result; } } diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/UserService.java b/flyfish-user/src/main/java/com/flyfish/framework/service/UserService.java index 8bf5ca2..7478989 100644 --- a/flyfish-user/src/main/java/com/flyfish/framework/service/UserService.java +++ b/flyfish-user/src/main/java/com/flyfish/framework/service/UserService.java @@ -1,11 +1,19 @@ package com.flyfish.framework.service; +import com.flyfish.framework.domain.UserQo; +import com.flyfish.framework.domain.authorized.AuthorizedUserDetails; +import com.flyfish.framework.domain.base.Qo; import com.flyfish.framework.domain.po.User; +import com.flyfish.framework.enums.UserType; import com.flyfish.framework.repository.UserRepository; import com.flyfish.framework.service.impl.BaseReactiveServiceImpl; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; +import java.util.ArrayList; + /** * 异步用户service * @@ -25,4 +33,22 @@ public class UserService extends BaseReactiveServiceImpl implements UserFi return ((UserRepository) repository).findByUsername(username); } + /** + * 分页查询,这里使用作用域查询 + * + * @param query 查询实体 + * @return 结果 + */ + @Override + public Mono> getPageList(Qo query) { + // 非超级管理员,永远返回作用域的部门人员 + if (query.getUser().getType() != UserType.SUPER_ADMIN) { + AuthorizedUserDetails userDetails = (AuthorizedUserDetails) query.getUser(); + UserQo qo = (UserQo) query; + if (CollectionUtils.isEmpty(qo.getDepartments())) { + qo.setDepartments(new ArrayList<>(userDetails.getVisibleDeparts())); + } + } + return super.getPageList(query); + } } diff --git a/flyfish-web/src/main/java/com/flyfish/framework/controller/reactive/ReactiveTreeController.java b/flyfish-web/src/main/java/com/flyfish/framework/controller/reactive/ReactiveTreeController.java index 5edf066..b986190 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/controller/reactive/ReactiveTreeController.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/controller/reactive/ReactiveTreeController.java @@ -1,6 +1,7 @@ package com.flyfish.framework.controller.reactive; import com.flyfish.framework.bean.Result; +import com.flyfish.framework.configuration.annotations.PagedQuery; import com.flyfish.framework.domain.tree.RootTreeNode; import com.flyfish.framework.domain.tree.TreeDomain; import com.flyfish.framework.domain.tree.TreeQo; @@ -45,7 +46,7 @@ public abstract class ReactiveTreeController, Q extends * @return 结果 */ @GetMapping("tree") - public Mono>> getTree(Q qo) { + public Mono>> getTree(@PagedQuery Q qo) { qo.setRecursive(true); // 第一步,查询全部,并根据条件筛选 return reactiveService.getList(qo) diff --git a/flyfish-web/src/main/java/com/flyfish/framework/utils/ReactiveRedisOperations.java b/flyfish-web/src/main/java/com/flyfish/framework/utils/ReactiveRedisOperations.java index fc94ce8..2379401 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/utils/ReactiveRedisOperations.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/utils/ReactiveRedisOperations.java @@ -73,6 +73,16 @@ public class ReactiveRedisOperations { return Mono.just(0L); } + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + public Mono del(Flux key) { + return redisTemplate.delete(key); + } + + // ============================String============================= /**