From 273a51613d1e8ad56d74434b12fd9c71673ccd5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Tue, 17 Mar 2026 18:07:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(barcode):=20=E6=96=B0=E5=A2=9E=E6=9D=A1?= =?UTF-8?q?=E7=A0=81=E6=89=93=E5=8D=B0=E5=8A=9F=E8=83=BD=E7=9A=84=E5=B7=A5?= =?UTF-8?q?=E5=8E=82=E4=BB=93=E5=BA=93=E5=82=A8=E4=BD=8D=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在BarcodePrintingAddQO中新增工厂、仓库、储位相关字段验证 - 在BarcodePrintingEditQO中新增工厂仓库储位的ID和编号字段 - 在BarcodePrintingVO中新增工厂仓库储位显示字段 - 扩展BarCodeProcessStage枚举,新增入库、出库、质检等状态 - 扩展BarCodeType枚举,新增采购、库存、生产等条码类型 - 集成dictionaryItemService、IWmsWarehouseService、IWmsBinService服务 - 优化条码生成逻辑,关联工厂、仓库、储位信息 - 添加工厂仓库储位数据验证和错误处理机制 - 新增大包装条码标签HTML模板文件 --- .../controller/BarcodePrintingController.java | 92 +++++++++++++--- .../controller/NormalOrderController.java | 85 +++++++++------ .../admin/controller/PackingController.java | 83 ++++++++++++-- .../controller/QrCodeMasterController.java | 71 +++++++++++- .../template/qrcode/big-box-label.html | 70 ++++++++++++ .../resources/template/qrcode/big-box.html | 66 +++++++++++ .../template/qrcode/medium-box-label.html | 89 +++++++++++++++ .../resources/template/qrcode/medium-box.html | 82 ++++++++++++++ .../common/constant/BarCodeProcessStage.java | 30 +++++ .../nflg/wms/common/constant/BarCodeType.java | 15 +++ .../common/pojo/dto/QrCodeMasterPrintDTO.java | 6 + .../common/pojo/qo/BarcodePrintingAddQO.java | 21 ++++ .../common/pojo/qo/BarcodePrintingEditQO.java | 35 ++++++ .../wms/common/pojo/qo/MaterialMinQO.java | 9 +- .../wms/common/pojo/vo/BarcodePrintingVO.java | 16 +++ .../nflg/wms/common/pojo/vo/QrCodeItemVO.java | 2 + .../entity/WmsInventoryBarcodePrinting.java | 35 ++++++ .../repository/entity/WmsQrCodeMaster.java | 11 +- .../WmsInventoryBarcodePrintingMapper.java | 4 + .../IWmsInventoryBarcodePrintingService.java | 7 +- ...msInventoryBarcodePrintingServiceImpl.java | 7 ++ .../WmsInventoryBarcodePrintingMapper.xml | 48 ++++---- .../com/nflg/wms/shipment/util/PathUtils.java | 22 ++++ .../wms/shipment/util/PdfGeneratorUtil.java | 103 ++++++++++++++++++ 24 files changed, 918 insertions(+), 91 deletions(-) create mode 100644 nflg-wms-admin/src/main/resources/template/qrcode/big-box-label.html create mode 100644 nflg-wms-admin/src/main/resources/template/qrcode/big-box.html create mode 100644 nflg-wms-admin/src/main/resources/template/qrcode/medium-box-label.html create mode 100644 nflg-wms-admin/src/main/resources/template/qrcode/medium-box.html create mode 100644 nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PathUtils.java create mode 100644 nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PdfGeneratorUtil.java diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/BarcodePrintingController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/BarcodePrintingController.java index 3ca369cf..17539483 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/BarcodePrintingController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/BarcodePrintingController.java @@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil; import com.nflg.wms.admin.util.*; import com.nflg.wms.common.constant.BarCodeProcessStage; import com.nflg.wms.common.constant.BarCodeType; +import com.nflg.wms.common.constant.Constant; import com.nflg.wms.common.constant.STATE; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; @@ -15,10 +16,8 @@ import com.nflg.wms.common.pojo.dto.QrCodeMasterPrintDTO; import com.nflg.wms.common.pojo.qo.*; import com.nflg.wms.common.pojo.vo.BarcodePrintingVO; import com.nflg.wms.common.util.*; -import com.nflg.wms.repository.entity.WmsInventoryBarcodePrinting; -import com.nflg.wms.repository.entity.WmsQrCodeMaster; -import com.nflg.wms.repository.service.IWmsInventoryBarcodePrintingService; -import com.nflg.wms.repository.service.IWmsQrCodeMasterService; +import com.nflg.wms.repository.entity.*; +import com.nflg.wms.repository.service.*; import com.nflg.wms.starter.annotation.ApiMark; import com.nflg.wms.starter.service.FileUploadService; import jakarta.annotation.Resource; @@ -70,6 +69,15 @@ public class BarcodePrintingController extends BaseController { @Resource private IWmsQrCodeMasterService qrCodeMasterService; + @Resource + private IDictionaryItemService dictionaryItemService; + + @Resource + private IWmsWarehouseService warehouseService; + + @Resource + private IWmsBinService wmsBinService; + /** * 列表 */ @@ -85,12 +93,7 @@ public class BarcodePrintingController extends BaseController { @PostMapping("items") @ApiMark(moduleName = "仓储物流打印", apiName = "获取编辑记录") public ApiResult> getItems(@Valid @RequestBody @NotEmpty List ids) { - List items = printingService.listByIds(ids); - List vos = new ArrayList<>(); - if (CollectionUtil.isNotEmpty(items)) { - vos = Convert.toList(BarcodePrintingVO.class, items); - } - return ApiResult.success(vos); + return ApiResult.success(printingService.getVOList(ids)); } /** @@ -144,7 +147,7 @@ public class BarcodePrintingController extends BaseController { .limit(it.getLabelNum()) .map(index -> new WmsQrCodeMaster() .setBarcodeCode(KeyUtil.next()) - .setProcessStage(BarCodeProcessStage.Unpackaged.getState()) + .setProcessStage(BarCodeProcessStage.InBound.getState()) .setBarcodeType(BarCodeType.Inventory.getState()) .setMaterialCode(it.getMaterialNo()) .setMaterialDescription(it.getMaterialDes()) @@ -153,6 +156,9 @@ public class BarcodePrintingController extends BaseController { .setBatchNo(it.getBatchNumber()) .setSerialNo(CollectionUtil.get(StrUtil.split(it.getSerialNumbers(), ","), index - 1)) .setExtendId(it.getId()) + .setFactoryCode(it.getFactoryCode()) + .setStorageLocation(it.getWarehouseNo()) + .setBinLocation(it.getBinNo()) .setCreateUserId(UserUtil.getUserId()) .setCreateUserName(UserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) @@ -174,7 +180,7 @@ public class BarcodePrintingController extends BaseController { .limit(it.getLabelNum()) .map(index -> new WmsQrCodeMaster() .setBarcodeCode(KeyUtil.next()) - .setProcessStage(BarCodeProcessStage.Unpackaged.getState()) + .setProcessStage(BarCodeProcessStage.InBound.getState()) .setBarcodeType(BarCodeType.Inventory.getState()) .setMaterialCode(it.getMaterialNo()) .setMaterialDescription(it.getMaterialDes()) @@ -183,6 +189,9 @@ public class BarcodePrintingController extends BaseController { .setBatchNo(it.getBatchNumber()) .setSerialNo(CollectionUtil.get(StrUtil.split(it.getSerialNumbers(), ","), index - 1)) .setExtendId(it.getId()) + .setFactoryCode(it.getFactoryCode()) + .setStorageLocation(it.getWarehouseNo()) + .setBinLocation(it.getBinNo()) .setCreateUserId(UserUtil.getUserId()) .setCreateUserName(UserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) @@ -219,8 +228,11 @@ public class BarcodePrintingController extends BaseController { VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(data)).throwMessage("导入文件内容为空"); // 检查 List codes = new ArrayList<>(); - + List factorys = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_FACTORY); + List warehouses = warehouseService.lambdaQuery().select(WmsWarehouse::getId, WmsWarehouse::getNo).list(); + List bins = wmsBinService.lambdaQuery().select(WmsBin::getId, WmsBin::getNo).list(); for (BarcodePrintingAddDTO item : data) { + Long factoryId,warehouseId,binId = null; StringBuilder errorBuild = new StringBuilder(); if (StrUtil.isBlank(item.getMaterialNo())) { errorBuild.append("物料编号必填;"); @@ -228,6 +240,49 @@ public class BarcodePrintingController extends BaseController { if (StrUtil.isBlank(item.getMaterialDes())) { errorBuild.append("物料描述必填;"); } + if (StrUtil.isBlank(item.getFactoryCode())) { + errorBuild.append("所属工厂必填;"); + factoryId = factorys.stream() + .filter(it -> StrUtil.equals(it.getCode(), item.getFactoryCode())) + .findFirst() + .map(DictionaryItem::getId) + .orElse(null); + if (Objects.isNull(factoryId)){ + errorBuild.append("所属工厂不存在;"); + } + } else { + factoryId = null; + } + if (StrUtil.isBlank(item.getWarehouseNo())) { + errorBuild.append("库存地点必填;"); + if (Objects.nonNull(factoryId)){ + warehouseId = warehouses.stream() + .filter(it -> Objects.equals(it.getFactoryId(), factoryId) && StrUtil.equals(it.getNo(), item.getWarehouseNo())) + .findFirst() + .map(WmsWarehouse::getId) + .orElse(null); + if (Objects.isNull(warehouseId)){ + errorBuild.append("库存地点不存在;"); + } + } else { + warehouseId = null; + } + } else { + warehouseId = null; + } + if (StrUtil.isBlank(item.getBinNo())) { + errorBuild.append("储位必填;"); + if (Objects.nonNull(warehouseId)){ + binId = bins.stream() + .filter(it -> Objects.equals(it.getWarehouseId(), warehouseId) && StrUtil.equals(it.getNo(), item.getBinNo())) + .findFirst() + .map(WmsBin::getId) + .orElse(null); + if (Objects.isNull(binId)){ + errorBuild.append("储位不存在;"); + } + } + } if (StrUtil.isBlank(item.getUnit())) { errorBuild.append("单位必填;"); } @@ -245,6 +300,12 @@ public class BarcodePrintingController extends BaseController { item.setError(errorBuild.toString()); } else { WmsInventoryBarcodePrinting entity = Convert.convert(WmsInventoryBarcodePrinting.class, item); + entity.setFactoryId(factoryId); + entity.setFactoryCode(item.getFactoryCode()); + entity.setWarehouseId(warehouseId); + entity.setWarehouseNo(item.getWarehouseNo()); + entity.setBinId(binId); + entity.setBinNo(item.getBinNo()); entity.setCreateBy(UserUtil.getUserName()); entity.setCreateTime(LocalDateTime.now()); codes.add(entity); @@ -260,7 +321,7 @@ public class BarcodePrintingController extends BaseController { .limit(it.getLabelNum()) .map(index -> new WmsQrCodeMaster() .setBarcodeCode(KeyUtil.next()) - .setProcessStage(BarCodeProcessStage.Unpackaged.getState()) + .setProcessStage(BarCodeProcessStage.InBound.getState()) .setBarcodeType(BarCodeType.Inventory.getState()) .setMaterialCode(it.getMaterialNo()) .setMaterialDescription(it.getMaterialDes()) @@ -269,6 +330,9 @@ public class BarcodePrintingController extends BaseController { .setBatchNo(it.getBatchNumber()) .setSerialNo(CollectionUtil.get(StrUtil.split(it.getSerialNumbers(), ","), index - 1)) .setExtendId(it.getId()) + .setFactoryCode(it.getFactoryCode()) + .setStorageLocation(it.getWarehouseNo()) + .setBinLocation(it.getBinNo()) .setCreateUserId(UserUtil.getUserId()) .setCreateUserName(UserUtil.getUserName()) .setCreateTime(LocalDateTime.now()) diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalOrderController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalOrderController.java index d78cbe12..1ea0cd99 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalOrderController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalOrderController.java @@ -433,23 +433,33 @@ public class NormalOrderController extends BaseController { * @param materials 物料列表 */ @PostMapping("exportBoxImageZip") - public ResponseEntity exportBoxImageZip(@RequestBody @NotEmpty List materials) throws Exception { + public ResponseEntity exportBoxImageZip(@Valid @RequestBody @NotEmpty List materials) throws Exception { //TODO 箱子码 + List suppliers = userSupplierService.listByIds(materials.stream().map(MaterialMinQO::getSupplierId).toList()); List qrCodeMasters = materials.stream() - .map(it -> new WmsQrCodeMaster() - .setBarcodeCode(KeyUtil.next()) - .setProcessStage(BarCodeProcessStage.Unpackaged.getState()) - .setBarcodeType(BarCodeType.Purchase.getState()) - .setMaterialCode(it.getMaterialNo()) - .setMaterialDescription(it.getMaterialDes()) - .setPackagingType((short) 1) - .setCreateUserId(UserUtil.getUserId()) - .setUnit("箱") - .setQuantity(BigDecimal.valueOf(1.0)) - .setSupplierCode(it.getSupplierCode()) - .setSupplierId(it.getSupplierId()) - .setCreateUserName(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now())) + .map(it -> { + UserSupplier supplier = suppliers.stream() + .filter(s -> s.getId().equals(it.getSupplierId())) + .findFirst() + .orElse(null); + VUtil.trueThrowBusinessError(Objects.isNull(supplier)).throwMessage("供应商不存在"); + return new WmsQrCodeMaster() + .setBarcodeCode(KeyUtil.next()) + .setProcessStage(BarCodeProcessStage.Unpackaged.getState()) + .setBarcodeType(BarCodeType.Purchase.getState()) + .setMaterialCode(it.getMaterialNo()) + .setMaterialDescription(it.getMaterialDes()) + .setPackagingType((short) 1) + .setCreateUserId(UserUtil.getUserId()) + .setUnit("箱") + .setQuantity(BigDecimal.ZERO) + .setSupplierCode(supplier.getSupplierCode()) + .setSupplierId(it.getSupplierId()) + .setSupplierName(supplier.getSupplierName()) + .setBatchNo(NoUtil.getBatchNo(supplier.getSupplierCode())) + .setCreateUserName(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()); + }) .toList(); qrCodeMasterService.saveBatch(qrCodeMasters); List printDTOS = qrCodeMasters.stream().map(data -> @@ -463,8 +473,8 @@ public class NormalOrderController extends BaseController { try (ZipOutputStream zos = new ZipOutputStream(baos)) { for (QrCodeMasterPrintDTO it : printDTOS) { Map variables = new HashMap<>(); - variables.put("list", List.of(it)); - String html = ThymeleafUtil.generator("/template/qrcode/", "dp-1-label", ".html", variables); + variables.put("item", it); + String html = ThymeleafUtil.generator("/template/qrcode/", "medium-box-label", ".html", variables); ZipEntry entry = new ZipEntry(it.getBarcodeCode() + ".png"); zos.putNextEntry(entry); byte[] imageBytes = HtmlToImageUtil.convertToPng(html, 600); @@ -485,26 +495,37 @@ public class NormalOrderController extends BaseController { */ @PostMapping("exportBoxPdf") public void exportBoxPdf(HttpServletResponse response, @RequestBody @NotEmpty List materials) throws Exception { + List suppliers = userSupplierService.listByIds(materials.stream().map(MaterialMinQO::getSupplierId).toList()); List qrCodeMasters = materials.stream() - .map(it -> new WmsQrCodeMaster() - .setBarcodeCode(KeyUtil.next()) - .setProcessStage(BarCodeProcessStage.Unpackaged.getState()) - .setBarcodeType(BarCodeType.Purchase.getState()) - .setMaterialCode(it.getMaterialNo()) - .setMaterialDescription(it.getMaterialDes()) - .setPackagingType((short) 1) - .setCreateUserId(UserUtil.getUserId()) - .setUnit("箱") - .setQuantity(BigDecimal.valueOf(1.0)) - .setSupplierCode(it.getSupplierCode()) - .setSupplierId(it.getSupplierId()) - .setCreateUserName(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now())) + .map(it -> { + UserSupplier supplier = suppliers.stream() + .filter(s -> s.getId().equals(it.getSupplierId())) + .findFirst() + .orElse(null); + VUtil.trueThrowBusinessError(Objects.isNull(supplier)).throwMessage("供应商不存在"); + return new WmsQrCodeMaster() + .setBarcodeCode(KeyUtil.next()) + .setProcessStage(BarCodeProcessStage.Unpackaged.getState()) + .setBarcodeType(BarCodeType.Purchase.getState()) + .setMaterialCode(it.getMaterialNo()) + .setMaterialDescription(it.getMaterialDes()) + .setPackagingType((short) 1) + .setCreateUserId(UserUtil.getUserId()) + .setUnit("箱") + .setQuantity(BigDecimal.ZERO) + .setSupplierCode(supplier.getSupplierCode()) + .setSupplierId(it.getSupplierId()) + .setSupplierName(supplier.getSupplierName()) + .setBatchNo(NoUtil.getBatchNo(supplier.getSupplierCode())) + .setCreateUserName(UserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()); + } + ) .toList(); qrCodeMasterService.saveBatch(qrCodeMasters); Map variables = new HashMap<>(); variables.put("list", convertToPrintDTO(qrCodeMasters)); - String html = ThymeleafUtil.generator("/template/qrcode/", "dp-2", ".html", variables); + String html = ThymeleafUtil.generator("/template/qrcode/", "medium-box", ".html", variables); URL baseUrl = new ClassPathResource("template/qrcode/").getURL(); PdfGeneratorUtil.generatePdf("箱码标签图片", html, baseUrl.toString(), response); } diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/PackingController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/PackingController.java index 1ac7f144..47567da3 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/PackingController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/PackingController.java @@ -5,12 +5,15 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import com.nflg.wms.admin.service.BasdeSerialNumberControllerService; +import com.nflg.wms.admin.util.*; import com.nflg.wms.common.constant.BarCodeProcessStage; +import com.nflg.wms.common.constant.BarCodeType; import com.nflg.wms.common.constant.UserType; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; import com.nflg.wms.common.pojo.dto.PackageChildDTO; import com.nflg.wms.common.pojo.dto.PackageDTO; +import com.nflg.wms.common.pojo.dto.QrCodeMasterPrintDTO; import com.nflg.wms.common.pojo.qo.*; import com.nflg.wms.common.pojo.vo.*; import com.nflg.wms.common.util.StringUtil; @@ -21,19 +24,31 @@ import com.nflg.wms.repository.service.*; import com.nflg.wms.starter.BaseController; import com.nflg.wms.starter.annotation.ApiMark; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.annotations.Result; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.io.ByteArrayOutputStream; import java.math.BigDecimal; +import java.net.URL; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * 打包管理 @@ -73,7 +88,8 @@ public class PackingController extends BaseController { Short packageType = 0; WmsPackage wmsPackage = new WmsPackage(); wmsPackage.setId(IdUtil.getSnowflakeNextId()); - wmsPackage.setPackageCode(serialNumberControllerService.generateSerialNumber(29)); +// wmsPackage.setPackageCode(serialNumberControllerService.generateSerialNumber(29)); + wmsPackage.setPackageCode(KeyUtil.next()); wmsPackage.setPackageStatus(packageType); wmsPackage.setSupplierId(UserUtil.getUserId()); wmsPackage.setCreateTime(LocalDateTime.now()); @@ -146,7 +162,7 @@ public class PackingController extends BaseController { } /** - * 获取包装物 + * 获取包装物 * @param request * @return */ @@ -158,7 +174,7 @@ public class PackingController extends BaseController { } /** - * 获取包装物的小码物料 + * 获取包装物的小码物料 * @param request * @return */ @@ -199,7 +215,6 @@ public class PackingController extends BaseController { /** * 验证条形码并返回对应的物料数量。 - * * @return 返回该条形码对应的物料数量,类型为BigDecimal */ private PackageDTO BarcodeValidation(WmsQrCodeMaster qrCodeMaster, BarCodeProcessStage processStage) { @@ -219,7 +234,7 @@ public class PackingController extends BaseController { packageDTO.setMaterialCode(qrCodeMaster.getMaterialCode()); // 根据条形码类型计算物料数量 BigDecimal quantity = BigDecimal.valueOf(0); - if ( qrCodeMaster.getPackagingType() == 0) { + if (qrCodeMaster.getPackagingType() == 0) { // 直接获取单个条形码的数量 quantity = qrCodeMaster.getQuantity(); } @@ -242,7 +257,6 @@ public class PackingController extends BaseController { /** * 对SRM收货单物料进行校验,确保收货数量合法。 - * * @param item 收货单物料项,包含物料的基本信息、已收货数量和待收货数量等 * @param quantity 当前打包的收货数量 */ @@ -408,10 +422,10 @@ public class PackingController extends BaseController { * 拆包 */ @PostMapping("pda/unpacking/del") - @ApiMark(moduleName = "拆包-删除", apiName = "-拆包删除") - public ApiResult unpackingDel(@Valid @RequestBody PackingItemDelQO request) { + @ApiMark(moduleName = "拆包-删除", apiName = "拆包删除") + public ApiResult unpackingDel(@RequestBody @NotNull Long id) { WmsPackageItem item = packageItemService.lambdaQuery() - .eq(WmsPackageItem::getId, request.getId()) + .eq(WmsPackageItem::getId, id) .one(); VUtil.trueThrowBusinessError(ObjectUtil.isNull(item)) .throwMessage("此条数据不存在"); @@ -450,7 +464,56 @@ public class PackingController extends BaseController { List childMasters = Convert.toList(WmsQrCodeMaster.class, barcodeResult.getChildren()); qrCodeMasters.addAll(childMasters); } - packageService.unpackingDel(request.getId(), qrCodeMasters, item.getPackageId()); + packageService.unpackingDel(id, qrCodeMasters, item.getPackageId()); return ApiResult.success(); } + + /** + * 导出包装箱标签图片为ZIP + */ + @PostMapping("exportToZip") + public ResponseEntity exportToZip(@Valid @RequestBody @NotEmpty List datas) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(baos)) { + for (PackingVO it : datas) { + Map variables = new HashMap<>(); + variables.put("item",new QrCodeMasterPrintDTO() + .setBarcodeCode(it.getPackageCode()) + .setQrCode(QRCodeUtil.generateQRCodeBase64(it.getPackageCode(), 100, 100)) + .setBatchNo(NoUtil.getBatchNo(it.getSupplierCode())) + .setSupplierName(it.getSupplierName()) + ); + String html = ThymeleafUtil.generator("/template/qrcode/", "big-box-label", ".html", variables); + ZipEntry entry = new ZipEntry(it.getPackageCode() + ".png"); + zos.putNextEntry(entry); + byte[] imageBytes = HtmlToImageUtil.convertToPng(html, 600); + zos.write(imageBytes, 0, imageBytes.length); + zos.closeEntry(); + } + } + byte[] zipBytes = baos.toByteArray(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.valueOf("application/zip")); + headers.setContentLength(zipBytes.length); + return new ResponseEntity<>(zipBytes, headers, HttpStatus.OK); + } + + /** + * 导出包装箱标签图片为PDF + */ + @PostMapping("exportToPdf") + public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List datas) throws Exception { + Map variables = new HashMap<>(); + variables.put("list", datas.stream() + .map(data -> new QrCodeMasterPrintDTO() + .setBarcodeCode(data.getPackageCode()) + .setQrCode(QRCodeUtil.generateQRCodeBase64(data.getPackageCode(), 100, 100)) + .setBatchNo(NoUtil.getBatchNo(data.getSupplierCode())) + .setSupplierName(data.getSupplierName()) + ).toList() + ); + String html = ThymeleafUtil.generator("/template/qrcode/", "big-box", ".html", variables); + URL baseUrl = new ClassPathResource("template/qrcode/").getURL(); + PdfGeneratorUtil.generatePdf("包装箱标签图片", html, baseUrl.toString(), response); + } } diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/QrCodeMasterController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/QrCodeMasterController.java index 5468834b..eeb17dc1 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/QrCodeMasterController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/QrCodeMasterController.java @@ -3,36 +3,51 @@ package com.nflg.wms.admin.controller; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; +import com.nflg.wms.admin.util.HtmlToImageUtil; +import com.nflg.wms.admin.util.PdfGeneratorUtil; +import com.nflg.wms.admin.util.QRCodeUtil; +import com.nflg.wms.admin.util.ThymeleafUtil; import com.nflg.wms.common.constant.BarCodeProcessStage; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; import com.nflg.wms.common.pojo.dto.InventoryDTO; -import com.nflg.wms.common.pojo.dto.PackageChildDTO; +import com.nflg.wms.common.pojo.dto.QrCodeMasterPrintDTO; import com.nflg.wms.common.pojo.qo.*; import com.nflg.wms.common.pojo.vo.QrCodeItemVO; import com.nflg.wms.common.pojo.vo.QrCodeVO; import com.nflg.wms.common.pojo.vo.StrappingVO; -import com.nflg.wms.common.pojo.vo.TransferOrderVO; -import com.nflg.wms.common.util.DateTimeUtil; +import com.nflg.wms.common.util.NumberUtil; import com.nflg.wms.common.util.UserUtil; import com.nflg.wms.common.util.VUtil; import com.nflg.wms.repository.entity.WmsQrCodeMaster; import com.nflg.wms.repository.service.IWmsQrCodeMasterService; -import com.nflg.wms.starter.BaseController; import com.nflg.wms.starter.annotation.ApiMark; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.io.ByteArrayOutputStream; import java.math.BigDecimal; +import java.net.URL; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * 装箱管理 @@ -325,4 +340,52 @@ public class QrCodeMasterController extends BaseController { } return ApiResult.success(qrCodeVO); } + + /** + * 导出标签图片为ZIP + * @param datas 二维码列表 + */ + @PostMapping(value = "exportToZip", produces = "application/zip") + public ResponseEntity exportToZip(@Valid @RequestBody @NotEmpty List datas) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(baos)) { + for (QrCodeItemVO it : datas) { + QrCodeMasterPrintDTO dto = Convert.convert(QrCodeMasterPrintDTO.class, it); + dto.setQuantity(NumberUtil.format(it.getQuantity())); + dto.setQrCode(QRCodeUtil.generateQRCodeBase64(generateQRContent(dto), 100, 100)); + Map variables = new HashMap<>(); + variables.put("list", List.of(dto)); + String html = ThymeleafUtil.generator("/template/qrcode/", "dp-1-label", ".html", variables); + ZipEntry entry = new ZipEntry(it.getBarcodeCode() + ".png"); + zos.putNextEntry(entry); + byte[] imageBytes = HtmlToImageUtil.convertToPng(html, 600); + zos.write(imageBytes, 0, imageBytes.length); + zos.closeEntry(); + } + } + byte[] zipBytes = baos.toByteArray(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.valueOf("application/zip")); + headers.setContentLength(zipBytes.length); + return new ResponseEntity<>(zipBytes, headers, HttpStatus.OK); + } + + /** + * 导出标签图片为PDF + * @param datas 二维码列表 + */ + @PostMapping("exportToPdf") + public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List datas) throws Exception { + Map variables = new HashMap<>(); + variables.put("list", datas.stream().map(data -> + { + QrCodeMasterPrintDTO dto = Convert.convert(QrCodeMasterPrintDTO.class, data); + dto.setQuantity(NumberUtil.format(data.getQuantity())); + dto.setQrCode(QRCodeUtil.generateQRCodeBase64(generateQRContent(dto), 100, 100)); + return dto; + }).toList()); + String html = ThymeleafUtil.generator("/template/qrcode/", "dp-1", ".html", variables); + URL baseUrl = new ClassPathResource("template/qrcode/").getURL(); + PdfGeneratorUtil.generatePdf("箱码标签图片", html, baseUrl.toString(), response); + } } diff --git a/nflg-wms-admin/src/main/resources/template/qrcode/big-box-label.html b/nflg-wms-admin/src/main/resources/template/qrcode/big-box-label.html new file mode 100644 index 00000000..dd77a224 --- /dev/null +++ b/nflg-wms-admin/src/main/resources/template/qrcode/big-box-label.html @@ -0,0 +1,70 @@ + + + + + 大包条码标签 + + + + + + + + + + + + + + + + + + +
+ logo + + 南方路机包装条码(大包) +
+ +
dsafasffsaf
+
+ 批次号: + + 2554565655 +
+ 供应商: + + 地方都是发的顺丰寄 +
+ + \ No newline at end of file diff --git a/nflg-wms-admin/src/main/resources/template/qrcode/big-box.html b/nflg-wms-admin/src/main/resources/template/qrcode/big-box.html new file mode 100644 index 00000000..fcb91590 --- /dev/null +++ b/nflg-wms-admin/src/main/resources/template/qrcode/big-box.html @@ -0,0 +1,66 @@ + + + + + 大包条码标签 + + + + + + + + + + + + + + + + + + +
+ logo + + 南方路机包装条码(大包) +
+ +
dsafasffsaf
+
+ 批次号: + + 2554565655 +
+ 供应商: + + 地方都是发的顺丰寄 +
+ + \ No newline at end of file diff --git a/nflg-wms-admin/src/main/resources/template/qrcode/medium-box-label.html b/nflg-wms-admin/src/main/resources/template/qrcode/medium-box-label.html new file mode 100644 index 00000000..d246f7d0 --- /dev/null +++ b/nflg-wms-admin/src/main/resources/template/qrcode/medium-box-label.html @@ -0,0 +1,89 @@ + + + + + 南方路机包装条码(中包) + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ logo + + 南方路机包装条码(中包) +
+ +
dsafasffsaf
+
+ SAP编码: + + 5215465224 +
+ 物料描述: + + 反垄断法加快速度街坊 +
+ 批次号: + + 2554565655 +
+ 供应商: + + 地方都是发的顺丰寄 +
+ + \ No newline at end of file diff --git a/nflg-wms-admin/src/main/resources/template/qrcode/medium-box.html b/nflg-wms-admin/src/main/resources/template/qrcode/medium-box.html new file mode 100644 index 00000000..19d5b413 --- /dev/null +++ b/nflg-wms-admin/src/main/resources/template/qrcode/medium-box.html @@ -0,0 +1,82 @@ + + + + + 南方路机包装条码(中包) + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ logo + + 南方路机包装条码(中包) +
+ +
dsafasffsaf
+
+ SAP编码: + + 5215465224 +
+ 物料描述: + + 反垄断法加快速度街坊 +
+ 批次号: + + 2554565655 +
+ 供应商: + + 地方都是发的顺丰寄 +
+ + \ No newline at end of file diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeProcessStage.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeProcessStage.java index 5b0b9bb0..081e7242 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeProcessStage.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeProcessStage.java @@ -8,15 +8,45 @@ import java.util.Objects; @Getter @AllArgsConstructor public enum BarCodeProcessStage { + /** + * 未装箱 + */ Unpackaged((short) 0, "未装箱"), + /** + * 已装箱 + */ Packaged((short) 1, "已装箱"), + /** + * 未打包 + */ UnLoaded((short) 2, "未打包"), + /** + * 已打包 + */ Loaded((short) 3, "已打包"), + /** + * 已收货 + */ Received((short) 4, "已收货"), + /** + * 质检中 + */ Checking((short) 5, "质检中"), + /** + * 已入库 + */ InBound((short) 6, "已入库"), + /** + * 已出库 + */ OutBound((short) 7, "已出库"), //已被使用,只有退库的时候才会被重新激活 + /** + * 已挂起 + */ Hold((short) 8, "已挂起"), + /** + * 质检完成 + */ Checked((short) 9, "质检已完成"); // 用于仓库转储,出库之后此二维码还需要继续使用,用一个特殊的状态标记 private final short state; private final String description; diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeType.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeType.java index af261fb6..57fa7d86 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeType.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/constant/BarCodeType.java @@ -9,10 +9,25 @@ import java.util.Objects; @AllArgsConstructor public enum BarCodeType { + /** + * 钢构包 + */ Package((short) 0, "钢构包"), + /** + * 采购物料 + */ Purchase((short) 1, "采购物料"), + /** + * 库存物料 + */ Inventory((short) 2, "库存物料"), + /** + * 拆解物料 + */ Disassemble((short) 3, "拆解(返修)物料"), + /** + * 生产物料 + */ Production((short) 4, "生产物料"); private final short state; diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/QrCodeMasterPrintDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/QrCodeMasterPrintDTO.java index 30b1f868..6f5f6f13 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/QrCodeMasterPrintDTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/QrCodeMasterPrintDTO.java @@ -1,5 +1,6 @@ package com.nflg.wms.common.pojo.dto; +import jakarta.validation.constraints.NotBlank; import lombok.Data; import lombok.experimental.Accessors; @@ -81,4 +82,9 @@ public class QrCodeMasterPrintDTO { * 送货单行号 */ private String deliveryLineNo; + + /** + * 供应商名称 + */ + private String supplierName; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingAddQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingAddQO.java index 3f2fa364..498be256 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingAddQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingAddQO.java @@ -25,6 +25,27 @@ public class BarcodePrintingAddQO { @ExcelColumn("物料描述(*)") private String materialDes; + /** + * 所属工厂 + */ + @NotBlank + @ExcelColumn("所属工厂(*)") + private String factoryCode; + + /** + * 仓库编号 + */ + @NotBlank + @ExcelColumn("库存地点(*)") + private String warehouseNo; + + /** + * 储位编号 + */ + @NotBlank + @ExcelColumn("储位(*)") + private String binNo; + /** * 单位 */ diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingEditQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingEditQO.java index 80475cbe..1656ed2c 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingEditQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BarcodePrintingEditQO.java @@ -62,4 +62,39 @@ public class BarcodePrintingEditQO { return NumberUtil.calculateLabelNum(qty, packingNum); } + /** + * 所属工厂id + */ + @NotNull + private Long factoryId; + + /** + * 所属工厂 + */ + @NotBlank + private String factoryCode; + + /** + * 仓库id + */ + @NotNull + private Long warehouseId; + + /** + * 仓库编号 + */ + @NotBlank + private String warehouseNo; + + /** + * 储位id + */ + @NotNull + private Long binId; + + /** + * 储位编号 + */ + @NotBlank + private String binNo; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialMinQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialMinQO.java index 54cc7c7d..a0a60217 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialMinQO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/MaterialMinQO.java @@ -1,5 +1,7 @@ package com.nflg.wms.common.pojo.qo; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; @Data @@ -8,6 +10,7 @@ public class MaterialMinQO { /** * 物料编号 */ + @NotBlank private String materialNo; /** @@ -15,13 +18,9 @@ public class MaterialMinQO { */ private String materialDes; - /** - * 供应商code - */ - private String supplierCode; - /** * 供应商Id */ + @NotNull private Long supplierId; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/BarcodePrintingVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/BarcodePrintingVO.java index 1dd8ddc4..1b7040b9 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/BarcodePrintingVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/BarcodePrintingVO.java @@ -1,5 +1,6 @@ package com.nflg.wms.common.pojo.vo; +import jakarta.validation.constraints.NotBlank; import lombok.Data; import lombok.experimental.Accessors; @@ -21,6 +22,21 @@ public class BarcodePrintingVO { */ private String materialDes; + /** + * 所属工厂 + */ + private String factoryCode; + + /** + * 仓库编号 + */ + private String warehouseNo; + + /** + * 储位编号 + */ + private String binNo; + /** * 单位 */ diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QrCodeItemVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QrCodeItemVO.java index 50c30d48..62c61ae4 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QrCodeItemVO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/QrCodeItemVO.java @@ -19,11 +19,13 @@ public class QrCodeItemVO { /** * 条码类型(使用枚举扩展) + * @see com.nflg.wms.common.constant.BarCodeType */ private Short barcodeType; /** * 条码流程位置 + * @see com.nflg.wms.common.constant.BarCodeProcessStage */ private Short processStage; diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsInventoryBarcodePrinting.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsInventoryBarcodePrinting.java index 29410da2..0476d829 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsInventoryBarcodePrinting.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsInventoryBarcodePrinting.java @@ -1,8 +1,10 @@ package com.nflg.wms.repository.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -75,6 +77,39 @@ public class WmsInventoryBarcodePrinting implements Serializable { */ private Integer labelNum; + /** + * 所属工厂id + */ + private Long factoryId; + + /** + * 所属工厂 + */ + @TableField(exist = false) + private String factoryCode; + + /** + * 仓库id + */ + private Long warehouseId; + + /** + * 仓库编号 + */ + @TableField(exist = false) + private String warehouseNo; + + /** + * 储位id + */ + private Long binId; + + /** + * 储位编号 + */ + @TableField(exist = false) + private String binNo; + /** * 创建人 */ diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsQrCodeMaster.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsQrCodeMaster.java index 1ba4d071..2b0987eb 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsQrCodeMaster.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsQrCodeMaster.java @@ -1,9 +1,6 @@ package com.nflg.wms.repository.entity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.Version; +import com.baomidou.mybatisplus.annotation.*; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -183,4 +180,10 @@ public class WmsQrCodeMaster implements Serializable { * wms送货单行id */ private Long receiptItemId; + + /** + * 供应商名称 + */ + @TableField(exist = false) + private String supplierName; } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsInventoryBarcodePrintingMapper.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsInventoryBarcodePrintingMapper.java index 28351788..b0ec3912 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsInventoryBarcodePrintingMapper.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsInventoryBarcodePrintingMapper.java @@ -9,6 +9,8 @@ import com.nflg.wms.common.pojo.vo.BarcodePrintingVO; import com.nflg.wms.common.pojo.vo.SrmOrderVO; import com.nflg.wms.repository.entity.WmsInventoryBarcodePrinting; +import java.util.List; + /** *

* Mapper 接口 @@ -19,4 +21,6 @@ import com.nflg.wms.repository.entity.WmsInventoryBarcodePrinting; */ public interface WmsInventoryBarcodePrintingMapper extends BaseMapper { IPage search(BarcodePrintingQO request, Page objectPage); + + List getVOList(List ids); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryBarcodePrintingService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryBarcodePrintingService.java index 922ba3e3..102110d6 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryBarcodePrintingService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsInventoryBarcodePrintingService.java @@ -6,6 +6,9 @@ import com.nflg.wms.common.pojo.vo.BarcodePrintingVO; import com.nflg.wms.repository.entity.WmsInventoryBarcodePrinting; import com.baomidou.mybatisplus.extension.service.IService; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; + +import java.util.List; /** *

@@ -17,5 +20,7 @@ import jakarta.validation.Valid; */ public interface IWmsInventoryBarcodePrintingService extends IService { - IPage search(@Valid BarcodePrintingQO request); + IPage search(BarcodePrintingQO request); + + List getVOList(List ids); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryBarcodePrintingServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryBarcodePrintingServiceImpl.java index 015b9bf9..070af279 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryBarcodePrintingServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsInventoryBarcodePrintingServiceImpl.java @@ -10,6 +10,8 @@ import com.nflg.wms.repository.service.IWmsInventoryBarcodePrintingService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; +import java.util.List; + /** *

* 服务实现类 @@ -25,4 +27,9 @@ public class WmsInventoryBarcodePrintingServiceImpl extends ServiceImpl search(BarcodePrintingQO request) { return baseMapper.search(request, new Page<>(request.getPage(), request.getPageSize())); } + + @Override + public List getVOList(List ids) { + return baseMapper.getVOList(ids); + } } diff --git a/nflg-wms-repository/src/main/resources/mapper/WmsInventoryBarcodePrintingMapper.xml b/nflg-wms-repository/src/main/resources/mapper/WmsInventoryBarcodePrintingMapper.xml index 7f8caf8e..090438d5 100644 --- a/nflg-wms-repository/src/main/resources/mapper/WmsInventoryBarcodePrintingMapper.xml +++ b/nflg-wms-repository/src/main/resources/mapper/WmsInventoryBarcodePrintingMapper.xml @@ -3,50 +3,56 @@ + + diff --git a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PathUtils.java b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PathUtils.java new file mode 100644 index 00000000..aa61e4ee --- /dev/null +++ b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PathUtils.java @@ -0,0 +1,22 @@ +package com.nflg.wms.shipment.util; + +import java.io.File; + +public class PathUtils { + + public static String getPath() { + String classPath = PathUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + System.out.println("classPath:" + classPath); + // 如果是jar包运行,获取jar包所在目录 + if (classPath.contains(".jar")) { + File jarFile = new File(classPath); + return jarFile.getParent(); + } + // 如果是开发环境,获取target/classes目录的父目录 + File classDir = new File(classPath); + if (classDir.getName().equals("classes")) { + return classDir.getParentFile().getParentFile().getAbsolutePath(); + } + return new File(classPath).getAbsolutePath(); + } +} diff --git a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PdfGeneratorUtil.java b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PdfGeneratorUtil.java new file mode 100644 index 00000000..e92ee069 --- /dev/null +++ b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/util/PdfGeneratorUtil.java @@ -0,0 +1,103 @@ +package com.nflg.wms.shipment.util; + + +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfReader; +import com.itextpdf.kernel.pdf.PdfWriter; +import com.itextpdf.kernel.utils.PdfMerger; +import com.lowagie.text.pdf.BaseFont; +import com.nflg.wms.common.util.VUtil; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.io.FilenameUtils; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.xhtmlrenderer.pdf.ITextRenderer; + +import java.io.*; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; + +public class PdfGeneratorUtil { + + private static final Set SUPPORTED_EXTENSIONS = new HashSet<>(Arrays.asList( + "ttf", "ttc", "otf", "pfb" + )); + + public static void generatePdf(String name,String html, HttpServletResponse response) throws Exception { + URL baseUrl = new ClassPathResource("template/").getURL(); + generatePdf(name,html,baseUrl.toString(),response); + } + + public static void generatePdf(String name,String html,String baseUrl, HttpServletResponse response) throws Exception { + ITextRenderer renderer = new ITextRenderer(); + loadFonts(renderer); + renderer.setDocumentFromString(html,baseUrl); + renderer.layout(); + renderer.createPDF(response.getOutputStream()); + response.setContentType(MediaType.APPLICATION_PDF_VALUE); + String encode = URLEncoder.encode(name + ".pdf", StandardCharsets.UTF_8); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline;filename*=UTF-8''" + encode); + } + + public static void generatePdf(String name, String html,OutputStream output) throws Exception { + URL baseUrl = new ClassPathResource("template/").getURL(); + generatePdf(name,html,baseUrl.toString(),output); + } + + public static void generatePdf(String name, String html, String baseUrl, OutputStream output) throws Exception { + ITextRenderer renderer = new ITextRenderer(); + loadFonts(renderer); + renderer.setDocumentFromString(html,baseUrl); + renderer.layout(); + renderer.createPDF(output); + } + + public static void generatePdf(String name, List htmls, HttpServletResponse response) throws Exception { + response.setContentType(MediaType.APPLICATION_PDF_VALUE); + String encode = URLEncoder.encode(name + ".pdf", StandardCharsets.UTF_8); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline;filename*=UTF-8''" + encode); + URL baseUrl = new ClassPathResource("template/").getURL(); + List pdfParts = new ArrayList<>(); + for (String html : htmls) { + ITextRenderer renderer = new ITextRenderer(); + loadFonts(renderer); + renderer.setDocumentFromString(html, baseUrl.toString()); + renderer.layout(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + renderer.createPDF(baos); + pdfParts.add(baos.toByteArray()); + baos.close(); + renderer.finishPDF(); + } + mergePdfs(pdfParts, response.getOutputStream()); + } + + private static void mergePdfs(List pdfBytesList, OutputStream outputStream) throws IOException { + PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outputStream)); + PdfMerger merger = new PdfMerger(pdfDoc); + for (byte[] bytes : pdfBytesList) { + PdfDocument srcDoc = new PdfDocument(new PdfReader(new ByteArrayInputStream(bytes))); + merger.merge(srcDoc, 1, srcDoc.getNumberOfPages()); + srcDoc.close(); + } + pdfDoc.close(); + } + + private static void loadFonts(ITextRenderer renderer) throws IOException { + Path fontsDir = Paths.get(PathUtils.getPath(), "fonts"); + VUtil.trueThrowBusinessError(!Files.exists(fontsDir) || !Files.isDirectory(fontsDir)) + .throwMessage("fonts文件夹不存在: " + fontsDir); + File directory = fontsDir.toFile(); + File[] fonts = directory.listFiles((dir, name) -> SUPPORTED_EXTENSIONS.contains(FilenameUtils.getExtension(name))); + VUtil.trueThrowBusinessError(Objects.isNull(fonts) || fonts.length == 0).throwMessage("未找到有效字体"); + for (File font : fonts) { + renderer.getFontResolver().addFont(font.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED); + } + } +} \ No newline at end of file