类似 : 两位单据前缀 + yyMMdd + 6位流水
RQ 20230220 000003
String number = idGenerator.generateCompleteN("RQ",6);
package com.tcl.tms.shipplatform.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
/**
* 编码生成器
*/
@Component(value = "idGeneratorServer")
public class IdGenerator {
@Autowired
private RedisTemplate redisTemplate;
private static String GENERATOR = "GENERATOR";
private static String GENERATOR_N = "GENERATOR_N";
private static String FORMAT = "yyMMdd";
private static String COMPLETE_FORMAT = "yyyyMMdd";
/**
* @Description: 根据参数type生成各类单据号:两位单据前缀 + yyMMdd + 三位流水
* @Param: type String
* @return:
* @Date: 2021/9/17 11:39
*/
public String generate(String type) {
//六位年月日 yyMMdd
String now = dateNow(FORMAT);
//根据日期每天生成一个key
String key = GENERATOR + ":" + type + now;
Long result = redisTemplate.opsForValue().increment(key, 1);
//过期时间,设置每天过期
Long expireTime = getSecondsNextEarlyMorning();
//每天编号重新开始
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
//序列号格式化3位
String order = String.format("%1$03d", result);
return String.format("%s%s%s", type, now, order);
}
/**
* @Description: 根据参数type生成各类单据号:两位单据前缀 + yyMMdd + 四位流水
* @Param: type String
* @Date: 2021/9/17 11:39
*/
public String generateFour(String type) {
//六位年月日 yyMMdd
String now = dateNow(FORMAT);
//根据日期每天生成一个key
String key = GENERATOR + ":" + type + now;
//生成序列从1开始,每次自增1
Long result = redisTemplate.opsForValue().increment(key, 1);
//过期时间,设置每天过期
Long expireTime = getSecondsNextEarlyMorning();
//每天编号重新开始
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
//序列号格式化4位
String order = String.format("%1$04d", result);
// int counter = getCounterFour(key);
//type:单据前缀,now:日期(yyMMdd),order:四位流水号
return String.format("%s%s%s", type, now, order);
}
/**
* @Description: 根据参数type生成各类单据号:两位单据前缀 + yyMMdd + 四位流水
* @Param: type String
* @return:
* @Date: 2021/9/17 11:39
*/
public String generateCompleteFour(String type) {
//六位年月日 yyMMdd
String now = dateNow(COMPLETE_FORMAT);
//根据日期每天生成一个key
String key = GENERATOR + ":" + type + now;
//生成序列从1开始,每次自增1
Long result = redisTemplate.opsForValue().increment(key, 1);
//过期时间,设置每天过期
Long expireTime = getSecondsNextEarlyMorning();
//每天编号重新开始
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
//序列号格式化4位
String order = String.format("%1$04d", result);
// int counter = getCounterFour(key);
//type:单据前缀,now:日期(yyMMdd),order:四位流水号
return String.format("%s%s%s", type, now, order);
}
/**
* @Description: 根据参数type生成各类单据号:两位单据前缀 + yyMMdd + 六位流水
* @Param: type String
* @return:
* @Date: 2021/9/17 11:39
*/
public String generateCompleteSix(String type) {
//六位年月日 yyMMdd
String now = dateNow(COMPLETE_FORMAT);
//根据日期每天生成一个key
String key = GENERATOR + ":" + type + now;
//生成序列从1开始,每次自增1
Long result = redisTemplate.opsForValue().increment(key, 1);
//过期时间,设置每天过期
Long expireTime = getSecondsNextEarlyMorning();
//每天编号重新开始
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
//序列号格式化4位
String order = String.format("%1$06d", result);
// int counter = getCounterFour(key);
//type:单据前缀,now:日期(yyMMdd),order:四位流水号
return String.format("%s%s%s", type, now, order);
}
/**
* @Description: 根据参数type生成各类单据号:两位单据前缀 + yyMMdd + 四位流水
* @Param: type String
* @Param: sequence 序号,生成多少位流水
* @return:
* @Date: 2022/8/11 11:39
*/
public String generateCompleteN(String type, int sequence) {
if (sequence < 1) {
sequence = 4;
}
//六位年月日 yyMMdd
String now = dateNow(COMPLETE_FORMAT);
//根据日期每天生成一个key
String key = GENERATOR_N + ":" + type + now;
//生成序列从1开始,每次自增1
Long result = redisTemplate.opsForValue().increment(key, 1);
//过期时间,设置每天过期
Long expireTime = getSecondsNextEarlyMorning();
//每天编号重新开始
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
//序列号格式化sequence位
String order = String.format("%1$0" + sequence + "d", result);
//type:单据前缀,now:日期(yyMMdd),order:sequence位流水号
return String.format("%s%s%s", type, now, order);
}
/**
* @Description: 判断当前时间距离第二天凌晨的秒数
* @Param: null
* @return: 返回值单位为[s:秒]
* @Date: 2021/9/17 11:41
*/
private static Long getSecondsNextEarlyMorning() {
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;
}
/**
* @Description: 获取当前日期的string格式,yyMMdd
* @Param: * @param String
* @return:
* @Date: 2021/9/22 15:35
*/
private static String dateNow(String format) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
return formatter.format(LocalDateTime.now());
}
}