83 lines
2.5 KiB
Java
83 lines
2.5 KiB
Java
|
package com.greenorange.promotion.utils;
|
|||
|
|
|||
|
import java.text.SimpleDateFormat;
|
|||
|
import java.util.Date;
|
|||
|
import java.util.concurrent.atomic.AtomicInteger;
|
|||
|
import java.util.concurrent.locks.Lock;
|
|||
|
import java.util.concurrent.locks.ReentrantLock;
|
|||
|
|
|||
|
public class OrderNumberUtils {
|
|||
|
|
|||
|
|
|||
|
// 定义日期格式化器,精确到秒
|
|||
|
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
|
|||
|
|
|||
|
// 定义序列号最大值
|
|||
|
private static final int MAX_SEQUENCE = 999999;
|
|||
|
|
|||
|
// 当前日期,初始化为当天
|
|||
|
private static String currentDate = getCurrentDate();
|
|||
|
|
|||
|
// 自增序列号,线程安全
|
|||
|
private static final AtomicInteger sequence = new AtomicInteger(0);
|
|||
|
|
|||
|
// 锁对象,用于保护自增序列号的生成
|
|||
|
private static final Lock lock = new ReentrantLock();
|
|||
|
|
|||
|
|
|||
|
public static String generateOrderId() {
|
|||
|
// 获取当前日期
|
|||
|
String today = getCurrentDate();
|
|||
|
|
|||
|
// 如果日期发生变化,重置序列号
|
|||
|
if (!today.equals(currentDate)) {
|
|||
|
currentDate = today;
|
|||
|
sequence.set(0); // 重置序列号
|
|||
|
}
|
|||
|
|
|||
|
// 获取时间戳(精确到秒)
|
|||
|
String timestamp = DATE_FORMAT.format(new Date());
|
|||
|
|
|||
|
// 获取4位随机数
|
|||
|
String randomNumber = generateRandomNumber();
|
|||
|
|
|||
|
// 获取6位自增序列号,并确保不超过最大值
|
|||
|
int seq = getNextSequence();
|
|||
|
|
|||
|
// 格式化序列号为6位
|
|||
|
String formattedSequence = String.format("%06d", seq);
|
|||
|
|
|||
|
// 拼接生成订单号
|
|||
|
return timestamp + randomNumber + formattedSequence;
|
|||
|
}
|
|||
|
|
|||
|
// 获取当前日期(格式:yyyyMMdd)
|
|||
|
private static String getCurrentDate() {
|
|||
|
return new SimpleDateFormat("yyyyMMdd").format(new Date());
|
|||
|
}
|
|||
|
|
|||
|
// 生成4位随机数(范围:0000到9999)
|
|||
|
private static String generateRandomNumber() {
|
|||
|
int random = (int) (Math.random() * 10000); // 生成0到9999之间的随机数
|
|||
|
return String.format("%04d", random); // 格式化为4位
|
|||
|
}
|
|||
|
|
|||
|
// 获取下一个自增序列号,使用ReentrantLock来确保线程安全
|
|||
|
private static int getNextSequence() {
|
|||
|
lock.lock(); // 获取锁
|
|||
|
try {
|
|||
|
int seq = sequence.incrementAndGet();
|
|||
|
if (seq > MAX_SEQUENCE) {
|
|||
|
sequence.set(0); // 达到最大值后重置
|
|||
|
seq = sequence.incrementAndGet();
|
|||
|
}
|
|||
|
return seq;
|
|||
|
} finally {
|
|||
|
lock.unlock(); // 确保在最终释放锁
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|