“mitao”
2026-02-03 6b56672a7e02a0bf340021f00a4898bee9b13834
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPhysicalGoodsOrderServiceImpl.java
@@ -7,17 +7,21 @@
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.config.ICBCConfig;
import com.ruoyi.system.dto.PhysicalGoodsPlaceOrderDTO;
import com.ruoyi.system.enums.PhysicalGoodsOrderStatusEnum;
import com.ruoyi.system.mapper.TPhysicalGoodsMapper;
import com.ruoyi.system.mapper.TPhysicalGoodsOrderMapper;
import com.ruoyi.system.model.TCompany;
import com.ruoyi.system.model.TPhysicalGoods;
import com.ruoyi.system.model.TPhysicalGoodsOrder;
import com.ruoyi.system.query.BigGiftPackageQuery;
import com.ruoyi.system.service.TAppUserService;
import com.ruoyi.system.service.TPhysicalGoodsOrderService;
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.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -25,6 +29,7 @@
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * <p>
@@ -47,15 +52,40 @@
    @Autowired
    private ICBCConfig icbcConfig;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TAppUserService appUserService;
    /**
     * 实物商品支付参数 Redis Key 前缀
     */
    private static final String PHYSICAL_ORDER_PAY_PARAMS_KEY = "physical_order_pay_params:";
    /**
     * 支付参数缓存过期时间(24小时)
     */
    private static final long PAY_PARAMS_EXPIRE_HOURS = 60;
    @Override
    public Page<TPhysicalGoodsOrder> pageList(BigGiftPackageQuery query) {
        Page<TPhysicalGoodsOrder> page = new Page<>(query.getPageNum(), query.getPageSize());
        return this.baseMapper.pageList(page, query);
        Page<TPhysicalGoodsOrder> tPhysicalGoodsOrderPage = this.baseMapper.pageList(page, query);
        tPhysicalGoodsOrderPage.getRecords().forEach(order -> {
            order.setPhysicalGoodsName(JSONObject.parseObject(order.getPhysicalGoods()).getString("name"));
        });
        return tPhysicalGoodsOrderPage;
    }
    @Override
    public List<TPhysicalGoodsOrder> export(BigGiftPackageQuery query) {
        return this.baseMapper.export(query);
        List<TPhysicalGoodsOrder> export = this.baseMapper.export(query);
        export.forEach(order -> {
            order.setPhysicalGoodsName(JSONObject.parseObject(order.getPhysicalGoods()).getString("name"));
        });
        return export;
    }
    @Override
@@ -80,25 +110,68 @@
        // 支付方式:1=微信
        order.setPaymentMethod(1);
        // 订单状态:1=待付款
        order.setStatus(1);
        order.setStatus(PhysicalGoodsOrderStatusEnum.PENDING_PAYMENT.getCode());
        order.setDelFlag(0);
        //查询用户所属公司,获取经销商商户号
        TCompany company = appUserService.getUserCompany(appUserId);
        order.setCompanyId(company.getId());
        this.save(order);
        // 3. 更新商品销量
        Integer currentSales = physicalGoods.getSales() == null ? 0 : physicalGoods.getSales();
        physicalGoods.setSales(currentSales + 1);
        physicalGoodsMapper.updateById(physicalGoods);
        // 4. 调用工行支付
        log.info("实物商品下单,订单号:{},支付金额:{},用户ID:{}", orderCode, physicalGoods.getTotalPrice(), appUserId);
        JSONObject paymentParams = icbcPayUtil.wechatPay(orderCode, physicalGoods.getTotalPrice(), physicalGoods.getName(), openid,icbcConfig.getNotifyUrl()+"/physical/pay-notify");
        JSONObject paymentParams = icbcPayUtil.wechatPay(orderCode, physicalGoods.getTotalPrice(), physicalGoods.getName(),
                openid,icbcConfig.getNotifyUrl()+"/physical/pay-notify", company.getMerchantNumber(), company.getMerchantOpenid());
        // 5. 构建返回结果
        // 5. 缓存支付参数到 Redis(用于立即支付)
        String redisKey = PHYSICAL_ORDER_PAY_PARAMS_KEY + order.getId();
        redisTemplate.opsForValue().set(redisKey, paymentParams.toJSONString(), PAY_PARAMS_EXPIRE_HOURS, TimeUnit.MINUTES);
        log.info("实物商品支付参数已缓存,订单ID:{},Redis Key:{}", order.getId(), redisKey);
        // 6. 构建返回结果
        PlaceOrderVO vo = new PlaceOrderVO();
        vo.setOrderIds(Collections.singletonList(order.getId()));
        vo.setOrderCodes(Collections.singletonList(orderCode));
        vo.setPaymentParams(paymentParams);
        return vo;
    }
    @Override
    public PlaceOrderVO payNow(Integer orderId, Integer appUserId) {
        // 1. 查询订单
        TPhysicalGoodsOrder order = this.getById(orderId);
        if (order == null) {
            throw new ServiceException("订单不存在");
        }
        // 2. 校验订单所属用户
        if (!order.getAppUserId().equals(appUserId)) {
            throw new ServiceException("无权操作此订单");
        }
        // 3. 校验订单状态(必须是待付款)
        if (!PhysicalGoodsOrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
            throw new ServiceException("订单状态不正确,无法支付");
        }
        // 4. 从 Redis 获取缓存的支付参数
        String redisKey = PHYSICAL_ORDER_PAY_PARAMS_KEY + orderId;
        Object cachedParams = redisTemplate.opsForValue().get(redisKey);
        if (cachedParams == null) {
            throw new ServiceException("支付参数已过期,请重新下单");
        }
        // 5. 构建返回结果
        PlaceOrderVO vo = new PlaceOrderVO();
        vo.setOrderIds(Collections.singletonList(order.getId()));
        vo.setOrderCodes(Collections.singletonList(order.getCode()));
        vo.setPaymentParams(JSON.parseObject(cachedParams.toString()));
        log.info("实物商品立即支付,订单ID:{},用户ID:{}", orderId, appUserId);
        return vo;
    }
}