From 25999c575dd42b4715e49d3fe57e73c2c3204ccb Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期日, 20 九月 2026 11:45:05 +0800
Subject: [PATCH] update
---
admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java | 273 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 273 insertions(+), 0 deletions(-)
diff --git a/admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java b/admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java
index 2f20254..4b6d333 100644
--- a/admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java
+++ b/admin-server/src/main/java/com/estate/expert/admin/service/impl/ReportServiceImpl.java
@@ -5,23 +5,42 @@
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.ErrorRecordRepository;
+import com.estate.expert.admin.domain.exam.task.check.CheckTask;
+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;
import com.estate.expert.admin.service.eval.EvalScoreService;
import com.estate.expert.admin.stat.report.builder.DeviceReportBuilder;
+import com.estate.expert.admin.stat.report.builder.ChengduHengtaiSystemReportBuilder;
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.DaiguanDeviceFuzzyReportData;
+import com.estate.expert.admin.stat.report.data.impl.DaiguanDeviceScoreReportData;
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;
import com.estate.expert.admin.stat.report.data.impl.SystemScoreReportData;
import com.estate.expert.common.exception.BizException;
+import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
+import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* 报告数据服务实现类
@@ -29,6 +48,12 @@
@Slf4j
@Service
public class ReportServiceImpl implements ReportService {
+
+ private static final String DAIGUAN_TECH_REMARK = "岱观科技";
+ private static final String DAIGUAN_SYSTEM_TEMPLATE_FILE = "第三方评估报告new.docx";
+ private static final String DAIGUAN_REMARK = "岱观科技";
+ private static final String DAIGUAN_DEVICE_TEMPLATE_FILE = "设备风险评估报告new.docx";
+ private static final String CHENGDU_HENGTAI_REMARK = "成都衡泰";
@Resource
private ReportTemplateService reportTemplateService;
@@ -47,6 +72,12 @@
@Resource
private ErrorRecordService errorRecordService;
+
+ @Resource
+ private ErrorRecordRepository errorRecordRepository;
+
+ @Resource
+ private CheckTaskRepository checkTaskRepository;
@Resource
private DeviceService deviceService;
@@ -116,13 +147,66 @@
return builder.buildReport(reportData, template.getConfig());
}
+ @Override
+ public void fuzzyReportPdf(Integer checkTaskId, Integer templateId, OutputStream outputStream) {
+ try (var doc = fuzzyReport(checkTaskId, templateId)) {
+ convertToPdf(doc, outputStream);
+ } catch (Exception e) {
+ log.error("生成模糊评价PDF报告失败", e);
+ throw new BizException("生成模糊评价PDF报告失败");
+ }
+ }
+
+ @Override
+ public void scoreReportPdf(Integer checkTaskId, Integer templateId, OutputStream outputStream) {
+ try (var doc = scoreReport(checkTaskId, templateId)) {
+ convertToPdf(doc, outputStream);
+ } catch (Exception e) {
+ log.error("生成打分评价PDF报告失败", e);
+ throw new BizException("生成打分评价PDF报告失败");
+ }
+ }
+
+ /**
+ * 将Word文档转换为PDF
+ * @param template Word模板
+ * @param outputStream 输出流
+ */
+ private void convertToPdf(XWPFTemplate template, OutputStream outputStream) throws Exception {
+ // 先将Word模板写入字节数组
+ ByteArrayOutputStream docOutputStream = new ByteArrayOutputStream();
+ template.write(docOutputStream);
+
+ // 从字节数组读取Word文档
+ ByteArrayInputStream docInputStream = new ByteArrayInputStream(docOutputStream.toByteArray());
+ org.apache.poi.xwpf.usermodel.XWPFDocument document = new org.apache.poi.xwpf.usermodel.XWPFDocument(docInputStream);
+
+ // 转换为PDF
+ PdfOptions options = PdfOptions.create();
+ PdfConverter.getInstance().convert(document, outputStream, options);
+
+ // 关闭资源
+ document.close();
+ docInputStream.close();
+ docOutputStream.close();
+ }
+
private ReportBuilderBase getReportBuilder(Integer templateId) {
var reportTemplate = reportTemplateService.get(templateId);
BizResultCode.BIZ_REPORT_TEMPLATE_NOT_EXIST.check(reportTemplate == null);
switch (reportTemplate.getType()) {
case ThirdPartyReport:
+ if (isChengduHengtaiTemplate(reportTemplate)) {
+ return new ChengduHengtaiSystemReportBuilder(userFileService);
+ }
+ if (isDaiguanTechTemplate(reportTemplate)) {
+ return new SystemReportBuilder(userFileService, DAIGUAN_SYSTEM_TEMPLATE_FILE);
+ }
return new SystemReportBuilder(userFileService);
case DeviceReport:
+ if (DAIGUAN_REMARK.equals(reportTemplate.getRemark())) {
+ return new DeviceReportBuilder(userFileService, DAIGUAN_DEVICE_TEMPLATE_FILE);
+ }
return new DeviceReportBuilder(userFileService);
default:
throw new BizException(BizResultCode.BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST);
@@ -139,6 +223,9 @@
var devices= deviceUsages.stream().map(DeviceUsage::getDevice).toList();
var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent();
+ var problemFrequency = buildSystemProblemFrequency(project.getId(), records);
+ var projectCheckCount = countProjectChecks(project.getId());
+
// 生成报告数据
return SystemFuzzyReportData.builder()
.reportId(evalFuzzyResult.getId())
@@ -150,6 +237,8 @@
.projectInfo(projectInfo)
.devices(devices)
.records(records)
+ .problemHazardCounts(problemFrequency.problemHazardCounts())
+ .projectCheckCount(projectCheckCount)
.build()
.generate();
}
@@ -164,6 +253,9 @@
var devices= deviceUsages.stream().map(DeviceUsage::getDevice).toList();
var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent();
+ var problemFrequency = buildSystemProblemFrequency(project.getId(), records);
+ var projectCheckCount = countProjectChecks(project.getId());
+
// 生成报告数据
return SystemScoreReportData.builder()
.reportId(evalFuzzyResult.getId())
@@ -175,8 +267,111 @@
.projectInfo(projectInfo)
.devices(devices)
.records(records)
+ .problemHazardCounts(problemFrequency.problemHazardCounts())
+ .projectCheckCount(projectCheckCount)
.build()
.generate();
+ }
+
+ private record ProblemFrequency(Map<Integer, Long> problemHazardCounts) {
+ }
+
+ private record DeviceProblemFrequency(Map<String, Long> problemHazardCounts, Map<Integer, Long> deviceCheckCounts) {
+ }
+
+ 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());
+ }
+
+ 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());
+ }
+
+ var taskIds = checkTaskRepository.listTaskIdsByProjectAndPlanState(projectId, PlanState.COMPLETE);
+ if (taskIds == null || taskIds.isEmpty()) {
+ return new ProblemFrequency(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());
+ }
+
+ return new ProblemFrequency(hazardCounts);
+ }
+
+ private DeviceProblemFrequency buildDeviceProblemFrequency(Integer projectId, Integer clientId) {
+ var taskIds = listTaskIdsByProjectAndClient(projectId, clientId);
+ if (taskIds.isEmpty()) {
+ return new DeviceProblemFrequency(Collections.emptyMap(), Collections.emptyMap());
+ }
+
+ Map<String, Long> hazardCounts = new HashMap<>();
+ for (var row : errorRecordRepository.countDeviceHazardsByTaskIds(taskIds)) {
+ collectDeviceProblemFrequency(row, hazardCounts);
+ }
+
+ Map<Integer, Long> deviceCheckCounts = buildDeviceCheckFrequencyByCompletedTasks(projectId, clientId);
+
+ return new DeviceProblemFrequency(hazardCounts, deviceCheckCounts);
+ }
+
+ private void collectDeviceProblemFrequency(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 Map<Integer, Long> buildDeviceCheckFrequencyByCompletedTasks(Integer projectId, Integer clientId) {
+ if (projectId == null || clientId == null) {
+ return Collections.emptyMap();
+ }
+ var tasks = checkTaskRepository.listClosedByProjectAndClient(projectId, clientId);
+ if (tasks == null || tasks.isEmpty()) {
+ return Collections.emptyMap();
+ }
+ Map<Integer, Long> deviceCheckCounts = new HashMap<>();
+ for (CheckTask task : tasks) {
+ for (Integer deviceId : collectTaskCheckedDeviceIds(task)) {
+ deviceCheckCounts.merge(deviceId, 1L, Long::sum);
+ }
+ }
+ return deviceCheckCounts;
+ }
+
+ private Set<Integer> collectTaskCheckedDeviceIds(CheckTask task) {
+ Set<Integer> deviceIds = new HashSet<>();
+ if (task == null) {
+ return deviceIds;
+ }
+ addDeviceIds(task.getDeviceFuzzyMap(), deviceIds);
+ addDeviceIds(task.getDeviceScoreMap(), deviceIds);
+ return deviceIds;
+ }
+
+ private void addDeviceIds(Map<Integer, Float> deviceMap, Set<Integer> target) {
+ if (deviceMap == null || deviceMap.isEmpty()) {
+ return;
+ }
+ for (Integer deviceId : deviceMap.keySet()) {
+ if (deviceId == null) {
+ continue;
+ }
+ target.add(deviceId);
+ }
}
private JSONObject buildFuzzyDeviceReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult, ReportTemplate reportTemplate) {
@@ -187,6 +382,24 @@
var deviceIds = evalFuzzyResult.getDeviceResMap().keySet();
var devices = deviceService.findAllById(deviceIds);
var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent();
+ var clientId = project.getClient() != null ? project.getClient().getId() : null;
+ var problemFrequency = buildDeviceProblemFrequency(project.getId(), clientId);
+
+ if (isDaiguanTemplate(reportTemplate)) {
+ return DaiguanDeviceFuzzyReportData.builder()
+ .reportId(evalFuzzyResult.getId())
+ .deviceResMap(evalFuzzyResult.getDeviceResMap())
+ .deviceHierarchy(hierarchy)
+ .template(reportTemplate)
+ .project(project)
+ .projectInfo(projectInfo)
+ .devices(devices)
+ .records(records)
+ .deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
+ .deviceCheckCounts(problemFrequency.deviceCheckCounts())
+ .build()
+ .generate();
+ }
// 生成报告数据
return DeviceFuzzyReportData.builder()
@@ -198,6 +411,8 @@
.projectInfo(projectInfo)
.devices(devices)
.records(records)
+ .deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
+ .deviceCheckCounts(problemFrequency.deviceCheckCounts())
.build()
.generate();
}
@@ -210,6 +425,25 @@
var deviceIds = evalFuzzyResult.getDeviceResMap().keySet();
var devices = deviceService.findAllById(deviceIds);
var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent();
+ var clientId = project.getClient() != null ? project.getClient().getId() : null;
+ var problemFrequency = buildDeviceProblemFrequency(project.getId(), clientId);
+
+ if (isDaiguanTemplate(reportTemplate)) {
+ return DaiguanDeviceScoreReportData.builder()
+ .reportId(evalFuzzyResult.getId())
+ .deviceResMap(evalFuzzyResult.getDeviceResMap())
+ .deviceScoreResMap(evalScoreResult.getDeviceResMap())
+ .deviceHierarchy(hierarchy)
+ .template(reportTemplate)
+ .project(project)
+ .projectInfo(projectInfo)
+ .devices(devices)
+ .records(records)
+ .deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
+ .deviceCheckCounts(problemFrequency.deviceCheckCounts())
+ .build()
+ .generate();
+ }
// 生成报告数据
return DeviceScoreReportData.builder()
@@ -222,10 +456,49 @@
.projectInfo(projectInfo)
.devices(devices)
.records(records)
+ .deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
+ .deviceCheckCounts(problemFrequency.deviceCheckCounts())
.build()
.generate();
}
+ private List<Integer> listTaskIdsByProjectAndClient(Integer projectId, Integer clientId) {
+ if (projectId == null || clientId == null) {
+ return Collections.emptyList();
+ }
+ var taskIds = checkTaskRepository.listTaskIdsByProjectAndClient(projectId, clientId);
+ if (taskIds == null) {
+ return Collections.emptyList();
+ }
+ return taskIds;
+ }
+ private boolean isDaiguanTemplate(ReportTemplate reportTemplate) {
+ return reportTemplate != null && DAIGUAN_REMARK.equals(reportTemplate.getRemark());
+ }
+
+ private boolean isDaiguanTechTemplate(ReportTemplate reportTemplate) {
+ if (reportTemplate == null || reportTemplate.getRemark() == null) {
+ return false;
+ }
+ return DAIGUAN_TECH_REMARK.equals(reportTemplate.getRemark().trim());
+ }
+
+ private boolean isChengduHengtaiTemplate(ReportTemplate reportTemplate) {
+ return reportTemplate != null
+ && reportTemplate.getRemark() != null
+ && CHENGDU_HENGTAI_REMARK.equals(reportTemplate.getRemark().trim());
+ }
+
+ private long countProjectChecks(Integer projectId) {
+ if (projectId == null) {
+ return 0L;
+ }
+ var taskIds = checkTaskRepository.listTaskIdsByProjectAndPlanState(projectId, PlanState.COMPLETE);
+ if (taskIds == null) {
+ return 0L;
+ }
+ return taskIds.size();
+ }
}
--
Gitblit v1.7.1