refactor(权限点): 排序实现重构;支持新增时重新排序

This commit is contained in:
zhansihu 2023-09-14 11:36:53 +08:00
parent 3677cad80e
commit f7ae347b08
3 changed files with 73 additions and 65 deletions

View File

@ -12,8 +12,8 @@ public class PermissionConstant {
/** 权限点path分隔符 **/
public static final String FEATURE_PATH_DELIMITER = "/";
/** 无父级 **/
public static final String FEATURE_NO_PARENT = "0";
/** 无父级的parent_business_no **/
public static final String FEATURE_TOP_BIZ_NO = "0";
/** 顶级path **/
public static final String FEATURE_TOP_PATH = "/0/";
/** 权限点business_no前缀 **/

View File

@ -25,6 +25,7 @@ import cn.axzo.tyr.server.service.PermissionPointService;
import cn.axzo.tyr.server.service.SaasBasicDictService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -57,21 +58,9 @@ public class PermissionPointServiceImpl implements PermissionPointService {
@Override
public List<PermissionPointTreeNode> listTreeNodes(PermissionPointTreeQueryReq request) {
//条件转换 workspace --> terminal
workspace2Terminal(request);
//查询条件构建
LambdaQueryWrapper<SaasFeature> queryWrapper = new LambdaQueryWrapper<SaasFeature>()
.in(CollectionUtil.isNotEmpty(request.getTerminalList()), SaasFeature::getTerminal, request.getTerminalList());
//查指定节点子级处理条件
if (request.getParentId() != null && request.getParentId() != 0) {
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() + FEATURE_PATH_DELIMITER);
}
//构建查询条件
Wrapper<SaasFeature> queryWrapper = buildQueryWrapper(request);
List<SaasFeature> list = saasFeatureDao.list(queryWrapper);
//构建树形结构 整体排序保证层级内的有序 - 优化点构建树形结构时进行过滤
@ -85,7 +74,7 @@ public class PermissionPointServiceImpl implements PermissionPointService {
List<PermissionPointTreeNode> nodesResult = filterTreeNode(request, treeList);
//指定parent后不需要顶级的工作台
if (request.getParentId() != null) {
if (request.getParentId() != null || CollectionUtil.isEmpty(nodesResult)) {
return nodesResult;
}
@ -125,6 +114,25 @@ public class PermissionPointServiceImpl implements PermissionPointService {
return result;
}
private Wrapper<SaasFeature> buildQueryWrapper(PermissionPointTreeQueryReq request) {
//条件转换 workspace --> terminal
workspace2Terminal(request);
//查询条件构建
LambdaQueryWrapper<SaasFeature> queryWrapper = new LambdaQueryWrapper<SaasFeature>()
.in(CollectionUtil.isNotEmpty(request.getTerminalList()), SaasFeature::getTerminal, request.getTerminalList());
//查指定节点子级处理条件
if (request.getParentId() != null && request.getParentId() != 0) {
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() + FEATURE_PATH_DELIMITER);
}
return queryWrapper;
}
private void workspace2Terminal(PermissionPointTreeQueryReq request) {
if (CollectionUtil.isNotEmpty(request.getWorkspaceType())) {
List<String> terminals = new ArrayList<>();
@ -195,13 +203,11 @@ public class PermissionPointServiceImpl implements PermissionPointService {
@Override
public PermissionPointVO getDetail(Long permissionId) {
SaasFeature feature = this.saasFeatureDao.getById(permissionId);
if (feature == null) {
log.warn("no saasFeature found for:{}", permissionId);
throw new BizException(BaseCode.BAD_REQUEST);
}
SaasFeature feature = getAndCheck(permissionId);
PermissionPointVO vo = BeanMapper.copyBean(feature, PermissionPointVO.class);
vo.setFeatureTypeDesc(FeatureType.apply(vo.getFeatureType()).getDesc());
//按位拆分适配单位类型和节点类型
vo.applyFitOuTypeBit(feature.getFitOuTypeBit());
vo.applyFitOuNodeTypeBit(feature.getFitOuNodeTypeBit());
@ -222,11 +228,12 @@ public class PermissionPointServiceImpl implements PermissionPointService {
vo.setPathName(pathName);
return vo;
}
//查询所有父级
List<String> split = StrUtil.split(vo.getPath(), FEATURE_PATH_DELIMITER, true, true);
List<Long> ids = split.stream()
.filter(x -> !StrUtil.equals(FEATURE_NO_PARENT, x))
//查询所有父级 - path拆分查询
List<Long> ids = StrUtil.split(vo.getPath(), FEATURE_PATH_DELIMITER, true, true)
.stream()
.map(Long::valueOf)
.filter(id -> id < 1)
.collect(Collectors.toList());
Map<Long, SaasFeature> parentsMapping = this.saasFeatureDao.listByIds(ids)
.stream()
@ -284,23 +291,22 @@ public class PermissionPointServiceImpl implements PermissionPointService {
saasFeature.setFitOuNodeTypeBit(dto.mergeFitOuNodeTypeBit());
SaasFeature parent;
if (dto.getParentId() == null || dto.getParentId() < 1) {
parent = new SaasFeature();
parent.setPath(FEATURE_TOP_PATH);
parent.setBusinessNo("0");
//设置为0便于下面查询
parent.setParentId(0L);
saasFeature.setParentId(0L);
saasFeature.setPath(FEATURE_TOP_PATH);
saasFeature.setParentBusinessNo(FEATURE_TOP_BIZ_NO);
} else {
parent = this.saasFeatureDao.getById(dto.getParentId());
saasFeature.setPath(parent.getPath() + parent.getId() + FEATURE_PATH_DELIMITER);
saasFeature.setParentBusinessNo(parent.getBusinessNo());
}
//计算子节点作为sort
//生成biz_no
saasFeature.setBusinessNo(FEATURE_BIZ_NO_PREFIX + System.currentTimeMillis());
saasFeature.setParentBusinessNo(parent.getBusinessNo());
saasFeature.setPath(parent.getPath() + parent.getId() + FEATURE_PATH_DELIMITER);
this.saasFeatureDao.save(saasFeature);
dto.setId(saasFeature.getId());
dto.setBusinessNo(saasFeature.getBusinessNo());
//调整排序 - 兼容处理老数据数据规范化
changeSort(saasFeature, saasFeature.getSort());
return dto;
}
@ -338,7 +344,8 @@ public class PermissionPointServiceImpl implements PermissionPointService {
public void move(PermissionPointMoveRequest request) {
SaasFeature feature = getAndCheck(request.getPermissionId());
changeParent(feature, request);
changeSort(feature, request);
feature.setParentId(request.getParentId());
changeSort(feature, request.getSort());
}
@Override
@ -357,35 +364,36 @@ public class PermissionPointServiceImpl implements PermissionPointService {
.collect(Collectors.toList());
}
private void changeSort(SaasFeature feature, PermissionPointMoveRequest request) {
//原parent下节点排序会有缺失但无影响-不处理
private void changeSort(SaasFeature feature, Integer targetSort) {
//排序从1开始
//原parent下节点排序会有缺失 - 有节点新增时进行处理
//同terminal 同级节点
List<SaasFeature> saasFeatures = this.saasFeatureDao.listByParentIdAndTerminal(request.getParentId(),
List<SaasFeature> saasFeatures = this.saasFeatureDao.listByParentIdAndTerminal(feature.getParentId(),
feature.getTerminal());
//数据规范化
if (targetSort == null
|| targetSort > saasFeatures.size()) {
//默认在最后
targetSort = saasFeatures.size();
}
targetSort = targetSort < 1 ? 1 : targetSort;
//排序并排除自己
List<SaasFeature> sortedList = saasFeatures.stream()
.sorted(Comparator.comparing(SaasFeature::getSort))
.filter(x -> !x.getId().equals(feature.getId()))
.collect(Collectors.toList());
//将自己插入指定位置
sortedList.add(targetSort - 1, feature);
//记录排序
Map<Long, Integer> sortMap = new HashMap<>();
//插入指定位置
sortMap.put(request.getPermissionId(), request.getSort());
//找到需要更新排序其他节点
AtomicInteger sort = new AtomicInteger(0);
Integer targetSort = request.getSort();
saasFeatures.stream()
.sorted(Comparator.comparing(SaasFeature::getSort))
.forEach(x -> {
//跳过自己
if (!x.getId().equals(request.getPermissionId())) {
//记录位置
sort.incrementAndGet();
if (targetSort.equals(sort.get())) {
//找到指定位置当前节点需要移动到下一位置
sort.incrementAndGet();
}
if (!x.getSort().equals(sort.get())) {
// 排序需要修正
sortMap.put(x.getId(), sort.get());
}
}
});
//找到需要更新排序的节点
for (int i = 0; i < sortedList.size(); i++) {
SaasFeature saasFeature = sortedList.get(i);
if (!saasFeature.getSort().equals(i + 1)) {
sortMap.put(saasFeature.getId(), i + 1);
}
}
//执行更新 - 有一定性能问题
for (Map.Entry<Long, Integer> entry : sortMap.entrySet()) {
this.saasFeatureDao.updateSort(entry.getKey(), entry.getValue());

View File

@ -74,7 +74,7 @@ public class PermissionPointTest {
permissionPoint.setFeatureCode("CMS_WEB_PROJ_0158");
permissionPoint.setParentId(360L);
permissionPoint.setPath("/0/354/360/");
permissionPoint.setSort(6);
permissionPoint.setSort(3);
permissionPoint.setTerminal("NT_CMS_WEB_PROJ");
permissionPoint.setFeatureType(3);
permissionPoint.setAppName("tyr");
@ -82,7 +82,7 @@ public class PermissionPointTest {
permissionPoint.setNeedAuth(true);
permissionPoint.setNeedAuth(true);
System.out.println(JSON.toJSONString(permissionPoint));
//controller.savePermissionPoint(permissionPoint);
controller.savePermissionPoint(permissionPoint);
}
@Test
@ -107,8 +107,8 @@ public class PermissionPointTest {
@Test
public void testMove() {
PermissionPointMoveRequest request = new PermissionPointMoveRequest();
request.setPermissionId(360L);
request.setParentId(354L);
request.setPermissionId(3483L);
request.setParentId(360L);
request.setSort(1);
ApiResult<Void> result = controller.move(request);
System.out.println(JSON.toJSONString(result));