package com.estate.expert.admin.stat.report.data;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.estate.expert.admin.domain.exam.eval.fuzzy.FuzzyResult;
|
import com.estate.expert.admin.domain.exam.eval.fuzzy.FuzzyValue;
|
import com.estate.expert.admin.domain.exam.eval.score.ScoreResult;
|
import com.estate.expert.admin.domain.exam.eval.score.ScoreValue;
|
import com.estate.expert.admin.domain.exam.record.error.ErrorRecord;
|
import com.estate.expert.admin.domain.standard.hierachy.HierarchyData;
|
import com.estate.expert.admin.utils.tree.TreeNode;
|
import com.estate.expert.admin.utils.tree.TreeRoot;
|
import lombok.experimental.SuperBuilder;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Comparator;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
/**
|
* 第三方评估报告数据
|
*/
|
@Slf4j
|
@SuperBuilder
|
public abstract class SystemReportData extends ReportDataBase {
|
|
List<ErrorRecord> records;
|
|
TreeRoot<HierarchyData> systemHierarchy;
|
|
protected FuzzyResult sysResult;
|
|
protected ScoreResult scoreResult;
|
|
Map<Integer, Long> problemHazardCounts;
|
|
long projectCheckCount;
|
|
// 评估结果
|
@Override
|
protected JSONObject buildEvalInfo() {
|
JSONObject evalInfo = new JSONObject();
|
|
evalInfo.put("综合信息", buildAbstractInfo());
|
evalInfo.put("检查项", buildCheckItems());
|
evalInfo.put("隐患等级分布", buildErrorLevel(getFuzzyRoot()));
|
|
return evalInfo;
|
}
|
|
/**
|
* 获取模糊根节点
|
* @return 模糊根节点
|
*/
|
protected TreeNode<FuzzyValue> getFuzzyRoot(){
|
if(sysResult == null)
|
return null;
|
return sysResult.root();
|
}
|
|
protected TreeNode<ScoreValue> getScoreRoot(){
|
if(scoreResult == null)
|
return null;
|
return scoreResult.root();
|
}
|
|
/**
|
* 根据路径获取对应的模糊节点
|
* @param path 节点路径
|
* @return 模糊节点,如果不存在则返回null
|
*/
|
protected TreeNode<FuzzyValue> getFuzzyNodeByPath(String path) {
|
if(sysResult == null || path == null)
|
return null;
|
return sysResult.get(path);
|
}
|
|
/**
|
* 构建摘要信息
|
* @return 摘要信息
|
*/
|
protected abstract JSONObject buildAbstractInfo();
|
|
/**
|
* 构建节点
|
* @param info 信息
|
* @param node 节点
|
*/
|
protected abstract void buildNode(JSONObject info, TreeNode<ScoreValue> node);
|
|
/**
|
* 构建检查项
|
* @return 检查项
|
*/
|
protected JSONArray buildCheckItems(){
|
var root = getScoreRoot();
|
var result = new JSONArray();
|
if(root == null)
|
return result;
|
root.getChildren().values().forEach(node -> {
|
var item = buildCheckItem(node);
|
if(item!=null)
|
result.add(item);
|
});
|
return result;
|
}
|
|
// 处理检查项
|
/**
|
* 构建检查项
|
* @param node 节点
|
* @return 检查项
|
*/
|
private JSONObject buildCheckItem(TreeNode<ScoreValue> node){
|
if(node == null || node.getData().getTotalErrorCounts() == null)
|
return null;
|
|
var totalErrors = Arrays.stream(node.getData().getTotalErrorCounts()).sum();
|
if(totalErrors == 0)
|
return null;
|
|
JSONObject result = new JSONObject();
|
result.put("名称", node.getName());
|
buildNode(result, node);
|
|
var cfuzzyNode = getFuzzyNodeByPath(node.getPath());
|
if(cfuzzyNode != null){
|
result.put("模糊评价", cfuzzyNode.getData().getRiskLevel().getDesc());
|
result.put("模糊得分", formatFloat(cfuzzyNode.getData().getScore()));
|
}
|
|
var categoryItems = new ArrayList<>();
|
AtomicInteger index = new AtomicInteger();
|
List<Object> itemInfos = new ArrayList<>();
|
|
for(var child : node.getChildren().values()) {
|
for(var c : child.getChildren().values()) {
|
for(var n : c.getChildren().values()) {
|
var errorInfos = buildErrorInfo(n.getPath());
|
// if(CollectionUtils.isEmpty(errorInfos))
|
// continue;
|
|
JSONObject info = new JSONObject();
|
info.put("类别", n.getName());
|
info.put("序号", index.getAndIncrement() + 1);
|
buildNode(info, n);
|
|
// 从fuzzyNode中获取评价
|
var fuzzyNode = getFuzzyNodeByPath(n.getPath());
|
if(fuzzyNode != null && fuzzyNode.getData() != null && fuzzyNode.getData().getRiskLevel() != null) {
|
info.put("评价", fuzzyNode.getData().getRiskLevel().getDesc());
|
info.put("模糊得分", formatFloat(fuzzyNode.getData().getScore()));
|
} else {
|
info.put("评价", n.getData().getScore());
|
info.put("模糊得分", "-");
|
}
|
|
int errorCnt = Arrays.stream(n.getData().getTotalErrorCounts()).sum();
|
info.put("问题数量", errorCnt);
|
info.put("问题百分比", formatPercent(errorCnt * 1.0 / totalErrors));
|
|
info.put("问题", errorInfos);
|
itemInfos.add(info);
|
}
|
}
|
}
|
|
JSONObject categoryItem = new JSONObject();
|
categoryItem.put("类别", "合并项目");
|
categoryItem.put("分项", itemInfos);
|
categoryItems.add(categoryItem);
|
|
result.put("问题合计数量", totalErrors);
|
result.put("分项评估", categoryItems);
|
return result;
|
}
|
|
/**
|
* 构建错误信息
|
* @param nodePath 节点路径
|
* @return 错误信息
|
*/
|
protected List<Object> buildErrorInfo(String nodePath) {
|
var suffix = nodePath + "/";
|
var errors = new ArrayList<>();
|
// 按 problem.id 去重,相同问题只保留第一个记录
|
var nodeRecords = records.stream()
|
.filter(record -> record.getProblem() != null &&
|
record.getProblem().getHierarchyPath() != null &&
|
record.getProblem().getHierarchyPath().startsWith(suffix))
|
.collect(java.util.stream.Collectors.toMap(
|
record -> record.getProblem().getId(),
|
record -> record,
|
(existing, replacement) -> existing // 保留第一个遇到的记录
|
))
|
.values()
|
.stream()
|
// 按照record.errorLevel排序
|
.sorted(Comparator.comparing(ErrorRecord::getLevel, Comparator.nullsLast(Comparator.naturalOrder())))
|
.toList();
|
|
for(var record : nodeRecords){
|
var subItem = buildRecordDetail(record);
|
subItem.put("项目级别", errorNodeName(record));
|
subItem.put("同类隐患出现频次", getProblemHazardCount(record));
|
subItem.put("检查频次", getProblemCheckCount(record));
|
errors.add(subItem);
|
}
|
return errors;
|
}
|
|
private long getProblemHazardCount(ErrorRecord record) {
|
var problemId = record != null && record.getProblem() != null ? record.getProblem().getId() : null;
|
if (problemId == null || problemHazardCounts == null) {
|
return 0L;
|
}
|
return problemHazardCounts.getOrDefault(problemId, 0L);
|
}
|
|
private long getProblemCheckCount(ErrorRecord record) {
|
return Math.max(projectCheckCount, 0L);
|
}
|
|
/**
|
* 构建错误节点名称
|
* @param record 记录
|
* @return 错误节点名称
|
*/
|
protected String errorNodeName(ErrorRecord record){
|
var hierarchyPath = record.getProblem().getHierarchyPath();
|
return systemHierarchy.get(hierarchyPath).getName();
|
}
|
}
|