- 通过业务前缀以及当前date组合为key,在redis中存入当日生成的单号的数量,过期时间为当日的23:59:59:999
- 每次调用接口后对redis中的对应key的单号数量进行自增
- 不同的业务前缀对应的数量互不干扰
生成的id组成为 业务前缀+日期+自增号,
例如2023/12/15的第一个销售单:XSD20231215000001
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
@Component
public class BusinessFlowNumberGenerator {
private static RedisTemplate<String,Object> redisTemplate;
private static final String DEFAULT_KEY_PREFIX = "";
private static final String DATE_KEY = "date";
private static final String PREFIX_DATE_FORMAT = "yyMMdd";
private static final String FORMAT_TEMPLATE = "{prefix}{date}{number}";
@Resource
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
BusinessFlowNumberGenerator.redisTemplate = redisTemplate;
}
private static long getsNumberMillisecondsFromCurrentDateToEndToday(){
LocalDateTime currentTime = LocalDateTime.now();
LocalDateTime midnight = currentTime.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
return ChronoUnit.MILLIS.between(currentTime, midnight);
}
public static String generateFlowNumber(String prefix) {
String dateStr = (String) redisTemplate.opsForValue().get(DATE_KEY);
if (dateStr == null) {
dateStr = new SimpleDateFormat(PREFIX_DATE_FORMAT).format(System.currentTimeMillis());
redisTemplate.opsForValue().set(DATE_KEY, dateStr, getsNumberMillisecondsFromCurrentDateToEndToday(), TimeUnit.MILLISECONDS);
}
String key = prefix + dateStr;
if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
Long incr = redisTemplate.opsForValue().increment(key, 1);
return FORMAT_TEMPLATE.replace("{prefix}", prefix).replace("{date}", dateStr).replace("{number}", String.format("%06d", incr));
} else {
redisTemplate.opsForValue().set(key, 1, getsNumberMillisecondsFromCurrentDateToEndToday(), TimeUnit.MILLISECONDS);
Long incr = 1L;
return FORMAT_TEMPLATE.replace("{prefix}", prefix).replace("{date}", dateStr).replace("{number}", String.format("%06d", incr));
}
}
public static String generateFlowNumber(){
return generateFlowNumber(DEFAULT_KEY_PREFIX);
}
使用
System.out.println(BusinessFlowNumberGenerator.generateFlowNumber());