5 小时以前 6d910029b6c81db0a2b66caa66952781397b153a
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/framework/qrcode/MesProQrLabelBuilder.java
@@ -8,16 +8,39 @@
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 二维码标签构建器:统一"二维码编码纯码值 + 图片叠加可读文本"的文本组装规则,
 * 保证批次、托盘、袋码三种标签的关键信息保留一致
 * 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);
    }
    /**
@@ -26,16 +49,24 @@
    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("批次号", batch.getCode());
        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());
        }
        keyValues.put("产线", StrUtil.join(" / ", batch.getLineName(), batch.getLineCode()));
        keyValues.put("生产日期", batch.getProduceDate() == null ? ""
                : LocalDateTimeUtil.format(batch.getProduceDate(), "yyyy-MM-dd HH:mm"));
        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()));
        }
@@ -43,7 +74,7 @@
        if (user != null) {
            keyValues.put("责任人", user.getNickname());
        }
        return QrLabelInfo.builder().fileName(batch.getCode()).code(batch.getCode()).keyValues(keyValues).build();
        return QrLabelInfo.builder().fileName(code).code(buildQrCodeContent(code)).keyValues(keyValues).build();
    }
    /**
@@ -53,17 +84,24 @@
                                               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("托盘码", pallet.getCode());
        keyValues.put("托盘码", code);
        if (StrUtil.isEmpty(pallet.getCode())) {
            keyValues.put("状态", "未绑定批次");
        }
        keyValues.put("托盘序号", pallet.getPalletNo() == null ? "" : String.valueOf(pallet.getPalletNo()));
        keyValues.put("批次号", pallet.getBatchCode());
        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(pallet.getCode()).code(pallet.getCode()).keyValues(keyValues).build();
        return QrLabelInfo.builder().fileName(code).code(buildQrCodeContent(code)).keyValues(keyValues).build();
    }
    /**
@@ -83,7 +121,7 @@
        if (batch != null) {
            fillBatchKeyValues(keyValues, batch, itemMap, userMap);
        }
        return QrLabelInfo.builder().fileName(bagCode.getCode()).code(bagCode.getCode()).keyValues(keyValues).build();
        return QrLabelInfo.builder().fileName(bagCode.getCode()).code(buildQrCodeContent(bagCode.getCode())).keyValues(keyValues).build();
    }
    /**