inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsReportServiceImpl.java
@@ -46,6 +46,7 @@
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;
@@ -86,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
@@ -209,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);
@@ -330,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);
        // 发送企业微信通知(通知批准人审批)
@@ -473,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) {
@@ -537,6 +540,27 @@
        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));
        }
    }
    //报告批量下载
    @Override
@@ -576,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("下载报告失败,reportId={}", id, e);
            throw new ErrorException("报告下载失败");
        }
    }
    //批量上传
    @Override
    @Transactional(rollbackFor = Exception.class)