package com.estate.expert.admin.stat.report.data; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.estate.expert.admin.domain.business.device.Device; import com.estate.expert.admin.domain.business.device.DeviceType; import com.estate.expert.admin.domain.exam.eval.fuzzy.FuzzyResult; import com.estate.expert.admin.domain.exam.record.error.ErrorLevel; 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 org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.TreeMap; /** * 设备风险评估报告数据 */ @SuperBuilder public abstract class DeviceReportData extends ReportDataBase { List records; protected Map deviceResMap; TreeRoot deviceHierarchy; Map deviceProblemHazardCounts; Map deviceProblemCheckCounts; /** * 生成报告数据 * @return 报告数据 */ public JSONObject generate() { var result = buildReportInfo(); result.put("工程概况", buildProjectInfo()); result.put("设备信息", buildDeviceInfo()); result.put("评估结果", buildEvalInfo()); return result; } /** * 构建评估信息 * @return 评估信息 */ @Override protected JSONObject buildEvalInfo() { JSONObject evalInfo = new JSONObject(); evalInfo.put("分类评估", buildDeviceTypeCheckItem()); evalInfo.put("隐患等级分布汇总", buildDeviceErrorLevels()); return evalInfo; } // 按照设备类型分组 /** * 构建设备类型检查项 * @return 设备类型检查项 */ private JSONObject buildDeviceTypeCheckItem() { JSONObject result = new JSONObject(); var details = new ArrayList<>(); float totalScore = 0; int totalTypes = 0; int totalDevices = 0; for (var deviceType : DeviceType.values()) { var detail = buildDeviceTypeCheckDetail(deviceType); if (detail != null) { details.add(detail); totalTypes++; totalScore += Float.parseFloat((String) detail.get("分数")); totalDevices += (int) detail.get("数量"); } } result.put("详情", details); result.put("总数", totalTypes); result.put("设备总数", totalDevices); result.put("总分", formatFloat(totalScore / totalTypes)); return result; } /** * 获取设备分数 * @param deviceId 设备ID * @return 设备分数 */ protected abstract float getDeviceScore(Integer deviceId); /** * 构建设备类型检查项详情 * @param deviceType 设备类型 * @return 设备类型检查项详情 */ private JSONObject buildDeviceTypeCheckDetail(DeviceType deviceType) { int totalDevice = 0; float totalScore = 0; List deviceCheckItems = new ArrayList<>(); JSONArray records = new JSONArray(); int [] totalErrors = new int[4]; for(var deviceId: deviceResMap.keySet()){ var device = devices.stream().filter(d -> d.getId().equals(deviceId)).findFirst().orElse(null); if (device == null || device.getType() != deviceType) continue; // 汇总分数 var deviceData = deviceResMap.get(deviceId).root().getData(); totalScore += getDeviceScore(deviceId); totalDevice++; for(int i = 0; i < 4; i++){ totalErrors[i] += deviceData.getTotalErrorCounts()[i]; } var c = buildDeviceErrorLevels(device); if(c != null){ deviceCheckItems.addAll(c); } var r = buildDeviceErrorRecords(device); if(r != null){ records.addAll(r); } } if(totalDevice > 0){ JSONObject info = new JSONObject(); info.put("设备类型", deviceType.getDesc()); info.put("数量", totalDevice); info.put("分数", formatFloat(totalScore / totalDevice)); info.put("分项隐患", deviceCheckItems); info.put("分项问题", records); info.put("一级隐患", totalErrors[0]); info.put("二级隐患", totalErrors[1]); info.put("三级隐患", totalErrors[2]); info.put("四级隐患", totalErrors[3]); return info; } return null; } /** * 构建设备错误级别 * @return 设备错误级别 */ private JSONObject buildDeviceErrorLevels(){ int totalErrors = 0; var totalErrorCounts = new int[4]; for (var device : devices) { var deviceRes = deviceResMap.get(device.getId()); if (deviceRes == null) { continue; } var deviceErrorCounts = deviceRes.root().getData().getTotalErrorCounts(); for (int i = 0; i < 4; i++) { totalErrorCounts[i] += deviceErrorCounts[i]; totalErrors += deviceErrorCounts[i]; } } List errorInfos = new ArrayList<>(); for (int i = 0; i< 4; i++) { var errorLevel = ErrorLevel.values()[i]; var count = totalErrorCounts[i]; var info = new TreeMap<>(); info.put("隐患等级", errorLevel.getDesc()); info.put("隐患程度", errorLevel.getDesc2()); info.put("数量", count); info.put("比例", formatPercent(count * 1.0 / totalErrors)); errorInfos.add(info); } JSONObject result = new JSONObject(); result.put("隐患数量", totalErrors); result.put("分项", errorInfos); return result; } // 按照设备分组 /** * 构建设备错误级别 * @param device 设备 * @return 设备错误级别 */ private List buildDeviceErrorLevels(Device device){ var deviceRes = deviceResMap.get(device.getId()); if (deviceRes == null) { return null; } List result = new ArrayList<>(); JSONObject info = new JSONObject(); info.put("设备编号", device.getManufacturerNumber()); var errorCounts = deviceRes.root().getData().getTotalErrorCounts(); info.put("一级隐患", errorCounts[0]); info.put("二级隐患", errorCounts[1]); info.put("三级隐患", errorCounts[2]); info.put("四级隐患", errorCounts[3]); result.add(info); return result; } // 按照设备分组 /** * 构建设备错误记录 * @param device 设备 * @return 设备错误记录 */ private List buildDeviceErrorRecords(Device device){ var deviceRes = deviceResMap.get(device.getId()); if (deviceRes == null) { return null; } List result = new ArrayList<>(); JSONObject info = new JSONObject(); info.put("设备编号", device.getManufacturerNumber()); info.put("问题", buildDeviceErrorInfo(device)); result.add(info); return result; } /** * 构建设备错误信息 * @param device 设备 * @return 设备错误信息 */ private List buildDeviceErrorInfo(Device device){ var deviceRecords = buildDeviceRecords(device); List result = new ArrayList<>(); for (var record : deviceRecords) { JSONObject info = new JSONObject(); // 检查问题列:默认为问题备注,当问题备注为空时,填写问题描述(与安全报告一致) info.put("检查问题", StringUtils.hasText(record.getRemark()) ? record.getRemark() : record.getProblem().getDescription()); info.put("隐患等级", record.getLevel().getDesc()); info.put("同类隐患出现频次", getDeviceProblemHazardCount(record)); info.put("检查频次", getDeviceProblemCheckCount(record)); var subItem = buildRecordDetail(record); subItem.put("项目级别", errorNode(record).getName()); info.put("问题详情", subItem); result.add(info); } return result; } private long getDeviceProblemHazardCount(ErrorRecord record) { if (deviceProblemHazardCounts == null) { return 0L; } return deviceProblemHazardCounts.getOrDefault(buildDeviceProblemKey(record), 0L); } private long getDeviceProblemCheckCount(ErrorRecord record) { if (deviceProblemCheckCounts == null) { return 0L; } return deviceProblemCheckCounts.getOrDefault(buildDeviceProblemKey(record), 0L); } private String buildDeviceProblemKey(ErrorRecord record) { Integer deviceId = record != null && record.getDevice() != null ? record.getDevice().getId() : null; Integer problemId = record != null && record.getProblem() != null ? record.getProblem().getId() : null; return buildDeviceProblemKey(deviceId, problemId); } public static String buildDeviceProblemKey(Integer deviceId, Integer problemId) { return Objects.toString(deviceId, "") + "::" + Objects.toString(problemId, ""); } /** * 构建设备记录 * @param device 设备 * @return 设备记录 */ private List buildDeviceRecords(Device device){ return records.stream() .filter(r -> r.getDevice().getId().equals(device.getId())) .sorted(Comparator.comparing(r -> r.getLevel() != null ? r.getLevel().ordinal() : ErrorLevel.P4.ordinal())) .toList(); } /** * 构建错误节点 * @param record 错误记录 * @return 错误节点 */ protected TreeNode errorNode(ErrorRecord record){ var hierarchyPath = record.getProblem().getHierarchyPath(); return deviceHierarchy.get(hierarchyPath); } }