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(); // 确保在最终释放锁
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|