package cn.iocoder.yudao.module.mes.service.pro.qrexport;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
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.framework.qrcode.MesProQrLabelBuilder;
import cn.iocoder.yudao.module.mes.framework.qrcode.QrLabelInfo;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.batch.MesProBatchService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
/**
* MES 二维码标签装配器
*
* 统一「查出关联数据(批次/品种/责任人)→ 组装标签」的逻辑,供同步导出接口与后台导出任务共用,
* 避免同一条装配规则在多个入口各写一份而出现口径不一致(历史上标签缺项就是这么来的)。
*/
@Component
public class MesProQrLabelAssembler {
@Resource
private MesProBatchService batchService;
@Resource
private MesMdmItemService mdmItemService;
@Resource
private AdminUserApi adminUserApi;
/**
* 构建袋码二维码标签(对外追溯标签,含国标四要素)
*/
public List buildBagCodeLabels(List list) {
if (list.isEmpty()) {
return Collections.emptyList();
}
// 1. 获得关联数据(批次、品种、责任人);品种集合含袋码自身品种与历史批次品种
Map batchMap = convertMap(
batchService.getBatchList(convertSet(list, MesProBagCodeDO::getBatchId)), MesProBatchDO::getId);
Set itemIds = convertSet(list, MesProBagCodeDO::getItemId);
itemIds.addAll(convertSet(batchMap.values(), MesProBatchDO::getItemId));
Map itemMap = mdmItemService.getItemMap(itemIds);
Map userMap = adminUserApi.getUserMap(
convertSet(batchMap.values(), MesProBatchDO::getOwnerUserId));
// 2. 构建标签
List labels = new ArrayList<>(list.size());
for (MesProBagCodeDO bagCode : list) {
labels.add(MesProQrLabelBuilder.buildBagCodeLabel(
bagCode, batchMap.get(bagCode.getBatchId()), itemMap, userMap));
}
return labels;
}
/**
* 构建袋码业务二维码标签(二维码仅编码内部业务码值)
*/
public List buildBagBusinessLabels(List list) {
return list.stream().map(MesProQrLabelBuilder::buildBagBusinessCodeLabel).toList();
}
/**
* 构建托盘二维码标签
*/
public List buildPalletLabels(List list) {
if (list.isEmpty()) {
return Collections.emptyList();
}
Map batchMap = convertMap(
batchService.getBatchList(convertSet(list, MesProPalletDO::getBatchId)), MesProBatchDO::getId);
Map itemMap = mdmItemService.getItemMap(
convertSet(batchMap.values(), MesProBatchDO::getItemId));
Map userMap = adminUserApi.getUserMap(
convertSet(batchMap.values(), MesProBatchDO::getOwnerUserId));
List labels = new ArrayList<>(list.size());
for (MesProPalletDO pallet : list) {
labels.add(MesProQrLabelBuilder.buildPalletLabel(
pallet, batchMap.get(pallet.getBatchId()), itemMap, userMap));
}
return labels;
}
/**
* 构建托盘业务二维码标签
*/
public List buildPalletBusinessLabels(List list) {
return list.stream().map(MesProQrLabelBuilder::buildPalletBusinessCodeLabel).toList();
}
/**
* 构建批次二维码标签:批次图 + 该批次全部托盘图
*
* 批次与托盘同属一批,品种/责任人共用同一份关联数据。
*/
public List buildBatchLabels(MesProBatchDO batch, List pallets) {
Map itemMap = mdmItemService.getItemMap(
convertSet(Collections.singletonList(batch), MesProBatchDO::getItemId));
Map userMap = adminUserApi.getUserMap(
convertSet(Collections.singletonList(batch), MesProBatchDO::getOwnerUserId));
List labels = new ArrayList<>(pallets.size() + 1);
labels.add(MesProQrLabelBuilder.buildBatchLabel(batch, itemMap, userMap));
for (MesProPalletDO pallet : pallets) {
labels.add(MesProQrLabelBuilder.buildPalletLabel(pallet, batch, itemMap, userMap));
}
return labels;
}
/**
* 构建批次业务二维码标签:批次业务码 + 全部托盘业务码
*/
public List buildBatchBusinessLabels(MesProBatchDO batch, List pallets) {
List labels = new ArrayList<>(pallets.size() + 1);
labels.add(MesProQrLabelBuilder.buildBatchBusinessCodeLabel(batch));
for (MesProPalletDO pallet : pallets) {
labels.add(MesProQrLabelBuilder.buildPalletBusinessCodeLabel(pallet));
}
return labels;
}
}