Merge branch 'feature/REQ-1507' of axzsource.com:universal/infrastructure/backend/msg-center-plat into dev

This commit is contained in:
luofu 2023-11-15 14:16:22 +08:00
commit dc920d3580
8 changed files with 154 additions and 51 deletions

View File

@ -10,11 +10,16 @@ import cn.axzo.msg.center.service.group.request.MessageGroupNodeUpdateRequest;
import cn.axzo.msg.center.service.group.request.MessageGroupQueryRequest;
import cn.axzo.msg.center.service.group.response.MessageGroupNodeBriefResponse;
import cn.axzo.msg.center.service.group.response.MessageGroupTreeNodeResponse;
import cn.axzo.msg.center.utils.TreeHelperUtil;
import cn.azxo.framework.common.model.CommonResponse;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -57,6 +62,16 @@ public class MessageGroupController implements MessageGroupClient {
return CommonResponse.success(groupTreeNodes);
}
@Override
public CommonResponse<List<MessageGroupTreeNodeResponse>> listCutTree(MessageGroupQueryRequest request) {
List<MessageGroupTreeNodeResponse> groupTreeNodes = messageGroupNodeService
.listGroupTree(request.getCategory(), request.getNodeName()).stream()
.map(this::convertCutTree)
.filter(e -> CollectionUtils.isNotEmpty(e.getChildren()))
.collect(Collectors.toList());
return CommonResponse.success(groupTreeNodes);
}
@Override
public CommonResponse<List<MessageGroupNodeBriefResponse>> listNodeBriefInfo(MessageGroupNodeListRequest request) {
List<MessageGroupNodeBriefResponse> groupTreeNodes = messageGroupNodeService
@ -65,4 +80,34 @@ public class MessageGroupController implements MessageGroupClient {
.collect(Collectors.toList());
return CommonResponse.success(groupTreeNodes);
}
private MessageGroupTreeNodeResponse convertCutTree(GroupTreeNodeDTO srcRootNode) {
MessageGroupTreeNodeResponse tgtRootNode = convert(srcRootNode);
if (CollectionUtils.isEmpty(srcRootNode.getNodeChildren())) {
return tgtRootNode;
}
Map<GroupTreeNodeDTO, MessageGroupTreeNodeResponse> map = Maps.newHashMap();
map.put(srcRootNode, tgtRootNode);
LinkedList<GroupTreeNodeDTO> stack = new LinkedList<>(srcRootNode.getNodeChildren());
while (!stack.isEmpty()) {
GroupTreeNodeDTO node = stack.pop();
if (TreeHelperUtil.containsMountTemplateChild(node)) {
MessageGroupTreeNodeResponse child = convert(node);
map.get(node.getParentNode()).addChild(child);
map.put(node, child);
stack.addAll(node.getNodeChildren());
}
}
return tgtRootNode;
}
private MessageGroupTreeNodeResponse convert(GroupTreeNodeDTO node) {
return MessageGroupTreeNodeResponse.builder()
.category(node.getCategory())
.nodeName(node.getNodeName())
.nodeCode(node.getNodeCode())
.nodeIcon(node.getNodeIcon())
.parentNodeCode(node.getParentNodeCode())
.build();
}
}

View File

@ -1,6 +1,5 @@
package cn.axzo.msg.center.message.service.impl;
import cn.axzo.basics.common.util.TreeUtil;
import cn.axzo.msg.center.common.enums.TableIsDeleteEnum;
import cn.axzo.msg.center.common.redis.RedisUtil;
import cn.axzo.msg.center.dal.MessageGroupNodeDao;
@ -8,6 +7,7 @@ import cn.axzo.msg.center.domain.entity.MessageGroupNode;
import cn.axzo.msg.center.message.domain.dto.GroupTreeNodePathDTO;
import cn.axzo.msg.center.message.service.MessageGroupTreeNodeCacheService;
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
import cn.axzo.msg.center.utils.TreeHelperUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
@ -145,8 +145,8 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod
}
private synchronized void initialize(boolean refreshCache) {
List<GroupTreeNodeDTO> groupNodes = listAllValidNodesFromDB();
allGroupTreesCache = TreeUtil.buildTree(groupNodes);
List<MessageGroupNode> groupNodes = listAllValidNodesFromDB();
allGroupTreesCache = TreeHelperUtil.buildTrees(groupNodes);
leafTreeNodePathsCache = allGroupTreesCache.stream()
.flatMap(e -> parseRootNode(e).stream())
.collect(Collectors.toList());
@ -155,25 +155,10 @@ public class MessageGroupTreeNodeCacheServiceImpl implements MessageGroupTreeNod
}
}
private List<GroupTreeNodeDTO> listAllValidNodesFromDB() {
private List<MessageGroupNode> listAllValidNodesFromDB() {
return messageGroupNodeDao.lambdaQuery()
.eq(MessageGroupNode::getIsDelete, TableIsDeleteEnum.NORMAL.value)
.list().stream()
.map(this::convert)
.collect(Collectors.toList());
}
private GroupTreeNodeDTO convert(MessageGroupNode groupNode) {
return GroupTreeNodeDTO.builder()
.nodeId(groupNode.getId())
.nodeName(groupNode.getName())
.nodeCode(groupNode.getCode())
.nodeIcon(groupNode.getIcon())
.category(groupNode.getCategory())
.parentNodeCode(groupNode.getParentCode())
.isLeaf(groupNode.getIsLeaf())
.status(groupNode.getStatus())
.build();
.list();
}
private List<GroupTreeNodePathDTO> parseRootNode(GroupTreeNodeDTO root) {

View File

@ -1,17 +1,17 @@
package cn.axzo.msg.center.utils;
import cn.axzo.basics.common.model.IBaseTree;
import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
import cn.axzo.msg.center.service.dto.GroupTreeNodeDTO;
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
import com.google.common.collect.Maps;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@ -22,32 +22,64 @@ import java.util.stream.Collectors;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class TreeHelperUtil {
public static <T extends IBaseTree<T, O>, O> T wrapper(GroupTreeNodeDTO treeNode,
Function<GroupTreeNodeDTO, T> wrapperFunc) {
AssertUtil.notNull(treeNode, "treeNode is null");
AssertUtil.notNull(wrapperFunc, "wrapperFunc is null");
final Map<GroupTreeNodeDTO, T> convertMap = Maps.newHashMap();
T root = wrapperFunc.apply(treeNode);
convertMap.put(treeNode, root);
LinkedList<GroupTreeNodeDTO> treeNodeStack = new LinkedList<>();
treeNodeStack.push(treeNode);
while (!treeNodeStack.isEmpty()) {
treeNode = treeNodeStack.pop();
List<GroupTreeNodeDTO> children = treeNode.getNodeChildren();
convertMap.get(treeNode).setNodeChildren(children.stream()
.map(e -> {
T wrapper = wrapperFunc.apply(e);
convertMap.put(e, wrapper);
return wrapper;
}).collect(Collectors.toList()));
treeNodeStack.addAll(children);
public static List<GroupTreeNodeDTO> buildTrees(List<MessageGroupNode> nodes) {
if (CollectionUtils.isEmpty(nodes)) {
return Collections.emptyList();
}
return root;
List<GroupTreeNodeDTO> rootNodes = nodes.stream()
.filter(e -> StringUtils.isBlank(e.getParentCode()))
.map(TreeHelperUtil::convert)
.collect(Collectors.toList());
rootNodes.forEach(e -> buildTree(e, nodes));
return rootNodes;
}
public static boolean isLeafNodeCategory(MessageGroupNodeCategoryEnum category) {
return MessageGroupNodeCategoryEnum.GENERAL_MESSAGE_CATEGORY.equals(category)
|| MessageGroupNodeCategoryEnum.PENDING_MESSAGE_CATEGORY.equals(category);
}
public static boolean containsMountTemplateChild(GroupTreeNodeDTO treeNode) {
if (Objects.isNull(treeNode)) {
return false;
}
if (CollectionUtils.isEmpty(treeNode.getNodeChildren())) {
return treeNode.canMountTemplate();
}
LinkedList<GroupTreeNodeDTO> stack = new LinkedList<>(treeNode.getNodeChildren());
while (!stack.isEmpty()) {
GroupTreeNodeDTO node = stack.pop();
if (node.canMountTemplate()) {
return true;
}
stack.addAll(node.getNodeChildren());
}
return false;
}
private static void buildTree(GroupTreeNodeDTO parentNode, List<MessageGroupNode> nodes) {
List<MessageGroupNode> children = nodes.stream()
.filter(e -> Objects.equals(e.getParentCode(), parentNode.getNodeCode()))
.collect(Collectors.toList());
if (children.isEmpty()) {
return;
}
children.forEach(e -> {
GroupTreeNodeDTO child = convert(e);
parentNode.addChild(child);
buildTree(child, nodes);
});
}
private static GroupTreeNodeDTO convert(MessageGroupNode groupNode) {
return GroupTreeNodeDTO.builder()
.nodeId(groupNode.getId())
.nodeName(groupNode.getName())
.nodeCode(groupNode.getCode())
.nodeIcon(groupNode.getIcon())
.category(groupNode.getCategory())
.isLeaf(groupNode.getIsLeaf())
.status(groupNode.getStatus())
.build();
}
}

View File

@ -16,6 +16,7 @@ import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@ -56,7 +57,7 @@ public class GroupTreeNodeDTO implements IBaseTree<GroupTreeNodeDTO, String>, Se
/**
* 父节点
*/
private String parentNodeCode;
private GroupTreeNodeDTO parentNode;
/**
* 是否为叶节点
*/
@ -69,7 +70,23 @@ public class GroupTreeNodeDTO implements IBaseTree<GroupTreeNodeDTO, String>, Se
* 子节点列表
*/
@Builder.Default
private List<GroupTreeNodeDTO> nodeChildren = Collections.emptyList();
private List<GroupTreeNodeDTO> nodeChildren = Lists.newArrayList();
public void addChild(GroupTreeNodeDTO child) {
if (Objects.isNull(child)) {
return;
}
if (Objects.isNull(nodeChildren)) {
nodeChildren = Lists.newArrayList();
}
nodeChildren.add(child);
child.setParentNode(this);
}
@Override
public String getParentNodeCode() {
return Optional.ofNullable(parentNode).map(GroupTreeNodeDTO::getNodeCode).orElse(null);
}
public void setNodeChildren(List<GroupTreeNodeDTO> nodeChildren) {
this.nodeChildren = Optional.ofNullable(nodeChildren).orElseGet(Collections::emptyList);
@ -83,7 +100,7 @@ public class GroupTreeNodeDTO implements IBaseTree<GroupTreeNodeDTO, String>, Se
.category(category)
.nodeName(nodeName)
.nodeCode(nodeCode)
.parentNodeCode(parentNodeCode)
.parentNodeCode(getParentNodeCode())
.nodeIcon(nodeIcon)
.children(children)
.build();

View File

@ -64,6 +64,14 @@ public interface MessageGroupClient {
@PostMapping(value = "/message/group/node/list", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<List<MessageGroupTreeNodeResponse>> list(@RequestBody MessageGroupQueryRequest request);
/**
* 查询通知/待办的分类信息
*
* @param request 分页查询相关参数
*/
@PostMapping(value = "/message/group/cutTree/list", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<List<MessageGroupTreeNodeResponse>> listCutTree(@RequestBody MessageGroupQueryRequest request);
/**
* 查询通知/待办的分类信息
*

View File

@ -47,6 +47,12 @@ public class MessageGroupClientFallback implements MessageGroupClient {
return CommonResponse.error("fall back while listing message group node");
}
@Override
public CommonResponse<List<MessageGroupTreeNodeResponse>> listCutTree(MessageGroupQueryRequest request) {
log.error("fall back while listing message group cutTree. request:{}", request);
return CommonResponse.error("fall back while listing message group cutTree");
}
@Override
public CommonResponse<List<MessageGroupNodeBriefResponse>> listNodeBriefInfo(MessageGroupNodeListRequest request) {
log.error("fall back while listing message group node brief info. request:{}", request);

View File

@ -2,11 +2,13 @@ package cn.axzo.msg.center.service.group.response;
import cn.axzo.msg.center.service.enums.MessageGroupNodeCategoryEnum;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;
import java.io.Serializable;
import java.util.List;
@ -56,6 +58,14 @@ public class MessageGroupTreeNodeResponse implements Serializable {
*/
private List<MessageGroupTreeNodeResponse> children;
public void addChild(MessageGroupTreeNodeResponse treeNode) {
if (CollectionUtils.isEmpty(children)) {
children = Lists.newArrayList();
}
children.add(treeNode);
treeNode.setParentNodeCode(this.nodeCode);
}
@Override
public String toString() {
return JSON.toJSONString(this);

View File

@ -63,10 +63,10 @@ public interface PendingMessageClient {
CommonResponse<Page<PendingMessageResponse>> pageQuery(@RequestBody @Valid PendingMessagePageRequest request);
/**
* 代办列表指定item查询
* 代办列表指定待办的查询
*
* @param request 查询相关参数
* @return 指定的item数据
* @return 指定待办
*/
@PostMapping(value = "/pending-message/record/query", produces = {MediaType.APPLICATION_JSON_VALUE})
CommonResponse<PendingMessageResponse> query(@RequestBody @Valid PendingMessageQueryRequest request);