admin-server/src/main/java/com/estate/expert/admin/domain/exam/record/RecordRepository.java
New file @@ -0,0 +1,29 @@ package com.estate.expert.admin.domain.exam.record; import com.estate.expert.admin.domain.common.EntityBaseRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; public interface RecordRepository extends EntityBaseRepository<Record> { @Query("select r.problem.id, count(r) from Record r " + "where r.deleted = false " + "and r.device is null " + "and r.problem is not null " + "and r.problem.id in :problemIds " + "and r.checkTask.id in :taskIds " + "group by r.problem.id") List<Object[]> countSystemChecksByTaskIdsAndProblemIds(@Param("taskIds") List<Integer> taskIds, @Param("problemIds") List<Integer> problemIds); @Query(value = "select r.device_id, r.problem_id, count(*) " + "from record r " + "where r.deleted = false " + "and r.device_id is not null " + "and r.problem_id is not null " + "and r.check_task_id in (:taskIds) " + "group by r.device_id, r.problem_id", nativeQuery = true) List<Object[]> countDeviceChecksByTaskIds(@Param("taskIds") List<Integer> taskIds); } admin-server/src/main/java/com/estate/expert/admin/domain/exam/record/error/ErrorRecordRepository.java
@@ -99,6 +99,39 @@ "and w.deleted = false") List<ErrorRecord> listDeviceErrors(Integer checkTaskId); @Query("select w.problem.id, count(w) from ErrorRecord w " + "where w.deleted = false " + "and w.device is null " + "and w.level is not null " + "and w.problem is not null " + "and w.problem.id in :problemIds " + "and w.checkTask.project.id = :projectId " + "and w.checkTask.state in :taskStates " + "group by w.problem.id") List<Object[]> countSystemHazardsByProjectAndProblemIds(@Param("projectId") Integer projectId, @Param("taskStates") List<com.estate.expert.admin.domain.exam.task.check.CheckTaskState> taskStates, @Param("problemIds") List<Integer> problemIds); @Query("select w.problem.id, count(w) from ErrorRecord w " + "where w.deleted = false " + "and w.device is null " + "and w.problem is not null " + "and w.problem.id in :problemIds " + "and w.checkTask.id in :taskIds " + "group by w.problem.id") List<Object[]> countSystemHazardsByTaskIdsAndProblemIds(@Param("taskIds") List<Integer> taskIds, @Param("problemIds") List<Integer> problemIds); @Query(value = "select r.device_id, r.problem_id, count(*) " + "from record r " + "where r.deleted = false " + "and r.device_id is not null " + "and r.problem_id is not null " + "and r.record_type = 'error' " + "and r.check_task_id in (:taskIds) " + "group by r.device_id, r.problem_id", nativeQuery = true) List<Object[]> countDeviceHazardsByTaskIds(@Param("taskIds") List<Integer> taskIds); //根据人员来获取检查成果 @Query("select w from ErrorRecord w where w.deleted = false and w.creator.id = :creatorId"+ " and ( :startDate is null or w.createTime >= :startDate) " + "and ( :endDate is null or w.createTime < :endDate) " ) admin-server/src/main/java/com/estate/expert/admin/domain/exam/record/warning/WarningRecordRepository.java
@@ -24,6 +24,18 @@ "order by w.updateTime desc") List<WarningRecord> list(Integer checkTaskId); @Query("select w.problem.id, count(w) from WarningRecord w " + "where w.deleted = false " + "and w.device is null " + "and w.problem is not null " + "and w.problem.id in :problemIds " + "and w.checkTask.project.id = :projectId " + "and w.checkTask.state in :taskStates " + "group by w.problem.id") List<Object[]> countSystemWarningsByProjectAndProblemIds(@Param("projectId") Integer projectId, @Param("taskStates") List<com.estate.expert.admin.domain.exam.task.check.CheckTaskState> taskStates, @Param("problemIds") List<Integer> problemIds); @Query("select w from WarningRecord w where ( :clientId is null or w.checkTask.project.client.id = :clientId) " + "and ( :planId is null or w.checkTask.plan.id = :planId) " + "and ( :taskId is null or w.checkTask.id = :taskId) " + admin-server/src/main/java/com/estate/expert/admin/domain/exam/task/check/CheckTaskRepository.java
@@ -1,7 +1,9 @@ package com.estate.expert.admin.domain.exam.task.check; import com.estate.expert.admin.domain.common.EntityBaseRepository; import com.estate.expert.admin.domain.plan.PlanState; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; @@ -56,4 +58,12 @@ List<CheckTask> findAllByPlanIdAndDeleted(Integer planId, boolean deleted); CheckTask getFirstByPlanIdAndProjectIdAndDeleted(Integer planId, Integer projectId, boolean deleted); @Query("select t.id from CheckTask t " + "where t.deleted = false " + "and t.project.id = :projectId " + "and t.plan.deleted = false " + "and t.plan.state = :planState") List<Integer> listTaskIdsByProjectAndPlanState(@Param("projectId") Integer projectId, @Param("planState") PlanState planState); } admin-server/src/main/java/com/estate/expert/admin/domain/role/PermissionData.java
@@ -25,6 +25,11 @@ Permission.of("accidentMessageSetting", "status", "禁用启用_简讯号"), Permission.of("accidentMessageSetting", Permission.OP_DELETE, "删除_简讯") ) ,"项目进度设置", List.of( Permission.of("projectProgress", Permission.OP_ADD, "新增_进度"), Permission.of("projectProgress", Permission.OP_EDIT, "编辑_进度"), Permission.of("projectProgress", Permission.OP_DELETE, "删除_进度") ) ), "人事管理", mapN( "用户管理", List.of( admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java
@@ -5,7 +5,12 @@ import com.estate.expert.admin.domain.business.device.usage.DeviceUsage; import com.estate.expert.admin.domain.exam.eval.fuzzy.EvalFuzzyResult; import com.estate.expert.admin.domain.exam.eval.score.EvalScoreResult; import com.estate.expert.admin.domain.exam.record.error.ErrorRecord; import com.estate.expert.admin.domain.exam.record.error.ErrorRecordRepository; import com.estate.expert.admin.domain.exam.record.RecordRepository; import com.estate.expert.admin.domain.exam.task.check.CheckTaskRepository; import com.estate.expert.admin.domain.report.ReportTemplate; import com.estate.expert.admin.domain.plan.PlanState; import com.estate.expert.admin.enums.BizResultCode; import com.estate.expert.admin.service.*; import com.estate.expert.admin.service.eval.EvalFuzzyService; @@ -13,6 +18,7 @@ import com.estate.expert.admin.stat.report.builder.DeviceReportBuilder; import com.estate.expert.admin.stat.report.builder.ReportBuilderBase; import com.estate.expert.admin.stat.report.builder.SystemReportBuilder; import com.estate.expert.admin.stat.report.data.DeviceReportData; import com.estate.expert.admin.stat.report.data.impl.DeviceFuzzyReportData; import com.estate.expert.admin.stat.report.data.impl.DeviceScoreReportData; import com.estate.expert.admin.stat.report.data.impl.SystemFuzzyReportData; @@ -27,6 +33,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 报告数据服务实现类 @@ -52,6 +62,15 @@ @Resource private ErrorRecordService errorRecordService; @Resource private ErrorRecordRepository errorRecordRepository; @Resource private RecordRepository recordRepository; @Resource private CheckTaskRepository checkTaskRepository; @Resource private DeviceService deviceService; @@ -188,6 +207,8 @@ var devices= deviceUsages.stream().map(DeviceUsage::getDevice).toList(); var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent(); var problemFrequency = buildSystemProblemFrequency(project.getId(), records); // 生成报告数据 return SystemFuzzyReportData.builder() .reportId(evalFuzzyResult.getId()) @@ -199,6 +220,8 @@ .projectInfo(projectInfo) .devices(devices) .records(records) .problemHazardCounts(problemFrequency.problemHazardCounts()) .problemCheckCounts(problemFrequency.problemCheckCounts()) .build() .generate(); } @@ -213,6 +236,8 @@ var devices= deviceUsages.stream().map(DeviceUsage::getDevice).toList(); var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent(); var problemFrequency = buildSystemProblemFrequency(project.getId(), records); // 生成报告数据 return SystemScoreReportData.builder() .reportId(evalFuzzyResult.getId()) @@ -224,8 +249,87 @@ .projectInfo(projectInfo) .devices(devices) .records(records) .problemHazardCounts(problemFrequency.problemHazardCounts()) .problemCheckCounts(problemFrequency.problemCheckCounts()) .build() .generate(); } private record ProblemFrequency(Map<Integer, Long> problemHazardCounts, Map<Integer, Long> problemCheckCounts) { } private record DeviceProblemFrequency(Map<String, Long> problemHazardCounts, Map<String, Long> problemCheckCounts) { } private ProblemFrequency buildSystemProblemFrequency(Integer projectId, List<com.estate.expert.admin.domain.exam.record.error.ErrorRecord> currentTaskRecords) { if (projectId == null || currentTaskRecords == null || currentTaskRecords.isEmpty()) { return new ProblemFrequency(Collections.emptyMap(), Collections.emptyMap()); } var problemIds = currentTaskRecords.stream() .map(r -> r.getProblem() != null ? r.getProblem().getId() : null) .filter(java.util.Objects::nonNull) .distinct() .toList(); if (problemIds.isEmpty()) { return new ProblemFrequency(Collections.emptyMap(), Collections.emptyMap()); } var taskIds = checkTaskRepository.listTaskIdsByProjectAndPlanState(projectId, PlanState.COMPLETE); if (taskIds == null || taskIds.isEmpty()) { return new ProblemFrequency(Collections.emptyMap(), Collections.emptyMap()); } Map<Integer, Long> hazardCounts = new HashMap<>(); for (var row : errorRecordRepository.countSystemHazardsByTaskIdsAndProblemIds(taskIds, problemIds)) { if (row == null || row.length < 2 || row[0] == null || row[1] == null) { continue; } hazardCounts.put(((Number) row[0]).intValue(), ((Number) row[1]).longValue()); } Map<Integer, Long> checkCounts = new HashMap<>(); for (var row : recordRepository.countSystemChecksByTaskIdsAndProblemIds(taskIds, problemIds)) { if (row == null || row.length < 2 || row[0] == null || row[1] == null) { continue; } checkCounts.put(((Number) row[0]).intValue(), ((Number) row[1]).longValue()); } return new ProblemFrequency(hazardCounts, checkCounts); } private DeviceProblemFrequency buildDeviceProblemFrequency(Integer projectId) { if (projectId == null) { return new DeviceProblemFrequency(Collections.emptyMap(), Collections.emptyMap()); } var taskIds = checkTaskRepository.listTaskIdsByProjectAndPlanState(projectId, PlanState.COMPLETE); if (taskIds == null || taskIds.isEmpty()) { return new DeviceProblemFrequency(Collections.emptyMap(), Collections.emptyMap()); } Map<String, Long> hazardCounts = new HashMap<>(); for (var row : errorRecordRepository.countDeviceHazardsByTaskIds(taskIds)) { collectDeviceFrequency(row, hazardCounts); } Map<String, Long> checkCounts = new HashMap<>(); for (var row : recordRepository.countDeviceChecksByTaskIds(taskIds)) { collectDeviceFrequency(row, checkCounts); } return new DeviceProblemFrequency(hazardCounts, checkCounts); } private void collectDeviceFrequency(Object[] row, Map<String, Long> target) { if (row == null || row.length < 3 || row[0] == null || row[2] == null) { return; } Integer deviceId = ((Number) row[0]).intValue(); Integer problemId = row[1] == null ? null : ((Number) row[1]).intValue(); Long count = ((Number) row[2]).longValue(); target.put(DeviceReportData.buildDeviceProblemKey(deviceId, problemId), count); } private JSONObject buildFuzzyDeviceReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult, ReportTemplate reportTemplate) { @@ -236,6 +340,7 @@ var deviceIds = evalFuzzyResult.getDeviceResMap().keySet(); var devices = deviceService.findAllById(deviceIds); var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent(); var problemFrequency = buildDeviceProblemFrequency(project.getId()); // 生成报告数据 return DeviceFuzzyReportData.builder() @@ -247,6 +352,8 @@ .projectInfo(projectInfo) .devices(devices) .records(records) .deviceProblemHazardCounts(problemFrequency.problemHazardCounts()) .deviceProblemCheckCounts(problemFrequency.problemCheckCounts()) .build() .generate(); } @@ -259,6 +366,7 @@ var deviceIds = evalFuzzyResult.getDeviceResMap().keySet(); var devices = deviceService.findAllById(deviceIds); var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent(); var problemFrequency = buildDeviceProblemFrequency(project.getId()); // 生成报告数据 return DeviceScoreReportData.builder() @@ -271,6 +379,8 @@ .projectInfo(projectInfo) .devices(devices) .records(records) .deviceProblemHazardCounts(problemFrequency.problemHazardCounts()) .deviceProblemCheckCounts(problemFrequency.problemCheckCounts()) .build() .generate(); } admin-server/src/main/java/com/estate/expert/admin/stat/report/data/DeviceReportData.java
@@ -17,6 +17,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.TreeMap; /** @@ -30,6 +31,10 @@ protected Map<Integer, FuzzyResult> deviceResMap; TreeRoot<HierarchyData> deviceHierarchy; Map<String, Long> deviceProblemHazardCounts; Map<String, Long> deviceProblemCheckCounts; /** * 生成报告数据 @@ -241,6 +246,8 @@ // 检查问题列:默认为问题备注,当问题备注为空时,填写问题描述(与安全报告一致) 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); @@ -249,6 +256,30 @@ 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 设备 admin-server/src/main/java/com/estate/expert/admin/stat/report/data/SystemReportData.java
@@ -17,6 +17,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** @@ -33,6 +34,10 @@ protected FuzzyResult sysResult; protected ScoreResult scoreResult; Map<Integer, Long> problemHazardCounts; Map<Integer, Long> problemCheckCounts; // 评估结果 @Override @@ -200,11 +205,29 @@ 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) { var problemId = record != null && record.getProblem() != null ? record.getProblem().getId() : null; if (problemId == null || problemCheckCounts == null) { return 0L; } return problemCheckCounts.getOrDefault(problemId, 0L); } /** * 构建错误节点名称 * @param record 记录 admin-server/src/main/java/com/estate/expert/admin/stat/report/render/CheckInfoTablePolicy.java
@@ -93,6 +93,28 @@ RenderHelper.renderCell(row, info.getString("问题百分比")); } }break; case 6: { if(isErrorSummary){ // 问题汇总表(新增两列:同类隐患出现频次、检查频次) var errors = info.getJSONArray("问题"); if(!CollectionUtils.isEmpty(errors)){ var highLevelColor = RenderHelper.highLevelColor(errors); for(var error : errors){ var e = (JSONObject) error; var row = table.insertNewTableRow(table.getRows().size()); var errorLevel = e.getString("隐患等级"); var textColor = RenderHelper.getErrorLevelColor(errorLevel); RenderHelper.renderCell(row, info.getString("类别"), highLevelColor); RenderHelper.renderCell(row, e.getString("问题部位"), textColor); RenderHelper.renderCell(row, e.getString("问题备注"), textColor); RenderHelper.renderCell(row, e.getString("隐患等级"), textColor); RenderHelper.renderCell(row, String.valueOf(e.getLongValue("同类隐患出现频次")), textColor); RenderHelper.renderCell(row, String.valueOf(e.getLongValue("检查频次")), textColor); } } } }break; default: break; } admin-server/src/main/java/com/estate/expert/admin/stat/report/render/DeviceTablePolicy.java
@@ -20,6 +20,7 @@ @Override public void render(XWPFTable table, Object data) throws Exception { var deviceRecords = (JSONArray) data; int colCnt = table.getRow(1).getTableCells().size(); for (var d : deviceRecords) { var deviceInfo = (JSONObject) d; var records = deviceInfo.getJSONArray("问题"); @@ -34,6 +35,10 @@ RenderHelper.renderCell(row, name, highLevelColor); RenderHelper.renderCell(row, info.getString("检查问题"), textColor); RenderHelper.renderCell(row, info.getString("隐患等级"), textColor); if (colCnt >= 5) { RenderHelper.renderCell(row, String.valueOf(info.getLongValue("同类隐患出现频次")), textColor); RenderHelper.renderCell(row, String.valueOf(info.getLongValue("检查频次")), textColor); } } } } admin-server/src/main/resources/templates/第三方评估报告.docxBinary files differ
admin-server/src/main/resources/templates/设备风险评估报告.docxBinary files differ