GenerateOCAPIdUtil.java

package com.mycim.utils;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.valueobject.consts.OcapTypeEnum;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.ThreadLocalRandom;

public class GenerateOCAPIdUtil {

    public static final String SUFFIX_PLACEHOLDER = "___";

    private static final String PREFIX_TYPE = "OCAP";

    private static final String INLINE_PREFIX_TYPE = "OCAPI-";

    private static final String OFFLINE_PREFIX_TYPE = "OCAPO-";

    private static final String DATE_FORMAT = "yyyyMMddHHmmss";

    private static final String SUFFIX_PATTERN = "000";

    private static final Integer MAX_SEQUENCE = 999;

    private static final Integer PREFIX_LENGTH;

    private static final Integer ID_LENGTH;

    static {
        PREFIX_LENGTH = PREFIX_TYPE.length() + 2 + DATE_FORMAT.length() + SUFFIX_PLACEHOLDER.length();
        ID_LENGTH = PREFIX_LENGTH + SUFFIX_PATTERN.length();
    }

    public static String generate(String prefix, String maxPlanId, String planType) {
        int nextSeq = 1;
        if (StringUtils.isNotEmpty(maxPlanId)) {
            nextSeq += substringForSeq(maxPlanId);
            Assert.isFalse(nextSeq > MAX_SEQUENCE, Errors.create().content(
                    "The generated serial number has reached the maximum serial number of the day. Please " +
                            "apply again tomorrow.").build());
        }

        // 获取时间戳
        String currentTimeStr = System.currentTimeMillis() + "";
        currentTimeStr = StringUtils.substring(currentTimeStr, -3);
        // 以时间戳后三位作为随机数边界
        int boundaries = Integer.parseInt(currentTimeStr);
        int randomNum = ThreadLocalRandom.current().nextInt(boundaries);
        // 补充位数
        String randomStr = new DecimalFormat(SUFFIX_PATTERN).format(randomNum);
        // 替换前缀中的___
        prefix = StringUtils.replaceAll(prefix, SUFFIX_PLACEHOLDER, randomStr);

        StringBuilder stringBuilder = new StringBuilder().append(prefix);
        return stringBuilder.append(new DecimalFormat(SUFFIX_PATTERN).format(nextSeq)).toString();
    }

    public static String buildPrefix(String ocapType) {
        StringBuilder stringBuilder = new StringBuilder(ID_LENGTH);
        if (OcapTypeEnum.isInline(ocapType)) {
            stringBuilder.append(INLINE_PREFIX_TYPE);
        } else {
            stringBuilder.append(OFFLINE_PREFIX_TYPE);
        }
        stringBuilder.append(new SimpleDateFormat(DATE_FORMAT).format(Calendar.getInstance().getTime()));
        // 预留随机数位置
        stringBuilder.append(SUFFIX_PLACEHOLDER);
        return stringBuilder.toString();
    }

    private static int substringForSeq(String maxEcnId) {
        return Integer.parseInt(maxEcnId.substring(PREFIX_LENGTH, ID_LENGTH));
    }

}