Explorar o código

新增装运单打印查询以及储运中心拓展付跨信息

lingpeng.li hai 3 días
pai
achega
c75b592671

+ 6 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/controller/StorageBillController.java

@@ -2433,6 +2433,12 @@ public class StorageBillController extends JeecgController<StorageBill, IStorage
 		return Result.OK("添加成功!");
 	}
 
+	@ApiOperation(value="装运单打印表根据装运单id查询", notes="装运单打印表根据装运单id查询")
+	@GetMapping("/getByStorageBillId")
+	public Result<StorageBillPrintVO> getByStorageBillId(@RequestParam String storageBillId) {
+		StorageBillPrintVO result = storageBillPrintService.getByStorageBillId(storageBillId);
+		return Result.OK(result);
+	}
 
 	/**
 	 * 计算 本车车次

+ 12 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/dto/StorageBillPrintAddDTO.java

@@ -75,5 +75,17 @@ public class StorageBillPrintAddDTO {
     @Excel(name = "装运单ID", width = 15)
     @ApiModelProperty(value = "装运单ID")
     private String storageBillId;
+    /**
+     * 序号
+     */
+    @Excel(name = "序号", width = 15)
+    @ApiModelProperty(value = "序号")
+    private String number;
+    /**
+     * 班次信息
+     */
+    @Excel(name = "班次信息", width = 15)
+    @ApiModelProperty(value = "班次信息")
+    private String classes;
 
 }

+ 12 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/entity/StorageBillPrint.java

@@ -127,4 +127,16 @@ public class StorageBillPrint implements Serializable {
     @Excel(name = "装运单ID", width = 15)
     @ApiModelProperty(value = "装运单ID")
     private String storageBillId;
+    /**
+     * 序号
+     */
+    @Excel(name = "序号", width = 15)
+    @ApiModelProperty(value = "序号")
+    private String number;
+    /**
+     * 班次信息
+     */
+    @Excel(name = "班次信息", width = 15)
+    @ApiModelProperty(value = "班次信息")
+    private String classes;
 }

+ 4 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/service/IStorageBillPrintService.java

@@ -3,6 +3,7 @@ package org.jeecg.modules.billet.storageBill.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.jeecg.modules.billet.storageBill.dto.StorageBillPrintAddDTO;
 import org.jeecg.modules.billet.storageBill.entity.StorageBillPrint;
+import org.jeecg.modules.billet.storageBill.vo.StorageBillPrintVO;
 
 /**
  * @Description: 装运单打印表
@@ -13,4 +14,7 @@ import org.jeecg.modules.billet.storageBill.entity.StorageBillPrint;
 public interface IStorageBillPrintService extends IService<StorageBillPrint> {
 
     void saveStorageBillPrint(StorageBillPrintAddDTO addDTO);
+
+    StorageBillPrintVO getByStorageBillId(String storageBillId);
+
 }

+ 65 - 7
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/service/impl/StorageBillPrintServiceImpl.java

@@ -1,20 +1,24 @@
 package org.jeecg.modules.billet.storageBill.service.impl;
 
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.lang.StringUtils;
 import org.jeecg.modules.billet.storageBill.dto.StorageBillPrintAddDTO;
 import org.jeecg.modules.billet.storageBill.entity.StorageBillPrint;
 import org.jeecg.modules.billet.storageBill.mapper.StorageBillPrintMapper;
 import org.jeecg.modules.billet.storageBill.service.IStorageBillPrintService;
+import org.jeecg.modules.billet.storageBill.vo.StorageBillPrintVO;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import java.util.Map;
 
 /**
  * @Description: 装运单打印表
  * @Author: jeecg-boot
- * @Date:   2025-06-16
+ * @Date: 2025-06-16
  * @Version: V1.0
  */
 @Service
@@ -22,12 +26,28 @@ public class StorageBillPrintServiceImpl extends ServiceImpl<StorageBillPrintMap
 
     @Override
     public void saveStorageBillPrint(StorageBillPrintAddDTO addDTO) {
-        StorageBillPrint storageBillPrint = new StorageBillPrint();
+        if (addDTO.getStorageBillId() == null) {
+            throw new IllegalArgumentException("storageBillId 不能为空");
+        }
 
-        // 复制除 heatNo 之外的字段
-        BeanUtils.copyProperties(addDTO, storageBillPrint, "heatNo");
+        // 尝试根据 storageBillId 查询是否已存在记录
+        StorageBillPrint existing = this.lambdaQuery()
+                .eq(StorageBillPrint::getStorageBillId, addDTO.getStorageBillId())
+                .one();
+
+        StorageBillPrint storageBillPrint;
+
+        if (existing != null) {
+            // 修改:复制属性到已存在对象
+            storageBillPrint = existing;
+            BeanUtils.copyProperties(addDTO, storageBillPrint, "id", "heatNo", "createTime", "updateTime");
+        } else {
+            // 新增:创建新对象
+            storageBillPrint = new StorageBillPrint();
+            BeanUtils.copyProperties(addDTO, storageBillPrint, "heatNo");
+        }
 
-        // heatNo Map 转为 JSON 字符串
+        // heatNo Map 转 JSON
         if (addDTO.getHeatNo() != null) {
             try {
                 ObjectMapper objectMapper = new ObjectMapper();
@@ -38,7 +58,45 @@ public class StorageBillPrintServiceImpl extends ServiceImpl<StorageBillPrintMap
             }
         }
 
-        this.save(storageBillPrint);
+        // 保存或更新
+        this.saveOrUpdate(storageBillPrint);
+    }
+
+
+    @Override
+    public StorageBillPrintVO getByStorageBillId(String storageBillId) {
+        if (StringUtils.isBlank(storageBillId)) {
+            throw new IllegalArgumentException("storageBillId 不能为空");
+        }
+
+        StorageBillPrint entity = this.lambdaQuery()
+                .eq(StorageBillPrint::getStorageBillId, storageBillId)
+                .orderByDesc(StorageBillPrint::getCreateTime)
+                .last("LIMIT 1")
+                .one();
+
+
+        if (entity == null) {
+            return null;
+        }
+
+        StorageBillPrintVO vo = new StorageBillPrintVO();
+        BeanUtils.copyProperties(entity, vo);
+
+        // heatNo 字段是 JSON 字符串,解析为 Map
+        if (StringUtils.isNotBlank(entity.getHeatNo())) {
+            try {
+                ObjectMapper objectMapper = new ObjectMapper();
+                Map<String, Integer> heatNoMap = objectMapper.readValue(entity.getHeatNo(), new TypeReference<Map<String, Integer>>() {
+                });
+                vo.setHeatNo(heatNoMap);
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException("heatNo JSON 解析失败", e);
+            }
+        }
+
+        return vo;
     }
 
+
 }

+ 91 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/vo/StorageBillPrintVO.java

@@ -0,0 +1,91 @@
+package org.jeecg.modules.billet.storageBill.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Map;
+
+@Data
+public class StorageBillPrintVO {
+
+    /**
+     * 目的地
+     */
+    @Excel(name = "目的地", width = 15)
+    @ApiModelProperty(value = "目的地")
+    private String destination;
+    /**
+     * 到站时间
+     */
+    @Excel(name = "到站时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "到站时间")
+    private Date arrivalTime;
+    /**
+     * 车牌号
+     */
+    @Excel(name = "车牌号", width = 15)
+    @ApiModelProperty(value = "车牌号")
+    private String licensePlate;
+    /**
+     * 牌号
+     */
+    @Excel(name = "牌号", width = 15)
+    @ApiModelProperty(value = "牌号")
+    private String brandNum;
+    /**
+     * 炉号
+     */
+    @Excel(name = "炉号", width = 15)
+    @ApiModelProperty(value = "炉号")
+    private Map<String, Integer> heatNo;
+    /**
+     * 定尺
+     */
+    @Excel(name = "定尺", width = 15)
+    @ApiModelProperty(value = "定尺")
+    private String size;
+    /**
+     * 名称
+     */
+    @Excel(name = "名称", width = 15)
+    @ApiModelProperty(value = "名称")
+    private String name;
+    /**
+     * 支数
+     */
+    @Excel(name = "支数", width = 15)
+    @ApiModelProperty(value = "支数")
+    private Integer amountTotal;
+    /**
+     * 重量
+     */
+    @Excel(name = "重量", width = 15)
+    @ApiModelProperty(value = "重量")
+    private BigDecimal weight;
+    /**
+     * 装运单ID
+     */
+    @Excel(name = "装运单ID", width = 15)
+    @ApiModelProperty(value = "装运单ID")
+    private String storageBillId;
+    /**
+     * 序号
+     */
+    @Excel(name = "序号", width = 15)
+    @ApiModelProperty(value = "序号")
+    private String number;
+    /**
+     * 班次信息
+     */
+    @Excel(name = "班次信息", width = 15)
+    @ApiModelProperty(value = "班次信息")
+    private String classes;
+
+}

+ 18 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/vo/StorageCenterHeatNoInvoicingVO.java

@@ -17,6 +17,7 @@ public class StorageCenterHeatNoInvoicingVO {
     private StorageCenterHeatNoInvoicingVO.RollThreeHeatNo rollClubThreeDetails;
     private StorageCenterHeatNoInvoicingVO.RollHeightHeatNo rollHeightDetails;
     private StorageCenterHeatNoInvoicingVO.RollOutHeatNo rollOutShippDetails;
+    private StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo rollDeputyDetails;
 //    private StorageCenterHeatNoInvoicingVO.StackHeatNo stackingVehicles;
 //    private StorageCenterHeatNoInvoicingVO.UnknownHeatNo unknownDetails;
 
@@ -73,6 +74,23 @@ public class StorageCenterHeatNoInvoicingVO {
     }
 
 
+    @Data
+    public static class RollDeputyHeatNo {
+
+
+        @ApiModelProperty(value = "当前定尺总支数")
+        private Integer totalAmount;
+
+        @ApiModelProperty(value = "当前定尺总重量")
+        private BigDecimal totalWeight;
+
+        private List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetails;
+
+        private List<StorageCenterHeatNoInvoicingVO.RollChargeDetail> rollChargeDetails;
+
+    }
+
+
     @Data
     public static class RollHeightHeatNo {
 

+ 186 - 7
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/carUnit/service/impl/CarUnitServiceImpl.java

@@ -18,6 +18,8 @@ import org.jeecg.modules.billet.rollClubThree.entity.RollClubThreeDetails;
 import org.jeecg.modules.billet.rollClubThree.service.IRollClubThreeDetailsService;
 import org.jeecg.modules.billet.rollClubTwo.entity.RollClubTwoDetails;
 import org.jeecg.modules.billet.rollClubTwo.service.IRollClubTwoDetailsService;
+import org.jeecg.modules.billet.rollDeputyCross.entity.RollDeputyCrossDetails;
+import org.jeecg.modules.billet.rollDeputyCross.service.IRollDeputyCrossDetailsService;
 import org.jeecg.modules.billet.rollHeight.service.IRollHeightDetailsService;
 import org.jeecg.modules.billet.rollOutShipp.entity.RollOutShippDetails;
 import org.jeecg.modules.billet.rollOutShipp.service.IRollOutShippDetailsService;
@@ -88,6 +90,9 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
     @Autowired
     private IRollOutShippDetailsService rollOutShippDetailsService;
 
+    @Autowired
+    private IRollDeputyCrossDetailsService rollDeputyCrossDetailsService;
+
     @Autowired
     private IRollHeightDetailsService rollHeightDetailsService;
 
@@ -146,6 +151,14 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
                 }
             }
 
+            // 棒三 rollDeputyDetails
+            if (invoicing.getRollDeputyDetails() != null) {
+                for (StorageCenterHeatNoInvoicingVO.RollChargeDetail detail : invoicing.getRollDeputyDetails().getRollChargeDetails()) {
+                    StorageCenterExportRow row = convert(detail, ccmNo, "付跨");
+                    rows.add(row);
+                }
+            }
+
             // 上若 rollOutShippDetails(如有)
             if (invoicing.getRollOutShippDetails() != null) {
                 for (StorageCenterHeatNoInvoicingVO.RollChargeDetail detail : invoicing.getRollOutShippDetails().getRollChargeDetails()) {
@@ -1583,12 +1596,12 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
 
         List<StorageBill> billList = storageBillMapper.selectList(billQueryWrapper);
 
-        // 假设你已有以下数据结构
+        //构造数据
         Map<String, StorageCenterHeatNoInvoicingVO.RollOneHeatNo> rollOneMap = buildRollOneHeatNoMap(oneList); // 根据棒一明细构建
         Map<String, StorageCenterHeatNoInvoicingVO.RollTwoHeatNo> rollTwoMap = buildRollTwoHeatNoGroupByHeatNo(billList); // 根据棒二明细构建
         Map<String, StorageCenterHeatNoInvoicingVO.RollThreeHeatNo> rollThreeMap = buildRollThreeHeatNoGroupByHeatNo(billList);
         Map<String, StorageCenterHeatNoInvoicingVO.RollOutHeatNo> rollOutMap = buildRollOutHeatNoGroupByHeatNo(billList);
-
+        Map<String, StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo> rollDeputyMap = buildRollDeputyHeatNoGroupByHeatNo(billList);
 
         // 1. 按炉号聚合棒一和棒二数据到 StorageCenterHeatNoInvoicingVO
         Map<String, StorageCenterHeatNoInvoicingVO> heatNoVOMap = new HashMap<>();
@@ -1617,6 +1630,13 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
 
         }
 
+        for (String heatNo : rollDeputyMap.keySet()) {
+            StorageCenterHeatNoInvoicingVO vo = heatNoVOMap.computeIfAbsent(heatNo, k -> new StorageCenterHeatNoInvoicingVO());
+            StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo rollDeputy = rollDeputyMap.get(heatNo);
+            vo.setRollDeputyDetails(rollDeputy);
+
+        }
+
         // 2. 遍历所有炉号,构建最终返回列表
         List<StorageCenterInvoicingVO> resultList = new ArrayList<>();
         Set<String> allHeatNos = new HashSet<>();
@@ -1624,6 +1644,7 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
         allHeatNos.addAll(rollTwoMap.keySet());
         allHeatNos.addAll(rollThreeMap.keySet());
         allHeatNos.addAll(rollOutMap.keySet());
+        allHeatNos.addAll(rollDeputyMap.keySet());
 
         Map<String, StorageCenterInvoicingVO.HeatNoDetail> heatNoDetailMap = new HashMap<>();
 
@@ -1650,6 +1671,7 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
                     StorageCenterHeatNoInvoicingVO.RollTwoHeatNo rollTwo = null;
                     StorageCenterHeatNoInvoicingVO.RollThreeHeatNo rollThree = null;
                     StorageCenterHeatNoInvoicingVO.RollOutHeatNo rollOut = null;
+                    StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo rollDeputy = null;
 
                     StorageCenterHeatNoInvoicingVO vo = heatNoVOMap.get(heatNo);
                     if (vo != null) {
@@ -1657,6 +1679,7 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
                         rollTwo = vo.getRollClubTwoDetails();
                         rollThree = vo.getRollClubThreeDetails();
                         rollOut = vo.getRollOutShippDetails();
+                        rollDeputy = vo.getRollDeputyDetails();
                     }
 
                     // 初始化累计值
@@ -1687,6 +1710,12 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
                     if (rollOut != null && rollOut.getTotalWeight() != null) {
                         totalWeight = totalWeight.add(rollOut.getTotalWeight());
                     }
+                    if (rollDeputy != null && rollDeputy.getTotalAmount() != null) {
+                        totalAmount += rollDeputy.getTotalAmount();
+                    }
+                    if (rollDeputy != null && rollDeputy.getTotalWeight() != null) {
+                        totalWeight = totalWeight.add(rollDeputy.getTotalWeight());
+                    }
 
                     StorageCenterInvoicingVO.HeatNoDetail detail = new StorageCenterInvoicingVO.HeatNoDetail();
                     detail.setHeatNo(heatNo);
@@ -1703,6 +1732,8 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
                         finalCreateTime = rollTwo.getRollChargeDetails().get(0).getCreateTime();
                     } else if (rollThree != null && rollThree.getRollChargeDetails() != null && rollThree.getRollChargeDetails().get(0).getCreateTime() != null) {
                         finalCreateTime = rollThree.getRollChargeDetails().get(0).getCreateTime();
+                    } else if (rollDeputy != null && rollDeputy.getRollChargeDetails() != null && rollDeputy.getRollChargeDetails().get(0).getCreateTime() != null) {
+                        finalCreateTime = rollDeputy.getRollChargeDetails().get(0).getCreateTime();
                     } else if (rollOut != null && rollOut.getRollChargeDetails() != null && rollOut.getRollChargeDetails().get(0).getCreateTime() != null) {
                         finalCreateTime = rollOut.getRollChargeDetails().get(0).getCreateTime();
                     } else {
@@ -1780,11 +1811,14 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
                 .collect(Collectors.toSet());
 
         // 批量查询 billetBasicInfo,并按 billetNo 映射(保留创建时间最新的一条)
-        List<BilletBasicInfo> billetBasicInfos = billetBasicInfoService.list(
-                new LambdaQueryWrapper<BilletBasicInfo>()
-                        .in(BilletBasicInfo::getBilletNo, billetNoSet)
-                        .orderByDesc(BilletBasicInfo::getCreateTime)
-        );
+        List<BilletBasicInfo> billetBasicInfos = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(billetNoSet)) {
+            billetBasicInfos = billetBasicInfoService.list(
+                    new LambdaQueryWrapper<BilletBasicInfo>()
+                            .in(BilletBasicInfo::getBilletNo, billetNoSet)
+                            .orderByDesc(BilletBasicInfo::getCreateTime)
+            );
+        }
         Map<String, BilletBasicInfo> billetInfoMap = billetBasicInfos.stream()
                 .filter(b -> b.getBilletNo() != null)
                 .collect(Collectors.toMap(
@@ -2316,6 +2350,151 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
     }
 
 
+    private Map<String, StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo> buildRollDeputyHeatNoGroupByHeatNo(List<StorageBill> billList) {
+        Map<String, StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo> resultMap = new HashMap<>();
+
+        // 提取所有有效 billId
+        Set<String> billIdSet = billList.stream()
+                .map(StorageBill::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        if (CollectionUtils.isEmpty(billIdSet)) {
+            return Collections.emptyMap();
+        }
+
+        // 构建 billId -> StorageBill 映射
+        Map<String, StorageBill> billMap = billList.stream()
+                .filter(b -> b.getId() != null)
+                .collect(Collectors.toMap(StorageBill::getId, Function.identity()));
+
+        // 查询所有明细
+        List<RollDeputyCrossDetails> detailList = rollDeputyCrossDetailsService.list(
+                new LambdaQueryWrapper<RollDeputyCrossDetails>()
+                        .in(RollDeputyCrossDetails::getStorageBillId, billIdSet)
+        );
+
+        // 按 heatNo -> storageBillId -> List 分组
+        Map<String, Map<String, List<RollDeputyCrossDetails>>> grouped = detailList.stream()
+                .filter(d -> d.getHeatNo() != null && d.getStorageBillId() != null)
+                .collect(Collectors.groupingBy(
+                        RollDeputyCrossDetails::getHeatNo,
+                        Collectors.groupingBy(RollDeputyCrossDetails::getStorageBillId)
+                ));
+
+        for (Map.Entry<String, Map<String, List<RollDeputyCrossDetails>>> heatNoEntry : grouped.entrySet()) {
+            String heatNo = heatNoEntry.getKey();
+            Map<String, List<RollDeputyCrossDetails>> billGroupMap = heatNoEntry.getValue();
+
+            StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo rollDeputyHeatNo = resultMap.computeIfAbsent(heatNo, k -> {
+                StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo r = new StorageCenterHeatNoInvoicingVO.RollDeputyHeatNo();
+                r.setSizeDetails(new ArrayList<>());
+                r.setRollChargeDetails(new ArrayList<>());
+                return r;
+            });
+
+            for (Map.Entry<String, List<RollDeputyCrossDetails>> billEntry : billGroupMap.entrySet()) {
+                String billId = billEntry.getKey();
+                List<RollDeputyCrossDetails> heatNoList = billEntry.getValue();
+
+                StorageBill bill = billMap.get(billId);
+                if (bill == null) continue;
+
+                // 计算重量(仅根据明细的 blankOutput)
+                BigDecimal heatWeight = heatNoList.stream()
+                        .map(RollDeputyCrossDetails::getBlankOutput)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                // 获取 billetNo 列表(不去重)
+                List<String> billetNoList = heatNoList.stream()
+                        .map(RollDeputyCrossDetails::getBilletNo)
+                        .filter(StringUtils::isNotBlank)
+                        .flatMap(s -> Arrays.stream(s.split(",")))
+                        .map(String::trim)
+                        .filter(StringUtils::isNotBlank)
+                        .collect(Collectors.toList());
+
+                if (billetNoList.isEmpty()) continue;
+
+                // 累加总支数与重量
+                rollDeputyHeatNo.setTotalAmount(
+                        Optional.ofNullable(rollDeputyHeatNo.getTotalAmount()).orElse(0) + billetNoList.size()
+                );
+                rollDeputyHeatNo.setTotalWeight(
+                        Optional.ofNullable(rollDeputyHeatNo.getTotalWeight()).orElse(BigDecimal.ZERO).add(heatWeight)
+                );
+
+                // 统计 billetNo 出现次数
+                Map<String, Long> billetNoCountMap = billetNoList.stream()
+                        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
+
+                // 查询基础信息(去重查询)
+                List<BilletBasicInfo> billetBasicInfoList = billetBasicInfoService.list(
+                        new LambdaQueryWrapper<BilletBasicInfo>()
+                                .eq(BilletBasicInfo::getHeatNo, heatNo)
+                                .in(BilletBasicInfo::getBilletNo, billetNoCountMap.keySet())
+                );
+
+                if (CollectionUtils.isEmpty(billetBasicInfoList)) continue;
+
+                // 扩展 billetBasicInfo 按照 billetNo 出现次数
+                List<BilletBasicInfo> expandedList = new ArrayList<>();
+                for (BilletBasicInfo info : billetBasicInfoList) {
+                    long count = billetNoCountMap.getOrDefault(info.getBilletNo(), 1L);
+                    for (int i = 0; i < count; i++) {
+                        expandedList.add(info);
+                    }
+                }
+
+                // 按长度分组
+                Map<Integer, List<BilletBasicInfo>> groupedBySize = expandedList.stream()
+                        .filter(b -> b.getLength() != null)
+                        .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
+
+                for (Map.Entry<Integer, List<BilletBasicInfo>> sizeEntry : groupedBySize.entrySet()) {
+                    Integer size = sizeEntry.getKey();
+                    List<BilletBasicInfo> sizeList = sizeEntry.getValue();
+
+                    BigDecimal totalWeight = sizeList.stream()
+                            .map(BilletBasicInfo::getBilletWeight)
+                            .filter(Objects::nonNull)
+                            .map(BigDecimal::valueOf)
+                            .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                    if (size != null && size.equals(9100)) {
+                        size = 8790;
+                    }
+
+                    // 添加尺寸明细
+                    StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                    sizeDetail.setSize(size);
+                    sizeDetail.setSizeWeight(totalWeight);
+                    sizeDetail.setSizeAmount(sizeList.size());
+                    rollDeputyHeatNo.getSizeDetails().add(sizeDetail);
+
+                    // 添加计费信息
+                    StorageCenterHeatNoInvoicingVO.RollChargeDetail chargeDetail = new StorageCenterHeatNoInvoicingVO.RollChargeDetail();
+                    chargeDetail.setSize(size);
+                    chargeDetail.setSpec(Optional.ofNullable(sizeList.get(0).getSpec()).orElse("Unknown"));
+                    chargeDetail.setWeight(totalWeight);
+                    chargeDetail.setAmount(sizeList.size());
+                    chargeDetail.setLicensePlate(Optional.ofNullable(bill.getLicensePlate()).orElse("未知"));
+                    chargeDetail.setBtype(Optional.ofNullable(bill.getBtype()).orElse("未知"));
+                    chargeDetail.setHeatNo(heatNo);
+                    chargeDetail.setCarNum(Optional.ofNullable(bill.getCarNum()).orElse(1));
+                    chargeDetail.setBrandNum(Optional.ofNullable(bill.getBrandNum()).orElse(""));
+                    chargeDetail.setCreateTime(Optional.ofNullable(bill.getOutTime()).orElse(new Date()));
+                    rollDeputyHeatNo.getRollChargeDetails().add(chargeDetail);
+                }
+            }
+        }
+
+        return resultMap;
+    }
+
+
     public static String getTransportUnitNameByCarNumber(String carNumber) {
         if (StringUtils.isBlank(carNumber)) return "";