import com.alibaba.druid.util.StringUtils; import com.google.common.base.Preconditions; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.concurrent.TimeUnit; import lombok.AllArgsConstructor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; /** * 生成编号组件类 * * @author huangkl * @version v1.0 * @date 2020/9/27/027 9:31 */ @Component @AllArgsConstructor @Slf4j public class ProductionSerialNOComponent { private final RedisTemplate redisTemplate; private final String REDIS_CACHE_KEY = "com:keyu:codes_of_unused:"; /** * 生成编号: 基于redis实现, 第一次获取编号先往redis中预存不重复的code, 再取出用作生成流水号以保证不重复, code数量不足时位数自动增加一位, 每天凌晨0点清理预存 * * @param digits 位数 * @param prefix 前缀 * @return Boolean * @author huangkl */ public String getNO(Integer digits, String prefix) { Preconditions.checkNotNull(digits, "位数不能为空"); Preconditions.checkArgument(digits < 7, "位数不能超过六位"); Preconditions.checkArgument(!StringUtils.isEmpty(prefix), "前缀不能为空"); String code = getCode(digits); String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); return prefix + date + code; } private String getCode(Integer digits) { String key = REDIS_CACHE_KEY + digits; Integer code = (Integer) redisTemplate.opsForSet().pop(key); if (code == null) { Integer[] nos = generateCodes(digits); redisTemplate.opsForSet().add(key, nos); redisTemplate.expire(key, getNowToNextDaySeconds(), TimeUnit.SECONDS); code = (Integer) redisTemplate.opsForSet().pop(key); } else { if (redisTemplate.opsForSet().size(key) == 0) { // code用完了,向下一位进 int length = code.toString().length() + 1; Integer[] list = generateCodes(length); redisTemplate.opsForSet().add(key, list); redisTemplate.expire(key, getNowToNextDaySeconds(), TimeUnit.SECONDS); } } return code.toString(); } private Integer[] generateCodes(Integer digits) { StringBuffer minString = new StringBuffer("1"); StringBuffer maxString = new StringBuffer("9"); List<Integer> list = new ArrayList<>(); for (int i = 1; i < digits; i++) { minString.append("0"); maxString.append("9"); } int min = Integer.parseInt(minString.toString()); int max = Integer.parseInt(maxString.toString()); for (int k = min; k <= max; k++) { list.add(k); } Integer[] array = list.toArray(new Integer[list.size()]); return array; } /** * 计算第二天凌晨与当前时间的时间差秒数 * * @param * @return java.lang.Long * @author huangkl */ private Long getNowToNextDaySeconds() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_YEAR, 1); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.MILLISECOND, 0); return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000; } }
编号,订单号生成
最新推荐文章于 2024-09-15 10:16:54 发布