package cn.iocoder.yudao.module.mes.service.pro.qrexport;
|
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.pallet.MesProPalletDO;
|
import cn.iocoder.yudao.module.mes.enums.pro.MesProPalletStatusEnum;
|
import cn.iocoder.yudao.module.mes.enums.pro.MesProQrExportBizTypeEnum;
|
import cn.iocoder.yudao.module.mes.framework.qrcode.QrLabelInfo;
|
import cn.iocoder.yudao.module.mes.service.pro.bagcode.MesProBagCodeService;
|
import cn.iocoder.yudao.module.mes.service.pro.batch.MesProBatchService;
|
import cn.iocoder.yudao.module.mes.service.pro.pallet.MesProPalletService;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Component;
|
|
import java.util.List;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_BATCH_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_PALLET_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_QR_EXPORT_PARAMS_INVALID;
|
|
/**
|
* 二维码标签数据源工厂
|
* <p>
|
* 把「业务类型 + 导出参数」翻译成统一的数据源,使后台导出任务不必关心标签是怎么来的,
|
* 也让同步导出路径与后台路径共用同一套取数与装配口径。
|
*/
|
@Component
|
public class MesProQrLabelSourceFactory {
|
|
@Resource
|
private MesProBagCodeService bagCodeService;
|
@Resource
|
private MesProPalletService palletService;
|
@Resource
|
private MesProBatchService batchService;
|
@Resource
|
private MesProQrLabelAssembler assembler;
|
|
/**
|
* 创建标签数据源;参数不合法时直接抛出业务异常
|
*
|
* @param bizType 业务类型
|
* @param uuid 生成组 UUID(袋码类导出可用)
|
* @param batchId 生产批次编号(袋码类可用,其余类型必填)
|
*/
|
public MesProQrLabelSource create(MesProQrExportBizTypeEnum bizType, String uuid, Long batchId) {
|
if (bizType == null) {
|
throw exception(PRO_QR_EXPORT_PARAMS_INVALID);
|
}
|
return switch (bizType) {
|
case BAG_LABEL -> bagSource(uuid, batchId, false);
|
case BAG_BUSINESS -> bagSource(uuid, batchId, true);
|
case PALLET_LABEL -> palletSource(requireBatchId(batchId), false);
|
case PALLET_BUSINESS -> palletSource(requireBatchId(batchId), true);
|
case BATCH_LABEL -> batchSource(requireBatchId(batchId), false);
|
case BATCH_BUSINESS -> batchSource(requireBatchId(batchId), true);
|
};
|
}
|
|
/**
|
* 统计标签张数(分流判断用,不装配标签内容)
|
*/
|
public long count(MesProQrExportBizTypeEnum bizType, String uuid, Long batchId) {
|
return create(bizType, uuid, batchId).count();
|
}
|
|
private Long requireBatchId(Long batchId) {
|
if (batchId == null) {
|
throw exception(PRO_QR_EXPORT_PARAMS_INVALID);
|
}
|
return batchId;
|
}
|
|
// ==================== 各业务类型的数据源 ====================
|
|
/**
|
* 袋码类数据源(标签 / 业务码)
|
*/
|
private MesProQrLabelSource bagSource(String uuid, Long batchId, boolean business) {
|
if (StrUtil.isBlank(uuid) && batchId == null) {
|
throw exception(PRO_QR_EXPORT_PARAMS_INVALID);
|
}
|
boolean byUuid = StrUtil.isNotBlank(uuid);
|
String zipName = (business ? "袋码业务二维码-" : "袋码二维码-") + (byUuid ? uuid : batchId);
|
return new MesProQrLabelSource() {
|
|
@Override
|
public long count() {
|
return byUuid ? bagCodeService.getPrintableBagCodeCountByUuid(uuid)
|
: bagCodeService.getPrintableBagCodeCountByBatchId(batchId);
|
}
|
|
@Override
|
public List<QrLabelInfo> fetchPage(int pageNo, int pageSize) {
|
List<MesProBagCodeDO> bags = byUuid
|
? bagCodeService.getPrintableBagCodePageByUuid(uuid, pageNo, pageSize)
|
: bagCodeService.getPrintableBagCodePageByBatchId(batchId, pageNo, pageSize);
|
return business ? assembler.buildBagBusinessLabels(bags) : assembler.buildBagCodeLabels(bags);
|
}
|
|
@Override
|
public String zipName() {
|
return zipName;
|
}
|
};
|
}
|
|
/**
|
* 托盘类数据源
|
* <p>
|
* 一个批次下的托盘数量有上界(受每托袋数约束),故一次性取出后按页切片,无需真分页查询。
|
*/
|
private MesProQrLabelSource palletSource(Long batchId, boolean business) {
|
List<MesProPalletDO> pallets = palletService.getPalletListByBatchId(batchId);
|
if (business) {
|
// 业务码导出需排除已作废托盘,避免作废码被印出
|
pallets = pallets.stream()
|
.filter(record -> !MesProPalletStatusEnum.CANCELED.getStatus().equals(record.getStatus()))
|
.toList();
|
}
|
if (pallets.isEmpty()) {
|
throw exception(PRO_PALLET_NOT_EXISTS);
|
}
|
List<QrLabelInfo> labels = business ? assembler.buildPalletBusinessLabels(pallets)
|
: assembler.buildPalletLabels(pallets);
|
String zipName = business ? "托盘业务二维码" : "托盘码二维码-" + batchId;
|
return fixedSource(labels, zipName);
|
}
|
|
/**
|
* 批次类数据源:批次图 + 该批次全部托盘图
|
*/
|
private MesProQrLabelSource batchSource(Long batchId, boolean business) {
|
MesProBatchDO batch = batchService.getBatch(batchId);
|
if (batch == null) {
|
throw exception(PRO_BATCH_NOT_EXISTS);
|
}
|
List<MesProPalletDO> pallets = palletService.getPalletListByBatchId(batchId);
|
if (business) {
|
pallets = pallets.stream()
|
.filter(record -> !MesProPalletStatusEnum.CANCELED.getStatus().equals(record.getStatus()))
|
.toList();
|
}
|
List<QrLabelInfo> labels = business ? assembler.buildBatchBusinessLabels(batch, pallets)
|
: assembler.buildBatchLabels(batch, pallets);
|
String zipName = business ? "批次业务二维码-" + batch.getBusinessCode()
|
: "批次二维码-" + StrUtil.blankToDefault(batch.getCode(), batch.getTempCode());
|
return fixedSource(labels, zipName);
|
}
|
|
/**
|
* 由已装配好的标签列表构造数据源(适用于总量有上界的场景)
|
*/
|
private MesProQrLabelSource fixedSource(List<QrLabelInfo> labels, String zipName) {
|
return new MesProQrLabelSource() {
|
|
@Override
|
public long count() {
|
return labels.size();
|
}
|
|
@Override
|
public List<QrLabelInfo> fetchPage(int pageNo, int pageSize) {
|
int from = (pageNo - 1) * pageSize;
|
if (from >= labels.size()) {
|
return List.of();
|
}
|
return labels.subList(from, Math.min(from + pageSize, labels.size()));
|
}
|
|
@Override
|
public String zipName() {
|
return zipName;
|
}
|
};
|
}
|
|
}
|