package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.enums.BigGiftPackageOrderStatusEnum; import com.ruoyi.system.mapper.TBigGiftPackageMapper; import com.ruoyi.system.mapper.TCommissionTransactionFlowMapper; 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.TCommissionTransactionFlow; import com.ruoyi.system.model.TCompany; import com.ruoyi.system.query.BigGiftPackageOrderQuery; import com.ruoyi.system.query.GoldChangeRecordQuery; import com.ruoyi.system.query.ProfitPageListQuery; import com.ruoyi.system.query.UserProfitPageListQuery; import com.ruoyi.system.service.TAppUserService; import com.ruoyi.system.service.TBigGiftPackageOrderService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.service.TCommissionTransactionFlowService; import com.ruoyi.system.vo.ProfitPageListVo; import com.ruoyi.system.utils.ICBCPayUtil; import com.ruoyi.system.utils.OrderCodeGenerator; import com.ruoyi.system.vo.PlaceOrderVO; import com.ruoyi.system.vo.UserProfitPageListVo; 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.Objects; import java.util.stream.Collectors; /** *

* 大礼包订单 服务实现类 *

* * @author xiaochen * @since 2025-12-08 */ @Slf4j @Service public class TBigGiftPackageOrderServiceImpl extends ServiceImpl implements TBigGiftPackageOrderService { @Resource private TCompanyMapper companyMapper; @Resource private TBigGiftPackageMapper bigGiftPackageMapper; @Resource private TCommissionTransactionFlowMapper commissionTransactionFlowMapper; @Autowired private ICBCPayUtil icbcPayUtil; @Autowired private ICBCConfig icbcConfig; @Autowired private TAppUserService appUserService; @Override public List pageList(Page tBigGiftPackageOrderPage, BigGiftPackageOrderQuery query) { String sTime = null; String eTime = null; if(query.getTime()!=null && !query.getTime().isEmpty()){ String[] split = query.getTime().split(" - "); sTime = split[0] + " 00:00:00"; eTime = split[1] + " 23:59:59"; } List tBigGiftPackageOrders = this.baseMapper.pageList(tBigGiftPackageOrderPage, query, sTime, eTime); if(!tBigGiftPackageOrders.isEmpty()){ List companyId = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getCompanyId).collect(Collectors.toList()); List tCompanies = companyMapper.selectBatchIds(companyId); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TCompany tCompany1 = tCompanies.stream().filter(tCompany -> tCompany.getId().equals(tBigGiftPackageOrder.getCompanyId())).findFirst().orElse(null); if(tCompany1!=null){ tBigGiftPackageOrder.setCompanyName(tCompany1.getName()); } }); List goodsIds = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getBigGiftPackageId).collect(Collectors.toList()); List bigGiftPackages = bigGiftPackageMapper.selectBatchIds(goodsIds); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TBigGiftPackage bigGiftPackage = bigGiftPackages.stream().filter(tBigGiftPackage -> tBigGiftPackage.getId().equals(tBigGiftPackageOrder.getBigGiftPackageId())).findFirst().orElse(null); if(bigGiftPackage!=null){ tBigGiftPackageOrder.setBigGiftPackageName(bigGiftPackage.getName()); } }); } return tBigGiftPackageOrders ; } @Override public List export(BigGiftPackageOrderQuery query) { String sTime = null; String eTime = null; if(query.getTime()!=null && !query.getTime().isEmpty()){ String[] split = query.getTime().split(" - "); sTime = split[0] + " 00:00:00"; eTime = split[1] + " 23:59:59"; } List tBigGiftPackageOrders = this.baseMapper.export(query, sTime, eTime); if(!tBigGiftPackageOrders.isEmpty()){ List companyId = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getCompanyId).collect(Collectors.toList()); List tCompanies = companyMapper.selectBatchIds(companyId); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TCompany tCompany1 = tCompanies.stream().filter(tCompany -> tCompany.getId().equals(tBigGiftPackageOrder.getCompanyId())).findFirst().orElse(null); if(tCompany1!=null){ tBigGiftPackageOrder.setCompanyName(tCompany1.getName()); } }); List goodsIds = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getBigGiftPackageId).collect(Collectors.toList()); List bigGiftPackages = bigGiftPackageMapper.selectBatchIds(goodsIds); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TBigGiftPackage bigGiftPackage = bigGiftPackages.stream().filter(tBigGiftPackage -> tBigGiftPackage.getId().equals(tBigGiftPackageOrder.getBigGiftPackageId())).findFirst().orElse(null); if(bigGiftPackage!=null){ tBigGiftPackageOrder.setBigGiftPackageName(bigGiftPackage.getName()); } }); } return tBigGiftPackageOrders ; } @Override public List profitPageList(Page page, ProfitPageListQuery query) { if (Objects.isNull(query.getCompanyId())) { throw new ServiceException("公司ID不能为空"); } String sTime = null; String eTime = null; if(query.getCreateTime()!=null && !query.getCreateTime().isEmpty()){ String[] split = query.getCreateTime().split(" - "); sTime = split[0] + " 00:00:00"; eTime = split[1] + " 23:59:59"; } List profitPageListVos = this.baseMapper.profitPageList(page, query, sTime, eTime); if(!profitPageListVos.isEmpty()){ List orderIds = profitPageListVos.stream().map(ProfitPageListVo::getId).collect(Collectors.toList()); List tCommissionTransactionFlows = commissionTransactionFlowMapper.selectList(new LambdaQueryWrapper().in(TCommissionTransactionFlow::getOrderId, orderIds)); for (ProfitPageListVo profitPageListVo : profitPageListVos) { TCommissionTransactionFlow flow = tCommissionTransactionFlows.stream().filter(e -> e.getOrderId().equals(profitPageListVo.getId()) && e.getAppUserType()==2).findFirst().orElse( null); if(flow!=null){ profitPageListVo.setSaleProfit(flow.getCommissionAmount()); } TCommissionTransactionFlow flow1 = tCommissionTransactionFlows.stream().filter(e -> e.getOrderId().equals(profitPageListVo.getId()) && e.getAppUserType()==3).findFirst().orElse( null); if(flow1!=null){ profitPageListVo.setPartnerProfit(flow1.getCommissionAmount()); } } } return profitPageListVos; } @Override public List profitPageListExport(ProfitPageListQuery query) { String sTime = null; String eTime = null; if(query.getCreateTime()!=null && !query.getCreateTime().isEmpty()){ String[] split = query.getCreateTime().split(" - "); sTime = split[0] + " 00:00:00"; eTime = split[1] + " 23:59:59"; } List profitPageListVos = this.baseMapper.profitPageListExport(query, sTime, eTime); if(!profitPageListVos.isEmpty()){ List orderIds = profitPageListVos.stream().map(ProfitPageListVo::getId).collect(Collectors.toList()); List tCommissionTransactionFlows = commissionTransactionFlowMapper.selectList(new LambdaQueryWrapper().in(TCommissionTransactionFlow::getOrderId, orderIds)); for (ProfitPageListVo profitPageListVo : profitPageListVos) { TCommissionTransactionFlow flow = tCommissionTransactionFlows.stream().filter(e -> e.getOrderId().equals(profitPageListVo.getId()) && e.getAppUserType()==2).findFirst().orElse( null); if(flow!=null){ profitPageListVo.setSaleProfit(flow.getCommissionAmount()); } TCommissionTransactionFlow flow1 = tCommissionTransactionFlows.stream().filter(e -> e.getOrderId().equals(profitPageListVo.getId()) && e.getAppUserType()==3).findFirst().orElse( null); if(flow1!=null){ profitPageListVo.setPartnerProfit(flow1.getCommissionAmount()); } } } return profitPageListVos; } @Override public List pageOrderList(Page tBigGiftPackageOrderPage, GoldChangeRecordQuery query) { List tBigGiftPackageOrders = this.baseMapper.pageOrderList(tBigGiftPackageOrderPage, query); if(!tBigGiftPackageOrders.isEmpty()){ List companyId = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getCompanyId).collect(Collectors.toList()); List tCompanies = companyMapper.selectBatchIds(companyId); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TCompany tCompany1 = tCompanies.stream().filter(tCompany -> tCompany.getId().equals(tBigGiftPackageOrder.getCompanyId())).findFirst().orElse(null); if(tCompany1!=null){ tBigGiftPackageOrder.setCompanyName(tCompany1.getName()); } }); List goodsIds = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getBigGiftPackageId).collect(Collectors.toList()); List bigGiftPackages = bigGiftPackageMapper.selectBatchIds(goodsIds); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TBigGiftPackage bigGiftPackage = bigGiftPackages.stream().filter(tBigGiftPackage -> tBigGiftPackage.getId().equals(tBigGiftPackageOrder.getBigGiftPackageId())).findFirst().orElse(null); if(bigGiftPackage!=null){ tBigGiftPackageOrder.setBigGiftPackageName(bigGiftPackage.getName()); } }); } return tBigGiftPackageOrders; } @Override public List profitUserPageList(Page page, UserProfitPageListQuery query) { String sTime = null; String eTime = null; if(query.getCreateTime()!=null && !query.getCreateTime().isEmpty()){ String[] split = query.getCreateTime().split(" - "); sTime = split[0] + " 00:00:00"; eTime = split[1] + " 23:59:59"; } List profitPageListVos = this.baseMapper.profitUserPageList(page,query, sTime, eTime); if(!profitPageListVos.isEmpty()){ List orderIds = profitPageListVos.stream().map(UserProfitPageListVo::getId).collect(Collectors.toList()); List tCommissionTransactionFlows = commissionTransactionFlowMapper.selectList(new LambdaQueryWrapper().in(TCommissionTransactionFlow::getOrderId, orderIds)); for (UserProfitPageListVo profitPageListVo : profitPageListVos) { List flows = tCommissionTransactionFlows.stream().filter(e -> e.getOrderId().equals(profitPageListVo.getId()) && e.getAppUserId().equals(query.getUserId())).collect(Collectors.toList()); profitPageListVo.setSelfProfit(flows.stream().map(TCommissionTransactionFlow::getCommissionAmount).reduce(BigDecimal.ZERO,BigDecimal::add)); } } return profitPageListVos; } @Override public List profitUserPageListExport(UserProfitPageListQuery query) { String sTime = null; String eTime = null; if(query.getCreateTime()!=null && !query.getCreateTime().isEmpty()){ String[] split = query.getCreateTime().split(" - "); sTime = split[0] + " 00:00:00"; eTime = split[1] + " 23:59:59"; } List profitPageListVos = this.baseMapper.profitUserPageListExport(query, sTime, eTime); if(!profitPageListVos.isEmpty()){ List orderIds = profitPageListVos.stream().map(UserProfitPageListVo::getId).collect(Collectors.toList()); List tCommissionTransactionFlows = commissionTransactionFlowMapper.selectList(new LambdaQueryWrapper().in(TCommissionTransactionFlow::getOrderId, orderIds)); for (UserProfitPageListVo profitPageListVo : profitPageListVos) { List flows = tCommissionTransactionFlows.stream().filter(e -> e.getOrderId().equals(profitPageListVo.getId()) && e.getAppUserId().equals(query.getUserId())).collect(Collectors.toList()); profitPageListVo.setSelfProfit(flows.stream().map(TCommissionTransactionFlow::getCommissionAmount).reduce(BigDecimal.ZERO,BigDecimal::add)); } } return profitPageListVos; } @Override public List pageOrderListExport(GoldChangeRecordQuery query) { List tBigGiftPackageOrders = this.baseMapper.pageOrderListExport( query); if(!tBigGiftPackageOrders.isEmpty()){ List companyId = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getCompanyId).collect(Collectors.toList()); List tCompanies = companyMapper.selectBatchIds(companyId); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TCompany tCompany1 = tCompanies.stream().filter(tCompany -> tCompany.getId().equals(tBigGiftPackageOrder.getCompanyId())).findFirst().orElse(null); if(tCompany1!=null){ tBigGiftPackageOrder.setCompanyName(tCompany1.getName()); } }); List goodsIds = tBigGiftPackageOrders.stream().map(TBigGiftPackageOrder::getBigGiftPackageId).collect(Collectors.toList()); List bigGiftPackages = bigGiftPackageMapper.selectBatchIds(goodsIds); tBigGiftPackageOrders.forEach(tBigGiftPackageOrder -> { TBigGiftPackage bigGiftPackage = bigGiftPackages.stream().filter(tBigGiftPackage -> tBigGiftPackage.getId().equals(tBigGiftPackageOrder.getBigGiftPackageId())).findFirst().orElse(null); if(bigGiftPackage!=null){ tBigGiftPackageOrder.setBigGiftPackageName(bigGiftPackage.getName()); } }); } 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 orderList = new ArrayList<>(); List orderCodes = new ArrayList<>(); String goodsJson = JSON.toJSONString(bigGiftPackage); LocalDateTime now = LocalDateTime.now(); //查询用户所属公司,获取经销商商户号 TCompany company = appUserService.getUserCompany(appUserId); for (int i = 0; i < dto.getQuantity(); i++) { TBigGiftPackageOrder order = new TBigGiftPackageOrder(); String orderCode = OrderCodeGenerator.generateBigGiftOrderCode(); order.setCode(orderCode); order.setCompanyId(company.getId()); 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()); order.setPaymentPrice(dto.getPaymentType().equals(1) ? bigGiftPackage.getDeposit() : bigGiftPackage.getTotalPrice()); // 订单状态:1=待付款 order.setStatus(BigGiftPackageOrderStatusEnum.PENDING_PAYMENT.getCode()); order.setDelFlag(0); orderList.add(order); orderCodes.add(orderCode); } // 批量插入订单 this.saveBatch(orderList); // 获取订单ID列表 List 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", company.getMerchantNumber(), company.getMerchantOpenid()); // 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(); order.setFinalPaymentSerialNumber(finalPayOrderCode); this.updateById(order); //查询用户所属公司,获取经销商商户号 TCompany company = appUserService.getUserCompany(appUserId); // 7. 调用工行支付 log.info("大礼包尾款支付,订单ID:{},支付订单号:{},尾款金额:{},用户ID:{}", orderId, finalPayOrderCode, finalPayment, appUserId); JSONObject paymentParams = icbcPayUtil.wechatPay(finalPayOrderCode, finalPayment, "大礼包尾款", openid, icbcConfig.getNotifyUrl() + "/big-gift/final-pay-notify", company.getMerchantNumber(), company.getMerchantOpenid()); // 8. 构建返回结果 PlaceOrderVO vo = new PlaceOrderVO(); vo.setOrderIds(Collections.singletonList(orderId)); vo.setOrderCodes(Collections.singletonList(order.getCode())); vo.setPaymentParams(paymentParams); return vo; } @Override @Transactional(rollbackFor = Exception.class) public PlaceOrderVO payNow(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 (!BigGiftPackageOrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) { throw new ServiceException("订单状态不正确,无法支付"); } // 4. 获取商品信息 TBigGiftPackage bigGiftPackage = bigGiftPackageMapper.selectById(order.getBigGiftPackageId()); String goodsName = bigGiftPackage != null ? bigGiftPackage.getName() : "大礼包商品"; // 5. 计算支付金额 BigDecimal paymentAmount; if (order.getPaymentType() == 1) { // 订金+尾款模式,支付订金 paymentAmount = order.getDeposit(); } else { // 全款模式 paymentAmount = order.getOrderPrice(); } // 6. 生成新的支付订单号 String newPayOrderCode = OrderCodeGenerator.generateBigGiftPayOrderCode(); // 7. 更新当前订单的 payOrderCode order.setPayOrderCode(newPayOrderCode); this.updateById(order); //查询用户所属公司,获取经销商商户号 TCompany company = appUserService.getUserCompany(appUserId); // 8. 调用工行支付 log.info("大礼包立即支付,订单ID:{},新支付订单号:{},支付金额:{},用户ID:{}", orderId, newPayOrderCode, paymentAmount, appUserId); JSONObject paymentParams = icbcPayUtil.wechatPay(newPayOrderCode, paymentAmount, goodsName, openid, icbcConfig.getNotifyUrl() + "/big-gift/pay-notify", company.getMerchantNumber(), company.getMerchantOpenid()); // 9. 构建返回结果 PlaceOrderVO vo = new PlaceOrderVO(); vo.setOrderIds(Collections.singletonList(orderId)); vo.setOrderCodes(Collections.singletonList(order.getCode())); vo.setPaymentParams(paymentParams); return vo; } }