package com.estate.expert.admin.service.impl;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.deepoove.poi.XWPFTemplate;
|
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;
|
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.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;
|
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.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* 报告数据服务实现类
|
**/
|
@Slf4j
|
@Service
|
public class ReportServiceImpl implements ReportService {
|
|
@Resource
|
private ReportTemplateService reportTemplateService;
|
|
@Resource
|
private ProjectInfoService projectInfoService;
|
|
@Resource
|
private DeviceUsageService deviceUsageService;
|
|
@Resource
|
private EvalFuzzyService evalFuzzyService;
|
|
@Resource
|
private EvalScoreService evalScoreService;
|
|
@Resource
|
private ErrorRecordService errorRecordService;
|
|
@Resource
|
private ErrorRecordRepository errorRecordRepository;
|
|
@Resource
|
private RecordRepository recordRepository;
|
|
@Resource
|
private CheckTaskRepository checkTaskRepository;
|
|
@Resource
|
private DeviceService deviceService;
|
|
@Resource
|
private UserFileService userFileService;
|
|
@Override
|
public JSONObject fuzzyReportData(Integer checkTaskId, Integer templateId) {
|
var evalFuzzyResult = evalFuzzyService.getByCheckTaskId(checkTaskId);
|
BizResultCode.EVAL_FUZZY_RESULT_NOT_EXIST.check(evalFuzzyResult == null);
|
|
var evalScoreResult = evalScoreService.getByCheckTaskId(checkTaskId);
|
BizResultCode.EVAL_SCORE_RESULT_NOT_EXIST.check(evalScoreResult == null);
|
|
var reportTemplate = reportTemplateService.get(templateId);
|
BizResultCode.BIZ_REPORT_TEMPLATE_NOT_EXIST.check(reportTemplate == null);
|
|
switch (reportTemplate.getType()) {
|
case ThirdPartyReport:
|
return buildFuzzySystemReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
|
case DeviceReport:
|
return buildFuzzyDeviceReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
|
default:
|
throw new BizException(BizResultCode.BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST);
|
}
|
}
|
|
@Override
|
public JSONObject scoreReportData(Integer checkTaskId, Integer templateId) {
|
var evalFuzzyResult = evalFuzzyService.getByCheckTaskId(checkTaskId);
|
BizResultCode.EVAL_FUZZY_RESULT_NOT_EXIST.check(evalFuzzyResult == null);
|
|
var evalScoreResult = evalScoreService.getByCheckTaskId(checkTaskId);
|
BizResultCode.EVAL_SCORE_RESULT_NOT_EXIST.check(evalScoreResult == null);
|
|
var reportTemplate = reportTemplateService.get(templateId);
|
BizResultCode.BIZ_REPORT_TEMPLATE_NOT_EXIST.check(reportTemplate == null);
|
|
switch (reportTemplate.getType()) {
|
case ThirdPartyReport:
|
return buildScoreSystemReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
|
case DeviceReport:
|
return buildScoreDeviceReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
|
default:
|
throw new BizException(BizResultCode.BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST);
|
}
|
}
|
|
@Override
|
public XWPFTemplate fuzzyReport(Integer checkTaskId, Integer templateId) {
|
var reportData = fuzzyReportData(checkTaskId, templateId);
|
var builder = getReportBuilder(templateId);
|
var template = reportTemplateService.get(templateId);
|
|
// reportData to JSONObject
|
return builder.buildReport(reportData, template.getConfig());
|
}
|
|
@Override
|
public XWPFTemplate scoreReport(Integer checkTaskId, Integer templateId) {
|
var reportData = scoreReportData(checkTaskId, templateId);
|
var builder = getReportBuilder(templateId);
|
var template = reportTemplateService.get(templateId);
|
|
// reportData to JSONObject
|
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:
|
return new SystemReportBuilder(userFileService);
|
case DeviceReport:
|
return new DeviceReportBuilder(userFileService);
|
default:
|
throw new BizException(BizResultCode.BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST);
|
}
|
}
|
|
private JSONObject buildFuzzySystemReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult, ReportTemplate reportTemplate) {
|
// 查询必须要的数据
|
var records = errorRecordService.listSystemErrors(evalFuzzyResult.getTask().getId());
|
var project = evalFuzzyResult.getProject();
|
var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
|
// var projectInfo = projectInfoService.getByCheckTaskId(evalFuzzyResult.getTask().getId());
|
var deviceUsages = deviceUsageService.listUsages(project.getId(), null);
|
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())
|
.systemHierarchy(hierarchy)
|
.sysResult(evalFuzzyResult.getSystemRes())
|
.scoreResult(scoreResult.getSystemRes())
|
.template(reportTemplate)
|
.project(project)
|
.projectInfo(projectInfo)
|
.devices(devices)
|
.records(records)
|
.problemHazardCounts(problemFrequency.problemHazardCounts())
|
.problemCheckCounts(problemFrequency.problemCheckCounts())
|
.build()
|
.generate();
|
}
|
|
private JSONObject buildScoreSystemReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult, ReportTemplate reportTemplate) {
|
// 查询必须要的数据
|
var records = errorRecordService.listSystemErrors(evalFuzzyResult.getTask().getId());
|
var project = evalFuzzyResult.getProject();
|
// var projectInfo = projectInfoService.latest(evalFuzzyResult.getProject().getId());
|
var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
|
var deviceUsages = deviceUsageService.listUsages(project.getId(), null);
|
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())
|
.systemHierarchy(hierarchy)
|
.sysResult(evalFuzzyResult.getSystemRes())
|
.scoreResult(scoreResult.getSystemRes())
|
.template(reportTemplate)
|
.project(project)
|
.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) {
|
var records = errorRecordService.listDeviceErrors(evalFuzzyResult.getTask().getId());
|
var project = evalFuzzyResult.getProject();
|
var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
|
// var projectInfo = projectInfoService.getByCheckTaskId(evalFuzzyResult.getTask().getId());
|
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()
|
.reportId(evalFuzzyResult.getId())
|
.deviceResMap(evalFuzzyResult.getDeviceResMap())
|
.deviceHierarchy(hierarchy)
|
.template(reportTemplate)
|
.project(project)
|
.projectInfo(projectInfo)
|
.devices(devices)
|
.records(records)
|
.deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
|
.deviceProblemCheckCounts(problemFrequency.problemCheckCounts())
|
.build()
|
.generate();
|
}
|
|
private JSONObject buildScoreDeviceReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult evalScoreResult, ReportTemplate reportTemplate) {
|
var records = errorRecordService.listDeviceErrors(evalFuzzyResult.getTask().getId());
|
var project = evalFuzzyResult.getProject();
|
// var projectInfo = projectInfoService.getByCheckTaskId(evalFuzzyResult.getTask().getId());
|
var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
|
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()
|
.reportId(evalFuzzyResult.getId())
|
.deviceResMap(evalFuzzyResult.getDeviceResMap())
|
.deviceScoreResMap(evalScoreResult.getDeviceResMap())
|
.deviceHierarchy(hierarchy)
|
.template(reportTemplate)
|
.project(project)
|
.projectInfo(projectInfo)
|
.devices(devices)
|
.records(records)
|
.deviceProblemHazardCounts(problemFrequency.problemHazardCounts())
|
.deviceProblemCheckCounts(problemFrequency.problemCheckCounts())
|
.build()
|
.generate();
|
}
|
|
|
|
}
|