feat(barcode): 添加成本中心退料条码功能并支持PDF和图片导出
- 在BarCodeType常量中新增CostcenterBack类型用于成本中心退料 - 实现成本中心退料物料条码PDF导出功能,支持逐个和整页两种模式 - 添加物料标签图片ZIP批量导出功能,生成PNG格式二维码标签 - 集成条码生成逻辑,自动为退料项目创建对应的二维码主数据 - 使用模板引擎生成标准化的条码打印页面布局 - 实现ZIP压缩流处理,支持多文件打包下载功能
This commit is contained in:
parent
f228433428
commit
63f62fd7bd
|
|
@ -7,46 +7,47 @@ import cn.hutool.core.util.IdUtil;
|
|||
import cn.hutool.core.util.StrUtil;
|
||||
import com.nflg.wms.admin.pojo.dto.PdfPageDTO;
|
||||
import com.nflg.wms.admin.pojo.request.NoScanningItemDataRequest;
|
||||
import com.nflg.wms.admin.pojo.request.NoScanningItemRequest;
|
||||
import com.nflg.wms.admin.pojo.request.NoScanningRequest;
|
||||
import com.nflg.wms.admin.repository.InMaterialScanRecordRespository;
|
||||
import com.nflg.wms.admin.service.BasdeSerialNumberControllerService;
|
||||
import com.nflg.wms.admin.service.NoScanningBaseControllerService;
|
||||
import com.nflg.wms.admin.service.SapService;
|
||||
import com.nflg.wms.admin.util.NoUtil;
|
||||
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.admin.util.*;
|
||||
import com.nflg.wms.common.constant.BarCodeProcessStage;
|
||||
import com.nflg.wms.common.constant.BarCodeType;
|
||||
import com.nflg.wms.common.pojo.ApiResult;
|
||||
import com.nflg.wms.common.pojo.PageData;
|
||||
import com.nflg.wms.common.pojo.document.InMaterialScanRecord;
|
||||
import com.nflg.wms.common.pojo.dto.C_MaterialReturnDTO;
|
||||
import com.nflg.wms.common.pojo.dto.DepartmentMaterialReturnSlipDTO;
|
||||
import com.nflg.wms.common.pojo.dto.InventoryInDTO;
|
||||
import com.nflg.wms.common.pojo.dto.OptRecordDTO;
|
||||
import com.nflg.wms.common.pojo.dto.*;
|
||||
import com.nflg.wms.common.pojo.qo.*;
|
||||
import com.nflg.wms.common.pojo.vo.*;
|
||||
import com.nflg.wms.common.util.UserUtil;
|
||||
import com.nflg.wms.common.util.VUtil;
|
||||
import com.nflg.wms.repository.entity.*;
|
||||
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.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.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 成本中心退料相关
|
||||
|
|
@ -563,4 +564,89 @@ public class InCostCenterBackController extends BaseController {
|
|||
String html = ThymeleafUtil.generator("/template/", "成本中心退料单", ".html", variables);
|
||||
PdfGeneratorUtil.generatePdf("成本中心退料入库单" + order.getNo(), html, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出物料条码pdf(逐个)
|
||||
* @param id 订单ID
|
||||
* @param type 1:逐个,2:一页
|
||||
*/
|
||||
@GetMapping("exportMaterialsPdf")
|
||||
public void exportMaterials(HttpServletResponse response, @Valid @RequestParam @NotNull Long id
|
||||
, @Valid @RequestParam @NotNull Integer type) throws Exception {
|
||||
WmsInCostcenterBack order = inCostcenterBackService.getById(id);
|
||||
VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("订单不存在");
|
||||
List<WmsInCostcenterBackItem> items = inCostcenterBackItemService.lambdaQuery()
|
||||
.eq(WmsInCostcenterBackItem::getOrderId, id)
|
||||
.list();
|
||||
List<QrCodeMasterPrintDTO> datas = convertToPrintDTO(getQrCodesByItems(items));
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("list", datas);
|
||||
if (Objects.equals(type, 1)) {
|
||||
String html = ThymeleafUtil.generator("/template/qrcode/", "dp-1", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/qrcode/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("普通物料条码(逐个)", html, baseUrl.toString(), response);
|
||||
} else {
|
||||
String html = ThymeleafUtil.generator("/template/qrcode/", "dp-2", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/qrcode/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("普通物料条码(整张)", html, baseUrl.toString(), response);
|
||||
}
|
||||
}
|
||||
|
||||
private List<WmsQrCodeMaster> getQrCodesByItems(List<WmsInCostcenterBackItem> items) {
|
||||
List<WmsQrCodeMaster> qrCodeMasters = qrCodeMasterService.getByExtendIds(items.stream().map(WmsInCostcenterBackItem::getId).toList());
|
||||
items.removeIf(it -> qrCodeMasters.stream().anyMatch(qr -> qr.getExtendId().equals(it.getId())));
|
||||
if (CollectionUtil.isNotEmpty(items)) {
|
||||
List<WmsQrCodeMaster> qrNew = items.stream().map(it -> new WmsQrCodeMaster()
|
||||
.setBarcodeCode(KeyUtil.next())
|
||||
.setProcessStage(BarCodeProcessStage.ForStorage.getState())
|
||||
.setBarcodeType(BarCodeType.CostcenterBack.getState())
|
||||
.setMaterialCode(it.getMatnr())
|
||||
.setMaterialDescription(it.getMaktx())
|
||||
.setPackagingType((short) 0)
|
||||
.setQuantity(it.getNum())
|
||||
.setUnit(it.getMeins())
|
||||
.setBatchNo(serialNumberControllerService.generateInventoryInBatchNo(it.getMatnr()))
|
||||
.setSerialNo("")
|
||||
.setExtendId(it.getId())
|
||||
.setCreateUserId(UserUtil.getUserId())
|
||||
.setCreateUserName(UserUtil.getUserName())
|
||||
.setCreateTime(LocalDateTime.now())
|
||||
).toList();
|
||||
qrCodeMasterService.saveBatch(qrNew);
|
||||
qrCodeMasters.addAll(qrNew);
|
||||
}
|
||||
return qrCodeMasters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出物料标签图片ZIP
|
||||
* @param id 订单ID
|
||||
*/
|
||||
@GetMapping(value = "exportItemImageZip", produces = "application/zip")
|
||||
public ResponseEntity<byte[]> exportItemImageZip(@Valid @RequestParam @NotNull Long id) throws Exception {
|
||||
WmsInCostcenterBack order = inCostcenterBackService.getById(id);
|
||||
VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("订单不存在");
|
||||
List<WmsInCostcenterBackItem> items = inCostcenterBackItemService.lambdaQuery()
|
||||
.eq(WmsInCostcenterBackItem::getOrderId, id)
|
||||
.list();
|
||||
List<QrCodeMasterPrintDTO> datas = convertToPrintDTO(getQrCodesByItems(items));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
|
||||
for (QrCodeMasterPrintDTO it : datas) {
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("list", List.of(it));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,11 @@ public enum BarCodeType {
|
|||
/**
|
||||
* 生产物料
|
||||
*/
|
||||
Production((short) 4, "生产物料");
|
||||
Production((short) 4, "生产物料"),
|
||||
/**
|
||||
* 成本中心退料
|
||||
*/
|
||||
CostcenterBack((short) 5, "成本中心退料");
|
||||
|
||||
private final short state;
|
||||
private final String description;
|
||||
|
|
|
|||
Loading…
Reference in New Issue