提交 b7aa2dec authored 作者: liruixin's avatar liruixin

提前生成运单号

上级 08a9adbb
......@@ -16,4 +16,6 @@ public class RedisConstants {
public static final String TRUCK_LOCATION_KEY = "performance:truck_location_key:";
public static final String CARRIER_ORDER_NUM_POOL_KEY = "carrier:order:orderNumPool:{date}";
}
package com.clx.performance.job;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.clx.performance.constant.RedisConstants;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class OrderNoGenerateJob implements InitializingBean {
@Autowired
private ThreadPoolExecutor executor;
@Autowired
private ListOperations<String, Object> opsForListJson;
@Autowired
private RedisTemplate<String, Object> jsonTemplate;
/**
* 每天早上2点生成第二天的订单号 cron = "0 0 2 * * ?"
*
* 提前生成订单号
*/
@XxlJob("generateOrderNo")
public void generateOrderNo() throws InterruptedException {
LocalDateTime today = LocalDateTime.now();
//检验今天的订单池有没有,没有就生成一套
String todayKey = RedisConstants.CARRIER_ORDER_NUM_POOL_KEY.replace("{date}", today.format(DateTimeFormatter.BASIC_ISO_DATE));
Integer orderNum = (Integer) opsForListJson.leftPop(todayKey);
if(null == orderNum){
log.warn("开始生成订单池: key->{}", todayKey);
saveUniqueOrderNumList(todayKey, generateOrderNumList());
log.warn("生成订单池完成: key->{}", todayKey);
jsonTemplate.expire(todayKey, 1, TimeUnit.DAYS);
}
LocalDateTime tomorrow = today.plusDays(1);
//检验明天的订单池,没有就生成一套
String tomorrowKey = RedisConstants.CARRIER_ORDER_NUM_POOL_KEY.replace("{date}", tomorrow.format(DateTimeFormatter.BASIC_ISO_DATE));
orderNum = (Integer) opsForListJson.leftPop(tomorrowKey);
if(null == orderNum){
log.warn("开始生成订单池: key->{}", tomorrowKey);
saveUniqueOrderNumList(tomorrowKey, generateOrderNumList());
log.warn("生成订单池完成: key->{}", tomorrowKey);
jsonTemplate.expire(tomorrowKey, 2, TimeUnit.DAYS);
}
}
/**
* 保存到Redis
* @author wangjianxin
* @param key
* @param data
*/
private void saveUniqueOrderNumList(String key, List data) {
if(StringUtils.isBlank(key)){
log.info(key, "key不能为空");
}
if(CollectionUtils.isEmpty(data)){
log.info(key, "data不能为空");
}
for (int i = 0, j = 0; i < data.size(); i += 10000){
if(i >= data.size()){
i = data.size() -1;
}
j = i + 10000;
if(j > data.size()){
j = data.size();
}
try {
opsForListJson.leftPushAll(key, data.subList(i, j));
} catch (Exception e){
e.printStackTrace();
continue;
}
}
}
/**
* 生成乱序的6位的订单编号
* @author wangjianxin
* @return 乱序的6位订单编号从100000到999999
*/
private List<Integer> generateOrderNumList(){
List<Integer> orderNumList = new ArrayList<>();
for (Integer i = 100000; i < 999999; ++i){
orderNumList.add(i);
}
shuffleSort(orderNumList);
return orderNumList;
}
/**
* 交换
* @author wangjianxin
* @param data
* @param i
* @param j
*/
private static void swap(List<Integer> data, int i, int j) {
if (i == j) {
return;
}
Integer temp = data.get(i);
data.set(i, data.get(j));
data.set(j, temp);
}
/**
* 洗牌
* @author
* @param data
*/
private static void shuffleSort(List<Integer> data) {
for (int i = 0; i < data.size() - 1; i++) {
int j = ThreadLocalRandom.current().nextInt(data.size());
swap(data, i, j);
}
}
/**
* 初始化
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
//初始化redis中的订单池
executor.execute(new Runnable() {
@Override
public void run() {
try {
generateOrderNo();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论