You've already forked FrameTour-BE
订单支付
This commit is contained in:
@@ -56,6 +56,8 @@ import com.ycwl.basic.utils.SnowFlakeUtil;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.context.annotation.ScopedProxyMode;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -76,10 +78,14 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||||
public class OrderServiceImpl implements OrderService {
|
public class OrderServiceImpl implements OrderService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private OrderMapper orderMapper;
|
private OrderMapper orderMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OrderServiceImpl self;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SourceMapper sourceMapper;
|
private SourceMapper sourceMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -493,21 +499,30 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public ApiResponse<Map<String, Object>> createOrder(Long userId, CreateOrderReqVO createOrderReqVO) throws Exception {
|
public ApiResponse<Map<String, Object>> createOrder(Long userId, CreateOrderReqVO createOrderReqVO) throws Exception {
|
||||||
|
// 防重复提交检查:基于用户ID、景区ID、商品类型、商品ID生成唯一键
|
||||||
|
String orderKey = String.format("createOrder:%d:%d:%d:%d",
|
||||||
|
userId, createOrderReqVO.getScenicId(),
|
||||||
|
createOrderReqVO.getGoodsType(), createOrderReqVO.getGoodsId());
|
||||||
|
|
||||||
|
// 使用synchronized确保同一用户对同一商品的订单创建操作串行化
|
||||||
|
synchronized (orderKey.intern()) {
|
||||||
IsBuyRespVO isBuy = orderBiz.isBuy(userId, createOrderReqVO.getScenicId(), createOrderReqVO.getGoodsType(), createOrderReqVO.getGoodsId());
|
IsBuyRespVO isBuy = orderBiz.isBuy(userId, createOrderReqVO.getScenicId(), createOrderReqVO.getGoodsType(), createOrderReqVO.getGoodsId());
|
||||||
if (isBuy.isBuy()) {
|
if (isBuy.isBuy()) {
|
||||||
return ApiResponse.fail("您已购买此内容,无需重复购买!");
|
return ApiResponse.fail("您已购买此内容,无需重复购买!");
|
||||||
}
|
}
|
||||||
// 看看有没有之前购买的订单
|
// 看看有没有之前购买的订单
|
||||||
OrderEntity order = orderMapper.getUserOrderItem(userId, createOrderReqVO.getScenicId(), 0, null, createOrderReqVO.getGoodsType(), createOrderReqVO.getGoodsId());
|
OrderEntity order = orderMapper.getUserOrderItem(userId, createOrderReqVO.getScenicId(), 0, null, createOrderReqVO.getGoodsType(), createOrderReqVO.getGoodsId());
|
||||||
boolean haveOldOrder = order != null;
|
boolean haveOldOrder = false;
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
if (order.getStatus() != OrderStateEnum.PAID.getState() && order.getStatus() != OrderStateEnum.UNPAID.getState()) {
|
// 如果订单已支付,直接返回错误,不允许重复购买
|
||||||
haveOldOrder = false;
|
if (order.getStatus() == OrderStateEnum.PAID.getState()) {
|
||||||
|
return ApiResponse.fail("您已购买此内容,无需重复购买!");
|
||||||
}
|
}
|
||||||
if (!DateUtil.isSameDay(order.getCreateAt(), new Date())) {
|
// 只有未支付的订单才允许复用
|
||||||
haveOldOrder = false;
|
if (order.getStatus() == OrderStateEnum.UNPAID.getState()
|
||||||
|
&& DateUtil.isSameDay(order.getCreateAt(), new Date())) {
|
||||||
|
haveOldOrder = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!haveOldOrder) {
|
if (!haveOldOrder) {
|
||||||
@@ -536,6 +551,9 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
order.setStatus(OrderStateEnum.UNPAID.getState());
|
order.setStatus(OrderStateEnum.UNPAID.getState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 只有新订单才计算优惠券,避免重复处理
|
||||||
|
if (!haveOldOrder) {
|
||||||
// coupon
|
// coupon
|
||||||
CouponRecordQueryResp couponRecord = null;
|
CouponRecordQueryResp couponRecord = null;
|
||||||
switch (createOrderReqVO.getGoodsType()) {
|
switch (createOrderReqVO.getGoodsType()) {
|
||||||
@@ -572,30 +590,62 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
order.setCouponPrice(BigDecimal.ZERO);
|
order.setCouponPrice(BigDecimal.ZERO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
List<OrderItemEntity> orderItems = new ArrayList<>();
|
List<OrderItemEntity> orderItems = new ArrayList<>();
|
||||||
OrderItemEntity orderItem = new OrderItemEntity();
|
OrderItemEntity orderItem = new OrderItemEntity();
|
||||||
orderItem.setGoodsId(createOrderReqVO.getGoodsId());
|
orderItem.setGoodsId(createOrderReqVO.getGoodsId());
|
||||||
orderItem.setGoodsType(createOrderReqVO.getGoodsType());
|
orderItem.setGoodsType(createOrderReqVO.getGoodsType());
|
||||||
orderItem.setOrderId(order.getId());
|
orderItem.setOrderId(order.getId());
|
||||||
orderItems.add(orderItem);
|
orderItems.add(orderItem);
|
||||||
if (!haveOldOrder) {
|
// 在事务中保存订单数据
|
||||||
orderMapper.add(order);
|
try {
|
||||||
int addOrderItems = orderMapper.addOrderItems(orderItems);
|
self.saveOrderInTransaction(order, orderItems, haveOldOrder);
|
||||||
if (addOrderItems == NumberConstant.ZERO) {
|
} catch (Exception e) {
|
||||||
log.error("订单明细添加失败");
|
log.error("保存订单失败", e);
|
||||||
return ApiResponse.fail("订单添加失败");
|
return ApiResponse.fail("订单创建失败");
|
||||||
}
|
|
||||||
} else {
|
|
||||||
orderMapper.updateOrderPrice(order);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断是否需要支付(事务外处理)
|
||||||
if (order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
|
if (order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
// 只有新创建的订单才需要执行支付完成逻辑
|
||||||
|
if (!haveOldOrder) {
|
||||||
|
try {
|
||||||
orderBiz.paidOrder(order.getId());
|
orderBiz.paidOrder(order.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理免费订单失败", e);
|
||||||
|
return ApiResponse.fail("订单处理失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
HashMap<String, Object> data = new HashMap<>();
|
HashMap<String, Object> data = new HashMap<>();
|
||||||
data.put("needPay", false);
|
data.put("needPay", false);
|
||||||
return ApiResponse.success(data);
|
return ApiResponse.success(data);
|
||||||
} else {
|
} else {
|
||||||
|
// 发起支付(事务外调用外部服务)
|
||||||
|
try {
|
||||||
Map<String, Object> wxPayRespVO = initiatePayment(order, orderItems);
|
Map<String, Object> wxPayRespVO = initiatePayment(order, orderItems);
|
||||||
return ApiResponse.success(wxPayRespVO);
|
return ApiResponse.success(wxPayRespVO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发起支付失败", e);
|
||||||
|
return ApiResponse.fail("支付发起失败,请重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // synchronized 块结束
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在事务中保存订单数据
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
protected void saveOrderInTransaction(OrderEntity order, List<OrderItemEntity> orderItems, boolean haveOldOrder) {
|
||||||
|
if (!haveOldOrder) {
|
||||||
|
orderMapper.add(order);
|
||||||
|
int addOrderItems = orderMapper.addOrderItems(orderItems);
|
||||||
|
if (addOrderItems == NumberConstant.ZERO) {
|
||||||
|
throw new RuntimeException("订单明细添加失败");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 对于旧订单,只更新价格相关字段,不重复处理业务逻辑
|
||||||
|
orderMapper.updateOrderPrice(order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user