|
|
@@ -7,8 +7,12 @@ import cn.start.tz.framework.common.exception.ErrorCode;
|
|
|
import cn.start.tz.framework.common.exception.ServiceException;
|
|
|
import cn.start.tz.framework.common.pojo.PageResult;
|
|
|
import cn.start.tz.framework.common.util.object.BeanUtils;
|
|
|
+import cn.start.tz.framework.common.util.http.HttpUtils;
|
|
|
import cn.start.tz.framework.env.core.enums.EnvEnum;
|
|
|
+import cn.start.tz.framework.excel.core.handler.SelectSheetWriteHandler;
|
|
|
+import cn.start.tz.framework.ip.core.utils.AreaUtils;
|
|
|
import cn.start.tz.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
+import cn.start.tz.module.infra.api.file.FileApi;
|
|
|
import cn.start.tz.module.member.api.user.MemberUserApi;
|
|
|
import cn.start.tz.module.member.api.user.dto.MemberUserReqVo;
|
|
|
import cn.start.tz.module.member.api.user.dto.MemberUserRespDTO;
|
|
|
@@ -38,6 +42,9 @@ import cn.start.tz.module.system.api.dict.dto.DictDataRespDTO;
|
|
|
import cn.start.tz.module.system.api.user.AdminUserApi;
|
|
|
import cn.start.tz.module.system.api.user.dto.AdminUserRespDTO;
|
|
|
import com.alibaba.excel.annotation.ExcelProperty;
|
|
|
+import com.alibaba.excel.EasyExcel;
|
|
|
+import com.alibaba.excel.converters.longconverter.LongStringConverter;
|
|
|
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import io.swagger.v3.oas.annotations.media.Schema;
|
|
|
@@ -54,6 +61,14 @@ import org.springframework.validation.annotation.Validated;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.zip.ZipEntry;
|
|
|
+import java.util.zip.ZipOutputStream;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
|
|
import static cn.start.tz.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
import static cn.start.tz.framework.common.util.json.JsonUtils.getHandleDateValue;
|
|
|
@@ -71,6 +86,12 @@ public class BoilerTaskOrderInspectionServiceImpl implements BoilerTaskOrderInsp
|
|
|
@Value("${tz.env.name}")
|
|
|
private String env;
|
|
|
|
|
|
+ @Value("${tz.minio.host}")
|
|
|
+ private String minioHost;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private FileApi fileApi;
|
|
|
+
|
|
|
@Resource
|
|
|
private RedissonClient redissonClient;
|
|
|
|
|
|
@@ -368,8 +389,190 @@ public class BoilerTaskOrderInspectionServiceImpl implements BoilerTaskOrderInsp
|
|
|
|
|
|
@Override
|
|
|
public String opinionReported(InspectionOpinionReportedVo inspectionOpinionReportedVo) {
|
|
|
- //TODO
|
|
|
- return "";
|
|
|
+ // 获取所有任务单设备报告
|
|
|
+ LambdaQueryWrapperX<BoilerTaskOrderItemReportDO> queryOrderItemReport = new LambdaQueryWrapperX<>();
|
|
|
+ queryOrderItemReport.in(BoilerTaskOrderItemReportDO::getOrderItemId, inspectionOpinionReportedVo.getOrderItemIds());
|
|
|
+ List<BoilerTaskOrderItemReportDO> taskOrderItemReportDOS = taskOrderItemReportMapper.selectList(queryOrderItemReport);
|
|
|
+
|
|
|
+ if (CollUtil.isEmpty(taskOrderItemReportDOS)) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取设备信息(包含equipCode和区域)
|
|
|
+ BoilerTaskOrderPageReqVO pageReqVO = new BoilerTaskOrderPageReqVO();
|
|
|
+ pageReqVO.setOrderItemIds(inspectionOpinionReportedVo.getOrderItemIds());
|
|
|
+ pageReqVO.setPageSize(1000);
|
|
|
+ PageResult<BoilerOrderItemPageRespVO> pageResult = boilerTaskOrderService.inspectionOpinionPage(pageReqVO);
|
|
|
+ List<BoilerOrderItemPageRespVO> taskOrderItemDOS = pageResult.getList();
|
|
|
+
|
|
|
+ Map<String, String> equipCodeMap = taskOrderItemDOS.stream()
|
|
|
+ .collect(Collectors.toMap(BoilerOrderItemPageRespVO::getId, BoilerOrderItemPageRespVO::getEquipCode, (v1, v2) -> v1));
|
|
|
+ Map<String, Integer> beDistrictMap = taskOrderItemDOS.stream()
|
|
|
+ .collect(Collectors.toMap(BoilerOrderItemPageRespVO::getId, BoilerOrderItemPageRespVO::getEquipDistrict, (v1, v2) -> v1));
|
|
|
+
|
|
|
+ // businessType=0: 仅获取意见通知书
|
|
|
+ if (Integer.valueOf(0).equals(inspectionOpinionReportedVo.getBusinessType())) {
|
|
|
+ List<BoilerTaskOrderItemReportDO> opinionReports = taskOrderItemReportDOS.stream()
|
|
|
+ .filter(x -> Integer.valueOf(400).equals(x.getReportType()) && !Integer.valueOf(200).equals(x.getTaskStatus()))
|
|
|
+ .toList();
|
|
|
+ return buildOpinionReportZip(opinionReports, equipCodeMap, beDistrictMap);
|
|
|
+ } else {
|
|
|
+ // businessType=2: 获取意见通知书 + 主报告结论
|
|
|
+ List<BoilerTaskOrderItemReportDO> opinionReports = taskOrderItemReportDOS.stream()
|
|
|
+ .filter(x -> Integer.valueOf(400).equals(x.getReportType()) && !Integer.valueOf(200).equals(x.getTaskStatus()))
|
|
|
+ .toList();
|
|
|
+ return buildOpinionReportZip(opinionReports, equipCodeMap, beDistrictMap);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String buildOpinionReportZip(List<BoilerTaskOrderItemReportDO> reports,
|
|
|
+ Map<String, String> equipCodeMap,
|
|
|
+ Map<String, Integer> beDistrictMap) {
|
|
|
+ if (CollUtil.isEmpty(reports)) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ ByteArrayOutputStream zipBaos = new ByteArrayOutputStream();
|
|
|
+ try (ZipOutputStream zipOut = new ZipOutputStream(zipBaos)) {
|
|
|
+ List<InspectionOpinionFirstReportExcelVO> excelVOS = new ArrayList<>();
|
|
|
+
|
|
|
+ Map<String, List<BoilerTaskOrderItemReportDO>> groupedByOrderItem = reports.stream()
|
|
|
+ .filter(r -> r.getOrderItemId() != null)
|
|
|
+ .collect(Collectors.groupingBy(BoilerTaskOrderItemReportDO::getOrderItemId));
|
|
|
+
|
|
|
+ for (Map.Entry<String, List<BoilerTaskOrderItemReportDO>> entry : groupedByOrderItem.entrySet()) {
|
|
|
+ String orderItemId = entry.getKey();
|
|
|
+ List<BoilerTaskOrderItemReportDO> itemReports = entry.getValue();
|
|
|
+
|
|
|
+ String equipCode = equipCodeMap.getOrDefault(orderItemId, orderItemId);
|
|
|
+ Integer beDistrict = beDistrictMap.getOrDefault(orderItemId, -1);
|
|
|
+ String beDistrictName = AreaUtils.getAreaName(beDistrict);
|
|
|
+ if (beDistrictName == null || beDistrictName.isBlank()) {
|
|
|
+ beDistrictName = "无区域";
|
|
|
+ }
|
|
|
+
|
|
|
+ for (BoilerTaskOrderItemReportDO report : itemReports) {
|
|
|
+ if (report.getIssueUrl() != null && !report.getIssueUrl().isBlank()) {
|
|
|
+ String reportUrl = minioHost + report.getIssueUrl();
|
|
|
+ try {
|
|
|
+ byte[] pdfBytes = HttpUtils.downloadPdfFromUrl(reportUrl);
|
|
|
+ String fileName = "检验意见通知文件/" + beDistrictName + "/" + report.getReportNo() + "(" + equipCode + ").pdf";
|
|
|
+ zipOut.putNextEntry(new ZipEntry(fileName));
|
|
|
+ zipOut.write(pdfBytes);
|
|
|
+ zipOut.closeEntry();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("下载PDF文件失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ InspectionOpinionFirstReportExcelVO excelVO = new InspectionOpinionFirstReportExcelVO();
|
|
|
+ excelVO.setDeDistrictName(beDistrictName);
|
|
|
+ excelVO.setOpinionType(report.getReportName());
|
|
|
+ excelVO.setEquipmentType("锅炉");
|
|
|
+ if (report.getRatifyTime() != null) {
|
|
|
+ excelVO.setDate(report.getRatifyTime().toLocalDate());
|
|
|
+ }
|
|
|
+ excelVO.setReportNo(report.getReportNo());
|
|
|
+ excelVOS.add(excelVO);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (report.getRectificationImage() != null && !report.getRectificationImage().isBlank()) {
|
|
|
+ String[] imageUrls = report.getRectificationImage().split(",");
|
|
|
+ for (String imageUrl : imageUrls) {
|
|
|
+ try {
|
|
|
+ byte[] data = fileApi.getFileByPath(imageUrl).getData();
|
|
|
+ String fileName = "检验意见通知文件/" + beDistrictName + "/" + report.getReportNo() + "(" + equipCode + ")/" + imageUrl;
|
|
|
+ zipOut.putNextEntry(new ZipEntry(fileName));
|
|
|
+ zipOut.write(data);
|
|
|
+ zipOut.closeEntry();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("下载图片文件失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (report.getRectificationUrl() != null && !report.getRectificationUrl().isBlank()) {
|
|
|
+ String[] attachmentUrls = report.getRectificationUrl().split(",");
|
|
|
+ for (String attachmentUrl : attachmentUrls) {
|
|
|
+ try {
|
|
|
+ byte[] data = fileApi.getFileByPath(attachmentUrl).getData();
|
|
|
+ String fileName = "检验意见通知文件/" + beDistrictName + "/" + report.getReportNo() + "(" + equipCode + ")/" + attachmentUrl;
|
|
|
+ zipOut.putNextEntry(new ZipEntry(fileName));
|
|
|
+ zipOut.write(data);
|
|
|
+ zipOut.closeEntry();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("下载附件文件失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (report.getRectificationVideo() != null && !report.getRectificationVideo().isBlank()) {
|
|
|
+ String[] videoUrls = report.getRectificationVideo().split(",");
|
|
|
+ for (String videoUrl : videoUrls) {
|
|
|
+ try {
|
|
|
+ byte[] data = fileApi.getFileByPath(videoUrl).getData();
|
|
|
+ String fileName = "检验意见通知文件/" + beDistrictName + "/" + report.getReportNo() + "(" + equipCode + ")/" + videoUrl;
|
|
|
+ zipOut.putNextEntry(new ZipEntry(fileName));
|
|
|
+ zipOut.write(data);
|
|
|
+ zipOut.closeEntry();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("下载视频文件失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分区域生成资料清单Excel
|
|
|
+ Map<String, List<InspectionOpinionFirstReportExcelVO>> listMap = excelVOS.stream()
|
|
|
+ .collect(Collectors.groupingBy(InspectionOpinionFirstReportExcelVO::getDeDistrictName));
|
|
|
+ for (Map.Entry<String, List<InspectionOpinionFirstReportExcelVO>> mapEntry : listMap.entrySet()) {
|
|
|
+ try {
|
|
|
+ ByteArrayOutputStream excelBaos = new ByteArrayOutputStream();
|
|
|
+ EasyExcel.write(excelBaos, InspectionOpinionFirstReportExcelVO.class)
|
|
|
+ .autoCloseStream(false)
|
|
|
+ .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
|
|
+ .registerConverter(new LongStringConverter())
|
|
|
+ .sheet("清单").doWrite(mapEntry.getValue());
|
|
|
+ String fileName = "检验意见通知文件/" + mapEntry.getKey() + "/资料清单-" + mapEntry.getKey() + ".xlsx";
|
|
|
+ zipOut.putNextEntry(new ZipEntry(fileName));
|
|
|
+ zipOut.write(excelBaos.toByteArray());
|
|
|
+ zipOut.closeEntry();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("生成区域Excel失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 总体清单Excel
|
|
|
+ try {
|
|
|
+ ByteArrayOutputStream excelBaos = new ByteArrayOutputStream();
|
|
|
+ EasyExcel.write(excelBaos, InspectionOpinionFirstReportExcelVO.class)
|
|
|
+ .autoCloseStream(false)
|
|
|
+ .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
|
|
+ .registerConverter(new LongStringConverter())
|
|
|
+ .sheet("清单").doWrite(excelVOS);
|
|
|
+ zipOut.putNextEntry(new ZipEntry("检验意见通知清单.xlsx"));
|
|
|
+ zipOut.write(excelBaos.toByteArray());
|
|
|
+ zipOut.closeEntry();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("生成总体Excel失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ zipOut.finish();
|
|
|
+
|
|
|
+ String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
|
|
|
+ String uuid = UUID.randomUUID() + ".zip";
|
|
|
+ String zipFilePath = fileApi.createFile("temp/" + datePath + "/" + uuid, zipBaos.toByteArray());
|
|
|
+ log.info("生成ZIP报告文件路径:{}", zipFilePath);
|
|
|
+ return zipFilePath;
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("创建ZIP文件失败", e);
|
|
|
+ return "";
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ zipBaos.close();
|
|
|
+ } catch (IOException ignored) {}
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|