更新了商品管理模块
This commit is contained in:
parent
724529846e
commit
ef5354abb3
|
@ -0,0 +1,24 @@
|
||||||
|
package com.cultural.heritage.constant;
|
||||||
|
|
||||||
|
public interface OrderStatusConstant {
|
||||||
|
|
||||||
|
|
||||||
|
String PENDING_PAYMENT = "待支付";
|
||||||
|
|
||||||
|
|
||||||
|
String PENDING_SHIPMENT = "待发货";
|
||||||
|
|
||||||
|
|
||||||
|
String PENDING_DELIVERY = "待收货";
|
||||||
|
|
||||||
|
|
||||||
|
String TRANSACTION_CLOSED = "交易关闭";
|
||||||
|
|
||||||
|
|
||||||
|
String TRANSACTION_SUCCESSFUL = "交易成功";
|
||||||
|
|
||||||
|
|
||||||
|
String PAYMENT_REFUNDED = "已退款";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import com.cultural.heritage.annotation.AuthCheck;
|
||||||
import com.cultural.heritage.common.BaseResponse;
|
import com.cultural.heritage.common.BaseResponse;
|
||||||
import com.cultural.heritage.common.ErrorCode;
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
import com.cultural.heritage.common.ResultUtils;
|
import com.cultural.heritage.common.ResultUtils;
|
||||||
|
import com.cultural.heritage.constant.OrderStatusConstant;
|
||||||
import com.cultural.heritage.constant.UserConstant;
|
import com.cultural.heritage.constant.UserConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.exception.ThrowUtils;
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
|
@ -23,6 +24,7 @@ import com.cultural.heritage.model.vo.order.OrderVO;
|
||||||
import com.cultural.heritage.service.order.OrderItemService;
|
import com.cultural.heritage.service.order.OrderItemService;
|
||||||
import com.cultural.heritage.service.order.OrderService;
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
import com.cultural.heritage.service.user.UserService;
|
import com.cultural.heritage.service.user.UserService;
|
||||||
|
import com.cultural.heritage.utils.OrderNumberUtils;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
@ -78,6 +80,11 @@ public class OrderController {
|
||||||
Order order = new Order();
|
Order order = new Order();
|
||||||
BeanUtils.copyProperties(orderAddRequest, order);
|
BeanUtils.copyProperties(orderAddRequest, order);
|
||||||
order.setUserId(loginUser.getId());
|
order.setUserId(loginUser.getId());
|
||||||
|
// 生成订单编号
|
||||||
|
String orderNumber = OrderNumberUtils.generateOrderId();
|
||||||
|
order.setOrderNumber(orderNumber);
|
||||||
|
// 设置订单状态
|
||||||
|
order.setOrderStatus(OrderStatusConstant.PENDING_PAYMENT);
|
||||||
// 校验订单
|
// 校验订单
|
||||||
orderService.validOrder(order);
|
orderService.validOrder(order);
|
||||||
boolean result = orderService.save(order);
|
boolean result = orderService.save(order);
|
||||||
|
|
|
@ -4,6 +4,7 @@ package com.cultural.heritage.controller.wx;
|
||||||
import com.cultural.heritage.common.BaseResponse;
|
import com.cultural.heritage.common.BaseResponse;
|
||||||
import com.cultural.heritage.common.ErrorCode;
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
import com.cultural.heritage.common.ResultUtils;
|
import com.cultural.heritage.common.ResultUtils;
|
||||||
|
import com.cultural.heritage.constant.OrderStatusConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.exception.ThrowUtils;
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
import com.cultural.heritage.model.dto.CommonRequest;
|
import com.cultural.heritage.model.dto.CommonRequest;
|
||||||
|
@ -55,7 +56,7 @@ public class WeChatPayController {
|
||||||
Long orderId = commonRequest.getId();
|
Long orderId = commonRequest.getId();
|
||||||
Order order = ordersService.getById(orderId);
|
Order order = ordersService.getById(orderId);
|
||||||
ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
|
ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
|
||||||
// ThrowUtils.throwIf(order.getState() != 0, ErrorCode.OPERATION_ERROR, "订单状态错误");
|
ThrowUtils.throwIf(!order.getOrderStatus().equals(OrderStatusConstant.PENDING_PAYMENT), ErrorCode.OPERATION_ERROR, "订单状态错误");
|
||||||
if (!loginUser.getId().equals(order.getUserId())) {
|
if (!loginUser.getId().equals(order.getUserId())) {
|
||||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "你不是该订单用户!");
|
throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "你不是该订单用户!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,12 @@ public class OrderMainInfoAddRequest implements Serializable {
|
||||||
@Schema(description = "用户昵称", example = "Hello")
|
@Schema(description = "用户昵称", example = "Hello")
|
||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* 订单编号
|
// * 订单编号
|
||||||
*/
|
// */
|
||||||
@Schema(description = "订单编号", example = "1432442845453453")
|
// @Schema(description = "订单编号", example = "1432442845453453")
|
||||||
private String orderNumber;
|
// private String orderNumber;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,11 +69,11 @@ public class OrderMainInfoAddRequest implements Serializable {
|
||||||
@Schema(description = "订单总金额", example = "560")
|
@Schema(description = "订单总金额", example = "560")
|
||||||
private BigDecimal totalAmount;
|
private BigDecimal totalAmount;
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 订单状态
|
// * 订单状态
|
||||||
*/
|
// */
|
||||||
@Schema(description = "订单状态", example = "已支付")
|
// @Schema(description = "订单状态", example = "已支付")
|
||||||
private String orderStatus;
|
// private String orderStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单备注
|
* 订单备注
|
||||||
|
|
|
@ -97,8 +97,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||||
Long contactsId = orderMainInfoAddRequest.getContactsId();
|
Long contactsId = orderMainInfoAddRequest.getContactsId();
|
||||||
Long couponId = orderMainInfoAddRequest.getCouponId();
|
Long couponId = orderMainInfoAddRequest.getCouponId();
|
||||||
String orderType = orderMainInfoAddRequest.getOrderType();
|
String orderType = orderMainInfoAddRequest.getOrderType();
|
||||||
String orderNumber = orderMainInfoAddRequest.getOrderNumber();
|
|
||||||
String orderStatus = orderMainInfoAddRequest.getOrderStatus();
|
|
||||||
String note = orderMainInfoAddRequest.getNote();
|
String note = orderMainInfoAddRequest.getNote();
|
||||||
BigDecimal totalAmount = orderMainInfoAddRequest.getTotalAmount();
|
BigDecimal totalAmount = orderMainInfoAddRequest.getTotalAmount();
|
||||||
List<OrderItemMainInfoAddRequest> orderItemMainInfoAddRequestList = orderMainInfoAddRequest.getOrderItemMainInfoAddRequestList();
|
List<OrderItemMainInfoAddRequest> orderItemMainInfoAddRequestList = orderMainInfoAddRequest.getOrderItemMainInfoAddRequestList();
|
||||||
|
@ -144,8 +142,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||||
// 创建订单详细信息请求体
|
// 创建订单详细信息请求体
|
||||||
OrderAddRequest orderAddRequest = new OrderAddRequest();
|
OrderAddRequest orderAddRequest = new OrderAddRequest();
|
||||||
orderAddRequest.setUserName(userName);
|
orderAddRequest.setUserName(userName);
|
||||||
orderAddRequest.setOrderNumber(orderNumber);
|
|
||||||
orderAddRequest.setOrderStatus(orderStatus);
|
|
||||||
orderAddRequest.setOrderType(orderType);
|
orderAddRequest.setOrderType(orderType);
|
||||||
orderAddRequest.setNote(note);
|
orderAddRequest.setNote(note);
|
||||||
orderAddRequest.setTotalAmount(totalAmount);
|
orderAddRequest.setTotalAmount(totalAmount);
|
||||||
|
|
|
@ -4,11 +4,13 @@ package com.cultural.heritage.service.wxpay.impl;
|
||||||
import cn.binarywang.wx.miniapp.api.WxMaMsgService;
|
import cn.binarywang.wx.miniapp.api.WxMaMsgService;
|
||||||
import cn.binarywang.wx.miniapp.api.WxMaService;
|
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||||
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
|
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.cultural.heritage.common.ErrorCode;
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
import com.cultural.heritage.config.WxOpenConfig;
|
import com.cultural.heritage.config.WxOpenConfig;
|
||||||
import com.cultural.heritage.config.WxPayConfig;
|
import com.cultural.heritage.config.WxPayConfig;
|
||||||
|
import com.cultural.heritage.constant.OrderStatusConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
import com.cultural.heritage.model.entity.Order;
|
import com.cultural.heritage.model.entity.Order;
|
||||||
import com.cultural.heritage.service.order.OrderService;
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
import com.cultural.heritage.service.wxpay.WeChatService;
|
import com.cultural.heritage.service.wxpay.WeChatService;
|
||||||
|
@ -31,11 +33,7 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -53,9 +51,8 @@ public class WeChatServiceImpl implements WeChatService {
|
||||||
private WxOpenConfig wxOpenConfig;
|
private WxOpenConfig wxOpenConfig;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private OrderService ordersService;
|
private OrderService orderService;
|
||||||
|
|
||||||
private String orderNumber;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求参数
|
* 请求参数
|
||||||
|
@ -80,12 +77,15 @@ public class WeChatServiceImpl implements WeChatService {
|
||||||
Payer payer = new Payer();
|
Payer payer = new Payer();
|
||||||
payer.setOpenid(miniOpenId);
|
payer.setOpenid(miniOpenId);
|
||||||
request.setPayer(payer);
|
request.setPayer(payer);
|
||||||
|
// 获取订单号
|
||||||
|
Order order = orderService.getById(orderId);
|
||||||
|
String orderNumber = order.getOrderNumber();
|
||||||
// 描述
|
// 描述
|
||||||
request.setDescription("订单号:" + orderId);
|
request.setDescription("订单号:" + orderNumber);
|
||||||
// 微信回调地址
|
// 微信回调地址
|
||||||
request.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/payment/callback");
|
request.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/payment/callback");
|
||||||
// 商户订单号
|
// 商户订单号
|
||||||
this.orderNumber = RandomUtil.randomNumbers(12);
|
|
||||||
request.setOutTradeNo(orderNumber);
|
request.setOutTradeNo(orderNumber);
|
||||||
//返回数据,前端调起支付
|
//返回数据,前端调起支付
|
||||||
return wxPayConfig.getJsapiServiceExtension().prepayWithRequestPayment(request);
|
return wxPayConfig.getJsapiServiceExtension().prepayWithRequestPayment(request);
|
||||||
|
@ -99,54 +99,32 @@ public class WeChatServiceImpl implements WeChatService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public synchronized boolean paymentCallback(Transaction transaction) throws IOException {
|
public synchronized boolean paymentCallback(Transaction transaction) {
|
||||||
System.out.println("---------------------------微信支付回调(开始)-------------------------------");
|
System.out.println("---------------------------微信支付回调(开始)-------------------------------");
|
||||||
// 获取订单信息
|
// 获取订单信息
|
||||||
String orderIdByString = transaction.getOutTradeNo();
|
String orderIdByString = transaction.getOutTradeNo();
|
||||||
Order order = ordersService.getById(orderIdByString);
|
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("orderNumber", orderIdByString);
|
||||||
|
Order order = orderService.getOne(queryWrapper);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
log.error("订单不存在");
|
log.error("订单不存在");
|
||||||
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在,订单号:" + transaction.getOutTradeNo());
|
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在,订单号:" + transaction.getOutTradeNo());
|
||||||
}
|
}
|
||||||
// 生成取餐码
|
// 修改订单状态
|
||||||
// 获取当日的日期
|
order.setOrderStatus(OrderStatusConstant.PENDING_SHIPMENT);
|
||||||
LocalDate today = LocalDate.now();
|
boolean update = orderService.updateById(order);
|
||||||
// 获取当日的 00:00 时间
|
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态修改失败");
|
||||||
LocalDateTime startTime = today.atStartOfDay();
|
|
||||||
// 获取当日的 23:59 时间
|
|
||||||
LocalDateTime endTime = today.atTime(LocalTime.MAX);
|
|
||||||
// // 生成取餐码
|
|
||||||
// QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
|
|
||||||
// queryWrapper.eq("businessId", order.getBusinessId());
|
|
||||||
// queryWrapper.between("createTime", startTime, endTime);
|
|
||||||
// queryWrapper.in("state", 1, 2);
|
|
||||||
// long count = ordersService.count(queryWrapper);
|
|
||||||
// String pickupCode = String.format("%04d", count + 1);
|
|
||||||
// // 修改订单信息
|
|
||||||
// order.setState(1);
|
|
||||||
// order.setPickupCode(pickupCode);
|
|
||||||
// Date date = new Date();
|
|
||||||
// order.setUpdateTime(date);
|
|
||||||
// boolean update = ordersService.updateById(order);
|
|
||||||
// ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
|
|
||||||
// // 通知商家新订单
|
|
||||||
// Business business = businessService.getById(order.getBusinessId());
|
|
||||||
// Long userId = order.getUserId();
|
|
||||||
// Long businessId = business.getUserId();
|
|
||||||
// MessageVO messageVO = new MessageVO();
|
|
||||||
// messageVO.setType(1);
|
|
||||||
// messageVO.setUserId(userId);
|
|
||||||
// messageVO.setToUserId(businessId);
|
|
||||||
// messageVO.setContent(orderIdByString);
|
|
||||||
// String message = JSONUtil.toJsonStr(messageVO);
|
|
||||||
// // 通知商家新订单
|
|
||||||
// webSocketServer.onMessage(message);
|
|
||||||
System.out.println("---------------------------微信支付回调(结束)-------------------------------");
|
System.out.println("---------------------------微信支付回调(结束)-------------------------------");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Refund refundPayment(String orderId, BigDecimal amount) {
|
public Refund refundPayment(String orderId, BigDecimal amount) {
|
||||||
|
// 获取订单号
|
||||||
|
Order order = orderService.getById(orderId);
|
||||||
|
ThrowUtils.throwIf(order == null, ErrorCode.OPERATION_ERROR, "该订单不存在");
|
||||||
|
String orderNumber = order.getOrderNumber();
|
||||||
// 退款请求
|
// 退款请求
|
||||||
CreateRequest createRequest = new CreateRequest();
|
CreateRequest createRequest = new CreateRequest();
|
||||||
// 商户订单号
|
// 商户订单号
|
||||||
|
@ -181,10 +159,18 @@ public class WeChatServiceImpl implements WeChatService {
|
||||||
System.out.println("---------------------------微信退款回调(开始)-------------------------------");
|
System.out.println("---------------------------微信退款回调(开始)-------------------------------");
|
||||||
// 获取订单信息
|
// 获取订单信息
|
||||||
String orderIdByString = refundNotification.getOutTradeNo();
|
String orderIdByString = refundNotification.getOutTradeNo();
|
||||||
Order order = ordersService.getById(orderIdByString);
|
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
|
||||||
// 修改订单信息
|
queryWrapper.eq("orderNumber", orderIdByString);
|
||||||
order.setOrderStatus("已退款");
|
Order order = orderService.getOne(queryWrapper);
|
||||||
ordersService.updateById(order);
|
if (order == null) {
|
||||||
|
log.error("订单不存在");
|
||||||
|
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在,订单号:" + orderIdByString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改订单状态
|
||||||
|
order.setOrderStatus(OrderStatusConstant.PAYMENT_REFUNDED);
|
||||||
|
boolean update = orderService.updateById(order);
|
||||||
|
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态修改失败");
|
||||||
System.out.println("---------------------------微信退款回调(结束)-------------------------------");
|
System.out.println("---------------------------微信退款回调(结束)-------------------------------");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.cultural.heritage.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(); // 确保在最终释放锁
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
135
src/test/java/com/cultural/heritage/order/OrderIdGenerator.java
Normal file
135
src/test/java/com/cultural/heritage/order/OrderIdGenerator.java
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
package com.cultural.heritage.order;
|
||||||
|
|
||||||
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class OrderIdGenerator {
|
||||||
|
|
||||||
|
// 定义日期格式化器,精确到秒
|
||||||
|
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(); // 确保在最终释放锁
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 模拟高并发生成订单号
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
// 创建一个线程池
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(100);
|
||||||
|
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
|
||||||
|
// 记录生成的订单号数量
|
||||||
|
final int totalOrders = 999999;
|
||||||
|
final CountDownLatch latch = new CountDownLatch(totalOrders);
|
||||||
|
|
||||||
|
// 使用线程池并发生成订单号
|
||||||
|
for (int i = 0; i < totalOrders; i++) {
|
||||||
|
executorService.submit(() -> {
|
||||||
|
// 每个线程生成一个订单号
|
||||||
|
String orderId = generateOrderId();
|
||||||
|
|
||||||
|
map.compute(orderId.substring(orderId.length() - 6), (key, value) -> {
|
||||||
|
if (value == null) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return value + 1; // 如果有重复,则计数
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
System.out.println(orderId.substring(orderId.length() - 6));
|
||||||
|
latch.countDown(); // 完成一个订单号生成
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 等待所有订单号生成完成
|
||||||
|
latch.await();
|
||||||
|
|
||||||
|
// 关闭线程池
|
||||||
|
executorService.shutdown();
|
||||||
|
|
||||||
|
System.out.println("所有订单号生成完毕!");
|
||||||
|
|
||||||
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() > 1) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单号重复, 订单号为:" + entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("订单号唯一性验证通过!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user