新增打印预览
This commit is contained in:
funny 2026-04-14 11:31:12 +08:00
parent 79bad56f77
commit 1f9687b20d
6 changed files with 305 additions and 1 deletions

View File

@ -622,7 +622,7 @@ public class NormalPGIControllerService {
// 这里需要同步一个信息就是把箱码的状态也要改为收货状态,
List<Long> parentIds = dto.getQrCodes().stream()
.filter(qrCode -> qrCode.getPackagingType() == 0)
.map(WmsQrCodeMaster::getId)
.map(WmsQrCodeMaster::getParentBarcodeId)
.distinct()
.toList();
if (CollectionUtil.isNotEmpty(parentIds)) {

View File

@ -0,0 +1,64 @@
package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* 物料码打印DTO
*/
@Data
@Accessors(chain = true)
public class MaterialCodePrintDTO {
/**
* 二维码Base64
*/
private String qrCode;
/**
* 唯一码
*/
private String no;
/**
* 物料编号
*/
private String materialNo;
/**
* 物料描述
*/
private String materialDescribe;
/**
* 数量
*/
private BigDecimal num;
/**
* 数量文本
*/
private String numText;
/**
* 单位
*/
private String unit;
/**
* 机台编号
*/
private String deviceNo;
/**
* 客户名称
*/
private String customerName;
/**
* 图片Base64
*/
private String lst;
}

View File

@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.MaterialCodePrintDTO;
import com.nflg.wms.common.pojo.dto.MaterialPdfDTO;
import com.nflg.wms.common.pojo.qo.*;
import com.nflg.wms.common.pojo.vo.MaterialPdfVO;
@ -51,6 +52,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@ -819,4 +821,45 @@ public class MaterialCodeController extends BaseController {
InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
return ApiResult.success(fileUploadService.upload("tmp/sp/" + RandomUtil.randomString(10) + "/" + material.getNo() + "老鼠图.pdf", inputStream, MediaType.APPLICATION_PDF_VALUE));
}
/**
* 导出标签图片PDF打印预览
*
* @param response HTTP响应
* @param ids 清单明细id列表
*/
@PostMapping("exportToPdf")
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception {
List<ShipmentMaterialCodeQRVO> datas = materialCodeItemQrService.getListVOByItemIds(ids);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("没有需要导出的数据");
// 获取物料图片
Map<String, String> images = materialService.lambdaQuery()
.select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)
.in(WmsShipmentMaterial::getNo, datas.stream().map(ShipmentMaterialCodeQRVO::getMaterialNo).collect(Collectors.toSet()))
.list()
.stream()
.collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage));
// 构建打印数据
Map<String, Object> variables = new HashMap<>();
variables.put("list", datas.stream()
.map(data -> new MaterialCodePrintDTO()
.setNo(data.getNo())
.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200))
.setMaterialNo(data.getMaterialNo())
.setMaterialDescribe(data.getMaterialDescribe())
.setNum(data.getNum())
.setNumText(data.getNumText())
.setUnit(data.getUnit())
.setDeviceNo(data.getDeviceNo())
.setCustomerName(data.getCustomerName())
.setLst(images.get(data.getMaterialNo()))
).toList()
);
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables);
URL baseUrl = new ClassPathResource("template/label/").getURL();
PdfGeneratorUtil.generatePdf("物料码标签", html, baseUrl.toString(), response);
}
}

View File

@ -22,6 +22,7 @@ import com.nflg.wms.repository.service.*;
import com.nflg.wms.shipment.service.BasdeSerialNumberControllerService;
import com.nflg.wms.shipment.util.HtmlToImageUtil;
import com.nflg.wms.shipment.util.KeyUtil;
import com.nflg.wms.shipment.util.PdfGeneratorUtil;
import com.nflg.wms.shipment.util.QRCodeUtil;
import com.nflg.wms.shipment.util.ThymeleafUtil;
import com.nflg.wms.starter.BaseController;
@ -34,10 +35,12 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@ -406,4 +409,34 @@ public class PackagingCodeController extends BaseController {
headers.setContentLength(zipBytes.length);
return new ResponseEntity<>(zipBytes, headers, HttpStatus.OK);
}
/**
* 导出标签图片PDF打印预览
*/
@PostMapping("exportToPdf")
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<ShipmentPackagingCodeVO> list) throws Exception {
List<DictionaryItem> types = dictionaryItemService.getListByDictionaryCode("PackagingType");
// 构建打印数据
Map<String, Object> variables = new HashMap<>();
variables.put("list", list.stream()
.map(data -> {
String typeName = types.stream()
.filter(type -> type.getId().equals(data.getType()))
.map(DictionaryItem::getName)
.findFirst()
.orElse("");
ShipmentPackagingCodeVO vo = new ShipmentPackagingCodeVO();
vo.setNo(data.getNo());
vo.setName(data.getName());
vo.setTypeName(typeName);
vo.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getNo(), 100, 100));
return vo;
}).toList()
);
String html = ThymeleafUtil.generator("/template/label/", "packaging-pdf", ".html", variables);
URL baseUrl = new ClassPathResource("template/label/").getURL();
PdfGeneratorUtil.generatePdf("包装码标签", html, baseUrl.toString(), response);
}
}

View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>物料码标签</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<style>
body {
font-size: 10pt;
font-family: SimSun, Arial, sans-serif;
margin: 0;
padding: 0;
}
.label-page {
width: 1200px;
height: 800px;
page-break-after: always;
}
.label-page:last-child {
page-break-after: auto;
}
table {
width: 1200px;
height: 800px;
border: 3px solid #000;
border-collapse: collapse;
table-layout: fixed;
}
th, td {
border: 3px solid #000;
padding: 10px;
text-align: center;
vertical-align: middle;
word-wrap: break-word;
overflow-wrap: break-word;
}
.qrcode {
width: 380px;
height: 380px;
}
.lst {
width: 800px;
height: auto;
}
</style>
</head>
<body>
<div class="label-page" th:each="item, iterStat : ${list}" th:style="${iterStat.index == 0} ? 'page-break-before: auto;' : 'page-break-before: always;'">
<table>
<tr>
<td style="text-align: center; width: 400px" rowspan="3">
<img alt="" class="qrcode" th:src="${item.qrCode}"/>
<div style="font-size: 16pt" th:text="${item.no}">0PC7B724KV6FM</div>
</td>
<td style="width: 140px;">
机台编号
</td>
<td style="width: 200px;" th:text="${item.no}">
26LBZ4000L001
</td>
<td style="width: 140px;">
客户名称
</td>
<td style="text-align: left" th:text="${item.customerName}">
北京市京联鑫路用材料有限公司
</td>
</tr>
<tr>
<td>
物料编码
</td>
<td th:text="${item.materialNo}">
3100006701
</td>
<td>
数量
</td>
<td th:text="${item.numText}">
10
</td>
</tr>
<tr>
<td colspan="4">
<img style="width: 750px;" alt="" class="lst" th:src="${item.lst}"/>
</td>
</tr>
</table>
</div>
</body>
</html>

View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>包装码标签</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<style>
body {
font-size: 10pt;
font-family: SimSun, Arial, sans-serif;
margin: 0;
padding: 0;
}
.label-page {
width: 600px;
height: 400px;
page-break-after: always;
}
.label-page:last-child {
page-break-after: auto;
}
table {
width: 600px;
height: 400px;
border: 3px solid #000;
border-collapse: collapse;
}
th, td {
border: 3px solid #000;
}
.div-with-border {
border-bottom: 3px solid #000;
padding: 18px;
text-align: left;
width: 320px;
display: block;
vertical-align: middle
}
.qrcode {
width: 260px;
height: 260px;
margin: 10px;
}
</style>
</head>
<body>
<div class="label-page" th:each="item, iterStat : ${list}" th:style="${iterStat.index == 0} ? 'page-break-before: auto;' : 'page-break-before: always;'">
<table>
<tr>
<td style="text-align: center;">
<img alt="" class="qrcode" th:src="${item.qrCode}"/>
<div style="font-size: 16pt" th:text="${item.no}">NFLG-QZ-002</div>
</td>
<td style="text-align: left;vertical-align: top">
<div class="div-with-border">包装名称: <span th:text="${item.name}">NFLG-QZ-002 测试包装名称</span></div>
<div class="div-with-border">包装类型: <span th:text="${item.typeName}">托盘</span></div>
</td>
</tr>
</table>
</div>
</body>
</html>