diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/controller/BmReportController.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/controller/BmReportController.java index 6d126922..52a7fd9a 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/controller/BmReportController.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/controller/BmReportController.java @@ -9,16 +9,34 @@ import com.bonus.common.core.web.controller.BaseController; import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.material.basic.domain.report.*; import com.bonus.material.basic.service.BmReportService; +import com.bonus.material.common.utils.DocxUtil; +import com.bonus.material.common.utils.HttpFileUtil; +import com.bonus.material.part.domain.PartTypeCheckInfo; +import com.bonus.material.part.domain.PartTypeQueryDto; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.poi.util.IOUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.URLEncoder; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.LinkedHashMap; + +import static com.bonus.common.core.web.page.TableSupport.PAGE_NUM; +import static com.bonus.common.core.web.page.TableSupport.PAGE_SIZE; /** * @Author ma_sh @@ -568,4 +586,153 @@ public class BmReportController extends BaseController { ExcelUtil util = new ExcelUtil<>(ScrapDetailsInfo.class); util.exportExcel(response, list, "设备追溯查询-报废报表详情查询"); } + + + /** + * 报告查询 + */ + @ApiOperation("报告查询") + @GetMapping("/reportList") + public AjaxResult reportList(ReportQuery bean) { + final List list = bmReportService.getReportList(bean); + final Integer pageIndex = Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1); + final Integer pageSize = Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10); + return AjaxResult.success(ListPagingUtil.paging(pageIndex, pageSize, list)); + } + + @PostMapping("/downloadSingle") + public void downloadSingle(@RequestBody DownloadRequest request, HttpServletResponse response) throws IOException { + handleDownload(request, response); + } + + @PostMapping("/downloadBulk") + public void downloadBulk(@RequestBody DownloadRequest request, HttpServletResponse response) throws IOException { + String zipName = request.getZipName() != null ? request.getZipName() : "报告下载_" + LocalDate.now(); + String encoded = URLEncoder.encode(zipName + ".zip", "UTF-8"); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + + try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(response.getOutputStream())) { + + // 按工程 + 领用日期分组 + Map>> grouped = request.getItems().stream() + .collect(Collectors.groupingBy( + item -> sanitize(item.getProName()), // 工程 + LinkedHashMap::new, + Collectors.groupingBy(item -> sanitize(item.getTestTime()), LinkedHashMap::new, Collectors.toList()) // 日期 + )); + + for (Map.Entry>> projectEntry : grouped.entrySet()) { + String projectFolder = projectEntry.getKey(); + Map> dateMap = projectEntry.getValue(); + + for (Map.Entry> dateEntry : dateMap.entrySet()) { + String dateFolder = dateEntry.getKey(); + List items = dateEntry.getValue(); + String baseDatePath = projectFolder + "/" + dateFolder + "/"; + + // 1. 生成合并的出库检验报告 + byte[] mergedReport = DocxUtil.generateReportByList(items); + addToZip(zipOut, baseDatePath + "出库检验报告.docx", mergedReport); + + // 2. 遍历每个类型-规格,创建文件夹并添加附加文件 + Map> typeMap = items.stream() + .collect(Collectors.groupingBy(item -> sanitize(item.getTypeName() + "-" + item.getTypeModelName()))); + + for (Map.Entry> typeEntry : typeMap.entrySet()) { + String typeFolder = typeEntry.getKey(); + String typePath = baseDatePath + typeFolder + "/"; + + // **先创建空文件夹** + ZipArchiveEntry folderEntry = new ZipArchiveEntry(typePath); + zipOut.putArchiveEntry(folderEntry); + zipOut.closeArchiveEntry(); + + // 再添加附加文件(如果存在) + for (DownloadRequest.ItemInfo item : typeEntry.getValue()) { + addFileIfExists(zipOut, typePath, "合格证", item.getQualifiedUrl()); + addFileIfExists(zipOut, typePath, "型式试验报告", item.getTestReportUrl()); + addFileIfExists(zipOut, typePath, "第三方检测报告", item.getThirdReportUrl()); + addFileIfExists(zipOut, typePath, "出厂检测报告", item.getFactoryReportUrl()); + addFileIfExists(zipOut, typePath, "其他文件", item.getOtherReportUrl()); + } + } + } + } + + zipOut.finish(); + } + } + + + /** 将多条 ItemInfo 转成生成报告需要的列表 */ + private static List flattenItemMap(Map> typeMap) { + List list = new ArrayList<>(); + typeMap.values().forEach(list::addAll); + return list; + } + + + + private void handleDownload(DownloadRequest request, HttpServletResponse response) throws IOException { + String zipName = request.getZipName() != null ? request.getZipName() : "报告下载"; + String encoded = URLEncoder.encode(zipName + ".zip", "UTF-8"); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + + try (ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(response.getOutputStream())) { + for (DownloadRequest.ItemInfo item : request.getItems()) { + String projectFolder = sanitize(item.getProName()); + String matFolder = sanitize(item.getTypeName() + "-" + item.getTypeModelName()); + String basePath = projectFolder + "/" + matFolder + "/"; + + // 1. 生成出库检验报告.docx + byte[] docBytes = DocxUtil.generateReport(item); + addToZip(zipOut, basePath + "出库检验报告.docx", docBytes); + + // 2. 附加各类报告文件 + addFileIfExists(zipOut, basePath, "合格证", item.getQualifiedUrl()); + addFileIfExists(zipOut, basePath, "型式试验报告", item.getTestReportUrl()); + addFileIfExists(zipOut, basePath, "第三方检测报告", item.getThirdReportUrl()); + addFileIfExists(zipOut, basePath, "出厂检测报告", item.getFactoryReportUrl()); + addFileIfExists(zipOut, basePath, "其他文件", item.getOtherReportUrl()); + } + zipOut.finish(); + } + } + + private void addFileIfExists(ZipArchiveOutputStream zipOut, String base, String name, String url) { + if (url == null || url.isEmpty()) { + return; + } + try { + byte[] bytes = HttpFileUtil.downloadFile(url); + if (bytes != null) { + addToZip(zipOut, base + name + getFileExtension(url), bytes); + } + } catch (Exception e) { + System.err.println("跳过文件:" + url + " -> " + e.getMessage()); + } + } + + private void addToZip(ZipArchiveOutputStream zipOut, String path, byte[] bytes) throws IOException { + ZipArchiveEntry entry = new ZipArchiveEntry(path); + zipOut.putArchiveEntry(entry); + try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) { + IOUtils.copy(in, zipOut); + } + zipOut.closeArchiveEntry(); + } + + private String sanitize(String name) { + if (name == null) { + return "未知"; + } + return name.replaceAll("[\\\\/:*?\"<>|]", "_"); + } + + private String getFileExtension(String url) { + int idx = url.lastIndexOf('.'); + return (idx > 0 && idx < url.length() - 1) ? url.substring(idx) : ""; + } } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/domain/report/DownloadRequest.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/domain/report/DownloadRequest.java new file mode 100644 index 00000000..39849a7f --- /dev/null +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/domain/report/DownloadRequest.java @@ -0,0 +1,66 @@ +package com.bonus.material.basic.domain.report; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class DownloadRequest { + private String zipName; + private List items; + + @Data + public static class ItemInfo { + private String taskId; + private String id; + private String proName; + private String typeName; + private String typeModelName; + private String qualifiedUrl; + private String testReportUrl; + private String thirdReportUrl; + private String factoryReportUrl; + private String otherReportUrl; + /** + * 分公司 + */ + private String impUnitName; + + /** + * 项目部 + */ + private String departName; + @ApiModelProperty(value = "计量单位") + private String unit; + + @ApiModelProperty(value = "数量") + private BigDecimal num; + + @ApiModelProperty(value = "编码") + private String maCode; + + @ApiModelProperty("额定载荷") + private String ratedLoad; + + @ApiModelProperty("试验载荷") + private String testLoad; + + @ApiModelProperty("持荷时间") + private String holdingTime; + + @ApiModelProperty("试验日期") + private String testTime; + + @ApiModelProperty("下次试验日期") + private String nextTestTime; + + @ApiModelProperty("验收结论") + private String checkResult; + + @ApiModelProperty("备注") + private String remark; + + } +} diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/domain/report/ReportQuery.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/domain/report/ReportQuery.java new file mode 100644 index 00000000..f450bf30 --- /dev/null +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/domain/report/ReportQuery.java @@ -0,0 +1,144 @@ +package com.bonus.material.basic.domain.report; + +import com.bonus.common.core.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class ReportQuery { + + private Long id; + + /** + * 分公司 + */ + private String impUnitName; + + /** + * 项目部 + */ + private String departName; + + /** + * 工程 + */ + private String proName; + + @ApiModelProperty(value = "物资名称") + private String typeName; + + @ApiModelProperty(value = "规格型号") + private String typeModelName; + + @ApiModelProperty(value = "计量单位") + private String unit; + + @ApiModelProperty(value = "数量") + private BigDecimal num; + + @ApiModelProperty(value = "编码") + private String maCode; + + @ApiModelProperty(value="二维码") + private String qrCode; + + /** + * 领用日期 + */ + private String leaseTime; + + /** + * 合格证文件名称 + */ + private String qualifiedName; + /** + * 合格证文件路径 + */ + private String qualifiedUrl; + /** + * 型式试验报告文件名称 + */ + private String testReportName; + /** + * 型式试验报告文件路径 + */ + private String testReportUrl; + /** + * 出厂检测报告名称 + */ + private String factoryReportName; + /** + * 出厂检测报告路径 + */ + private String factoryReportUrl; + /** + * 第三方检测报告名称 + */ + private String thirdReportName; + /** + * 第三方检测报告路径 + */ + private String thirdReportUrl; + /** + * 其他报告名称 + */ + private String otherReportName; + /** + * 其他报告路径 + */ + private String otherReportUrl; + + @ApiModelProperty(value="开始时间") + private String startTime; + + @ApiModelProperty(value="结束时间") + private String endTime; + + private String keyword; + + @ApiModelProperty(value = "设备ID") + private Long maId; + + /** 类型ID */ + @ApiModelProperty(value = "类型ID") + private Long typeId; + + @ApiModelProperty(value = "任务ID") + private Long taskId; + + /** + * i8工程id集合 + */ + private List projectIdList; + + @ApiModelProperty(value = "实施单位id") + private String impUnit; + + @ApiModelProperty("机具类型(1机具,2安全工器具)") + private String jiJuType; + + @ApiModelProperty("额定载荷") + private String ratedLoad; + + @ApiModelProperty("试验载荷") + private String testLoad; + + @ApiModelProperty("持荷时间") + private String holdingTime; + + @ApiModelProperty("试验日期") + private String testTime; + + @ApiModelProperty("下次试验日期") + private String nextTestTime; + + @ApiModelProperty("验收结论") + private String checkResult; + + @ApiModelProperty("备注") + private String remark; + +} diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/mapper/BmReportMapper.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/mapper/BmReportMapper.java index a6bce0ce..600e8f75 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/mapper/BmReportMapper.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/mapper/BmReportMapper.java @@ -124,4 +124,11 @@ public interface BmReportMapper { * @return */ String selectUserNameById(String repairPersonName); + + /** + * 报表查询 + * @param bean + * @return + */ + List getReportList(ReportQuery bean); } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/BmReportService.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/BmReportService.java index 01187019..eb02ff41 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/BmReportService.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/BmReportService.java @@ -116,4 +116,11 @@ public interface BmReportService { * @return */ List getScrapDetailsList(ScrapInfo bean); + + /** + * 报表查询 + * @param bean + * @return + */ + List getReportList(ReportQuery bean); } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/impl/BmReportServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/impl/BmReportServiceImpl.java index 231927f0..079525f4 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/impl/BmReportServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/basic/service/impl/BmReportServiceImpl.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -389,6 +390,16 @@ public class BmReportServiceImpl implements BmReportService { return bmReportMapper.getScrapDetailsList(bean); } + @Override + public List getReportList(ReportQuery bean) { + try { + return bmReportMapper.getReportList(bean); + } catch (Exception e) { + e.printStackTrace(); + return new ArrayList<>(); + } + } + /** * 判断字符串是否为纯数字(可用于判断是否为用户ID) */ diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/common/utils/DocxUtil.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/common/utils/DocxUtil.java new file mode 100644 index 00000000..96acf0ab --- /dev/null +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/common/utils/DocxUtil.java @@ -0,0 +1,256 @@ +package com.bonus.material.common.utils; + +import com.bonus.material.basic.domain.report.DownloadRequest; +import org.apache.poi.xwpf.usermodel.*; +import org.apache.poi.util.Units; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; + +import java.io.*; +import java.math.BigInteger; +import java.util.List; + +/** + * 出库检验报告生成工具类(横向 A4) + * 格式与模板一致,页面为横向,且带印章 + */ +public class DocxUtil { + + public static byte[] generateReport(DownloadRequest.ItemInfo item) { + try (XWPFDocument doc = new XWPFDocument(); ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + + // ===== 页面方向设为横向 ===== + CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr(); + CTPageSz pageSize = sectPr.addNewPgSz(); + pageSize.setOrient(STPageOrientation.LANDSCAPE); + pageSize.setW(BigInteger.valueOf(16840)); // A4横向宽 + pageSize.setH(BigInteger.valueOf(11900)); // A4横向高 + + // ===== 标题 ===== + XWPFParagraph title = doc.createParagraph(); + title.setAlignment(ParagraphAlignment.CENTER); + XWPFRun runTitle = title.createRun(); + runTitle.setText("施工机具设备出库检验记录表"); + runTitle.setBold(true); + runTitle.setFontFamily("宋体"); + runTitle.setFontSize(16); + + // ===== 工程、单位信息 ===== + XWPFParagraph info = doc.createParagraph(); + info.setAlignment(ParagraphAlignment.LEFT); + XWPFRun runInfo = info.createRun(); + runInfo.setFontFamily("宋体"); + runInfo.setFontSize(12); + runInfo.setText("领用工程:" + safe(item.getProName()) + " 使用单位:" + safe(item.getDepartName())); + runInfo.addBreak(); + + // ===== 表格(1标题行 + 数据行) ===== + int colNum = 12; + XWPFTable table = doc.createTable(1, colNum); + table.setWidth("100%"); + + // 表头文字 + String[] headers = { + "机具名称", "规格型号", "单位", "数量", "设备编码", + "额定载荷KN", "试验载荷KN", "持荷时间min", + "试验日期", "下次试验日期", "检验结论", "备注" + }; + + // 设置表头样式 + XWPFTableRow headerRow = table.getRow(0); + for (int i = 0; i < headers.length; i++) { + XWPFTableCell cell = headerRow.getCell(i); + setCellText(cell, headers[i], true); + } + + // 数据行 + XWPFTableRow dataRow = table.createRow(); + String[] values = { + safe(item.getTypeName()), + safe(item.getTypeModelName()), + safe(item.getUnit()), + safe(String.valueOf(item.getNum())), + safe(item.getMaCode()), + safe(item.getRatedLoad()), + safe(item.getTestLoad()), + safe(item.getHoldingTime()), + safe(item.getTestTime()), + safe(item.getNextTestTime()), + safe(item.getCheckResult()), + safe(item.getRemark()) + }; + + for (int i = 0; i < colNum; i++) { + XWPFTableCell cell = dataRow.getCell(i); + setCellText(cell, values[i], false); + } + + // ===== 检验单位 ===== + XWPFParagraph footer = doc.createParagraph(); + footer.setAlignment(ParagraphAlignment.LEFT); + footer.setSpacingBefore(400); + XWPFRun runFooter = footer.createRun(); + runFooter.setFontFamily("宋体"); + runFooter.setFontSize(12); + runFooter.setText("检验单位:"); + + // ===== 插入印章图片 ===== + // 使用类路径读取图片 + InputStream is = DocxUtil.class.getClassLoader().getResourceAsStream("template/gaizhang.png"); + if (is == null) { + throw new FileNotFoundException("找不到资源:template/gaizhang.png"); + } + + // 在同一个 Run 后面插入图片 + runFooter.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, "gaizhang.png", Units.toEMU(80), Units.toEMU(80)); + is.close(); + + + doc.write(bos); + return bos.toByteArray(); + + } catch (Exception e) { + e.printStackTrace(); + return new byte[0]; + } + } + + /** 单元格通用设置 */ + private static void setCellText(XWPFTableCell cell, String text, boolean isHeader) { + XWPFParagraph p = cell.getParagraphs().get(0); + p.setAlignment(ParagraphAlignment.CENTER); + XWPFRun run = p.createRun(); + run.setFontFamily("宋体"); + run.setFontSize(10); + run.setText(text == null ? "" : text); + if (isHeader) { + run.setBold(true); + } + // 设置单元格宽度 + cell.getCTTc().addNewTcPr().addNewTcW().setW(BigInteger.valueOf(1200)); + } + + private static String safe(String s) { + return s == null ? "" : s; + } + + /** + * 读取图片文件为 byte 数组 + * @param file 图片文件 + * @return 图片的字节数据 + */ + private static byte[] getImageBytes(File file) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + try (FileInputStream fileInputStream = new FileInputStream(file)) { + byte[] buffer = new byte[1024]; + int length; + while ((length = fileInputStream.read(buffer)) != -1) { + byteArrayOutputStream.write(buffer, 0, length); + } + } + return byteArrayOutputStream.toByteArray(); + } + + /** + * 根据文件扩展名获取图片类型 + * @param fileName 文件名 + * @return 图片类型 + */ + private static int getPictureType(String fileName) { + String ext = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase(); + switch (ext) { + case "png": + return XWPFDocument.PICTURE_TYPE_PNG; + case "jpeg": + case "jpg": + return XWPFDocument.PICTURE_TYPE_JPEG; + case "gif": + return XWPFDocument.PICTURE_TYPE_GIF; + default: + throw new IllegalArgumentException("Unsupported image type: " + ext); + } + } + + public static byte[] generateReportByList(List items) { + if (items == null || items.isEmpty()) { + return new byte[0]; + } + + DownloadRequest.ItemInfo first = items.get(0); + + try (XWPFDocument doc = new XWPFDocument(); ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + // 页面横向 + CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr(); + CTPageSz pageSize = sectPr.addNewPgSz(); + pageSize.setOrient(STPageOrientation.LANDSCAPE); + pageSize.setW(BigInteger.valueOf(16840)); + pageSize.setH(BigInteger.valueOf(11900)); + + // 标题 + XWPFParagraph title = doc.createParagraph(); + title.setAlignment(ParagraphAlignment.CENTER); + XWPFRun runTitle = title.createRun(); + runTitle.setText("施工机具设备出库检验记录表"); + runTitle.setBold(true); + runTitle.setFontFamily("宋体"); + runTitle.setFontSize(16); + + // 工程、单位 + XWPFParagraph info = doc.createParagraph(); + info.setAlignment(ParagraphAlignment.LEFT); + XWPFRun runInfo = info.createRun(); + runInfo.setFontFamily("宋体"); + runInfo.setFontSize(12); + runInfo.setText("领用工程:" + safe(first.getProName()) + " 使用单位:" + safe(first.getDepartName())); + runInfo.addBreak(); + + // 表格 + int colNum = 12; + XWPFTable table = doc.createTable(1, colNum); + table.setWidth("100%"); + + String[] headers = { + "机具名称", "规格型号", "单位", "数量", "设备编码", + "额定载荷KN", "试验载荷KN", "持荷时间min", + "试验日期", "下次试验日期", "检验结论", "备注" + }; + XWPFTableRow headerRow = table.getRow(0); + for (int i = 0; i < headers.length; i++) { + setCellText(headerRow.getCell(i), headers[i], true); + } + + for (DownloadRequest.ItemInfo item : items) { + XWPFTableRow row = table.createRow(); + String[] values = { + safe(item.getTypeName()), safe(item.getTypeModelName()), safe(item.getUnit()), safe(String.valueOf(item.getNum())), + safe(item.getMaCode()), safe(item.getRatedLoad()), safe(item.getTestLoad()), safe(item.getHoldingTime()), + safe(item.getTestTime()), safe(item.getNextTestTime()), safe(item.getCheckResult()), safe(item.getRemark()) + }; + for (int i = 0; i < colNum; i++) { + setCellText(row.getCell(i), values[i], false); + } + } + + // 检验单位 + 印章 + XWPFParagraph footer = doc.createParagraph(); + footer.setAlignment(ParagraphAlignment.LEFT); + footer.setSpacingBefore(400); + XWPFRun runFooter = footer.createRun(); + runFooter.setFontFamily("宋体"); + runFooter.setFontSize(12); + runFooter.setText("检验单位:"); + + InputStream is = DocxUtil.class.getClassLoader().getResourceAsStream("template/gaizhang.png"); + if (is != null) { + runFooter.addPicture(is, XWPFDocument.PICTURE_TYPE_PNG, "gaizhang.png", Units.toEMU(80), Units.toEMU(80)); + } + + doc.write(bos); + return bos.toByteArray(); + + } catch (Exception e) { + e.printStackTrace(); + return new byte[0]; + } + } + +} diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/common/utils/HttpFileUtil.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/common/utils/HttpFileUtil.java new file mode 100644 index 00000000..0ed5954d --- /dev/null +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/common/utils/HttpFileUtil.java @@ -0,0 +1,23 @@ +package com.bonus.material.common.utils; + +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; + +public class HttpFileUtil { + + public static byte[] downloadFile(String url) throws IOException { + try (CloseableHttpClient client = HttpClients.createDefault()) { + HttpGet get = new HttpGet(url); + try (CloseableHttpResponse response = client.execute(get)) { + HttpEntity entity = response.getEntity(); + return entity != null ? EntityUtils.toByteArray(entity) : null; + } + } + } +} diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/domain/Type.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/domain/Type.java index 47a00f84..c4060e74 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/domain/Type.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/domain/Type.java @@ -308,4 +308,46 @@ public class Type extends BaseEntity { private String resultMsg; private Integer inputType; + + /** + * 合格证文件名称 + */ + private String qualifiedName; + /** + * 合格证文件路径 + */ + private String qualifiedUrl; + /** + * 型式试验报告文件名称 + */ + private String testReportName; + /** + * 型式试验报告文件路径 + */ + private String testReportUrl; + /** + * 出厂检测报告名称 + */ + private String factoryReportName; + /** + * 出厂检测报告路径 + */ + private String factoryReportUrl; + /** + * 第三方检测报告名称 + */ + private String thirdReportName; + /** + * 第三方检测报告路径 + */ + private String thirdReportUrl; + /** + * 其他报告名称 + */ + private String otherReportName; + /** + * 其他报告路径 + */ + private String otherReportUrl; + } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/service/impl/DirectRotationImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/service/impl/DirectRotationImpl.java index 6769fb14..01179450 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/service/impl/DirectRotationImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/ma/service/impl/DirectRotationImpl.java @@ -372,8 +372,8 @@ public class DirectRotationImpl implements DirectRotationService { } List detailById = mapper.getDetailById(sltAgreementInfo); List list = mapper.selectDetails(sltAgreementInfo); - int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId()); - String codes = genderTaskCode(thisMonthMaxOrder); + int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDateTwo(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId()); + String codes = genderZzBackTaskCode(thisMonthMaxOrder); TmTask task = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(), BackTaskStatusEnum.BACK_TASK_IN_FINISHED.getStatus(), null,thisMonthMaxOrder + 1, codes); @@ -395,8 +395,8 @@ public class DirectRotationImpl implements DirectRotationService { extractedCheckDetails(backApplyInfo, detailById, result); } // 审核通过,处理转入单位领料逻辑 - int maxOrderByDate = tmTaskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_LEASE.getTaskTypeId()); - String taskCode = genderLeaseTaskCode(maxOrderByDate); + int maxOrderByDate = tmTaskMapper.getMonthMaxOrderByDateTwo(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_LEASE.getTaskTypeId()); + String taskCode = genderZzLeaseTaskCode(maxOrderByDate); TmTask tmTask1 = new TmTask(null, TmTaskTypeEnum.TM_TASK_LEASE.getTaskTypeId(), LeaseTaskStatusEnum.LEASE_TASK_FINISHED.getStatus(),null ,maxOrderByDate + 1, taskCode); @@ -616,6 +616,14 @@ public class DirectRotationImpl implements DirectRotationService { return MaterialConstants.BACK_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1); } + private String genderZzBackTaskCode(int thisMonthMaxOrder) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date nowDate = DateUtils.getNowDate(); + String format = dateFormat.format(nowDate); + String result = format.replace("-", ""); + return "ZT" + result + String.format("-%03d", thisMonthMaxOrder + 1); + } + /** * 新增退料信息 * @param info @@ -732,6 +740,14 @@ public class DirectRotationImpl implements DirectRotationService { return MaterialConstants.LEASE_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1); } + private static String genderZzLeaseTaskCode(Integer thisMonthMaxOrder) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date nowDate = DateUtils.getNowDate(); + String format = dateFormat.format(nowDate); + String result = format.replace("-", ""); + return "ZL" + result + String.format("-%03d", thisMonthMaxOrder + 1); + } + /** * 新增lease_apply_details表数据 * @param list diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java index b38357c2..fef60d29 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/service/impl/PurchaseCheckInfoServiceImpl.java @@ -705,6 +705,35 @@ public class PurchaseCheckInfoServiceImpl implements IPurchaseCheckInfoService { o.setCreateTime(DateUtils.getNowDate()); }); bmFileInfoMapper.insertBmFileInfos(bmFileInfos); + Type type = new Type(); + for (BmFileInfo bmFileInfo : bmFileInfos){ + //将对应数据插入ma_type表 + if (bmFileInfo.getFileType()!=null){ + if (bmFileInfo.getFileType()==0){ + type.setQualifiedName(bmFileInfo.getName()); + type.setQualifiedUrl(bmFileInfo.getUrl()); + } + if (bmFileInfo.getFileType()==1){ + type.setTestReportName(bmFileInfo.getName()); + type.setTestReportUrl(bmFileInfo.getUrl()); + } + if (bmFileInfo.getFileType()==2){ + type.setFactoryReportName(bmFileInfo.getName()); + type.setFactoryReportUrl(bmFileInfo.getUrl()); + } + if (bmFileInfo.getFileType()==3){ + type.setThirdReportName(bmFileInfo.getName()); + type.setThirdReportUrl(bmFileInfo.getUrl()); + } + if (bmFileInfo.getFileType()==4){ + type.setOtherReportName(bmFileInfo.getName()); + type.setOtherReportUrl(bmFileInfo.getUrl()); + } + } + } + type.setTypeId(bmFileInfos.get(0).getModelId()); + //更新ma_type表 + int res = typeMapper.updateType(type); } Type type = new Type(); type.setTypeId(details.getTypeId()); diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/task/mapper/TmTaskMapper.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/task/mapper/TmTaskMapper.java index cfd5d572..56ed6618 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/task/mapper/TmTaskMapper.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/task/mapper/TmTaskMapper.java @@ -43,6 +43,8 @@ public interface TmTaskMapper { */ int getMonthMaxOrderByDate(@Param("year") String year, @Param("month") String month, @Param("taskType") Integer taskType); + int getMonthMaxOrderByDateTwo(@Param("year") String year, @Param("month") String month, @Param("taskType") Integer taskType); + /** * 查询任务列表 * @@ -211,4 +213,5 @@ public interface TmTaskMapper { * @return */ List selectRepairInfo(TmTask info); + } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/work/service/impl/SysWorkflowRecordHistoryServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/work/service/impl/SysWorkflowRecordHistoryServiceImpl.java index 70b3e020..f2b6787b 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/work/service/impl/SysWorkflowRecordHistoryServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/work/service/impl/SysWorkflowRecordHistoryServiceImpl.java @@ -579,8 +579,8 @@ public class SysWorkflowRecordHistoryServiceImpl implements SysWorkflowRecordHis } List detailById = mapper.getDetailById(sltAgreementInfo); List list = mapper.selectDetails(sltAgreementInfo); - int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId()); - String codes = genderTaskCode(thisMonthMaxOrder); + int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDateTwo(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId()); + String codes = genderZzBackTaskCode(thisMonthMaxOrder); TmTask task = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(), BackTaskStatusEnum.BACK_TASK_IN_FINISHED.getStatus(), null,thisMonthMaxOrder + 1, codes); @@ -601,8 +601,8 @@ public class SysWorkflowRecordHistoryServiceImpl implements SysWorkflowRecordHis extractedCheckDetails(backApplyInfo, detailById, result); } // 审核通过,处理转入单位领料逻辑 - int maxOrderByDate = tmTaskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_LEASE.getTaskTypeId()); - String taskCode = genderLeaseTaskCode(maxOrderByDate); + int maxOrderByDate = tmTaskMapper.getMonthMaxOrderByDateTwo(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_LEASE.getTaskTypeId()); + String taskCode = genderZzLeaseTaskCode(maxOrderByDate); TmTask tmTask1 = new TmTask(null, TmTaskTypeEnum.TM_TASK_LEASE.getTaskTypeId(), LeaseTaskStatusEnum.LEASE_TASK_FINISHED.getStatus(),null ,maxOrderByDate + 1, taskCode); @@ -1367,6 +1367,14 @@ public class SysWorkflowRecordHistoryServiceImpl implements SysWorkflowRecordHis return MaterialConstants.LEASE_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1); } + private static String genderZzLeaseTaskCode(Integer thisMonthMaxOrder) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date nowDate = DateUtils.getNowDate(); + String format = dateFormat.format(nowDate); + String result = format.replace("-", ""); + return "ZL" + result + String.format("-%03d", thisMonthMaxOrder + 1); + } + /** * 保存退料详情数据 back_check_details * @param backApplyInfo @@ -1483,6 +1491,14 @@ public class SysWorkflowRecordHistoryServiceImpl implements SysWorkflowRecordHis return MaterialConstants.BACK_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1); } + private String genderZzBackTaskCode(int thisMonthMaxOrder) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date nowDate = DateUtils.getNowDate(); + String format = dateFormat.format(nowDate); + String result = format.replace("-", ""); + return "ZT" + result + String.format("-%03d", thisMonthMaxOrder + 1); + } + /** * 过滤字符串,保留 sourceStr 中在 referenceStr 里也存在的元素(都用逗号分隔) * diff --git a/bonus-modules/bonus-material/src/main/resources/mapper/material/basic/BmReportMapper.xml b/bonus-modules/bonus-material/src/main/resources/mapper/material/basic/BmReportMapper.xml index fb3addcb..6eecb34e 100644 --- a/bonus-modules/bonus-material/src/main/resources/mapper/material/basic/BmReportMapper.xml +++ b/bonus-modules/bonus-material/src/main/resources/mapper/material/basic/BmReportMapper.xml @@ -613,5 +613,89 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" WHERE u.user_id = #{repairPersonName} + diff --git a/bonus-modules/bonus-material/src/main/resources/mapper/material/ma/TypeMapper.xml b/bonus-modules/bonus-material/src/main/resources/mapper/material/ma/TypeMapper.xml index 86d9d0de..b91920b4 100644 --- a/bonus-modules/bonus-material/src/main/resources/mapper/material/ma/TypeMapper.xml +++ b/bonus-modules/bonus-material/src/main/resources/mapper/material/ma/TypeMapper.xml @@ -341,6 +341,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" keep_user_id = #{keeperUserId}, is_check = #{isCheck}, jiJu_type = #{jiJuType}, + qualified_name = #{qualifiedName}, + qualified_url = #{qualifiedUrl}, + test_report_name = #{testReportName}, + test_report_url = #{testReportUrl}, + factory_report_name = #{factoryReportName}, + factory_report_url = #{factoryReportUrl}, + third_report_name = #{thirdReportName}, + third_report_url = #{thirdReportUrl}, + other_report_name = #{otherReportName}, + other_report_url = #{otherReportUrl}, where type_id = #{typeId} diff --git a/bonus-modules/bonus-material/src/main/resources/mapper/material/task/TmTaskMapper.xml b/bonus-modules/bonus-material/src/main/resources/mapper/material/task/TmTaskMapper.xml index 423e691d..a16cd9fa 100644 --- a/bonus-modules/bonus-material/src/main/resources/mapper/material/task/TmTaskMapper.xml +++ b/bonus-modules/bonus-material/src/main/resources/mapper/material/task/TmTaskMapper.xml @@ -126,6 +126,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" month(create_time) = #{month} and year(create_time) = #{year} and task_type = #{taskType} + + and `code` NOT LIKE concat('%', 'ZL', '%') + + + and `code` NOT LIKE concat('%', 'ZT', '%') + @@ -334,5 +340,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" GROUP BY type_id + diff --git a/bonus-modules/bonus-material/src/main/resources/template/gaizhang.png b/bonus-modules/bonus-material/src/main/resources/template/gaizhang.png new file mode 100644 index 00000000..f751e5b8 Binary files /dev/null and b/bonus-modules/bonus-material/src/main/resources/template/gaizhang.png differ