package com.baiyue.common.event; import java.util.Locale; /** 跨服务业务事实使用的真实集装箱号,只规范化空白和大小写,不校验 ISO 格式。 */ public final class ContainerNumbers { private ContainerNumbers() { } /** 柜号必须非空;统一移除格式空白并转大写,保留业务录入值。 */ public static String normalizeRequired(String value) { if (value == null || value.isBlank()) { throw new IllegalArgumentException("containerNo is required"); } StringBuilder compact = new StringBuilder(value.length()); value.codePoints().filter(codePoint -> !Character.isWhitespace(codePoint) && !Character.isSpaceChar(codePoint)).forEach(compact::appendCodePoint); String normalized = compact.toString().toUpperCase(Locale.ROOT); if (normalized.isEmpty()) { throw new IllegalArgumentException("containerNo is required"); } return normalized; } /** 冻结事实必须已规范化,避免生产与消费端的快照或哈希发生漂移。 */ public static String requireCanonical(String value) { String normalized = normalizeRequired(value); if (!normalized.equals(value)) { throw new IllegalArgumentException("containerNo must be normalized"); } return normalized; } }