Pu Zhibing
2025-11-27 a764dc672aaf0b7d87512ad1a75ef96672976228
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TOrderInvoiceServiceImpl.java
@@ -30,6 +30,9 @@
import com.ruoyi.other.api.feignClient.GoodsClient;
import com.ruoyi.other.api.feignClient.InvoiceTypeClient;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -40,6 +43,7 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@@ -85,6 +89,9 @@
   @Resource
   private TChargingOrderAccountingStrategyService chargingOrderAccountingStrategyService;
   @Autowired
   private RedissonClient redissonClient;
   
   
   
@@ -97,57 +104,67 @@
   @Override
   public AjaxResult addOrderInvoice(AddOrderInvoice addOrderInvoice) {
      Long userId = tokenService.getLoginUserApplet().getUserId();
      String orders = addOrderInvoice.getOrders();
      if(StringUtils.isEmpty(orders)){
         return AjaxResult.error("请选择有效的订单");
      }
      JSONArray parse = JSONArray.parse(orders);
      List<Long> orderIds = new ArrayList<>();
      Map<Long, BigDecimal> map = new HashMap<>();
      for (int i = 0; i < parse.size(); i++) {
         JSONObject jsonObject = parse.getJSONObject(i);
         Long id = jsonObject.getLong("id");
         BigDecimal amount = jsonObject.getBigDecimal("amount");
         orderIds.add(id);
         map.put(id, amount);
      }
      long count = orderInvoiceDetailService.count(new LambdaQueryWrapper<TOrderInvoiceDetail>().eq(TOrderInvoiceDetail::getOrderType, addOrderInvoice.getOrderType())
            .in(TOrderInvoiceDetail::getOrderId, orderIds));
      if(count > 0){
         return AjaxResult.error("不能重复申请开票,请刷新数据后重试");
      }
      SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
      String code = Double.valueOf(Math.random() * 1000).intValue() + sdf.format(new Date());
      //获取开票类型
      TInvoiceType invoiceType = invoiceTypeClient.getInvoiceType(addOrderInvoice.getInvoiceTypeId()).getData();
      addOrderInvoice.setInvoicingCompany(invoiceType.getInvoicingCompany());
      addOrderInvoice.setInvoiceType(invoiceType.getName());
      addOrderInvoice.setInvoiceMaterial(2);
      addOrderInvoice.setInvoicingMethod(invoiceType.getInvoicingMethod());
      addOrderInvoice.setAppUserId(userId);
      addOrderInvoice.setCode(code);
      addOrderInvoice.setStatus(1);
      addOrderInvoice.setCreateTime(LocalDateTime.now());
      this.save(addOrderInvoice);
      for (Long orderId : orderIds) {
         List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
               .eq(TChargingOrderAccountingStrategy::getChargingOrderId, orderId));
         BigDecimal electrovalence = list.stream().map(TChargingOrderAccountingStrategy::getElectrovalence).reduce(BigDecimal.ZERO, BigDecimal::add);
         BigDecimal serviceCharge = list.stream().map(TChargingOrderAccountingStrategy::getServiceCharge).reduce(BigDecimal.ZERO, BigDecimal::add);
         TOrderInvoiceDetail orderInvoiceDetail = new TOrderInvoiceDetail();
         orderInvoiceDetail.setOrderInvoiceId(addOrderInvoice.getId());
         orderInvoiceDetail.setInvoiceAmount(map.get(orderId));
         orderInvoiceDetail.setOrderType(addOrderInvoice.getOrderType());
         orderInvoiceDetail.setOrderId(orderId);
         orderInvoiceDetail.setElectricityTariff(invoiceType.getElectricityTariff());
         orderInvoiceDetail.setServiceTariff(invoiceType.getServiceTariff());
         orderInvoiceDetail.setAddedServiceTariff(invoiceType.getAddedServiceTariff());
         orderInvoiceDetail.setElectrovalence(electrovalence);
         orderInvoiceDetail.setServiceCharge(serviceCharge);
         orderInvoiceDetail.setAddedService(serviceCharge.multiply(null == invoiceType.getAddedServiceTariff()
               ? new BigDecimal(1) : invoiceType.getAddedServiceTariff().divide(new BigDecimal(100))));
         orderInvoiceDetailService.save(orderInvoiceDetail);
      RLock lock = redissonClient.getLock("ADD_ORDER_INVOICE:" + userId);
      try {
         boolean tryLock = lock.tryLock(5, TimeUnit.SECONDS);
         if(tryLock){
            String orders = addOrderInvoice.getOrders();
            if(StringUtils.isEmpty(orders)){
               return AjaxResult.error("请选择有效的订单");
            }
            JSONArray parse = JSONArray.parse(orders);
            List<Long> orderIds = new ArrayList<>();
            Map<Long, BigDecimal> map = new HashMap<>();
            for (int i = 0; i < parse.size(); i++) {
               JSONObject jsonObject = parse.getJSONObject(i);
               Long id = jsonObject.getLong("id");
               BigDecimal amount = jsonObject.getBigDecimal("amount");
               orderIds.add(id);
               map.put(id, amount);
            }
            long count = orderInvoiceDetailService.count(new LambdaQueryWrapper<TOrderInvoiceDetail>().eq(TOrderInvoiceDetail::getOrderType, addOrderInvoice.getOrderType())
                  .in(TOrderInvoiceDetail::getOrderId, orderIds));
            if(count > 0){
               return AjaxResult.error("不能重复申请开票,请刷新数据后重试");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            String code = Double.valueOf(Math.random() * 1000).intValue() + sdf.format(new Date());
            //获取开票类型
            TInvoiceType invoiceType = invoiceTypeClient.getInvoiceType(addOrderInvoice.getInvoiceTypeId()).getData();
            addOrderInvoice.setInvoicingCompany(invoiceType.getInvoicingCompany());
            addOrderInvoice.setInvoiceType(invoiceType.getName());
            addOrderInvoice.setInvoiceMaterial(2);
            addOrderInvoice.setInvoicingMethod(invoiceType.getInvoicingMethod());
            addOrderInvoice.setAppUserId(userId);
            addOrderInvoice.setCode(code);
            addOrderInvoice.setStatus(1);
            addOrderInvoice.setCreateTime(LocalDateTime.now());
            this.save(addOrderInvoice);
            for (Long orderId : orderIds) {
               List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
                     .eq(TChargingOrderAccountingStrategy::getChargingOrderId, orderId));
               BigDecimal electrovalence = list.stream().map(TChargingOrderAccountingStrategy::getElectrovalence).reduce(BigDecimal.ZERO, BigDecimal::add);
               BigDecimal serviceCharge = list.stream().map(TChargingOrderAccountingStrategy::getServiceCharge).reduce(BigDecimal.ZERO, BigDecimal::add);
               TOrderInvoiceDetail orderInvoiceDetail = new TOrderInvoiceDetail();
               orderInvoiceDetail.setOrderInvoiceId(addOrderInvoice.getId());
               orderInvoiceDetail.setInvoiceAmount(map.get(orderId));
               orderInvoiceDetail.setOrderType(addOrderInvoice.getOrderType());
               orderInvoiceDetail.setOrderId(orderId);
               orderInvoiceDetail.setElectricityTariff(invoiceType.getElectricityTariff());
               orderInvoiceDetail.setServiceTariff(invoiceType.getServiceTariff());
               orderInvoiceDetail.setAddedServiceTariff(invoiceType.getAddedServiceTariff());
               orderInvoiceDetail.setElectrovalence(electrovalence);
               orderInvoiceDetail.setServiceCharge(serviceCharge);
               orderInvoiceDetail.setAddedService(serviceCharge.multiply(null == invoiceType.getAddedServiceTariff()
                     ? new BigDecimal(1) : invoiceType.getAddedServiceTariff().divide(new BigDecimal(100))));
               orderInvoiceDetailService.save(orderInvoiceDetail);
            }
         }
      }catch (Exception e){
         e.printStackTrace();
      }finally {
         lock.unlock();
      }
      return AjaxResult.success();
   }