package com.box.redis.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* id生产器
*
* @author yuan.dingwang
* @date 2020年11月23日 17:00
*/
@Component
public class IdGeneratorFactory {
@Autowired
public RedisTemplate redisTemplate;
public static final String SERIAL_YYYYMMDD_PREFIX = "yyyyMMdd";
public static final String SERIAL_CACHE_PREFIX = "ID_GENERATOR:";
/**
* 生成单号前缀
*/
private static String getFormNoPrefix() {
//格式化时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(SERIAL_YYYYMMDD_PREFIX);
StringBuffer sb = new StringBuffer();
sb.append(formatter.format(LocalDateTime.now()));
return sb.toString();
}
/**
* 构建流水号缓存Key
*
* @param serialPrefix 流水号前缀
* @return 流水号缓存Key
*/
public static String getCacheKey(String serialPrefix) {
return SERIAL_CACHE_PREFIX.concat(serialPrefix);
}
/**
* 补全流水号
*
* @param serialPrefix 单号前缀
* @param incrementalSerial 当天自增流水号
* @author yuan.domhwamh
* @date 2019/1/1
*/
public static String completionSerial(String serialPrefix, Long incrementalSerial) {
StringBuffer sb = new StringBuffer(serialPrefix);
//需要补0的长度=流水号长度 -当日自增计数长度
int length = 7 - String.valueOf(incrementalSerial).length();
//补零
for (int i = 0; i < length; i++) {
sb.append("0");
}
//redis当日自增数
sb.append(incrementalSerial);
return sb.toString();
}
/**
* 补全随机数
*
* @param serialWithPrefix 当前单号
* @author yuan.dingwang
* @date 2019/1/1
*/
public static String completionRandom(String serialWithPrefix) {
StringBuffer sb = new StringBuffer(serialWithPrefix);
//随机数长度
int length = 5;
if (length > 0) {
Random random = new Random();
for (int i = 0; i < length; i++) {
//十以内随机数补全
sb.append(random.nextInt(10));
}
}
return sb.toString();
}
/**
* 获取表id
* @param table 表名称 IdTableEnum 类描述表名称
* @return
*/
public String generateTableNo(String table) {
//获得单号前缀
//格式 固定前缀 +时间前缀 示例 :YF20190101
String formNoPrefix = getFormNoPrefix();
//获得缓存key
String cacheKey = getCacheKey(table.toUpperCase());
//获得当日自增数
Long incrementalSerial = redisTemplate.opsForValue().increment(cacheKey, 1);
//设置失效时间1天
redisTemplate.expire(cacheKey, 1, TimeUnit.DAYS);
//组合单号并补全流水号
String serialWithPrefix = completionSerial(formNoPrefix, incrementalSerial);
//补全随机数
return completionRandom(serialWithPrefix);
}
}