| | |
| | | package com.ruoyi.system.service.impl; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.system.config.ICBCConfig; |
| | | import com.ruoyi.system.dto.BigGiftPlaceOrderDTO; |
| | | import com.ruoyi.system.mapper.TBigGiftPackageMapper; |
| | | import com.ruoyi.system.mapper.TBigGiftPackageOrderMapper; |
| | | import com.ruoyi.system.mapper.TCompanyMapper; |
| | | import com.ruoyi.system.model.TBigGiftPackage; |
| | | import com.ruoyi.system.model.TBigGiftPackageOrder; |
| | | import com.ruoyi.system.mapper.TBigGiftPackageOrderMapper; |
| | | import com.ruoyi.system.model.TCompany; |
| | | import com.ruoyi.system.query.BigGiftPackageOrderQuery; |
| | | import com.ruoyi.system.service.TBigGiftPackageOrderService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.system.utils.ICBCPayUtil; |
| | | import com.ruoyi.system.utils.OrderCodeGenerator; |
| | | import com.ruoyi.system.vo.PlaceOrderVO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | |
| | | * @author xiaochen |
| | | * @since 2025-12-08 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class TBigGiftPackageOrderServiceImpl extends ServiceImpl<TBigGiftPackageOrderMapper, TBigGiftPackageOrder> implements TBigGiftPackageOrderService { |
| | | |
| | |
| | | @Resource |
| | | private TBigGiftPackageMapper bigGiftPackageMapper; |
| | | |
| | | @Autowired |
| | | private ICBCPayUtil icbcPayUtil; |
| | | |
| | | @Autowired |
| | | private ICBCConfig icbcConfig; |
| | | |
| | | @Override |
| | | public List<TBigGiftPackageOrder> pageList(Page<TBigGiftPackageOrder> tBigGiftPackageOrderPage, BigGiftPackageOrderQuery query) { |
| | |
| | | } |
| | | return tBigGiftPackageOrders ; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public PlaceOrderVO placeOrder(BigGiftPlaceOrderDTO dto, Integer appUserId, String openid) { |
| | | // 1. 校验商品是否存在 |
| | | TBigGiftPackage bigGiftPackage = bigGiftPackageMapper.selectById(dto.getBigGiftPackageId()); |
| | | if (bigGiftPackage == null) { |
| | | throw new ServiceException("商品不存在"); |
| | | } |
| | | |
| | | // 2. 校验库存是否充足 |
| | | if (bigGiftPackage.getInventory() == null || bigGiftPackage.getInventory() < dto.getQuantity()) { |
| | | throw new ServiceException("商品库存不足"); |
| | | } |
| | | |
| | | // 3. 校验支付方式 |
| | | if (dto.getPaymentType() != 1 && dto.getPaymentType() != 2) { |
| | | throw new ServiceException("支付方式不正确"); |
| | | } |
| | | |
| | | // 4. 使用乐观锁扣减库存(防止超卖) |
| | | int updatedRows = bigGiftPackageMapper.deductInventory(dto.getBigGiftPackageId(), dto.getQuantity()); |
| | | if (updatedRows == 0) { |
| | | throw new ServiceException("商品库存不足,请稍后重试"); |
| | | } |
| | | |
| | | // 5. 计算支付金额 |
| | | BigDecimal paymentAmount; |
| | | if (dto.getPaymentType() == 1) { |
| | | // 订金+尾款模式,先支付订金 |
| | | paymentAmount = bigGiftPackage.getDeposit().multiply(new BigDecimal(dto.getQuantity())); |
| | | } else { |
| | | // 全款模式 |
| | | paymentAmount = bigGiftPackage.getTotalPrice().multiply(new BigDecimal(dto.getQuantity())); |
| | | } |
| | | |
| | | // 6. 先生成支付订单号(所有订单共用同一个支付订单号,便于支付回调时查询) |
| | | String payOrderCode = OrderCodeGenerator.generateBigGiftPayOrderCode(); |
| | | |
| | | // 7. 批量创建订单 |
| | | List<TBigGiftPackageOrder> orderList = new ArrayList<>(); |
| | | List<String> orderCodes = new ArrayList<>(); |
| | | String goodsJson = JSON.toJSONString(bigGiftPackage); |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | |
| | | for (int i = 0; i < dto.getQuantity(); i++) { |
| | | TBigGiftPackageOrder order = new TBigGiftPackageOrder(); |
| | | String orderCode = OrderCodeGenerator.generateBigGiftOrderCode(); |
| | | order.setCode(orderCode); |
| | | order.setPayOrderCode(payOrderCode); |
| | | order.setAppUserId(appUserId); |
| | | order.setCreateTime(now); |
| | | order.setBigGiftPackageId(dto.getBigGiftPackageId()); |
| | | order.setBigGiftPackage(goodsJson); |
| | | order.setOrderPrice(bigGiftPackage.getTotalPrice()); |
| | | order.setDeposit(bigGiftPackage.getDeposit()); |
| | | order.setFinalPayment(bigGiftPackage.getTotalPrice().subtract(bigGiftPackage.getDeposit())); |
| | | order.setPaymentType(dto.getPaymentType()); |
| | | order.setEffectDayFlag(dto.getEffectDayFlag()); |
| | | // 订单状态:1=待付款 |
| | | order.setStatus(1); |
| | | order.setDelFlag(0); |
| | | |
| | | orderList.add(order); |
| | | orderCodes.add(orderCode); |
| | | } |
| | | |
| | | // 批量插入订单 |
| | | this.saveBatch(orderList); |
| | | |
| | | // 获取订单ID列表 |
| | | List<Integer> orderIds = orderList.stream() |
| | | .map(TBigGiftPackageOrder::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 8. 调用工行支付 |
| | | log.info("大礼包下单,支付订单号:{},业务订单号:{},支付金额:{},用户ID:{}", payOrderCode, orderCodes, paymentAmount, appUserId); |
| | | JSONObject paymentParams = icbcPayUtil.wechatPay(payOrderCode, paymentAmount, bigGiftPackage.getName(), openid, |
| | | icbcConfig.getNotifyUrl() + "/big-gift/pay-notify"); |
| | | |
| | | // 9. 构建返回结果 |
| | | PlaceOrderVO vo = new PlaceOrderVO(); |
| | | vo.setOrderIds(orderIds); |
| | | vo.setOrderCodes(orderCodes); |
| | | vo.setPaymentParams(paymentParams); |
| | | return vo; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public PlaceOrderVO payFinalPayment(Integer orderId, Integer appUserId, String openid) { |
| | | // 1. 查询订单 |
| | | TBigGiftPackageOrder order = this.getById(orderId); |
| | | if (order == null) { |
| | | throw new ServiceException("订单不存在"); |
| | | } |
| | | |
| | | // 2. 校验订单归属 |
| | | if (!order.getAppUserId().equals(appUserId)) { |
| | | throw new ServiceException("无权操作此订单"); |
| | | } |
| | | |
| | | // 3. 校验支付方式(必须是订金+尾款模式) |
| | | if (order.getPaymentType() != 1) { |
| | | throw new ServiceException("该订单不支持尾款支付"); |
| | | } |
| | | |
| | | // 4. 校验订单状态(必须是已付订金状态) |
| | | if (order.getStatus() != 2) { |
| | | throw new ServiceException("订单状态不正确,无法支付尾款"); |
| | | } |
| | | |
| | | // 5. 获取尾款金额 |
| | | BigDecimal finalPayment = order.getFinalPayment(); |
| | | if (finalPayment == null || finalPayment.compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw new ServiceException("尾款金额异常"); |
| | | } |
| | | |
| | | // 6. 生成尾款支付订单号 |
| | | String finalPayOrderCode = OrderCodeGenerator.generateBigGiftFinalPayOrderCode(); |
| | | |
| | | // 7. 调用工行支付 |
| | | log.info("大礼包尾款支付,订单ID:{},支付订单号:{},尾款金额:{},用户ID:{}", orderId, finalPayOrderCode, finalPayment, appUserId); |
| | | JSONObject paymentParams = icbcPayUtil.wechatPay(finalPayOrderCode, finalPayment, "大礼包尾款", openid, |
| | | icbcConfig.getNotifyUrl() + "/big-gift/final-pay-notify"); |
| | | |
| | | // 8. 构建返回结果 |
| | | PlaceOrderVO vo = new PlaceOrderVO(); |
| | | vo.setOrderIds(Collections.singletonList(orderId)); |
| | | vo.setOrderCodes(Collections.singletonList(order.getCode())); |
| | | vo.setPaymentParams(paymentParams); |
| | | return vo; |
| | | } |
| | | } |