|
|
@@ -11,18 +11,17 @@ import com.ylx.common.core.domain.model.WxLoginUser;
|
|
|
import com.ylx.common.exception.ServiceException;
|
|
|
import com.ylx.common.utils.SecurityUtils;
|
|
|
import com.ylx.massage.domain.*;
|
|
|
-import com.ylx.massage.domain.dto.ProductOrderCreateRequest;
|
|
|
-import com.ylx.massage.domain.dto.ProductOrderOperateDTO;
|
|
|
-import com.ylx.massage.domain.dto.ProductOrderPageDTO;
|
|
|
-import com.ylx.massage.domain.dto.ProductOrderPayRequest;
|
|
|
+import com.ylx.massage.domain.dto.*;
|
|
|
import com.ylx.massage.domain.vo.ProductOrderDetailVo;
|
|
|
import com.ylx.massage.domain.vo.ProductOrderListVo;
|
|
|
import com.ylx.massage.domain.vo.ProductOrderPageVo;
|
|
|
import com.ylx.massage.enums.BillTypeEnum;
|
|
|
+import com.ylx.massage.enums.PaymentStatusEnum;
|
|
|
import com.ylx.massage.enums.ProductOrderStatusEnum;
|
|
|
import com.ylx.massage.mapper.ProductMapper;
|
|
|
import com.ylx.massage.mapper.ProductOrderInfoMapper;
|
|
|
import com.ylx.massage.mapper.ProductOrderItemMapper;
|
|
|
+import com.ylx.massage.mapper.ProductSkuMapper;
|
|
|
import com.ylx.massage.service.IProductOrderInfoService;
|
|
|
import com.ylx.massage.service.TConsumptionLogService;
|
|
|
import com.ylx.massage.service.TRechargeService;
|
|
|
@@ -71,6 +70,9 @@ public class ProductOrderInfoServiceImpl extends ServiceImpl<ProductOrderInfoMap
|
|
|
@Autowired
|
|
|
private IProductOrderAddressService productOrderAddressService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private ProductSkuMapper productSkuMapper;
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 创建商品订单
|
|
|
@@ -312,9 +314,12 @@ public class ProductOrderInfoServiceImpl extends ServiceImpl<ProductOrderInfoMap
|
|
|
throw new ServiceException("用户openId不能为空");
|
|
|
}
|
|
|
Page<ProductOrderListVo> result = productOrderInfoMapper.selectProductOrderListByOpenId(page, openId);
|
|
|
- // 设置订单状态名称
|
|
|
+
|
|
|
for (ProductOrderListVo vo : result.getRecords()) {
|
|
|
+ // 设置订单状态名称
|
|
|
vo.setOrderStatusName(ProductOrderStatusEnum.getDescByCode(vo.getOrderStatus()));
|
|
|
+ //设置支付状态名称
|
|
|
+ vo.setPayStatusName(PaymentStatusEnum.getDescByCode(vo.getPayStatus()));
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
@@ -351,6 +356,91 @@ public class ProductOrderInfoServiceImpl extends ServiceImpl<ProductOrderInfoMap
|
|
|
return detail;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取消商品订单
|
|
|
+ *
|
|
|
+ * @param request 取消订单请求
|
|
|
+ * @return R<?> 取消结果
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public R<?> cancelOrder(ProductOrderCancelRequest request) {
|
|
|
+ String orderNo = request.getOrderNo();
|
|
|
+ String openId = request.getOpenId();
|
|
|
+ String cancelReason = request.getCancelReason();
|
|
|
+ log.info("取消商品订单,订单号:{},openId:{},取消原因:{}", orderNo, openId, cancelReason);
|
|
|
+
|
|
|
+ // 1. 查询订单
|
|
|
+ LambdaQueryWrapper<ProductOrderInfo> queryWrapper = new LambdaQueryWrapper<ProductOrderInfo>()
|
|
|
+ .eq(ProductOrderInfo::getOrderNo, orderNo)
|
|
|
+ .eq(ProductOrderInfo::getOpenId, openId);
|
|
|
+ ProductOrderInfo order = productOrderInfoMapper.selectOne(queryWrapper);
|
|
|
+ if (order == null) {
|
|
|
+ throw new ServiceException("订单不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 幂等处理:已是已取消状态,直接返回成功
|
|
|
+ if (ProductOrderStatusEnum.CANCELLED.getCode().equals(order.getOrderStatus())) {
|
|
|
+ log.info("订单已是取消状态,无需重复处理,订单号:{}", orderNo);
|
|
|
+ return R.ok("订单已取消");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 前置校验:订单状态必须是待付款
|
|
|
+ if (!ProductOrderStatusEnum.WAIT_PAY.getCode().equals(order.getOrderStatus())) {
|
|
|
+ throw new ServiceException("只有待付款状态的订单才能取消");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 关闭微信支付订单(事务外,网络调用)
|
|
|
+ try {
|
|
|
+ rechargeService.closeWeChatOrder(orderNo);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("关闭微信订单异常,继续执行取消流程,订单号:{},错误:{}", orderNo, e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 查询订单商品明细
|
|
|
+ LambdaQueryWrapper<ProductOrderItem> itemQueryWrapper = new LambdaQueryWrapper<ProductOrderItem>()
|
|
|
+ .eq(ProductOrderItem::getOrderNo, orderNo);
|
|
|
+ ProductOrderItem orderItem = productOrderItemMapper.selectOne(itemQueryWrapper);
|
|
|
+
|
|
|
+ // 6. 事务内:释放库存 + 更新订单状态
|
|
|
+ releaseStockAndUpdateOrderStatus(order, orderItem, cancelReason);
|
|
|
+ log.info("订单取消成功,订单号:{}", orderNo);
|
|
|
+ return R.ok("订单取消成功");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 释放库存并更新订单状态(事务内执行)
|
|
|
+ *
|
|
|
+ * @param order 订单信息
|
|
|
+ * @param orderItem 订单商品明细
|
|
|
+ * @param cancelReason 取消原因
|
|
|
+ */
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void releaseStockAndUpdateOrderStatus(ProductOrderInfo order, ProductOrderItem orderItem, String cancelReason) {
|
|
|
+ // 释放库存
|
|
|
+ if (orderItem != null && orderItem.getSkuId() != null && orderItem.getQuantity() != null) {
|
|
|
+ int affectedRows = productSkuMapper.releaseStock(orderItem.getSkuId(), orderItem.getQuantity());
|
|
|
+ if (affectedRows == 0) {
|
|
|
+ throw new ServiceException("库存释放失败,库存不足");
|
|
|
+ }
|
|
|
+ log.info("库存释放成功,SKU:{},数量:{}", orderItem.getSkuId(), orderItem.getQuantity());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新订单状态为已取消
|
|
|
+ ProductOrderInfo updateOrder = new ProductOrderInfo();
|
|
|
+ updateOrder.setOrderStatus(ProductOrderStatusEnum.CANCELLED.getCode());
|
|
|
+ updateOrder.setCancelReason(cancelReason);
|
|
|
+ int updateRows = productOrderInfoMapper.update(updateOrder,
|
|
|
+ new LambdaQueryWrapper<ProductOrderInfo>()
|
|
|
+ .eq(ProductOrderInfo::getId, order.getId())
|
|
|
+ .eq(ProductOrderInfo::getOrderStatus, ProductOrderStatusEnum.WAIT_PAY.getCode()));
|
|
|
+ if (updateRows == 0) {
|
|
|
+ throw new ServiceException("订单状态已变更,取消失败");
|
|
|
+ }
|
|
|
+ log.info("订单状态更新为已取消,订单号:{}", order.getOrderNo());
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public boolean confirmReceipt(ProductOrderOperateDTO dto) {
|