package cn.iocoder.yudao.module.mes.framework.qrcode;
|
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.util.StrUtil;
|
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.system.api.user.dto.AdminUserRespDTO;
|
|
import java.nio.charset.StandardCharsets;
|
import java.net.URLEncoder;
|
import java.util.LinkedHashMap;
|
import java.util.Map;
|
|
/**
|
* MES 二维码标签构建器:统一"二维码编码内容 + 图片叠加可读文本"的文本组装规则,
|
* 保证批次、托盘、袋码三种标签的关键信息保留一致。
|
* <p>
|
* 配置了 {@code mes.trace-base-url} 时,二维码内容为 H5 溯源地址(带 code 参数),否则回退为纯码值(兼容旧码)
|
*/
|
public final class MesProQrLabelBuilder {
|
|
private MesProQrLabelBuilder() {
|
}
|
|
/**
|
* H5 溯源页面基础地址,由 {@code MesQrCodeConfig} 启动时注入;为空时二维码编码纯码值
|
*/
|
private static volatile String traceBaseUrl = "";
|
|
public static void setTraceBaseUrl(String traceBaseUrl) {
|
MesProQrLabelBuilder.traceBaseUrl = StrUtil.blankToDefault(traceBaseUrl, "");
|
}
|
|
/**
|
* 组装二维码内容:配置了溯源地址则拼 URL,否则返回纯码值
|
*/
|
private static String buildQrCodeContent(String code) {
|
if (StrUtil.isEmpty(traceBaseUrl)) {
|
return code;
|
}
|
return traceBaseUrl + "?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8);
|
}
|
|
/**
|
* 批次二维码标签
|
*/
|
public static QrLabelInfo buildBatchLabel(MesProBatchDO batch,
|
Map<Long, MesMdmItemDO> itemMap,
|
Map<Long, AdminUserRespDTO> userMap) {
|
// 未补录业务信息时用临时批次码作为二维码内容,并明确提示状态;品种/产线等信息缺失时不拼接空文本
|
String code = StrUtil.blankToDefault(batch.getCode(), batch.getTempCode());
|
LinkedHashMap<String, String> keyValues = new LinkedHashMap<>();
|
keyValues.put("批次号", code);
|
if (StrUtil.isEmpty(batch.getCode())) {
|
keyValues.put("状态", "待补录");
|
}
|
MesMdmItemDO item = itemMap.get(batch.getItemId());
|
if (item != null) {
|
keyValues.put("品种", item.getName());
|
keyValues.put("规格", item.getSpecification());
|
}
|
if (StrUtil.isNotEmpty(batch.getLineName()) || StrUtil.isNotEmpty(batch.getLineCode())) {
|
keyValues.put("产线", StrUtil.join(" / ", batch.getLineName(), batch.getLineCode()));
|
}
|
if (batch.getProduceDate() != null) {
|
keyValues.put("生产日期", LocalDateTimeUtil.format(batch.getProduceDate(), "yyyy-MM-dd HH:mm"));
|
}
|
if (batch.getPlanQuantity() != null) {
|
keyValues.put("计划数量", String.valueOf(batch.getPlanQuantity()));
|
}
|
AdminUserRespDTO user = userMap.get(batch.getOwnerUserId());
|
if (user != null) {
|
keyValues.put("责任人", user.getNickname());
|
}
|
return QrLabelInfo.builder().fileName(code).code(buildQrCodeContent(code)).keyValues(keyValues).build();
|
}
|
|
/**
|
* 托盘二维码标签
|
*/
|
public static QrLabelInfo buildPalletLabel(MesProPalletDO pallet,
|
MesProBatchDO batch,
|
Map<Long, MesMdmItemDO> itemMap,
|
Map<Long, AdminUserRespDTO> userMap) {
|
// 未绑定批次(临时托盘码)时用临时码作为二维码内容并明确提示状态
|
String code = StrUtil.blankToDefault(pallet.getCode(), pallet.getTempCode());
|
LinkedHashMap<String, String> keyValues = new LinkedHashMap<>();
|
keyValues.put("托盘码", code);
|
if (StrUtil.isEmpty(pallet.getCode())) {
|
keyValues.put("状态", "未绑定批次");
|
}
|
keyValues.put("托盘序号", pallet.getPalletNo() == null ? "" : String.valueOf(pallet.getPalletNo()));
|
if (StrUtil.isNotEmpty(pallet.getBatchCode())) {
|
keyValues.put("批次号", pallet.getBatchCode());
|
}
|
if (pallet.getBagCount() != null) {
|
keyValues.put("已装袋数", String.valueOf(pallet.getBagCount()));
|
}
|
if (batch != null) {
|
fillBatchKeyValues(keyValues, batch, itemMap, userMap);
|
}
|
return QrLabelInfo.builder().fileName(code).code(buildQrCodeContent(code)).keyValues(keyValues).build();
|
}
|
|
/**
|
* 袋码二维码标签
|
*/
|
public static QrLabelInfo buildBagCodeLabel(MesProBagCodeDO bagCode,
|
MesProBatchDO batch,
|
Map<Long, MesMdmItemDO> itemMap,
|
Map<Long, AdminUserRespDTO> userMap) {
|
LinkedHashMap<String, String> keyValues = new LinkedHashMap<>();
|
keyValues.put("袋码", bagCode.getCode());
|
keyValues.put("袋序号", bagCode.getBagNo() == null ? "" : String.valueOf(bagCode.getBagNo()));
|
keyValues.put("批次号", bagCode.getBatchCode());
|
if (StrUtil.isNotEmpty(bagCode.getPalletCode())) {
|
keyValues.put("绑定托盘", bagCode.getPalletCode());
|
}
|
if (batch != null) {
|
fillBatchKeyValues(keyValues, batch, itemMap, userMap);
|
}
|
return QrLabelInfo.builder().fileName(bagCode.getCode()).code(buildQrCodeContent(bagCode.getCode())).keyValues(keyValues).build();
|
}
|
|
/**
|
* 填充批次公共可读文本(品种、规格、产线、生产日期、责任人)
|
*/
|
private static void fillBatchKeyValues(LinkedHashMap<String, String> keyValues, MesProBatchDO batch,
|
Map<Long, MesMdmItemDO> itemMap, Map<Long, AdminUserRespDTO> userMap) {
|
MesMdmItemDO item = itemMap.get(batch.getItemId());
|
if (item != null) {
|
keyValues.put("品种", item.getName());
|
keyValues.put("规格", item.getSpecification());
|
}
|
keyValues.put("产线", StrUtil.join(" / ", batch.getLineName(), batch.getLineCode()));
|
keyValues.put("生产日期", batch.getProduceDate() == null ? ""
|
: LocalDateTimeUtil.format(batch.getProduceDate(), "yyyy-MM-dd HH:mm"));
|
AdminUserRespDTO user = userMap.get(batch.getOwnerUserId());
|
if (user != null) {
|
keyValues.put("责任人", user.getNickname());
|
}
|
}
|
|
}
|