feature(权限点): 增加列表查询接口;增加位置移动接口

This commit is contained in:
zhansihu 2023-09-13 09:54:06 +08:00
parent 905e216bd1
commit b100ec729b
10 changed files with 218 additions and 85 deletions

View File

@ -2,6 +2,8 @@ package cn.axzo.tyr.client.feign;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.tyr.client.model.permission.PermissionPointDTO;
import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointMoveRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.client.model.permission.PermissionPointVO;
@ -45,11 +47,11 @@ public interface PermissionPointApi {
ApiResult<Void> deletePermissionPoint(@PathVariable Long permissionId);
/** 更新父级节点 - 直接更新不校验 **/
@PostMapping(value = "/api/v1/permissionPoint/change/{permissionId}")
ApiResult<Void> changeParent(@RequestParam Long updater, @PathVariable Long permissionId, @RequestParam Long newParentId);
/** 位置移动 **/
@PostMapping(value = "/api/v1/permissionPoint/move")
ApiResult<Void> move(@RequestBody PermissionPointMoveRequest request);
/** 更改排序 **/
@PostMapping(value = "/api/v1/permissionPoint/sort/{permissionId}")
ApiResult<Void> updateSort(@RequestParam Long updater, @PathVariable Long permissionId, @RequestParam Integer direction);
/** 查询权限点列表 - 不组装树形结构 **/
@PostMapping(value = "/api/v1/permissionPoint/queryList")
ApiResult<List<PermissionPointTreeNode>> queryList(@RequestBody PermissionPointListQueryRequest request);
}

View File

@ -0,0 +1,36 @@
package cn.axzo.tyr.client.model.permission;
import lombok.Data;
/**
* 权限点列表查询对象
* 按需扩展
* @version V1.0
* @author: ZhanSiHu
* @date: 2023/9/12 18:51
*/
@Data
public class PermissionPointListQueryRequest {
/**
* 元素类别 0.模块 1.菜单 2页面 3按钮
* 参考FeatureType
* **/
private Integer featureType;
/**
* 权限点所属工作台
* **/
private String terminal;
/**
* 父级权限点ID
* **/
private Long parentId;
/**
* path左匹配
* **/
private String likePath;
}

View File

@ -0,0 +1,30 @@
package cn.axzo.tyr.client.model.permission;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 权限点移动请求
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2023/9/12 15:45
*/
@Data
public class PermissionPointMoveRequest {
/** 权限点ID **/
@NotNull(message = "权限点ID不能为空")
private Long permissionId;
/** 父级节点ID - 可为空-则parent为工作台 **/
private Long parentId = 0L;
/** 排序sort **/
@NotNull(message = "权限点排序不能为空")
private Integer sort;
/** 操作人 **/
private Long updaterId;
}

View File

@ -0,0 +1,21 @@
package cn.axzo.tyr.server.common.util;
import cn.axzo.framework.core.enums.ErrorLevel;
import cn.axzo.framework.core.enums.ErrorType;
import cn.axzo.framework.domain.web.BizException;
import cn.axzo.framework.domain.web.code.IRespCode;
/**
* 抛异常工具
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2023/9/12 11:25
*/
public class Throws {
/** 用于抛出请求参数类异常 **/
public static BizException paramException(IRespCode code, String message) {
throw new BizException(ErrorLevel.P2, ErrorType.ERROR_BUSINESS, code, message);
}
}

View File

@ -3,6 +3,8 @@ package cn.axzo.tyr.server.controller.permission;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.tyr.client.feign.PermissionPointApi;
import cn.axzo.tyr.client.model.permission.PermissionPointDTO;
import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointMoveRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.client.model.permission.PermissionPointVO;
@ -57,15 +59,15 @@ public class PermissionPointController implements PermissionPointApi {
return ApiResult.ok();
}
@Override
public ApiResult<Void> changeParent(Long updater, Long permissionId, Long newParentId) {
permissionPointService.changeParent(updater, permissionId, newParentId);
public ApiResult<Void> move(PermissionPointMoveRequest request) {
permissionPointService.move(request);
return ApiResult.ok();
}
@Override
public ApiResult<Void> updateSort(Long updater, Long permissionId, Integer direction) {
permissionPointService.updateSort(updater, permissionId, direction);
return ApiResult.ok();
public ApiResult<List<PermissionPointTreeNode>> queryList(PermissionPointListQueryRequest request) {
return ApiResult.ok(permissionPointService.queryList(request));
}
}

View File

@ -22,4 +22,6 @@ public interface SaasFeatureDao extends IService<SaasFeature> {
void updateSort(Long permissionId, int switchIndex);
List<SaasFeature> listLikePath(String path);
List<SaasFeature> listByParentIdAndTerminal(Long parentId, String terminal);
}

View File

@ -42,4 +42,11 @@ public class SaasFeatureDaoImpl extends ServiceImpl<SaasFeatureMapper, SaasFeatu
public List<SaasFeature> listLikePath(String path) {
return this.list(new LambdaQueryWrapper<SaasFeature>().likeRight(SaasFeature::getPath, path));
}
@Override
public List<SaasFeature> listByParentIdAndTerminal(Long parentId, String terminal) {
return this.list(new LambdaQueryWrapper<SaasFeature>()
.eq(SaasFeature::getParentId, parentId)
.eq(SaasFeature::getTerminal, terminal));
}
}

View File

@ -1,10 +1,11 @@
package cn.axzo.tyr.server.service;
import cn.axzo.tyr.client.model.permission.PermissionPointDTO;
import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointMoveRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.client.model.permission.PermissionPointVO;
import cn.axzo.tyr.server.repository.entity.SaasFeature;
import java.util.List;
@ -38,10 +39,8 @@ public interface PermissionPointService {
/** 删除权限点 **/
void delete(Long permissionId);
/** 更新父级 **/
void changeParent(Long updater, Long permissionId,Long newParentId);
/** 移动排序 **/
void updateSort(Long updater, Long permissionId, Integer direction);
/** 位置移动-父级和排序 **/
void move(PermissionPointMoveRequest request);
List<PermissionPointTreeNode> queryList(PermissionPointListQueryRequest request);
}

View File

@ -12,6 +12,8 @@ import cn.axzo.tyr.client.model.dict.response.BasicDictNodeResp;
import cn.axzo.tyr.client.model.dict.response.BasicDictTreeResp;
import cn.axzo.tyr.client.model.enums.FeatureType;
import cn.axzo.tyr.client.model.permission.PermissionPointDTO;
import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointMoveRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.client.model.permission.PermissionPointVO;
@ -30,6 +32,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -316,67 +319,92 @@ public class PermissionPointServiceImpl implements PermissionPointService {
this.saasPgroupPermissionRelationDao.removeByPermissionPointIds(delIds);
}
@Transactional(rollbackFor = Throwable.class)
@Override
public void changeParent(Long updater, Long permissionId, Long newParentId) {
SaasFeature feature = this.saasFeatureDao.getById(permissionId);
if (Objects.equals(feature.getParentId(), newParentId)) {
//父级未变
return;
}
SaasFeature parent = this.saasFeatureDao.getById(newParentId);
if (!StrUtil.equals(feature.getTerminal(), parent.getTerminal())) {
throw new BizException(BaseCode.BAD_REQUEST, "不允许跨工作台");
}
if (parent.getPath().contains(String.valueOf(permissionId))) {
throw new BizException(BaseCode.BAD_REQUEST, "不允许移到子级");
}
//当前节点
SaasFeature entity = new SaasFeature();
entity.setId(feature.getId());
entity.setParentId(newParentId);
entity.setParentBusinessNo(parent.getBusinessNo());
entity.setPath(parent.getPath() + parent.getId() + FEATURE_PATH_DELIMITER);
entity.setUpdateBy(updater);
this.saasFeatureDao.updateById(entity);
//更新子级path
this.saasFeatureDao.updateChildrenPath(updater, feature.getPath() + feature.getId() + FEATURE_PATH_DELIMITER,
entity.getPath() + entity.getId() + FEATURE_PATH_DELIMITER);
public void move(PermissionPointMoveRequest request) {
SaasFeature feature = getAndCheck(request.getPermissionId());
changeParent(feature, request);
changeSort(feature, request);
}
@Override
public void updateSort(Long updater, Long permissionId, Integer direction) {
//查询当前节点和所有同级节点
SaasFeature feature = this.saasFeatureDao.getById(permissionId);
List<SaasFeature> children = this.saasFeatureDao.listByParentId(feature.getParentId());
List<SaasFeature> sortedChildren = children.stream()
.sorted(Comparator.comparing(SaasFeature::getSort))
public List<PermissionPointTreeNode> queryList(PermissionPointListQueryRequest request) {
LambdaQueryWrapper<SaasFeature> wrapper = new LambdaQueryWrapper<SaasFeature>()
.eq(Objects.nonNull(request.getTerminal()), SaasFeature::getTerminal, request.getTerminal())
.eq(Objects.nonNull(request.getFeatureType()), SaasFeature::getFeatureType, request.getFeatureType())
.eq(Objects.nonNull(request.getParentId()), SaasFeature::getParentId, request.getParentId())
.likeRight(Objects.nonNull(request.getLikePath()), SaasFeature::getPath, request.getLikePath());
return this.saasFeatureDao.list(wrapper)
.stream()
.map(this::feature2Node)
.collect(Collectors.toList());
//确认当前节点index
Integer index = sortedChildren.stream()
.filter(x -> x.getId().equals(permissionId))
.map(sortedChildren::indexOf)
.findFirst().get();
int switchIndex = 0;
if (direction > 0) {
//向上
if (index == 0) {
//已经是第一个
return;
}
switchIndex = index - 1;
} else {
//向下
if (index == sortedChildren.size() - 1) {
//已经最后一个
return;
}
switchIndex = index + 1;
}
private void changeSort(SaasFeature feature, PermissionPointMoveRequest request) {
//原parent下节点排序会有缺失但无影响-不处理
//同terminal 同级节点
List<SaasFeature> saasFeatures = this.saasFeatureDao.listByParentIdAndTerminal(request.getParentId(),
feature.getTerminal());
//记录排序
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 (Map.Entry<Long, Integer> entry : sortMap.entrySet()) {
this.saasFeatureDao.updateSort(entry.getKey(), entry.getValue());
}
//更新当前节点
this.saasFeatureDao.updateSort(permissionId, switchIndex);
//更新交换节点
this.saasFeatureDao.updateSort(sortedChildren.get(switchIndex).getId(), index);
}
private void changeParent(SaasFeature feature, PermissionPointMoveRequest request) {
Long parentId = request.getParentId();
if (Objects.equals(feature.getParentId(), parentId)) {
//父级未变
return;
}
SaasFeature parent = null;
if (parentId != 0) {
parent = this.saasFeatureDao.getById(parentId);
if (!StrUtil.equals(feature.getTerminal(), parent.getTerminal())) {
throw new BizException(BaseCode.BAD_REQUEST, "不允许跨工作台");
}
if (parent.getPath().contains(String.valueOf(request.getPermissionId()))) {
throw new BizException(BaseCode.BAD_REQUEST, "不允许移到子级");
}
}
//当前节点更新
SaasFeature entity = new SaasFeature();
entity.setId(feature.getId());
entity.setParentId(parentId);
entity.setParentBusinessNo(parent == null ? "0" : parent.getBusinessNo());
entity.setPath(parent == null ? FEATURE_TOP_PATH : parent.getPath() + parent.getId() + FEATURE_PATH_DELIMITER);
entity.setUpdateBy(request.getUpdaterId());
this.saasFeatureDao.updateById(entity);
//更新子级path
this.saasFeatureDao.updateChildrenPath(request.getUpdaterId(), feature.getPath() + feature.getId() + FEATURE_PATH_DELIMITER,
entity.getPath() + entity.getId() + FEATURE_PATH_DELIMITER);
}
private PermissionPointTreeNode feature2Node(SaasFeature feature) {

View File

@ -1,7 +1,10 @@
package cn.axzo.tyr.server.permission;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.tyr.client.model.enums.FeatureType;
import cn.axzo.tyr.client.model.permission.PermissionPointDTO;
import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointMoveRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.client.model.permission.PermissionPointVO;
@ -99,27 +102,30 @@ public class PermissionPointTest {
controller.savePermissionPoint(permissionPoint);
}
@Test
public void testSort() {
//老数据可能会导致位置不对
Long updater = 111L;
Long permissionId = 3478L;
Integer direction = 1;
controller.updateSort(updater, permissionId, direction);
}
@Test
public void testChangeParent() {
Long updater = 111L;
Long permissionId = 360L;
Long newParentId = 354L;
controller.changeParent(updater, permissionId, newParentId);
public void testMove() {
PermissionPointMoveRequest request = new PermissionPointMoveRequest();
request.setPermissionId(360L);
request.setParentId(354L);
request.setSort(1);
ApiResult<Void> result = controller.move(request);
System.out.println(JSON.toJSONString(result));
}
@Test
public void testDelete() {
Long permissionId = 360L;
controller.deletePermissionPoint(permissionId);
}
@Test
public void testQueryList() {
PermissionPointListQueryRequest request = new PermissionPointListQueryRequest();
request.setFeatureType(FeatureType.BUTTON.getCode());
ApiResult<List<PermissionPointTreeNode>> result = controller.queryList(request);
System.out.println(JSON.toJSONString(result));
}
}