From fbd4ecb70baf2e671876ca809a81f6e6fe7342ee Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期日, 20 九月 2026 19:52:50 +0800
Subject: [PATCH] feat(inspect): 新增检测标准方法报告文本功能并优化报告生成 - 委托编号生成逻辑调整为下单时生成并校验唯一性,避免审核时重复 - 新增标准模板价格字段及对应的数据模型和数据库映射 - 订单费用详情查询逻辑重构为基于模板价格计算方式 - 新增标准模板与设备绑定关系的数据结构和管理功能 - 委托编号唯一性校验逻辑增强

---
 inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java |  138 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 107 insertions(+), 31 deletions(-)

diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java
index 2354d4d..bfb7516 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java
@@ -17,6 +17,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.config.Configure;
 import com.deepoove.poi.data.Pictures;
 import com.itextpdf.text.BadElementException;
 import com.itextpdf.text.DocumentException;
@@ -44,6 +45,8 @@
 import com.ruoyi.inspect.service.InsOrderService;
 import com.ruoyi.inspect.service.InsReportService;
 import com.ruoyi.inspect.service.RawMaterialOrderService;
+import com.ruoyi.inspect.util.PreserveReportPicturePlaceholderHandler;
+import com.ruoyi.inspect.util.ReportSignaturePictureUtils;
 import com.ruoyi.system.mapper.UserMapper;
 import com.ruoyi.system.service.InformationNotificationService;
 import lombok.extern.slf4j.Slf4j;
@@ -84,6 +87,9 @@
 @Slf4j
 public class InsReportServiceImpl extends ServiceImpl<InsReportMapper, InsReport>
         implements InsReportService {
+    private static final int DETECTION_REPORT = 0;
+    private static final int INSPECTION_REPORT = 1;
+
     @Resource
     private UserMapper userMapper;
     @Resource
@@ -207,30 +213,30 @@
         info.setViewStatus(false);
         info.setJumpPath(MenuJumpPathConstants.REPORT_PREPARATION);
         informationNotificationService.addInformationNotification(info);
-        //绯荤粺鐢熸垚鎶ュ憡鍦板潃
-        String url = insReport.getUrl();
-        //鎵嬪姩涓婁紶鎶ュ憡鍦板潃
-        String urlS = insReport.getUrlS();
+        String primaryReportUrl = getPrimaryReportUrl(insReport);
 
         // 鍒ゆ柇鏄惁鏄師鏉愭枡  闇�瑕佹浛鎹�****鎴愪緵搴斿晢
         IfsInventoryQuantity one = ifsInventoryQuantityMapper.selectOne(new LambdaQueryWrapper<IfsInventoryQuantity>()
                 .eq(IfsInventoryQuantity::getId, order.getIfsInventoryId()));
         if (one != null) {
             if (isRawMater && order.getOrderType().equals(InsOrderTypeConstants.ENTER_THE_FACTORY)) {
-                changeText(new HashMap<String, String>() {{
-                    put("**********", one.getSupplierName());
-                }}, (StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
+                for (String reportUrl : getApprovalReportUrls(insReport)) {
+                    changeText(new HashMap<String, String>() {{
+                        put("**********", one.getSupplierName());
+                    }}, reportUrl.replace("/word", wordUrl));
+                }
             }
         }
 
-        wordInsertUrl(new HashMap<String, Object>() {{
-            put("writeUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
+        Map<String, Object> writeMarks = new HashMap<String, Object>() {{
+            put("writeUrl", ReportSignaturePictureUtils.create(imgUrl, signatureUrl));
             put("writeDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(null)).create());
-            put("insUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
-        }}, (StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
+            put("insUrl", ReportSignaturePictureUtils.create(imgUrl, signatureUrl));
+        }};
+        writeMarksToReportFiles(insReport, writeMarks);
 
         // 淇敼涓存椂pdf
-        String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
+        String tempUrlPdf = wordToPdfTemp(primaryReportUrl.replace("/word", wordUrl));
         insReport.setTempUrlPdf("/word/" + tempUrlPdf);
 
         insReportMapper.updateById(insReport);
@@ -328,17 +334,15 @@
         info.setViewStatus(false);
         info.setJumpPath(MenuJumpPathConstants.REPORT_PREPARATION);
         informationNotificationService.addInformationNotification(info);
-        //绯荤粺鐢熸垚鎶ュ憡鍦板潃
-        String url = insReport.getUrl();
-        //鎵嬪姩涓婁紶鎶ュ憡鍦板潃
-        String urlS = insReport.getUrlS();
-        wordInsertUrl(new HashMap<String, Object>() {{
-            put("examineUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
+        String primaryReportUrl = getPrimaryReportUrl(insReport);
+        Map<String, Object> examineMarks = new HashMap<String, Object>() {{
+            put("examineUrl", ReportSignaturePictureUtils.create(imgUrl, signatureUrl));
             put("examineDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(null)).create());
-        }}, (StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
+        }};
+        writeMarksToReportFiles(insReport, examineMarks);
 
         // 淇敼涓存椂pdf
-        String tempUrlPdf = wordToPdfTemp((StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl));
+        String tempUrlPdf = wordToPdfTemp(primaryReportUrl.replace("/word", wordUrl));
         insReport.setTempUrlPdf("/word/" + tempUrlPdf);
 
         // 鍙戦�佷紒涓氬井淇¢�氱煡(閫氱煡鎵瑰噯浜哄鎵�)
@@ -471,28 +475,29 @@
         if (StringUtils.isBlank(sealUrl)) {
             throw new ErrorException(laboratory + "鎵句笉鍒版姤鍛婁笓鐢ㄧ珷");
         }
-        //绯荤粺鐢熸垚鎶ュ憡鍦板潃
-        String url = insReport.getUrl();
-        //鎵嬪姩涓婁紶鎶ュ憡鍦板潃
-        String urlS = insReport.getUrlS();
-        String finalUrl = (StrUtil.isBlank(urlS) ? url : urlS).replace("/word", wordUrl);
+        String primaryReportUrl = getPrimaryReportUrl(insReport);
+        String finalUrl = primaryReportUrl.replace("/word", wordUrl);
 
-        wordInsertUrl(new HashMap<String, Object>() {{
-            put("ratifyUrl", Pictures.ofLocal(imgUrl + "/" + signatureUrl).create());
+        Map<String, Object> ratifyMarks = new HashMap<String, Object>() {{
+            put("ratifyUrl", ReportSignaturePictureUtils.create(imgUrl, signatureUrl));
             put("ratifyDateUrl", Pictures.ofStream(DateImageUtil.createDateImage(null)).create());
             put("seal1", Pictures.ofLocal(imgUrl + "/" + sealUrl).create());
             put("seal2", Pictures.ofLocal(imgUrl + "/" + sealUrl).create());
-        }}, finalUrl);
+        }};
+        writeMarksToReportFiles(insReport, ratifyMarks);
 
         // 淇敼涓存椂pdf
-        insReport.setTempUrlPdf((StrUtil.isBlank(urlS) ? url : urlS).replace(".docx", ".pdf"));
+        insReport.setTempUrlPdf(primaryReportUrl.replace(".docx", ".pdf"));
 
         InsOrder insOrder = new InsOrder();
         insOrder.setId(insOrderId);
         insOrder.setState(4);
         insOrderMapper.updateById(insOrder);
 
-        wordToPdf(finalUrl, sealUrl, isRawMater && order.getOrderType().equals(InsOrderTypeConstants.ENTER_THE_FACTORY));
+        for (String reportUrl : getApprovalReportUrls(insReport)) {
+            wordToPdf(reportUrl.replace("/word", wordUrl), sealUrl,
+                    isRawMater && order.getOrderType().equals(InsOrderTypeConstants.ENTER_THE_FACTORY));
+        }
 
         // 鍒ゆ柇鏄惁涓哄師鏉愭枡
         if (isRawMater) {
@@ -523,13 +528,37 @@
 
     @Override
     public int wordInsertUrl(Map<String, Object> map, String url) {
-        XWPFTemplate template = XWPFTemplate.compile(url).render(map);
+        Configure configure = Configure.builder()
+                .setValidErrorHandler(new PreserveReportPicturePlaceholderHandler())
+                .build();
+        XWPFTemplate template = XWPFTemplate.compile(url, configure).render(map);
         try {
             template.writeAndClose(Files.newOutputStream(Paths.get(url)));
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
         return 1;
+    }
+
+    private String getPrimaryReportUrl(InsReport report) {
+        String reportUrl = StringUtils.isNotBlank(report.getUrlS()) ? report.getUrlS() : report.getUrl();
+        if (StringUtils.isBlank(reportUrl)) {
+            throw new ErrorException("妫�娴嬫姤鍛婃枃浠朵笉瀛樺湪");
+        }
+        return reportUrl;
+    }
+
+    private List<String> getApprovalReportUrls(InsReport report) {
+        return Arrays.asList(getPrimaryReportUrl(report), report.getInspectionUrl()).stream()
+                .filter(StringUtils::isNotBlank)
+                .distinct()
+                .collect(Collectors.toList());
+    }
+
+    private void writeMarksToReportFiles(InsReport report, Map<String, Object> marks) {
+        for (String reportUrl : getApprovalReportUrls(report)) {
+            wordInsertUrl(marks, reportUrl.replace("/word", wordUrl));
+        }
     }
 
 
@@ -571,6 +600,53 @@
         return "/word/zip/output.zip";
     }
 
+    @Override
+    public void download(Integer id, Integer reportType, Integer createOrderUser, HttpServletResponse response) {
+        if (id == null) {
+            throw new ErrorException("鎶ュ憡涓嶈兘涓虹┖");
+        }
+        reportType = reportType == null ? DETECTION_REPORT : reportType;
+        if (!Objects.equals(reportType, DETECTION_REPORT) && !Objects.equals(reportType, INSPECTION_REPORT)) {
+            throw new ErrorException("鎶ュ憡绫诲瀷涓嶆纭�");
+        }
+        InsReport report = insReportMapper.selectDownloadableReport(id, createOrderUser);
+        if (report == null) {
+            throw new ErrorException("鎶ュ憡涓嶅瓨鍦ㄣ�佸皻鏈敓鎴愭垨鏃犳潈涓嬭浇");
+        }
+        String reportUrl = Objects.equals(reportType, INSPECTION_REPORT)
+                ? report.getInspectionUrl() : getPrimaryReportUrl(report);
+        if (StringUtils.isBlank(reportUrl) || !reportUrl.replace('\\', '/').startsWith("/word/")) {
+            throw new ErrorException((Objects.equals(reportType, INSPECTION_REPORT) ? "妫�楠屾姤鍛�" : "妫�娴嬫姤鍛�")
+                    + "鏂囦欢涓嶅瓨鍦紝璇疯仈绯荤鐞嗗憳");
+        }
+        Path root = Paths.get(wordUrl).toAbsolutePath().normalize();
+        Path file = root.resolve(reportUrl.replace('\\', '/').substring("/word/".length())).normalize();
+        if (!file.startsWith(root) || !Files.isRegularFile(file)) {
+            throw new ErrorException("鎶ュ憡鏂囦欢涓嶅瓨鍦紝璇疯仈绯荤鐞嗗憳");
+        }
+        try {
+            String filename = file.getFileName().toString();
+            String encodedName = URLEncoder.encode(filename, "UTF-8").replace("+", "%20");
+            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
+            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedName);
+            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
+            response.setHeader("download-filename", encodedName);
+            response.setContentLengthLong(Files.size(file));
+            try (InputStream inputStream = Files.newInputStream(file);
+                 OutputStream outputStream = response.getOutputStream()) {
+                byte[] buffer = new byte[8192];
+                int length;
+                while ((length = inputStream.read(buffer)) != -1) {
+                    outputStream.write(buffer, 0, length);
+                }
+                outputStream.flush();
+            }
+        } catch (IOException e) {
+            log.error("涓嬭浇鎶ュ憡澶辫触锛宺eportId={}", id, e);
+            throw new ErrorException("鎶ュ憡涓嬭浇澶辫触");
+        }
+    }
+
     //鎵归噺涓婁紶
     @Override
     @Transactional(rollbackFor = Exception.class)

--
Gitblit v1.9.3