Merge branch 'refs/heads/master' into feature/REQ-2655
This commit is contained in:
commit
1bc9bb0e67
@ -21,6 +21,10 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.taobao.arthas</groupId>
|
||||
<artifactId>arthas-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.trade</groupId>
|
||||
<artifactId>trade-web-spring-boot-starter</artifactId>
|
||||
|
||||
@ -3,7 +3,10 @@ package cn.axzo.msg.center.message.service.group;
|
||||
import cn.axzo.maokai.api.vo.response.tree.NodeValue;
|
||||
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
|
||||
import cn.axzo.msg.center.utils.TreeHelperUtil;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
@ -16,6 +19,13 @@ public class NodeWrapper implements NodeValue {
|
||||
|
||||
private final MessageGroupNode node;
|
||||
private final Map<String, Long> code2Id;
|
||||
/**
|
||||
* cache path for better performance
|
||||
* visit via {@link RootNodeWrapper#getPath}
|
||||
*/
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private String cachedPath;
|
||||
|
||||
@Override
|
||||
public Long id() {
|
||||
|
||||
@ -1,22 +1,17 @@
|
||||
package cn.axzo.msg.center.message.service.group;
|
||||
|
||||
import cn.axzo.maokai.api.util.Ref;
|
||||
import cn.axzo.maokai.api.vo.response.tree.Node;
|
||||
import cn.axzo.maokai.api.vo.response.tree.RootNode;
|
||||
import cn.axzo.maokai.api.vo.response.tree.ValueNode;
|
||||
import cn.axzo.msg.center.common.utils.BizAssertions;
|
||||
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.function.Function.identity;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
@ -25,13 +20,14 @@ import static java.util.stream.Collectors.toMap;
|
||||
*/
|
||||
public class RootNodeWrapper {
|
||||
|
||||
private final RootNode<NodeWrapper> root;
|
||||
private final Map<String, ValueNode<NodeWrapper>> code2Node;
|
||||
private final Map<Long, ValueNode<NodeWrapper>> id2Node;
|
||||
|
||||
public RootNodeWrapper(RootNode<NodeWrapper> root) {
|
||||
this.root = root;
|
||||
RootNodeWrapper(RootNode<NodeWrapper> root) {
|
||||
this.code2Node = root.getValueNodes().stream()
|
||||
.collect(toMap(node -> node.getValue().getNodeCode(), Function.identity()));
|
||||
.collect(toMap(node -> node.getValue().getNodeCode(), identity()));
|
||||
this.id2Node = root.getValueNodes().stream()
|
||||
.collect(toMap(node -> node.getValue().unwrap().getId(), identity()));
|
||||
}
|
||||
|
||||
public Optional<ValueNode<NodeWrapper>> findValueNode(String groupNodeCode) {
|
||||
@ -39,18 +35,7 @@ public class RootNodeWrapper {
|
||||
}
|
||||
|
||||
public Optional<ValueNode<NodeWrapper>> findValueNode(Long id) {
|
||||
Ref<ValueNode<NodeWrapper>> ref = Ref.create();
|
||||
unwrap().walkDown(node -> {
|
||||
//noinspection unchecked
|
||||
ValueNode<NodeWrapper> valueNode = node.tryCast(ValueNode.class);
|
||||
if (valueNode == null)
|
||||
return true;
|
||||
MessageGroupNode groupNode = valueNode.getValue().unwrap();
|
||||
if (id.equals(groupNode.getId()))
|
||||
ref.set(valueNode);
|
||||
return ref.isNull();
|
||||
});
|
||||
return Optional.ofNullable(ref.get());
|
||||
return Optional.ofNullable(id2Node.get(id));
|
||||
}
|
||||
|
||||
public List<ValueNode<NodeWrapper>> getNodes(Collection<String> groupNodeCodes) {
|
||||
@ -63,24 +48,33 @@ public class RootNodeWrapper {
|
||||
}
|
||||
|
||||
public String getPath(ValueNode<NodeWrapper> node) {
|
||||
ArrayList<String> paths = new ArrayList<>();
|
||||
NodeWrapper wrapper = node.getValue();
|
||||
if (wrapper.getCachedPath() == null)
|
||||
wrapper.setCachedPath(getPathImpl(node));
|
||||
return wrapper.getCachedPath();
|
||||
}
|
||||
|
||||
private String getPathImpl(ValueNode<NodeWrapper> node) {
|
||||
// a1912618861c4dab8aaee954069762a0:a1912618861c4dab8aaee954069762a1:a1912618861c4dab8aaee954069762a2
|
||||
// code是uuid去掉-, 一般层级为3, 通过冒号分割, 所有长度为: 32 * 3 + 2 = 98
|
||||
// 初始长度直接设置为98, 避免频繁扩容
|
||||
StringBuilder builder = new StringBuilder(98);
|
||||
Node current = node;
|
||||
int stack = 0;
|
||||
while (current != null) {
|
||||
BizAssertions.assertTrue(stack <= 500, String.format(
|
||||
"分类层级过多或者数据错误, 最大层级: %s", JSON.toJSONString(current)));
|
||||
// Assuming a reasonable maximum depth to avoid frequent resizing
|
||||
BizAssertions.assertTrue(stack <= 500, "分类层级过多或者数据错误");
|
||||
stack++;
|
||||
//noinspection unchecked
|
||||
@SuppressWarnings("unchecked")
|
||||
ValueNode<NodeWrapper> valueNode = current.tryCast(ValueNode.class);
|
||||
if (valueNode != null)
|
||||
paths.add(valueNode.getValue().getNodeCode());
|
||||
if (valueNode != null) {
|
||||
if (builder.length() > 0)
|
||||
builder.insert(0, ":");
|
||||
builder.insert(0, valueNode.getValue().getNodeCode());
|
||||
}
|
||||
current = current.getParent();
|
||||
}
|
||||
Collections.reverse(paths);
|
||||
return String.join(":", paths);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public RootNode<NodeWrapper> unwrap() {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@ -7,8 +7,9 @@ import cn.axzo.msg.center.message.service.group.NodeWrapper;
|
||||
import cn.axzo.msg.center.service.enums.TodoType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yanglin
|
||||
@ -20,32 +21,24 @@ class LeafNodeStats {
|
||||
private final List<Todo> stats;
|
||||
private final GroupTemplates groupTemplates;
|
||||
|
||||
int getCount(ValueNode<NodeWrapper> node, TodoType todoType) {
|
||||
return getCount(Collections.singletonList(node), todoType);
|
||||
}
|
||||
|
||||
int getCount(List<ValueNode<NodeWrapper>> nodes, TodoType todoType) {
|
||||
int count = 0;
|
||||
Map<TodoType, Integer> collectStat(ValueNode<NodeWrapper> node) {
|
||||
HashMap<TodoType, Integer> type2Count = new HashMap<>();
|
||||
for (Todo stat : stats) {
|
||||
if (stat.getType() != todoType)
|
||||
continue;
|
||||
// 只统计叶子节点的数据, 显示列表不关心中间节点
|
||||
boolean leafNodeContainsTemplate = nodes.stream()
|
||||
.map(ValueNode::getValue)
|
||||
.filter(NodeWrapper::isLeaf)
|
||||
.anyMatch(node -> groupTemplates
|
||||
.groupContainsTemplate(node.getNodeCode(), stat.getTemplateCode()));
|
||||
if (leafNodeContainsTemplate)
|
||||
count += stat.getCount();
|
||||
boolean leafNodeContainsTemplate = groupTemplates.groupContainsTemplate(
|
||||
node.getValue().getNodeCode(), stat.getTemplateCode());
|
||||
if (leafNodeContainsTemplate) {
|
||||
Integer prevCount = type2Count.get(stat.getType());
|
||||
if (prevCount == null) prevCount = 0;
|
||||
Integer currentCount = prevCount + stat.getCount();
|
||||
type2Count.put(stat.getType(), currentCount);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int getCount(TodoType todoType) {
|
||||
return stats.stream()
|
||||
.filter(s -> s.getType() == todoType)
|
||||
.mapToInt(Todo::getCount)
|
||||
.sum();
|
||||
for (TodoType type : TodoType.values()) {
|
||||
if (!type2Count.containsKey(type))
|
||||
type2Count.put(type, 0);
|
||||
}
|
||||
return type2Count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static cn.axzo.msg.center.inside.notices.utils.Queries.query;
|
||||
@ -273,9 +274,10 @@ public class TodoRangeQueryService {
|
||||
groupStat.setGroupCode(node.getCode());
|
||||
groupStat.setGroupName(node.getName());
|
||||
groupStat.setGroupIcon(node.getIcon());
|
||||
Map<TodoType, Integer> type2Count = nodeStats.collectStat(valueNode);
|
||||
groupStat.setStat(new Stat(
|
||||
nodeStats.getCount(valueNode, TodoType.EXECUTABLE),
|
||||
nodeStats.getCount(valueNode, TodoType.COPIED_TO_ME)));
|
||||
type2Count.get(TodoType.EXECUTABLE),
|
||||
type2Count.get(TodoType.COPIED_TO_ME)));
|
||||
}
|
||||
PendingMessageStatisticResponseV2 resp = new PendingMessageStatisticResponseV2();
|
||||
resp.addGroupStats(stats);
|
||||
|
||||
5
pom.xml
5
pom.xml
@ -95,6 +95,11 @@
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.taobao.arthas</groupId>
|
||||
<artifactId>arthas-spring-boot-starter</artifactId>
|
||||
<version>3.7.1</version>
|
||||
</dependency>
|
||||
<!-- 子项目会直接继承的公共依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
||||
@ -17,7 +17,10 @@ spring:
|
||||
web:
|
||||
resources:
|
||||
add-mappings: false
|
||||
|
||||
arthas:
|
||||
app-name: ${spring.application.name}
|
||||
agent-id: ${ARTHAS_AGENT_ID:${spring.profiles.active}-${spring.application.name}}
|
||||
tunnel-server: ${ARTHAS_TUNNEL_SERVER:ws://localhost:7777/ws}
|
||||
# redis:
|
||||
# #外网地址和端口 禁止使用外网地址,会导致jenkins 部署 服务起不来
|
||||
# #host: 123.249.44.111
|
||||
|
||||
Loading…
Reference in New Issue
Block a user