| | |
| | | import cn.hutool.core.lang.UUID; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.deepoove.poi.XWPFTemplate; |
| | |
| | | import com.ruoyi.common.core.domain.entity.User; |
| | | import com.ruoyi.common.utils.QueryWrappers; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.SignatureImageUtil; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.ruoyi.framework.exception.ErrorException; |
| | | import com.ruoyi.inspect.mapper.InsOrderMapper; |
| | | import com.ruoyi.inspect.mapper.InsReportMapper; |
| | | import com.ruoyi.inspect.pojo.InsOrder; |
| | | import com.ruoyi.inspect.pojo.InsReport; |
| | | import com.ruoyi.inspect.util.HackLoopTableRenderPolicy; |
| | | import com.ruoyi.process.dto.ProcessReportDto; |
| | | import com.ruoyi.process.mapper.ProcessReportMapper; |
| | | import com.ruoyi.process.pojo.ProcessReport; |
| | | import com.ruoyi.process.service.ProcessReportService; |
| | | import com.ruoyi.system.mapper.UserMapper; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.poi.xwpf.usermodel.*; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | import java.io.*; |
| | | import java.net.URLEncoder; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Path; |
| | | import java.nio.file.Paths; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | |
| | | @Resource |
| | | private ProcessReportMapper processReportMapper; |
| | | |
| | | |
| | | @Value("${file.path}") |
| | | private String imgUrl; |
| | | @Value("${wordUrl}") |
| | | private String wordUrl; |
| | | |
| | | @Resource |
| | | private UserMapper userMapper; |
| | | |
| | | @Resource |
| | | private InsReportMapper insReportMapper; |
| | | |
| | | @Resource |
| | | private InsOrderMapper insOrderMapper; |
| | | |
| | | @Override |
| | | public IPage<ProcessReport> pageProcessReport(Page page, ProcessReport processReport) { |
| | | //todo 仅看我 |
| | | IPage<ProcessReport> processReportIPage = processReportMapper.pageProcessReport(page, QueryWrappers.queryWrappers(processReport)); |
| | | // for (ProcessReport record : processReportIPage.getRecords()) { |
| | | // List<String> name = new ArrayList<>(); |
| | | // for (String s : record.getSignatory().split(",")) { |
| | | // User user = userMapper.selectById(Integer.parseInt(s)); |
| | | // name.add(user.getName()); |
| | | // } |
| | | // String signatoryName = name.stream().collect(Collectors.joining(",")); |
| | | // record.setSignatoryName(signatoryName); |
| | | // } |
| | | public IPage<ProcessReportDto> pageProcessReport(Page page, ProcessReportDto processReport) { |
| | | // #21 打开列表时,自动带出已通过审批(批准状态=批准)但尚未登记的检验单 |
| | | autoBringOutApproved(); |
| | | IPage<ProcessReportDto> processReportIPage = processReportMapper.pageProcessReport(page, QueryWrappers.queryWrappers(processReport)); |
| | | |
| | | return processReportIPage; |
| | | } |
| | | |
| | | /** |
| | | * 扫描已批准但尚未进入报告结果登记表的检验报告,自动生成待登记记录(以报告编号去重,幂等)。 |
| | | */ |
| | | private void autoBringOutApproved() { |
| | | List<InsReport> approved = insReportMapper.selectList(Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getIsRatify, 1) |
| | | .eq(InsReport::getIsPass, 1)); |
| | | if (approved.isEmpty()) { |
| | | return; |
| | | } |
| | | Set<String> existing = this.list(Wrappers.<ProcessReport>lambdaQuery() |
| | | .select(ProcessReport::getInsReportCode)).stream() |
| | | .map(ProcessReport::getInsReportCode) |
| | | .filter(StringUtils::isNotBlank) |
| | | .collect(Collectors.toCollection(HashSet::new)); |
| | | for (InsReport report : approved) { |
| | | String code = report.getCode(); |
| | | if (StringUtils.isBlank(code) || existing.contains(code)) { |
| | | continue; |
| | | } |
| | | ProcessReport pr = new ProcessReport(); |
| | | pr.setInsReportCode(code); |
| | | pr.setInspectionOrderId(report.getInsOrderId()); |
| | | if (report.getRatifyTime() != null) { |
| | | pr.setSendTime(report.getRatifyTime().toLocalDate()); |
| | | } |
| | | if (report.getInsOrderId() != null) { |
| | | InsOrder order = insOrderMapper.selectById(report.getInsOrderId()); |
| | | if (order != null) { |
| | | pr.setSend(order.getCompany()); |
| | | pr.setMethod(getReportDeliveryName(order)); |
| | | } |
| | | } |
| | | this.save(pr); |
| | | existing.add(code); |
| | | } |
| | | } |
| | | |
| | | private String getReportDeliveryName(InsOrder order) { |
| | | if (order.getReportDelivery() != null) { |
| | | switch (order.getReportDelivery()) { |
| | | case 1: |
| | | return "自取"; |
| | | case 2: |
| | | return "快递"; |
| | | case 3: |
| | | return "电子传送"; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | // 兼容尚未维护 report_delivery 的历史委托单。 |
| | | return order.getSend() != null && order.getSend() == 1 ? "自取" : "其他"; |
| | | } |
| | | |
| | | @Override |
| | | public void exportProcessReport(List<Integer> ids, HttpServletResponse response) { |
| | | List<ProcessReport> processReports = processReportMapper.getIds(ids); |
| | | // for (ProcessReport record : processReports) { |
| | | // List<String> name = new ArrayList<>(); |
| | | // if(StringUtils.isNotBlank(record.getSignatory())){ |
| | | // for (String s : record.getSignatory().split(",")) { |
| | | // User user = userMapper.selectById(Integer.parseInt(s)); |
| | | // name.add(user.getName()); |
| | | // } |
| | | // String signatoryName = name.stream().collect(Collectors.joining(",")); |
| | | // record.setSignatoryName(signatoryName); |
| | | // } |
| | | // } |
| | | public void downloadStampedReport(Integer id, String format, HttpServletResponse response) { |
| | | if (id == null) { |
| | | throw new ErrorException("报告结果不能为空"); |
| | | } |
| | | ProcessReport processReport = getById(id); |
| | | if (processReport == null) { |
| | | throw new ErrorException("报告结果不存在"); |
| | | } |
| | | if (StringUtils.isBlank(processReport.getInsReportCode()) |
| | | && processReport.getInspectionOrderId() == null) { |
| | | throw new ErrorException("该记录未关联检验报告,无法下载"); |
| | | } |
| | | |
| | | String downloadFormat = StringUtils.isBlank(format) ? "pdf" : format.trim().toLowerCase(); |
| | | if (!"pdf".equals(downloadFormat) && !"word".equals(downloadFormat)) { |
| | | throw new ErrorException("下载格式不正确"); |
| | | } |
| | | |
| | | com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<InsReport> query = |
| | | Wrappers.<InsReport>lambdaQuery() |
| | | .eq(InsReport::getIsRatify, 1) |
| | | .eq(StringUtils.isNotBlank(processReport.getInsReportCode()), |
| | | InsReport::getCode, processReport.getInsReportCode()) |
| | | .eq(processReport.getInspectionOrderId() != null, |
| | | InsReport::getInsOrderId, processReport.getInspectionOrderId()) |
| | | .orderByDesc(InsReport::getId) |
| | | .last("limit 1"); |
| | | InsReport report = insReportMapper.selectOne(query); |
| | | if (report == null) { |
| | | throw new ErrorException("未找到已批准的报告,无法下载有章报告"); |
| | | } |
| | | |
| | | String fileUrl; |
| | | String extension; |
| | | String contentType; |
| | | if ("word".equals(downloadFormat)) { |
| | | fileUrl = StringUtils.isNotBlank(report.getUrlS()) ? report.getUrlS() : report.getUrl(); |
| | | extension = ".docx"; |
| | | contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; |
| | | } else { |
| | | fileUrl = report.getTempUrlPdf(); |
| | | extension = ".pdf"; |
| | | contentType = "application/pdf"; |
| | | } |
| | | if ("pdf".equals(downloadFormat) && StringUtils.isBlank(fileUrl)) { |
| | | String reportUrl = StringUtils.isNotBlank(report.getUrlS()) ? report.getUrlS() : report.getUrl(); |
| | | if (StringUtils.isNotBlank(reportUrl) && reportUrl.toLowerCase().endsWith(".docx")) { |
| | | fileUrl = reportUrl.substring(0, reportUrl.length() - 5) + ".pdf"; |
| | | } |
| | | } |
| | | if (StringUtils.isBlank(fileUrl) || !fileUrl.replace('\\', '/').startsWith("/word/")) { |
| | | throw new ErrorException("有章报告尚未生成,请先完成报告批准"); |
| | | } |
| | | |
| | | Path root = Paths.get(wordUrl).toAbsolutePath().normalize(); |
| | | Path file = root.resolve(fileUrl.replace('\\', '/').substring("/word/".length())).normalize(); |
| | | if (!file.startsWith(root) || !Files.isRegularFile(file)) { |
| | | throw new ErrorException("有章报告文件不存在,请重新批准生成"); |
| | | } |
| | | |
| | | try { |
| | | String filename = StringUtils.isNotBlank(processReport.getInsReportCode()) |
| | | ? processReport.getInsReportCode() + extension : file.getFileName().toString(); |
| | | String encodedName = URLEncoder.encode(filename, "UTF-8").replace("+", "%20"); |
| | | response.setContentType(contentType); |
| | | 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()) { |
| | | IOUtils.copy(inputStream, outputStream); |
| | | outputStream.flush(); |
| | | } |
| | | } catch (IOException e) { |
| | | throw new ErrorException("有章报告下载失败"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void exportProcessReport(ProcessReportDto dto, HttpServletResponse response) { |
| | | List<ProcessReportDto> processReports = processReportMapper.exportProcessReport(); |
| | | for (ProcessReportDto processReport : processReports) { |
| | | // 发送人生成签名图片 |
| | | processReport.setSendUserRender(StringUtils.isNotBlank(processReport.getSendUserUrl()) |
| | | ? Pictures.ofLocal(imgUrl + "/" + processReport.getSendUserUrl()).create() : null); |
| | | |
| | | // 签收人生成图片 |
| | | processReport.setSignatoryRender(StringUtils.isNotBlank(processReport.getSignatory()) |
| | | ? Pictures.ofStream(SignatureImageUtil.saveImageToFile(processReport.getSignatory())).create() : null); |
| | | } |
| | | |
| | | // 获取路径 |
| | | InputStream inputStream = this.getClass().getResourceAsStream("/static/report-deal.docx"); |
| | | Configure configure = Configure.builder() |
| | |
| | | template.write(os); |
| | | os.flush(); |
| | | os.close(); |
| | | inputStream.close(); |
| | | inputStream.close(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | throw new RuntimeException("导出失败"); |