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 org.apache.commons.lang3.StringUtils;
|
||||
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.transaction.annotation.Transactional;
|
||||
|
||||
@@ -76,10 +78,14 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
|
||||
@Autowired
|
||||
private OrderMapper orderMapper;
|
||||
|
||||
@Autowired
|
||||
private OrderServiceImpl self;
|
||||
@Autowired
|
||||
private SourceMapper sourceMapper;
|
||||
@Autowired
|
||||
@@ -493,21 +499,30 @@ public class OrderServiceImpl implements OrderService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
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());
|
||||
if (isBuy.isBuy()) {
|
||||
return ApiResponse.fail("您已购买此内容,无需重复购买!");
|
||||
}
|
||||
// 看看有没有之前购买的订单
|
||||
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.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) {
|
||||
@@ -536,6 +551,9 @@ public class OrderServiceImpl implements OrderService {
|
||||
order.setStatus(OrderStateEnum.UNPAID.getState());
|
||||
}
|
||||
}
|
||||
|
||||
// 只有新订单才计算优惠券,避免重复处理
|
||||
if (!haveOldOrder) {
|
||||
// coupon
|
||||
CouponRecordQueryResp couponRecord = null;
|
||||
switch (createOrderReqVO.getGoodsType()) {
|
||||
@@ -572,30 +590,62 @@ public class OrderServiceImpl implements OrderService {
|
||||
order.setCouponPrice(BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<OrderItemEntity> orderItems = new ArrayList<>();
|
||||
OrderItemEntity orderItem = new OrderItemEntity();
|
||||
orderItem.setGoodsId(createOrderReqVO.getGoodsId());
|
||||
orderItem.setGoodsType(createOrderReqVO.getGoodsType());
|
||||
orderItem.setOrderId(order.getId());
|
||||
orderItems.add(orderItem);
|
||||
if (!haveOldOrder) {
|
||||
orderMapper.add(order);
|
||||
int addOrderItems = orderMapper.addOrderItems(orderItems);
|
||||
if (addOrderItems == NumberConstant.ZERO) {
|
||||
log.error("订单明细添加失败");
|
||||
return ApiResponse.fail("订单添加失败");
|
||||
}
|
||||
} else {
|
||||
orderMapper.updateOrderPrice(order);
|
||||
// 在事务中保存订单数据
|
||||
try {
|
||||
self.saveOrderInTransaction(order, orderItems, haveOldOrder);
|
||||
} catch (Exception e) {
|
||||
log.error("保存订单失败", e);
|
||||
return ApiResponse.fail("订单创建失败");
|
||||
}
|
||||
|
||||
// 判断是否需要支付(事务外处理)
|
||||
if (order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
// 只有新创建的订单才需要执行支付完成逻辑
|
||||
if (!haveOldOrder) {
|
||||
try {
|
||||
orderBiz.paidOrder(order.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("处理免费订单失败", e);
|
||||
return ApiResponse.fail("订单处理失败");
|
||||
}
|
||||
}
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("needPay", false);
|
||||
return ApiResponse.success(data);
|
||||
} else {
|
||||
// 发起支付(事务外调用外部服务)
|
||||
try {
|
||||
Map<String, Object> wxPayRespVO = initiatePayment(order, orderItems);
|
||||
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