diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalQMController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalQMController.java index 5af24075..982b3ba6 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalQMController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/NormalQMController.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.nflg.wms.admin.pojo.dto.*; import com.nflg.wms.admin.pojo.request.UnqualifiedWarehousingRequest; import com.nflg.wms.admin.service.NormalQMControllerService; +import com.nflg.wms.admin.service.SapService; import com.nflg.wms.common.constant.BarCodeProcessStage; import com.nflg.wms.common.pojo.ApiResult; import com.nflg.wms.common.pojo.PageData; @@ -74,8 +75,11 @@ public class NormalQMController extends BaseController { @Resource private IWmsQrCodeMasterService qrCodeMasterService; + private SapService sapService; + /** * 获取SRM推送过来的质检单信息 + * * @param request * @return */ @@ -87,6 +91,7 @@ public class NormalQMController extends BaseController { /** * 导出质检单 + * * @param request 查询条件 * @return */ @@ -100,6 +105,7 @@ public class NormalQMController extends BaseController { /** * 质检物料上架任务(PDA) + * * @param orderNo 送货单号或任务单号 * @return */ @@ -112,6 +118,7 @@ public class NormalQMController extends BaseController { /** * 质检物料上架物料详情 + * * @param taskId 任务ID **/ @GetMapping("PDA/task/item") @@ -123,6 +130,7 @@ public class NormalQMController extends BaseController { /** * 质检物料上架任务确认 + * * @param request **/ @Transactional @@ -368,6 +376,7 @@ public class NormalQMController extends BaseController { /** * 无码质检任务上架确认 + * * @param request 任务ID * @return */ @@ -478,7 +487,16 @@ public class NormalQMController extends BaseController { WmsSrmQualityInspection inspection = wmsSrmQualityInspectionService.getById(request.getId()); VUtil.trueThrowBusinessError(Objects.isNull(inspection)).throwMessage("无效的质检单"); VUtil.trueThrowBusinessError(!inspection.getInspectionResult().equals("不合格")).throwMessage("该质检单不是不合格单"); - VUtil.trueThrowBusinessError(inspection.getReceiveQty().compareTo(BigDecimal.ZERO) > 0).throwMessage("该质检单已生成上架任务"); + VUtil.trueThrowBusinessError(inspection.getReceiveQty().compareTo(BigDecimal.ZERO) > 0).throwMessage("该质检单已完成冲销"); + List itemDTOs = new ArrayList<>(); + ZWM3A27ItemDTO itemDTO = new ZWM3A27ItemDTO() + .setEbeln(inspection.getPoNum()) + .setEbeln(inspection.getPoNum()). + setEbelp(Integer.valueOf(inspection.getPoLineNumber())). + setMenge(inspection.getDeliveryQty()).setMatDoc(inspection.getMaterialDoc105()) + .setDocYear(inspection.getMaterialDocYear105()); + itemDTOs.add(itemDTO); + sapService.zwm3a27(inspection.getMaterialDoc105(), inspection.getMaterialDocYear105(), itemDTOs); inspection.setReceiveQty(request.getReceiveQty()); wmsSrmQualityInspectionService.updateById(inspection); return ApiResult.success(); 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 c06c6867..42c411eb 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 @@ -54,7 +54,6 @@ import java.util.zip.ZipOutputStream; /** * 装箱管理 - * * @author: nflg * @date: 2022/3/17 * @description: @@ -86,7 +85,6 @@ public class QrCodeMasterController extends BaseController { /** * 获取包装箱和箱内物料信息 - * * @param request * @return */ @@ -126,7 +124,6 @@ public class QrCodeMasterController extends BaseController { /** * 包装箱编码获取包装箱和箱内物料信息 - * * @param request * @return */ @@ -161,7 +158,6 @@ public class QrCodeMasterController extends BaseController { /** * 箱码Validation - * * @param qrCodeMaster * @param smallQrCodeMasters */ @@ -209,7 +205,6 @@ public class QrCodeMasterController extends BaseController { /** * 装箱绑码 - * * @param request * @return */ @@ -265,7 +260,6 @@ public class QrCodeMasterController extends BaseController { /** * 拆箱删除 - * * @param request * @return */ @@ -294,7 +288,6 @@ public class QrCodeMasterController extends BaseController { /** * 换箱 * 针对库存地点内的物料箱合并,修改物料的箱属性和库存 - * * @param request * @return */ @@ -402,7 +395,6 @@ public class QrCodeMasterController extends BaseController { /** * 物料出入库统一扫码接口 - * * @param request * @return * @author @@ -437,7 +429,6 @@ public class QrCodeMasterController extends BaseController { /** * 换箱扫码接口 - * * @param request * @return * @author @@ -469,11 +460,12 @@ public class QrCodeMasterController extends BaseController { /** * 导出标签图片为ZIP - * * @param datas 二维码列表 */ @PostMapping(value = "exportToZip", produces = "application/zip") public ResponseEntity exportToZip(@Valid @RequestBody @NotEmpty List datas) throws Exception { + VUtil.trueThrowBusinessError(datas.stream().map(QrCodeItemVO::getPackagingType).collect(Collectors.toSet()).size() > 1) + .throwMessage("只能选择一种包装类型"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (ZipOutputStream zos = new ZipOutputStream(baos)) { for (QrCodeItemVO it : datas) { @@ -482,7 +474,8 @@ public class QrCodeMasterController extends BaseController { 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); + String html = ThymeleafUtil.generator("/template/qrcode/" + , datas.get(0).getPackagingType() == 0 ? "dp-1-label" : "medium-box-label", ".html", variables); ZipEntry entry = new ZipEntry(it.getBarcodeCode() + ".png"); zos.putNextEntry(entry); byte[] imageBytes = HtmlToImageUtil.convertToPng(html, 600); @@ -499,11 +492,12 @@ public class QrCodeMasterController extends BaseController { /** * 导出标签图片为PDF - * * @param datas 二维码列表 */ @PostMapping("exportToPdf") public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List datas) throws Exception { + VUtil.trueThrowBusinessError(datas.stream().map(QrCodeItemVO::getPackagingType).collect(Collectors.toSet()).size() > 1) + .throwMessage("只能选择一种包装类型"); Map variables = new HashMap<>(); variables.put("list", datas.stream().map(data -> { @@ -512,7 +506,8 @@ public class QrCodeMasterController extends BaseController { dto.setQrCode(QRCodeUtil.generateQRCodeBase64(generateQRContent(dto), 100, 100)); return dto; }).toList()); - String html = ThymeleafUtil.generator("/template/qrcode/", "dp-1", ".html", variables); + String html = ThymeleafUtil.generator("/template/qrcode/" + , datas.get(0).getPackagingType() == 0 ? "dp-1" : "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/service/NormalPGIControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/NormalPGIControllerService.java index 5984b517..320eca4a 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/NormalPGIControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/NormalPGIControllerService.java @@ -9,6 +9,7 @@ import com.nflg.wms.admin.pojo.dto.QCMaterialSyncDTO; import com.nflg.wms.admin.pojo.dto.ZWM3A17DTO; import com.nflg.wms.admin.repository.SrmMaterialReceiptNoScanCodesRepository; import com.nflg.wms.admin.repository.SrmMaterialReceiptScanCodesRepository; +import com.nflg.wms.common.constant.BarCodeProcessStage; import com.nflg.wms.common.pojo.document.SrmMaterialReceiptNoScanCodes; import com.nflg.wms.common.pojo.document.SrmMaterialReceiptScanCodes; import com.nflg.wms.common.pojo.dto.*; @@ -619,37 +620,30 @@ public class NormalPGIControllerService { } } - //编码管理 -// if (CollectionUtil.isNotEmpty(dto.getQrCodes())) { -// //同步箱码信息到物料码中 -// List parents = dto.getQrCodes() -// .stream() -// .filter(qrCode -> qrCode.getPackagingType() == 1) -// .toList(); -// if (CollectionUtil.isNotEmpty(parents)) { -// List children = qrCodeMasterService.lambdaQuery() -// .in(WmsQrCodeMaster::getParentBarcodeId, parents -// .stream() -// .map(WmsQrCodeMaster::getId) -// .toList() -// ) -// .list(); -// parents.forEach(p -> { -// children.stream() -// .filter(c -> c.getParentBarcodeId().equals(p.getId())) -// .forEach(c -> { -// c.setProcessStage(p.getProcessStage()); -// c.setLastScanBy(UserUtil.getUserId()); -// c.setLastScanByname(UserUtil.getUserName()); -// c.setLastScanTime(LocalDateTime.now()); -// c.setFactoryCode(p.getFactoryCode()); -// c.setStorageLocation(p.getStorageLocation()); -// c.setBinLocation(p.getBinLocation()); -// c.setReceiptItemId(p.getReceiptItemId()); -// }); -// }); -// dto.getQrCodes().addAll(children); -// } + // 这里需要同步一个信息,就是把箱码的状态也要改为收货状态, + List parentIds = dto.getQrCodes().stream() + .filter(qrCode -> qrCode.getPackagingType() == 0) + .map(WmsQrCodeMaster::getParentBarcodeId) + .distinct() + .toList(); + if (CollectionUtil.isNotEmpty(parentIds)) { + // 获取所有的父级物料信息 + List parents2 = qrCodeMasterService.lambdaQuery() + .in(WmsQrCodeMaster::getId, parentIds) + .list(); + for (WmsQrCodeMaster parent : parents2) { + boolean exists = dto.getQrCodes().stream().anyMatch(qrCode -> + qrCode.getBarcodeCode().equals(parent.getBarcodeCode())); + if (!exists) { + parent.setProcessStage(BarCodeProcessStage.Received.getState()); + parent.setLastScanBy(UserUtil.getUserId()); + parent.setLastScanByname(UserUtil.getUserName()); + parent.setLastScanTime(LocalDateTime.now()); + dto.getQrCodes().add(parent); + } + } + } + qrCodeMasterService.updateBarCode(dto.getQrCodes()); } } 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 index 19d5b413..0c0bf40e 100644 --- a/nflg-wms-admin/src/main/resources/template/qrcode/medium-box.html +++ b/nflg-wms-admin/src/main/resources/template/qrcode/medium-box.html @@ -6,74 +6,79 @@ - - - + - - + - + - + - + diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialCodePrintDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialCodePrintDTO.java new file mode 100644 index 00000000..2aeb0f02 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialCodePrintDTO.java @@ -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; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/MaterialItemPrintVO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/MaterialItemPrintVO.java new file mode 100644 index 00000000..15539d31 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/vo/MaterialItemPrintVO.java @@ -0,0 +1,84 @@ +package com.nflg.wms.common.pojo.vo; + +import com.nflg.wms.common.util.NumberUtil; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 物料明细打印预览VO + */ +@Data +public class MaterialItemPrintVO { + + private Long id; + + /** + * 物料编号 + */ + private String materialNo; + + /** + * 物料描述 + */ + private String materialDescribe; + + /** + * 数量 + */ + private BigDecimal num; + + /** + * 数量文本 + */ + private String numText; + + public String getNumText() { + return NumberUtil.format(num); + } + + /** + * 实发数量 + */ + private BigDecimal actualNum; + + /** + * 单位 + */ + private String unit; + + /** + * 项目类型 + */ + private String projectType; + + /** + * 生产订单号 + */ + private String productionOrderNumber; + + /** + * 箱号 + */ + private String boxNo; + + /** + * 机台编号 + */ + private String deviceNo; + + /** + * 客户名称 + */ + private String customerName; + + /** + * 二维码(Base64) + */ + private String qrCode; + + /** + * 图片(Base64) + */ + private String image; +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java index 148d3c40..9ff1427e 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemMapper.java @@ -1,6 +1,7 @@ package com.nflg.wms.repository.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO; import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem; @@ -20,4 +21,8 @@ public interface WmsShipmentMaterialCodeItemMapper extends BaseMapper getByCodeId(Long codeId); void updatePackingNum(Set ids); + + List getListByMaterialNos(Set materialNos); + + List getListByItemIds(List ids); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemQrMapper.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemQrMapper.java index 117e210f..aab075f9 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemQrMapper.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsShipmentMaterialCodeItemQrMapper.java @@ -5,6 +5,7 @@ import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO; import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItemQr; import java.util.List; +import java.util.Set; /** *

@@ -21,4 +22,6 @@ public interface WmsShipmentMaterialCodeItemQrMapper extends BaseMapper getListVOByItemIds(List ids); List getListVOByCodeIds(List ids); + + List getListVOByMaterialNos(Set materialNos); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemQrService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemQrService.java index 16aae7de..c01ff95a 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemQrService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemQrService.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import jakarta.validation.constraints.NotEmpty; import java.util.List; +import java.util.Set; /** *

@@ -22,4 +23,6 @@ public interface IWmsShipmentMaterialCodeItemQrService extends IService getListVOByItemIds(List ids); List getListVOByCodeIds(List ids); + + List getListVOByMaterialNos(Set materialNos); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java index 559274ec..602f11d1 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsShipmentMaterialCodeItemService.java @@ -1,5 +1,6 @@ package com.nflg.wms.repository.service; +import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO; import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem; import com.baomidou.mybatisplus.extension.service.IService; @@ -20,4 +21,8 @@ public interface IWmsShipmentMaterialCodeItemService extends IService getByCodeId(Long codeId); void updatePackingNum(Set ids); + + List getListByMaterialNos(Set materialNos); + + List getListByItemIds(List ids); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java index cd48a864..eb2315bf 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemQrServiceImpl.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Set; /** *

@@ -34,4 +35,9 @@ public class WmsShipmentMaterialCodeItemQrServiceImpl extends ServiceImpl getListVOByCodeIds(List ids) { return baseMapper.getListVOByCodeIds(ids); } + + @Override + public List getListVOByMaterialNos(Set materialNos) { + return baseMapper.getListVOByMaterialNos(materialNos); + } } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java index 400af821..818a8141 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsShipmentMaterialCodeItemServiceImpl.java @@ -1,5 +1,6 @@ package com.nflg.wms.repository.service.impl; +import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO; import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem; import com.nflg.wms.repository.mapper.WmsShipmentMaterialCodeItemMapper; @@ -30,4 +31,14 @@ public class WmsShipmentMaterialCodeItemServiceImpl extends ServiceImpl ids) { baseMapper.updatePackingNum(ids); } + + @Override + public List getListByMaterialNos(Set materialNos) { + return baseMapper.getListByMaterialNos(materialNos); + } + + @Override + public List getListByItemIds(List ids) { + return baseMapper.getListByItemIds(ids); + } } diff --git a/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml b/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml index 4849f5bb..76e4110a 100644 --- a/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml +++ b/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemMapper.xml @@ -25,4 +25,28 @@ #{id} + + + + diff --git a/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemQrMapper.xml b/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemQrMapper.xml index b579e906..b822d9ab 100644 --- a/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemQrMapper.xml +++ b/nflg-wms-repository/src/main/resources/mapper/WmsShipmentMaterialCodeItemQrMapper.xml @@ -31,4 +31,15 @@ #{item} + + diff --git a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java index 946a9425..1b27d02e 100644 --- a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java +++ b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/MaterialCodeController.java @@ -9,9 +9,11 @@ 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; +import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO; import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO; import com.nflg.wms.common.util.EecExcelUtil; @@ -51,6 +53,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 +822,92 @@ 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列表(wms_shipment_material.id) + */ + @PostMapping("exportToPdf") + public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List ids) throws Exception { + // 根据清单ID查询二维码数据 + List datas = materialCodeItemQrService.getListVOByCodeIds(ids); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("物料数据不存在"); + + // 取第一条数据 + ShipmentMaterialCodeQRVO data = datas.get(0); + + // 根据物料编号查询物料图片 + Map 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 variables = new HashMap<>(); + + Map info = new HashMap<>(); + info.put("no", data.getNo()); + info.put("materialNo", data.getMaterialNo()); + info.put("numText", data.getNumText()); + info.put("customerName", data.getCustomerName()); + + Map ext = new HashMap<>(); + ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200)); + ext.put("lst", images.get(data.getMaterialNo())); + + variables.put("info", info); + variables.put("ext", ext); + + String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables); + URL baseUrl = new ClassPathResource("template/label/").getURL(); + PdfGeneratorUtil.generatePdf("物料码标签", html, baseUrl.toString(), response); + } + + /** + * 根据明细ID导出物料明细PDF(打印预览) + * + * @param response HTTP响应 + * @param ids 明细id列表(wms_shipment_material_code_item.id) + */ + @PostMapping("exportItemToPdf") + public void exportItemToPdf(HttpServletResponse response, @RequestBody @NotEmpty List ids) throws Exception { + // 根据明细ID查询数据 + List datas = materialCodeItemQrService.getListVOByItemIds(ids); + VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("没有需要导出的数据"); + + // 取第一条数据 + ShipmentMaterialCodeQRVO data = datas.get(0); + + // 根据物料编号查询物料图片 + Map 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 variables = new HashMap<>(); + + Map info = new HashMap<>(); + info.put("no", data.getNo()); + info.put("materialNo", data.getMaterialNo()); + info.put("numText", data.getNumText()); + info.put("customerName", data.getCustomerName()); + + Map ext = new HashMap<>(); + ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200)); + ext.put("lst", images.get(data.getMaterialNo())); + + variables.put("info", info); + variables.put("ext", ext); + + String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables); + URL baseUrl = new ClassPathResource("template/label/").getURL(); + PdfGeneratorUtil.generatePdf("物料明细标签", html, baseUrl.toString(), response); + } } \ No newline at end of file diff --git a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java index c099aa5f..3b367d6b 100644 --- a/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java +++ b/nflg-wms-shipment/src/main/java/com/nflg/wms/shipment/controller/PackagingCodeController.java @@ -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,33 @@ 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 list) throws Exception { + List types = dictionaryItemService.getListByDictionaryCode("PackagingType"); + + // 构建打印数据 + Map variables = new HashMap<>(); + variables.put("list", list.stream() + .map(data -> { + ShipmentPackagingCodeVO vo = new ShipmentPackagingCodeVO(); + vo.setNo(data.getNo()); + vo.setName(data.getName()); + vo.setTypeName(types.stream() + .filter(type -> type.getId().equals(data.getType())) + .map(DictionaryItem::getName) + .findFirst() + .orElse("")); + 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); + } } diff --git a/nflg-wms-shipment/src/main/resources/template/label/material-pdf.html b/nflg-wms-shipment/src/main/resources/template/label/material-pdf.html new file mode 100644 index 00000000..813de42f --- /dev/null +++ b/nflg-wms-shipment/src/main/resources/template/label/material-pdf.html @@ -0,0 +1,90 @@ + + + + + 包装码 + + + + +

- logo +
+ logo + 南方路机包装条码(中包)
+ -
dsafasffsaf
- -
+
dsafasffsaf
+ +
SAP编码: - - + 5215465224
+ 物料描述: - - + 反垄断法加快速度街坊
+ 批次号: - - + 2554565655
+ 供应商: - - + 地方都是发的顺丰寄
+ + + + + + + + + + + + + + + + +
+ +
0PC7B724KV6FM
+
+ 机台编号 + + 26LBZ4000L001 + + 客户名称 + + 北京市京联鑫路用材料有限公司 +
+ 物料编码 + + 3100006701 + + 数量 + + 10 +
+ +
+ + \ No newline at end of file diff --git a/nflg-wms-shipment/src/main/resources/template/label/packaging-pdf.html b/nflg-wms-shipment/src/main/resources/template/label/packaging-pdf.html new file mode 100644 index 00000000..2b9df155 --- /dev/null +++ b/nflg-wms-shipment/src/main/resources/template/label/packaging-pdf.html @@ -0,0 +1,92 @@ + + + + + 包装码标签-A4打印版 + + + + + +
+
+ + + + + +
+ +
NFLG-QZ-002
+
+
包装名称: NFLG-QZ-002 测试包装名称
+
包装类型: 托盘
+
+
+
+ + + \ No newline at end of file diff --git a/nflg-wms-shipment/src/test/java/com/nflg/wms/shipment/MaterialImageUploadTest.java b/nflg-wms-shipment/src/test/java/com/nflg/wms/shipment/MaterialImageUploadTest.java new file mode 100644 index 00000000..f5be1db8 --- /dev/null +++ b/nflg-wms-shipment/src/test/java/com/nflg/wms/shipment/MaterialImageUploadTest.java @@ -0,0 +1,210 @@ +package com.nflg.wms.shipment; + +import cn.hutool.core.io.FileUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.nflg.wms.repository.entity.WmsShipmentMaterial; +import com.nflg.wms.repository.mapper.WmsShipmentMaterialMapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.*; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.io.File; + +/** + * 物料图片批量上传测试 + * 从桌面的Output文件夹读取所有图片并上传,然后更新物料表的image字段 + */ +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = ShipmentApplication.class) +public class MaterialImageUploadTest { + + @Resource + private WmsShipmentMaterialMapper materialMapper; + + @Resource + private RestTemplate restTemplate; + + // 文件上传接口地址 + private static final String UPLOAD_URL = "https://pomp.nflg.net/api/admin/file/uploadSingleFile1"; + + @Test + public void testUploadImagesFromZip() { + // 桌面路径 + String desktopPath = System.getProperty("user.home") + File.separator + "Desktop"; + String outputDirPath = desktopPath + File.separator + "Output"; + + log.info("开始处理Output文件夹: {}", outputDirPath); + + // 检查文件夹是否存在 + File outputDir = new File(outputDirPath); + if (!outputDir.exists()) { + log.error("Output文件夹不存在: {}", outputDirPath); + throw new RuntimeException("Output文件夹不存在: " + outputDirPath); + } + + if (!outputDir.isDirectory()) { + log.error("路径不是文件夹: {}", outputDirPath); + throw new RuntimeException("路径不是文件夹: " + outputDirPath); + } + + // 递归获取所有图片文件 + java.util.List imageFiles = new java.util.ArrayList<>(); + collectImageFiles(outputDir, imageFiles); + + if (imageFiles.isEmpty()) { + log.warn("Output文件夹中没有找到图片文件"); + return; + } + + log.info("找到 {} 个图片文件", imageFiles.size()); + + // 处理每个图片文件 + int successCount = 0; + int notFoundCount = 0; + int errorCount = 0; + + for (File imageFile : imageFiles) { + try { + // 获取文件名(不带后缀) + String fileNameWithoutExt = FileUtil.getPrefix(imageFile.getName()); + log.info("处理文件: {}, 文件名(无后缀): {}", imageFile.getName(), fileNameWithoutExt); + + // 上传文件 + String url = uploadFile(imageFile); + log.info("文件上传成功, url: {}", url); + + // 根据no字段查找物料 + WmsShipmentMaterial material = materialMapper.selectOne( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(WmsShipmentMaterial::getNo, fileNameWithoutExt) + ); + + if (material != null) { + // 更新image字段 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(WmsShipmentMaterial::getNo, fileNameWithoutExt) + .set(WmsShipmentMaterial::getImage, url); + + int updateCount = materialMapper.update(null, updateWrapper); + if (updateCount > 0) { + imageFile.delete(); + log.info("成功更新物料 {} 的图片url", fileNameWithoutExt); + successCount++; + } else { + log.error("更新物料 {} 的图片url失败", fileNameWithoutExt); + errorCount++; + } + } else { + log.warn("未找到物料编号为 {} 的物料记录", fileNameWithoutExt); + notFoundCount++; + } + } catch (Exception e) { + log.error("处理文件 {} 时发生错误: {}", imageFile.getName(), e.getMessage(), e); + errorCount++; + } + } + + // 输出统计信息 + log.info("========================================"); + log.info("处理完成!"); + log.info("总文件数: {}", imageFiles.size()); + log.info("成功更新: {}", successCount); + log.info("未找到物料: {}", notFoundCount); + log.info("处理错误: {}", errorCount); + log.info("========================================"); + } + + /** + * 上传文件 - 调用HTTP接口 + */ + private String uploadFile(File file) { + // 构建multipart请求 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + headers.add("authorization", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiM3pCT2dQT203ZmZTVEY5S0gxYldaZ0w0ZmJGVW85TnoiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.Ircp8zNaLX7Wly7IZxEEdQrFo2BVfufXxXDhn7wSdrk"); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("file", new FileSystemResource(file)); + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + + // 使用String接收响应,避免Jackson反序列化LocalDateTime的问题 + ResponseEntity responseEntity = restTemplate.postForEntity(UPLOAD_URL, requestEntity, String.class); + + // 检查响应 + if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody() == null) { + throw new RuntimeException("文件上传失败,HTTP状态码: " + responseEntity.getStatusCode()); + } + + // 手动解析JSON + String responseBody = responseEntity.getBody(); + log.debug("上传响应: {}", responseBody); + + cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(responseBody); + int code = jsonObject.getInt("code", -1); + + if (code != 200) { + String message = jsonObject.getStr("message", "未知错误"); + throw new RuntimeException("文件上传失败: " + message); + } + + // 提取url + cn.hutool.json.JSONObject result = jsonObject.getJSONObject("result"); + if (result == null) { + throw new RuntimeException("文件上传失败: 返回结果为空"); + } + + String url = result.getStr("url"); + if (url == null || url.isEmpty()) { + throw new RuntimeException("文件上传失败: URL为空"); + } + + return url; + } + + /** + * 递归收集所有图片文件 + */ + private void collectImageFiles(File dir, java.util.List imageFiles) { + File[] files = dir.listFiles(); + if (files == null) { + return; + } + + for (File file : files) { + if (file.isDirectory()) { + collectImageFiles(file, imageFiles); + } else { + String lowerName = file.getName().toLowerCase(); + if (lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg") || + lowerName.endsWith(".png") || lowerName.endsWith(".gif") || + lowerName.endsWith(".bmp")) { + imageFiles.add(file); + } + } + } + } + + /** + * 递归删除目录 + */ + private void deleteDirectory(File file) { + if (file.isDirectory()) { + File[] files = file.listFiles(); + if (files != null) { + for (File f : files) { + deleteDirectory(f); + } + } + } + file.delete(); + } +}