Merge remote-tracking branch 'origin/feature/REQ-1204' into feature/REQ-1204

This commit is contained in:
陈维伟 2023-09-07 16:29:28 +08:00
commit 4241d1b7da
8 changed files with 160 additions and 9 deletions

View File

@ -1,6 +1,7 @@
package cn.axzo.tyr.client.model.enums; package cn.axzo.tyr.client.model.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -12,6 +13,7 @@ import java.util.Map;
* @author: ZhanSiHu * @author: ZhanSiHu
* @date: 2023/9/6 11:05 * @date: 2023/9/6 11:05
*/ */
@Getter
@AllArgsConstructor @AllArgsConstructor
public enum DelegatedType { public enum DelegatedType {
@ -30,7 +32,7 @@ public enum DelegatedType {
} }
} }
public DelegatedType apply(Integer code) { public static DelegatedType apply(Integer code) {
return code == null ? null :MAPPING.get(code); return code == null ? null :MAPPING.get(code);
} }
} }

View File

@ -0,0 +1,39 @@
package cn.axzo.tyr.client.model.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
/**
* 权限点元素类型
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2023/9/6 21:03
*/
@Getter
@AllArgsConstructor
public enum FeatureType {
MODULE(0, "模块"),
MENU(1, "菜单"),
PAGE(2, "页面"),
BUTTON(3, "按钮"),
;
private Integer code;
private String desc;
private static final Map<Integer, FeatureType> MAPPING = new HashMap<>();
static {
for (FeatureType type : FeatureType.values()) {
MAPPING.put(type.code, type);
}
}
public static FeatureType apply(Integer code) {
return code == null ? null :MAPPING.get(code);
}
}

View File

@ -3,6 +3,7 @@ package cn.axzo.tyr.client.model.permission;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
/** /**
* 权限点对象 * 权限点对象
@ -35,10 +36,13 @@ public class PermissionPointDTO {
private String icon; private String icon;
/** /**
* 级权限点id * 级权限点id
*/ */
private Long parentId; private Long parentId;
/** 父级权限点名称 **/
private String parentName;
/** /**
* 页面路由 * 页面路由
@ -65,6 +69,9 @@ public class PermissionPointDTO {
*/ */
private String path; private String path;
/** 上级节点层级名称 **/
private List<String> parentPath;
/** /**
* 排序 * 排序
*/ */

View File

@ -40,6 +40,10 @@ public class PermissionPointTreeNode implements IBaseTree<PermissionPointTreeNod
/** 元素类别描述 - 对应featureType **/ /** 元素类别描述 - 对应featureType **/
private String featureTypeDesc; private String featureTypeDesc;
/**
* 授权策略类型允许为空 1-平台授权型 2-客户授权型 3-免授权型
*/
private Integer delegatedType;
/** 下级节点 **/ /** 下级节点 **/
private List<PermissionPointTreeNode> children; private List<PermissionPointTreeNode> children;

View File

@ -15,7 +15,7 @@ import java.util.List;
public class PermissionPointTreeQueryReq { public class PermissionPointTreeQueryReq {
/** 授权策略 0-全部 1-平台授权型 2-客户授权型 3-免授权型**/ /** 授权策略 0-全部 1-平台授权型 2-客户授权型 3-免授权型**/
private Integer delegateType; private Integer delegateType = 0;
/** 搜索关键字 - 名称模糊搜索 **/ /** 搜索关键字 - 名称模糊搜索 **/
private String keyword; private String keyword;

View File

@ -28,6 +28,7 @@ public class PermissionPointController implements PermissionPointApi {
@Override @Override
public ApiResult<List<PermissionPointTreeNode>> listTreeNodes(PermissionPointTreeQueryReq request) { public ApiResult<List<PermissionPointTreeNode>> listTreeNodes(PermissionPointTreeQueryReq request) {
//查询数据
return ApiResult.ok(permissionPointService.listTreeNodes(request)); return ApiResult.ok(permissionPointService.listTreeNodes(request));
} }
} }

View File

@ -1,21 +1,32 @@
package cn.axzo.tyr.server.service.impl; package cn.axzo.tyr.server.service.impl;
import cn.axzo.basics.common.BeanMapper; import cn.axzo.basics.common.BeanMapper;
import cn.axzo.basics.common.util.TreeUtil;
import cn.axzo.framework.domain.web.BizException;
import cn.axzo.framework.domain.web.code.BaseCode;
import cn.axzo.tyr.client.model.enums.FeatureType;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode; import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq; import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasFeature;
import cn.axzo.tyr.server.repository.service.SaasFeatureDao; import cn.axzo.tyr.server.repository.service.SaasFeatureDao;
import cn.axzo.tyr.server.service.PermissionPointService; import cn.axzo.tyr.server.service.PermissionPointService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* 权限点服务实现 * 权限点服务实现
@ -32,12 +43,81 @@ public class PermissionPointServiceImpl implements PermissionPointService {
@Override @Override
public List<PermissionPointTreeNode> listTreeNodes(PermissionPointTreeQueryReq request) { public List<PermissionPointTreeNode> listTreeNodes(PermissionPointTreeQueryReq request) {
List<SaasFeature> list = saasFeatureDao.list(new LambdaQueryWrapper<SaasFeature>() //查询条件构建
.eq(Objects.isNull(request.getDelegateType()), SaasFeature::getDelegatedType, request.getDelegateType()) LambdaQueryWrapper<SaasFeature> queryWrapper = new LambdaQueryWrapper<SaasFeature>()
.eq(Objects.isNull(request.getParentId()), SaasFeature::getParentId, request.getParentId()) .in(CollectionUtil.isNotEmpty(request.getTerminalList()), SaasFeature::getTerminal, request.getTerminalList());
.in(CollectionUtil.isEmpty(request.getTerminalList()), SaasFeature::getTerminal, request.getTerminalList()) //查指定节点子级处理条件
); if (request.getParentId() != null && request.getParentId() != 0) {
return list.stream().map(this::feature2Node).collect(Collectors.toList()); SaasFeature parent = this.saasFeatureDao.getById(request.getParentId());
if (parent == null) {
log.error("指定的父级节点不存在:{}", request.getParentId());
throw new BizException(BaseCode.BAD_REQUEST);
}
//追加条件path左匹配
queryWrapper.likeRight(SaasFeature::getPath, parent.getPath() + parent.getId() + "/");
}
List<SaasFeature> list = saasFeatureDao.list(queryWrapper);
//构建树形结构 整体排序保证层级内的有序 - 优化点构建树形结构时进行过滤
List<PermissionPointTreeNode> treeList = TreeUtil.buildTree(list.stream()
.map(this::feature2Node)
.sorted(Comparator.comparing(PermissionPointTreeNode::getSort))
.collect(Collectors.toList()));
list = null; //for GC
//搜索或需要按授权策略过滤 - 有额外的过滤条件
List<PermissionPointTreeNode> result = filterTreeNode(request, treeList);
//指定parent后不需要顶级的工作台
if (request.getParentId() != null) {
return result;
}
//按terminal分组
Map<String, List<PermissionPointTreeNode>> mappingNode = treeList.stream()
.collect(Collectors.groupingBy(PermissionPointTreeNode::getTerminal));
//构建terminal工作台层级
return result;
}
private List<PermissionPointTreeNode> filterTreeNode(PermissionPointTreeQueryReq request, List<PermissionPointTreeNode> treeList) {
//过滤条件
boolean needFilter = StrUtil.isNotBlank(request.getKeyword())
|| request.getDelegateType() != 0;
if (needFilter) {
return treeList.stream().filter(x -> this.recursionFilter(request, x)).collect(Collectors.toList());
}
return treeList;
}
private boolean recursionFilter(PermissionPointTreeQueryReq request, PermissionPointTreeNode node) {
//条件匹配 - 关键字
boolean matchKeyword = request.getKeyword() == null || node.getPermissionName().contains(request.getKeyword());
//条件匹配 - 授权策略类型
boolean matchDelegateType = request.getDelegateType() == 0 || Objects.equals(request.getDelegateType(), node.getDelegatedType());
if (matchKeyword && matchDelegateType) {
//如果匹配直接返回否则过滤子节点
return true;
}
if (CollectionUtil.isEmpty(node.getChildren())) {
return false;
}
//过滤子节点 - 递归 - 必要时改为循环
List<PermissionPointTreeNode> filterChildren = node.getChildren().stream()
.filter(x -> recursionFilter(request, x))
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(filterChildren)) {
return false;
}
node.setChildren(filterChildren);
return true;
} }
@Override @Override
@ -51,6 +131,10 @@ public class PermissionPointServiceImpl implements PermissionPointService {
node.setPermissionName(feature.getFeatureName()); node.setPermissionName(feature.getFeatureName());
node.setParentId(feature.getParentId()); node.setParentId(feature.getParentId());
node.setTerminal(feature.getTerminal()); node.setTerminal(feature.getTerminal());
node.setFeatureType(feature.getFeatureType());
node.setFeatureTypeDesc(FeatureType.apply(feature.getFeatureType()).getDesc());
node.setPath(feature.getPath());
node.setSort(feature.getSort());
return node; return node;
} }

View File

@ -1,9 +1,13 @@
package cn.axzo.tyr.server.permission; package cn.axzo.tyr.server.permission;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.server.controller.permission.PermissionPointController; import cn.axzo.tyr.server.controller.permission.PermissionPointController;
import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasFeature;
import cn.axzo.tyr.server.repository.service.SaasFeatureDao; import cn.axzo.tyr.server.repository.service.SaasFeatureDao;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
@ -30,4 +34,14 @@ public class PermissionPointTest {
List<SaasFeature> saasFeatures = saasFeatureDao.listByIds(Arrays.asList(206L, 207L, 208L)); List<SaasFeature> saasFeatures = saasFeatureDao.listByIds(Arrays.asList(206L, 207L, 208L));
System.out.println(JSON.toJSONString(saasFeatures)); System.out.println(JSON.toJSONString(saasFeatures));
} }
@Test
public void testListTreeNode() {
PermissionPointTreeQueryReq request = new PermissionPointTreeQueryReq();
request.setParentId(354L);
request.setKeyword("合同");
ApiResult<List<PermissionPointTreeNode>> result = controller.listTreeNodes(request);
System.out.println("---------------");
System.out.println(JSON.toJSONString(result, SerializerFeature.DisableCircularReferenceDetect));
}
} }