Просмотр исходного кода

完善储运中心列表查询热送数据的时间过滤

lingpeng.li 2 месяцев назад
Родитель
Сommit
474da501aa

+ 38 - 46
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/storageBill/service/impl/StorageBillServiceImpl.java

@@ -4012,12 +4012,12 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
         Date beginDate = queryDTO.getStorageTimeBegin();
         Date endDate = queryDTO.getStorageTimeEnd();
         if (beginDate != null) {
-            billQueryWrapper.ge(HeatsActuals::getCreateTime, DateUtils.getStartOfDayByDate(beginDate));
+            billQueryWrapper.ge(HeatsActuals::getUpdateTime, beginDate);
         }
         if (endDate != null) {
-            billQueryWrapper.le(HeatsActuals::getCreateTime, DateUtils.getEndOfDayByDate(endDate));
+            billQueryWrapper.le(HeatsActuals::getUpdateTime, endDate);
         }
-        billQueryWrapper.orderByDesc(HeatsActuals::getCreateTime);
+        billQueryWrapper.orderByDesc(HeatsActuals::getUpdateTime);
 
         Page<HeatsActuals> pageResult = heatsActualsService.page(heatsPage, billQueryWrapper);
         List<HeatsActuals> heatsActuals = pageResult.getRecords();
@@ -4047,20 +4047,14 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                     String shift = heat.getShift();
                     String shiftGroup = heat.getShiftGroup();
                     Date createTime = heat.getCreateTime();
+                    Date updateTime = heat.getUpdateTime();
                     List<BilletBasicInfo> billets = groupedByHeatNo.getOrDefault(heatNo, Collections.emptyList());
 
-                    // 汇总重量
-                    BigDecimal totalWeight = billets.stream()
-                            .map(BilletBasicInfo::getBilletWeight)
-                            .filter(Objects::nonNull)
-                            .map(BigDecimal::valueOf)
-                            .reduce(BigDecimal.ZERO, BigDecimal::add);
-
                     Integer ccmNo = Optional.ofNullable(heat.getCasterCode()).map(Integer::valueOf).orElse(0);
 
                     StorageCenterInvoicingVO.HeatNoDetail heatNoDetail = new StorageCenterInvoicingVO.HeatNoDetail();
 
-                    StorageCenterHeatNoInvoicingVO storageCenterHeatNoInvoicingVO = storageCenterInvoicingByHeatNo(heatNo);
+                    StorageCenterHeatNoInvoicingVO storageCenterHeatNoInvoicingVO = iCarUnitService.storageCenterInvoicingByHeatNo(heatNo,queryDTO);
 
                     BigDecimal sumWeight = BigDecimal.ZERO;
                     int sumAmount = 0;
@@ -4097,33 +4091,32 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                             }
 
                             if (storageTimeBegin != null && storageTimeEnd != null) {
-                                return !createTime1.before(DateUtils.getStartOfDayByDate(storageTimeBegin)) && !createTime1.after(DateUtils.getEndOfDayByDate(storageTimeEnd));
+                                return !createTime1.before(storageTimeBegin) && !createTime1.after(storageTimeEnd);
                             } else if (storageTimeBegin != null) {
-                                return !createTime1.before(DateUtils.getStartOfDayByDate(storageTimeBegin));
+                                return !createTime1.before(storageTimeBegin);
                             } else if (storageTimeEnd != null) {
-                                return !createTime1.after(DateUtils.getEndOfDayByDate(storageTimeEnd));
+                                return !createTime1.after(storageTimeEnd);
                             } else {
                                 return true; // 时间条件都为空,则不过滤
                             }
                         };
 
-
-                        Predicate<StorageCenterHeatNoInvoicingVO.RollSendDetail> timeFilterOther = detail -> {
-                            Date createTime1 = detail.getCreateTime();
-                            if (createTime1 == null) {
-                                return false; // 没有 createTime 的记录直接过滤掉
-                            }
-
-                            if (storageTimeBegin != null && storageTimeEnd != null) {
-                                return !createTime1.before(DateUtils.getStartOfDayByDate(storageTimeBegin)) && !createTime1.after(DateUtils.getEndOfDayByDate(storageTimeEnd));
-                            } else if (storageTimeBegin != null) {
-                                return !createTime1.before(DateUtils.getStartOfDayByDate(storageTimeBegin));
-                            } else if (storageTimeEnd != null) {
-                                return !createTime1.after(DateUtils.getEndOfDayByDate(storageTimeEnd));
-                            } else {
-                                return true; // 时间条件都为空,则不过滤
-                            }
-                        };
+//                        Predicate<StorageCenterHeatNoInvoicingVO.RollSendDetail> timeFilterOther = detail -> {
+//                            Date updateTime1 = detail.getUpdateTime();
+//                            if (updateTime1 == null) {
+//                                return false; // 没有 updateTime 的记录直接过滤掉
+//                            }
+//
+//                            if (storageTimeBegin != null && storageTimeEnd != null) {
+//                                return !updateTime1.before(storageTimeBegin) && !updateTime1.after(storageTimeEnd);
+//                            } else if (storageTimeBegin != null) {
+//                                return !updateTime1.before(storageTimeBegin);
+//                            } else if (storageTimeEnd != null) {
+//                                return !updateTime1.after(storageTimeEnd);
+//                            } else {
+//                                return true; // 时间条件都为空,则不过滤
+//                            }
+//                        };
 
                         // 过滤棒一
                         if (storageCenterHeatNoInvoicingVO.getRollClubOneDetails() != null) {
@@ -4131,7 +4124,6 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                                     .getRollClubOneDetails()
                                     .getRollSendDetails()
                                     .stream()
-                                    .filter(timeFilterOther)
                                     .collect(Collectors.toList());
                             storageCenterHeatNoInvoicingVO.getRollClubOneDetails().setRollSendDetails(filtered);
                         }
@@ -4143,7 +4135,6 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                                     .getRollHeightDetails()
                                     .getRollSendDetails()
                                     .stream()
-                                    .filter(timeFilterOther)
                                     .collect(Collectors.toList());
                             storageCenterHeatNoInvoicingVO.getRollHeightDetails().setRollSendDetails(filtered);
                         }
@@ -4187,10 +4178,10 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                     heatNoDetail.setCcmNo(ccmNo);
                     heatNoDetail.setHeatNoWeight(sumWeight);
                     heatNoDetail.setHeatNoAmount(sumAmount);
-                    heatNoDetail.setCreateTime(createTime);
+                    //根据修改时间过滤展示
+                    heatNoDetail.setCreateTime(updateTime);
                     heatNoDetail.setShift(shift);
                     heatNoDetail.setShiftGroup(shiftGroup);
-                    heatNoDetail.setCreateTime(createTime);
 
                     StorageCenterInvoicingVO vo = new StorageCenterInvoicingVO();
                     vo.setHeatNoDetails(Collections.singletonList(heatNoDetail));
@@ -5267,10 +5258,10 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
             // 使用 DateTimeFormatter 将 String 转换为 LocalDate 类型
             DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
-            // 按照 createTime(yyyy-MM-dd)分组
+            // 按照 updateTime(yyyy-MM-dd)分组
             Map<String, List<BilletBasicInfo>> groupedByDate = billetBasicInfos.stream()
-                    .filter(b -> b.getCreateTime() != null)
-                    .collect(Collectors.groupingBy(b -> dateFormatter.format(b.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())));
+                    .filter(b -> b.getUpdateTime() != null)
+                    .collect(Collectors.groupingBy(b -> dateFormatter.format(b.getUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())));
 
             List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = new ArrayList<>();
             List<StorageCenterHeatNoInvoicingVO.RollSendDetail> rollSendDetailList = new ArrayList<>();
@@ -5279,7 +5270,7 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                 List<BilletBasicInfo> dateBillets = dateEntry.getValue();
 
                 // 解析日期字符串为 LocalDate
-                LocalDate createDate = LocalDate.parse(dateEntry.getKey(), dateFormatter);
+                LocalDate updateDate = LocalDate.parse(dateEntry.getKey(), dateFormatter);
 
                 // 按照 length 再分组
                 Map<Integer, List<BilletBasicInfo>> groupedByLength = dateBillets.stream()
@@ -5310,8 +5301,9 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                     rollSendDetail.setAmount(count);
                     rollSendDetail.setSpec(spec);
 
-                    // 设置 createDate,只保留日期部分
-                    rollSendDetail.setCreateTime(java.sql.Date.valueOf(createDate));  // 只保留日期部分,清除时间部分
+                    rollSendDetail.setCreateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
+                    rollSendDetail.setUpdateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
+
                     rollSendDetailList.add(rollSendDetail);
                 });
             }
@@ -5341,8 +5333,8 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
 
             // 按照 createTime(yyyy-MM-dd)分组
             Map<String, List<BilletBasicInfo>> groupedByDate = billetBasicInfos.stream()
-                    .filter(b -> b.getCreateTime() != null)
-                    .collect(Collectors.groupingBy(b -> dateFormatter.format(b.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())));
+                    .filter(b -> b.getUpdateTime() != null)
+                    .collect(Collectors.groupingBy(b -> dateFormatter.format(b.getUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())));
 
             List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = new ArrayList<>();
             List<StorageCenterHeatNoInvoicingVO.RollSendDetail> rollSendDetailList = new ArrayList<>();
@@ -5351,7 +5343,7 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                 List<BilletBasicInfo> dateBillets = dateEntry.getValue();
 
                 // 解析日期字符串为 LocalDate
-                LocalDate createDate = LocalDate.parse(dateEntry.getKey(), dateFormatter);
+                LocalDate updateDate = LocalDate.parse(dateEntry.getKey(), dateFormatter);
 
                 // 按照 length 再分组
                 Map<Integer, List<BilletBasicInfo>> groupedByLength = dateBillets.stream()
@@ -5382,8 +5374,8 @@ public class StorageBillServiceImpl extends ServiceImpl<StorageBillMapper, Stora
                     rollSendDetail.setAmount(count);
                     rollSendDetail.setSpec(spec);
 
-                    // 设置 createDate,只保留日期部分
-                    rollSendDetail.setCreateTime(java.sql.Date.valueOf(createDate));  // 只保留日期部分,清除时间部分
+                    rollSendDetail.setCreateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
+                    rollSendDetail.setUpdateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
                     rollSendDetailList.add(rollSendDetail);
                 });
             }

+ 2 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/carUnit/service/ICarUnitService.java

@@ -23,4 +23,6 @@ public interface ICarUnitService extends IService<CarUnit> {
 
     StorageCenterHeatNoInvoicingVO storageCenterInvoicingByQueryDTO(StorageCenterQueryDTO queryDTO);
 
+    StorageCenterHeatNoInvoicingVO storageCenterInvoicingByHeatNo(String heatNo,StorageCenterQueryDTO queryDTO);
+
 }

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

@@ -40,8 +40,12 @@ import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 /**
@@ -731,6 +735,777 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
     }
 
 
+    @Override
+    public StorageCenterHeatNoInvoicingVO storageCenterInvoicingByHeatNo(String heatNo,StorageCenterQueryDTO queryDTO) {
+        StorageCenterHeatNoInvoicingVO storageCenterHeatNoInvoicingVO = new StorageCenterHeatNoInvoicingVO();
+
+        StorageCenterHeatNoInvoicingVO.RollOneHeatNo rollOneHeatNo = new StorageCenterHeatNoInvoicingVO.RollOneHeatNo();
+        StorageCenterHeatNoInvoicingVO.RollTwoHeatNo rollTwoHeatNo = new StorageCenterHeatNoInvoicingVO.RollTwoHeatNo();
+        StorageCenterHeatNoInvoicingVO.RollThreeHeatNo rollThreeHeatNo = new StorageCenterHeatNoInvoicingVO.RollThreeHeatNo();
+        StorageCenterHeatNoInvoicingVO.RollHeightHeatNo rollHeightHeatNo = new StorageCenterHeatNoInvoicingVO.RollHeightHeatNo();
+        StorageCenterHeatNoInvoicingVO.RollOutHeatNo rollOutHeatNo = new StorageCenterHeatNoInvoicingVO.RollOutHeatNo();
+
+        Date storageTimeBegin = queryDTO.getStorageTimeBegin();
+        Date storageTimeEnd = queryDTO.getStorageTimeEnd();
+
+
+        Predicate<BilletBasicInfo> timeFilterOther = detail -> {
+            Date updateTime1 = detail.getUpdateTime();
+            if (updateTime1 == null) {
+                return false; // 没有 updateTime 的记录直接过滤掉
+            }
+
+            if (storageTimeBegin != null && storageTimeEnd != null) {
+                return !updateTime1.before(storageTimeBegin) && !updateTime1.after(storageTimeEnd);
+            } else if (storageTimeBegin != null) {
+                return !updateTime1.before(storageTimeBegin);
+            } else if (storageTimeEnd != null) {
+                return !updateTime1.after(storageTimeEnd);
+            } else {
+                return true; // 时间条件都为空,则不过滤
+            }
+        };
+
+        // 查询 BilletBasicInfo 数据
+        LambdaQueryWrapper<BilletBasicInfo> basicInfoQueryWrapper = new LambdaQueryWrapper<>();
+        basicInfoQueryWrapper.eq(BilletBasicInfo::getHeatNo, heatNo);
+
+        List<BilletBasicInfo> list = billetBasicInfoService.list(basicInfoQueryWrapper);
+        if (oConvertUtils.listIsEmpty(list)) {
+            return storageCenterHeatNoInvoicingVO;
+        }
+
+
+        // 使用 timeFilterOther 过滤 list
+        List<BilletBasicInfo> filteredList = list.stream()
+                .filter(timeFilterOther)
+                .collect(Collectors.toList());
+
+
+        // 按照 belongTable 分组
+        Map<String, List<BilletBasicInfo>> groupedByBelongTable = filteredList.stream()
+                .collect(Collectors.groupingBy(
+                        b -> Optional.ofNullable(b.getBelongTable()).orElse("unknown") // 处理 null 值
+                ));
+
+
+        if (groupedByBelongTable.containsKey("roll_club_one")) {
+
+            List<BilletBasicInfo> billetBasicInfos = groupedByBelongTable.get("roll_club_one");
+
+            // 计算总重量 & 总条数
+            BigDecimal totalBlankOutput = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getBilletWeight)
+                    .filter(Objects::nonNull)
+                    .map(BigDecimal::valueOf)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            rollOneHeatNo.setTotalAmount(billetBasicInfos.size());
+            rollOneHeatNo.setTotalWeight(totalBlankOutput);
+
+            // 使用 DateTimeFormatter 将 String 转换为 LocalDate 类型
+            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+            // 按照 updateTime(yyyy-MM-dd)分组
+            Map<String, List<BilletBasicInfo>> groupedByDate = billetBasicInfos.stream()
+                    .filter(b -> b.getUpdateTime() != null)
+                    .collect(Collectors.groupingBy(b -> dateFormatter.format(b.getUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())));
+
+            List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = new ArrayList<>();
+            List<StorageCenterHeatNoInvoicingVO.RollSendDetail> rollSendDetailList = new ArrayList<>();
+
+            for (Map.Entry<String, List<BilletBasicInfo>> dateEntry : groupedByDate.entrySet()) {
+                List<BilletBasicInfo> dateBillets = dateEntry.getValue();
+
+                // 解析日期字符串为 LocalDate
+                LocalDate updateDate = LocalDate.parse(dateEntry.getKey(), dateFormatter);
+
+                // 按照 length 再分组
+                Map<Integer, List<BilletBasicInfo>> groupedByLength = dateBillets.stream()
+                        .filter(b -> b.getLength() != null)
+                        .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
+
+                groupedByLength.forEach((length, billets) -> {
+                    BigDecimal totalWeight = billets.stream()
+                            .map(BilletBasicInfo::getBilletWeight)
+                            .filter(Objects::nonNull)
+                            .map(BigDecimal::valueOf)
+                            .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                    int count = billets.size();
+                    String spec = Optional.ofNullable(billets.get(0).getSpec()).orElse("Unknown");
+
+                    // 添加 SizeDetail(汇总一次即可,不需重复)
+                    StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                    sizeDetail.setSize(length);
+                    sizeDetail.setSizeAmount(count);
+                    sizeDetail.setSizeWeight(totalWeight);
+                    sizeDetailsList.add(sizeDetail);
+
+                    // 添加每一条按日期分组的 RollSendDetail
+                    StorageCenterHeatNoInvoicingVO.RollSendDetail rollSendDetail = new StorageCenterHeatNoInvoicingVO.RollSendDetail();
+                    rollSendDetail.setSize(length);
+                    rollSendDetail.setWeight(totalWeight);
+                    rollSendDetail.setAmount(count);
+                    rollSendDetail.setSpec(spec);
+
+                    rollSendDetail.setCreateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
+                    rollSendDetail.setUpdateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
+
+                    rollSendDetailList.add(rollSendDetail);
+                });
+            }
+
+            // 最终赋值给 rollOneHeatNo
+            rollOneHeatNo.setSizeDetails(sizeDetailsList);
+            rollOneHeatNo.setRollSendDetails(rollSendDetailList);
+            storageCenterHeatNoInvoicingVO.setRollClubOneDetails(rollOneHeatNo);
+        }
+
+        if (groupedByBelongTable.containsKey("roll_height")) {
+
+            List<BilletBasicInfo> billetBasicInfos = groupedByBelongTable.get("roll_height");
+
+            // 计算总重量 & 总条数
+            BigDecimal totalBlankOutput = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getBilletWeight)
+                    .filter(Objects::nonNull)
+                    .map(BigDecimal::valueOf)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            rollHeightHeatNo.setTotalAmount(billetBasicInfos.size());
+            rollHeightHeatNo.setTotalWeight(totalBlankOutput);
+
+            // 使用 DateTimeFormatter 将 String 转换为 LocalDate 类型
+            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+            // 按照 createTime(yyyy-MM-dd)分组
+            Map<String, List<BilletBasicInfo>> groupedByDate = billetBasicInfos.stream()
+                    .filter(b -> b.getUpdateTime() != null)
+                    .collect(Collectors.groupingBy(b -> dateFormatter.format(b.getUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())));
+
+            List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = new ArrayList<>();
+            List<StorageCenterHeatNoInvoicingVO.RollSendDetail> rollSendDetailList = new ArrayList<>();
+
+            for (Map.Entry<String, List<BilletBasicInfo>> dateEntry : groupedByDate.entrySet()) {
+                List<BilletBasicInfo> dateBillets = dateEntry.getValue();
+
+                // 解析日期字符串为 LocalDate
+                LocalDate updateDate = LocalDate.parse(dateEntry.getKey(), dateFormatter);
+
+                // 按照 length 再分组
+                Map<Integer, List<BilletBasicInfo>> groupedByLength = dateBillets.stream()
+                        .filter(b -> b.getLength() != null)
+                        .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
+
+                groupedByLength.forEach((length, billets) -> {
+                    BigDecimal totalWeight = billets.stream()
+                            .map(BilletBasicInfo::getBilletWeight)
+                            .filter(Objects::nonNull)
+                            .map(BigDecimal::valueOf)
+                            .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                    int count = billets.size();
+                    String spec = Optional.ofNullable(billets.get(0).getSpec()).orElse("Unknown");
+
+                    // 添加 SizeDetail(汇总一次即可,不需重复)
+                    StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                    sizeDetail.setSize(length);
+                    sizeDetail.setSizeAmount(count);
+                    sizeDetail.setSizeWeight(totalWeight);
+                    sizeDetailsList.add(sizeDetail);
+
+                    // 添加每一条按日期分组的 RollSendDetail
+                    StorageCenterHeatNoInvoicingVO.RollSendDetail rollSendDetail = new StorageCenterHeatNoInvoicingVO.RollSendDetail();
+                    rollSendDetail.setSize(length);
+                    rollSendDetail.setWeight(totalWeight);
+                    rollSendDetail.setAmount(count);
+                    rollSendDetail.setSpec(spec);
+
+                    rollSendDetail.setCreateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
+                    rollSendDetail.setUpdateTime(java.sql.Date.valueOf(updateDate));  // 只保留日期部分,清除时间部分
+                    rollSendDetailList.add(rollSendDetail);
+                });
+            }
+
+            // 最终赋值给 rollHeightHeatNo
+            rollHeightHeatNo.setSizeDetails(sizeDetailsList);
+            rollHeightHeatNo.setRollSendDetails(rollSendDetailList);
+            storageCenterHeatNoInvoicingVO.setRollHeightDetails(rollHeightHeatNo);
+        }
+
+
+        if (groupedByBelongTable.containsKey("roll_club_two")) {
+
+            List<BilletBasicInfo> billetBasicInfos = groupedByBelongTable.get("roll_club_two");
+
+            // 计算总重量 & 总条数
+            BigDecimal totalBlankOutput = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getBilletWeight)
+                    .filter(Objects::nonNull)
+                    .map(BigDecimal::valueOf)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            rollTwoHeatNo.setTotalAmount(billetBasicInfos.size());
+            rollTwoHeatNo.setTotalWeight(totalBlankOutput);
+
+            // 批量查询 StorageBill,避免 for 循环里重复查询
+            Set<String> assemblyNumbers = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getAssemblyNumber)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+
+            // 只查询这些组坯号的 StorageBill
+            Map<String, StorageBill> storageBillMap = new HashMap<>();
+
+            // 遍历所有组坯号,使用 `like` 添加查询条件
+            if (!assemblyNumbers.isEmpty()) {
+                LambdaQueryWrapper<StorageBill> billQueryWrapper = new LambdaQueryWrapper<>();
+                billQueryWrapper.and(wrapper -> {
+                    for (String assemblyNumber : assemblyNumbers) {
+                        wrapper.or().like(StorageBill::getAssemblyNumber, assemblyNumber);
+                    }
+                });
+
+                List<StorageBill> storageBillList = storageBillMapper.selectList(billQueryWrapper);
+
+                storageBillMap = storageBillList.stream()
+                        .collect(Collectors.toMap(StorageBill::getAssemblyNumber, Function.identity(), (a, b) -> a));
+            }
+
+            // 按 getLength 分组
+            Map<Integer, List<BilletBasicInfo>> groupedByLength = billetBasicInfos.stream()
+                    .filter(b -> b.getLength() != null)
+                    .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
+
+            List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = groupedByLength.entrySet().stream()
+                    .map(entry -> {
+                        Integer length = entry.getKey();
+                        List<BilletBasicInfo> billets = entry.getValue();
+
+                        // 计算 weight 总和
+                        BigDecimal totalWeight = billets.stream()
+                                .map(BilletBasicInfo::getBilletWeight)
+                                .filter(Objects::nonNull)
+                                .map(BigDecimal::valueOf)
+                                .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                        StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                        sizeDetail.setSize(length);
+                        sizeDetail.setSizeWeight(totalWeight);
+                        sizeDetail.setSizeAmount(billets.size());
+
+                        return sizeDetail;
+                    })
+                    .collect(Collectors.toList());
+
+            rollTwoHeatNo.setSizeDetails(sizeDetailsList);
+
+            // 按 组坯号 (assemblyNumber) 分组
+            Map<String, List<BilletBasicInfo>> groupedByAssemblyNumber = billetBasicInfos.stream()
+                    .filter(b -> b.getAssemblyNumber() != null)
+                    .collect(Collectors.groupingBy(BilletBasicInfo::getAssemblyNumber));
+
+            List<StorageCenterHeatNoInvoicingVO.RollChargeDetail> rollChargeDetails = new ArrayList<>();
+
+            for (Map.Entry<String, List<BilletBasicInfo>> entry : groupedByAssemblyNumber.entrySet()) {
+                String assemblyNumber = entry.getKey();
+                List<BilletBasicInfo> billets = entry.getValue();
+
+                if (billets == null || billets.isEmpty()) {
+                    continue;
+                }
+
+                Integer size = Optional.ofNullable(billets.get(0).getLength()).orElse(0);
+                String spec = Optional.ofNullable(billets.get(0).getSpec()).orElse("Unknown");
+
+                // 计算 weight 总和
+                BigDecimal totalWeight = billets.stream()
+                        .map(BilletBasicInfo::getBilletWeight)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                // 查找所有匹配当前 assemblyNumber 的 StorageBill
+                List<StorageBill> matchedStorageBills = storageBillMap.entrySet().stream()
+                        .filter(entryPlate -> Arrays.asList(entryPlate.getKey().split(",")).contains(assemblyNumber))
+                        .map(Map.Entry::getValue)
+                        .collect(Collectors.toList());
+
+                String licensePlate = Optional.ofNullable(matchedStorageBills)
+                        .filter(list1 -> !list1.isEmpty())
+                        .flatMap(list1 -> list1.stream()
+                                .map(StorageBill::getLicensePlate)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("未知车牌");
+
+                String btype = Optional.ofNullable(matchedStorageBills)
+                        .filter(list2 -> !list2.isEmpty())
+                        .flatMap(list2 -> list2.stream()
+                                .map(StorageBill::getBtype)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("未知类型");
+
+                String brandNum = Optional.ofNullable(matchedStorageBills)
+                        .filter(list3 -> !list3.isEmpty())
+                        .flatMap(list3 -> list3.stream()
+                                .map(StorageBill::getBrandNum)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("");
+
+
+                Integer carNum = Optional.ofNullable(matchedStorageBills)
+                        .filter(list4 -> !list4.isEmpty())
+                        .flatMap(list4 -> list4.stream()
+                                .map(StorageBill::getCarNum)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse(1);
+
+                Date createTime = Optional.ofNullable(matchedStorageBills)
+                        .filter(list5 -> !list5.isEmpty())
+                        .flatMap(list5 -> list5.stream()
+                                .map(StorageBill::getCreateTime)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse(new Date());
+
+
+                StorageCenterHeatNoInvoicingVO.RollChargeDetail rollChargeDetail = new StorageCenterHeatNoInvoicingVO.RollChargeDetail();
+                rollChargeDetail.setSize(size);
+                rollChargeDetail.setSpec(spec);
+                rollChargeDetail.setWeight(totalWeight);
+                rollChargeDetail.setAmount(billets.size());
+                rollChargeDetail.setLicensePlate(licensePlate);
+                rollChargeDetail.setBtype(btype);
+                rollChargeDetail.setHeatNo(heatNo);
+                rollChargeDetail.setCarNum(carNum);
+                rollChargeDetail.setBrandNum(brandNum);
+                rollChargeDetail.setCreateTime(createTime);
+
+                rollChargeDetails.add(rollChargeDetail);
+            }
+
+            // 按 licensePlate 分组并累加 amount 和 weight
+            Map<String, StorageCenterHeatNoInvoicingVO.RollChargeDetail> groupedByLicensePlate = rollChargeDetails.stream()
+                    .collect(Collectors.toMap(
+                            StorageCenterHeatNoInvoicingVO.RollChargeDetail::getLicensePlate,
+                            detail -> {
+                                StorageCenterHeatNoInvoicingVO.RollChargeDetail newDetail = new StorageCenterHeatNoInvoicingVO.RollChargeDetail();
+                                newDetail.setSize(detail.getSize());  // 这里可以选择合适的 size 逻辑
+                                newDetail.setSpec(detail.getSpec());
+                                newDetail.setWeight(detail.getWeight());
+                                newDetail.setAmount(detail.getAmount());
+                                newDetail.setLicensePlate(detail.getLicensePlate());
+                                newDetail.setBtype(detail.getBtype());
+                                newDetail.setHeatNo(detail.getHeatNo());
+                                newDetail.setCarNum(detail.getCarNum());
+                                newDetail.setBrandNum(detail.getBrandNum());
+                                newDetail.setCreateTime(detail.getCreateTime());
+                                return newDetail;
+                            },
+                            (existing, newDetail) -> {
+                                existing.setAmount(existing.getAmount() + newDetail.getAmount());
+                                existing.setWeight(existing.getWeight().add(newDetail.getWeight())); // BigDecimal 累加
+                                return existing;
+                            }
+                    ));
+
+            // 转换为 List 并赋值
+            List<StorageCenterHeatNoInvoicingVO.RollChargeDetail> mergedRollChargeDetails = new ArrayList<>(groupedByLicensePlate.values());
+            mergedRollChargeDetails.sort(Comparator.comparing(StorageCenterHeatNoInvoicingVO.RollChargeDetail::getCarNum));
+
+
+            rollTwoHeatNo.setRollChargeDetails(mergedRollChargeDetails);
+            rollTwoHeatNo.setSizeDetails(sizeDetailsList);
+            storageCenterHeatNoInvoicingVO.setRollClubTwoDetails(rollTwoHeatNo);
+        }
+
+
+        if (groupedByBelongTable.containsKey("roll_club_three")) {
+
+            List<BilletBasicInfo> billetBasicInfos = groupedByBelongTable.get("roll_club_three");
+
+            // 计算总重量 & 总条数
+            BigDecimal totalBlankOutput = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getBilletWeight)
+                    .filter(Objects::nonNull)
+                    .map(BigDecimal::valueOf)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            rollThreeHeatNo.setTotalAmount(billetBasicInfos.size());
+            rollThreeHeatNo.setTotalWeight(totalBlankOutput);
+
+            // 批量查询 StorageBill,避免 for 循环里重复查询
+            Set<String> assemblyNumbers = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getAssemblyNumber)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+
+            // 只查询这些组坯号的 StorageBill
+            Map<String, StorageBill> storageBillMap = new HashMap<>();
+
+            // 遍历所有组坯号,使用 `like` 添加查询条件
+            if (!assemblyNumbers.isEmpty()) {
+                LambdaQueryWrapper<StorageBill> billQueryWrapper = new LambdaQueryWrapper<>();
+                billQueryWrapper.and(wrapper -> {
+                    for (String assemblyNumber : assemblyNumbers) {
+                        wrapper.or().like(StorageBill::getAssemblyNumber, assemblyNumber);
+                    }
+                });
+
+                List<StorageBill> storageBillList = storageBillMapper.selectList(billQueryWrapper);
+
+                storageBillMap = storageBillList.stream()
+                        .collect(Collectors.toMap(StorageBill::getAssemblyNumber, Function.identity(), (a, b) -> a));
+            }
+
+            // 按 getLength 分组
+            Map<Integer, List<BilletBasicInfo>> groupedByLength = billetBasicInfos.stream()
+                    .filter(b -> b.getLength() != null)
+                    .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
+
+            List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = groupedByLength.entrySet().stream()
+                    .map(entry -> {
+                        Integer length = entry.getKey();
+                        List<BilletBasicInfo> billets = entry.getValue();
+
+                        // 计算 weight 总和
+                        BigDecimal totalWeight = billets.stream()
+                                .map(BilletBasicInfo::getBilletWeight)
+                                .filter(Objects::nonNull)
+                                .map(BigDecimal::valueOf)
+                                .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                        StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                        sizeDetail.setSize(length);
+                        sizeDetail.setSizeWeight(totalWeight);
+                        sizeDetail.setSizeAmount(billets.size());
+
+                        return sizeDetail;
+                    })
+                    .collect(Collectors.toList());
+
+            rollThreeHeatNo.setSizeDetails(sizeDetailsList);
+
+            // 按 组坯号 (assemblyNumber) 分组
+            Map<String, List<BilletBasicInfo>> groupedByAssemblyNumber = billetBasicInfos.stream()
+                    .filter(b -> b.getAssemblyNumber() != null)
+                    .collect(Collectors.groupingBy(BilletBasicInfo::getAssemblyNumber));
+
+            List<StorageCenterHeatNoInvoicingVO.RollChargeDetail> rollChargeDetails = new ArrayList<>();
+
+            for (Map.Entry<String, List<BilletBasicInfo>> entry : groupedByAssemblyNumber.entrySet()) {
+                String assemblyNumber = entry.getKey();
+                List<BilletBasicInfo> billets = entry.getValue();
+
+                if (billets == null || billets.isEmpty()) {
+                    continue;
+                }
+
+                Integer size = Optional.ofNullable(billets.get(0).getLength()).orElse(0);
+                String spec = Optional.ofNullable(billets.get(0).getSpec()).orElse("Unknown");
+
+                // 计算 weight 总和
+                BigDecimal totalWeight = billets.stream()
+                        .map(BilletBasicInfo::getBilletWeight)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+
+                // 查找所有匹配当前 assemblyNumber 的 StorageBill
+                List<StorageBill> matchedStorageBills = storageBillMap.entrySet().stream()
+                        .filter(entryPlate -> Arrays.asList(entryPlate.getKey().split(",")).contains(assemblyNumber))
+                        .map(Map.Entry::getValue)
+                        .collect(Collectors.toList());
+
+
+                String licensePlate = Optional.ofNullable(matchedStorageBills)
+                        .filter(list1 -> !list1.isEmpty())
+                        .flatMap(list1 -> list1.stream()
+                                .map(StorageBill::getLicensePlate)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("未知车牌");
+
+                String btype = Optional.ofNullable(matchedStorageBills)
+                        .filter(list2 -> !list2.isEmpty())
+                        .flatMap(list2 -> list2.stream()
+                                .map(StorageBill::getBtype)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("未知类型");
+
+                String brandNum = Optional.ofNullable(matchedStorageBills)
+                        .filter(list3 -> !list3.isEmpty())
+                        .flatMap(list3 -> list3.stream()
+                                .map(StorageBill::getBrandNum)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("");
+
+
+                Integer carNum = Optional.ofNullable(matchedStorageBills)
+                        .filter(list4 -> !list4.isEmpty())
+                        .flatMap(list4 -> list4.stream()
+                                .map(StorageBill::getCarNum)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse(1);
+
+                Date createTime = Optional.ofNullable(matchedStorageBills)
+                        .filter(list5 -> !list5.isEmpty())
+                        .flatMap(list5 -> list5.stream()
+                                .map(StorageBill::getCreateTime)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse(new Date());
+
+                StorageCenterHeatNoInvoicingVO.RollChargeDetail rollChargeDetail = new StorageCenterHeatNoInvoicingVO.RollChargeDetail();
+                rollChargeDetail.setSize(size);
+                rollChargeDetail.setSpec(spec);
+                rollChargeDetail.setWeight(totalWeight);
+                rollChargeDetail.setAmount(billets.size());
+                rollChargeDetail.setLicensePlate(licensePlate);
+                rollChargeDetail.setBtype(btype);
+                rollChargeDetail.setHeatNo(heatNo);
+                rollChargeDetail.setCarNum(carNum);
+                rollChargeDetail.setBrandNum(brandNum);
+                rollChargeDetail.setCreateTime(createTime);
+
+                rollChargeDetails.add(rollChargeDetail);
+            }
+
+            // 按 licensePlate 分组并累加 amount 和 weight
+            Map<String, StorageCenterHeatNoInvoicingVO.RollChargeDetail> groupedByLicensePlate = rollChargeDetails.stream()
+                    .collect(Collectors.toMap(
+                            StorageCenterHeatNoInvoicingVO.RollChargeDetail::getLicensePlate,
+                            detail -> {
+                                StorageCenterHeatNoInvoicingVO.RollChargeDetail newDetail = new StorageCenterHeatNoInvoicingVO.RollChargeDetail();
+                                newDetail.setSize(detail.getSize());  // 这里可以选择合适的 size 逻辑
+                                newDetail.setSpec(detail.getSpec());
+                                newDetail.setWeight(detail.getWeight());
+                                newDetail.setAmount(detail.getAmount());
+                                newDetail.setLicensePlate(detail.getLicensePlate());
+                                newDetail.setBtype(detail.getBtype());
+                                newDetail.setHeatNo(detail.getHeatNo());
+                                newDetail.setCarNum(detail.getCarNum());
+                                newDetail.setBrandNum(detail.getBrandNum());
+                                newDetail.setCreateTime(detail.getCreateTime());
+                                return newDetail;
+                            },
+                            (existing, newDetail) -> {
+                                existing.setAmount(existing.getAmount() + newDetail.getAmount());
+                                existing.setWeight(existing.getWeight().add(newDetail.getWeight())); // BigDecimal 累加
+                                return existing;
+                            }
+                    ));
+
+            // 转换为 List 并赋值
+            List<StorageCenterHeatNoInvoicingVO.RollChargeDetail> mergedRollChargeDetails = new ArrayList<>(groupedByLicensePlate.values());
+            mergedRollChargeDetails.sort(Comparator.comparing(StorageCenterHeatNoInvoicingVO.RollChargeDetail::getCarNum));
+
+            rollThreeHeatNo.setRollChargeDetails(mergedRollChargeDetails);
+            rollThreeHeatNo.setSizeDetails(sizeDetailsList);
+            storageCenterHeatNoInvoicingVO.setRollClubThreeDetails(rollThreeHeatNo);
+        }
+
+
+        if (groupedByBelongTable.containsKey("roll_out_shipp")) {
+
+            List<BilletBasicInfo> billetBasicInfos = groupedByBelongTable.get("roll_out_shipp");
+
+            // 计算总重量 & 总条数
+            BigDecimal totalBlankOutput = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getBilletWeight)
+                    .filter(Objects::nonNull)
+                    .map(BigDecimal::valueOf)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            rollOutHeatNo.setTotalAmount(billetBasicInfos.size());
+            rollOutHeatNo.setTotalWeight(totalBlankOutput);
+
+            // 批量查询 StorageBill,避免 for 循环里重复查询
+            Set<String> assemblyNumbers = billetBasicInfos.stream()
+                    .map(BilletBasicInfo::getAssemblyNumber)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toSet());
+
+            // 只查询这些组坯号的 StorageBill
+            Map<String, StorageBill> storageBillMap = new HashMap<>();
+
+            // 遍历所有组坯号,使用 `like` 添加查询条件
+            if (!assemblyNumbers.isEmpty()) {
+                LambdaQueryWrapper<StorageBill> billQueryWrapper = new LambdaQueryWrapper<>();
+                billQueryWrapper.and(wrapper -> {
+                    for (String assemblyNumber : assemblyNumbers) {
+                        wrapper.or().like(StorageBill::getAssemblyNumber, assemblyNumber);
+                    }
+                });
+
+                List<StorageBill> storageBillList = storageBillMapper.selectList(billQueryWrapper);
+
+                storageBillMap = storageBillList.stream()
+                        .collect(Collectors.toMap(StorageBill::getAssemblyNumber, Function.identity(), (a, b) -> a));
+            }
+
+            // 按 getLength 分组
+            Map<Integer, List<BilletBasicInfo>> groupedByLength = billetBasicInfos.stream()
+                    .filter(b -> b.getLength() != null)
+                    .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
+
+            List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = groupedByLength.entrySet().stream()
+                    .map(entry -> {
+                        Integer length = entry.getKey();
+                        List<BilletBasicInfo> billets = entry.getValue();
+
+                        // 计算 weight 总和
+                        BigDecimal totalWeight = billets.stream()
+                                .map(BilletBasicInfo::getBilletWeight)
+                                .filter(Objects::nonNull)
+                                .map(BigDecimal::valueOf)
+                                .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                        StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                        sizeDetail.setSize(length);
+                        sizeDetail.setSizeWeight(totalWeight);
+                        sizeDetail.setSizeAmount(billets.size());
+
+                        return sizeDetail;
+                    })
+                    .collect(Collectors.toList());
+
+            rollOutHeatNo.setSizeDetails(sizeDetailsList);
+
+            // 按 组坯号 (assemblyNumber) 分组
+            Map<String, List<BilletBasicInfo>> groupedByAssemblyNumber = billetBasicInfos.stream()
+                    .filter(b -> b.getAssemblyNumber() != null)
+                    .collect(Collectors.groupingBy(BilletBasicInfo::getAssemblyNumber));
+
+            List<StorageCenterHeatNoInvoicingVO.RollChargeDetail> rollChargeDetails = new ArrayList<>();
+
+            for (Map.Entry<String, List<BilletBasicInfo>> entry : groupedByAssemblyNumber.entrySet()) {
+                String assemblyNumber = entry.getKey();
+                List<BilletBasicInfo> billets = entry.getValue();
+
+                if (billets == null || billets.isEmpty()) {
+                    continue;
+                }
+
+                Integer size = Optional.ofNullable(billets.get(0).getLength()).orElse(0);
+                String spec = Optional.ofNullable(billets.get(0).getSpec()).orElse("Unknown");
+
+                // 计算 weight 总和
+                BigDecimal totalWeight = billets.stream()
+                        .map(BilletBasicInfo::getBilletWeight)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                // 查找所有匹配当前 assemblyNumber 的 StorageBill
+                List<StorageBill> matchedStorageBills = storageBillMap.entrySet().stream()
+                        .filter(entryPlate -> Arrays.asList(entryPlate.getKey().split(",")).contains(assemblyNumber))
+                        .map(Map.Entry::getValue)
+                        .collect(Collectors.toList());
+
+                String licensePlate = Optional.ofNullable(matchedStorageBills)
+                        .filter(list1 -> !list1.isEmpty())
+                        .flatMap(list1 -> list1.stream()
+                                .map(StorageBill::getLicensePlate)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("未知车牌");
+
+                String btype = Optional.ofNullable(matchedStorageBills)
+                        .filter(list2 -> !list2.isEmpty())
+                        .flatMap(list2 -> list2.stream()
+                                .map(StorageBill::getBtype)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("未知类型");
+
+
+                String brandNum = Optional.ofNullable(matchedStorageBills)
+                        .filter(list3 -> !list3.isEmpty())
+                        .flatMap(list3 -> list3.stream()
+                                .map(StorageBill::getBrandNum)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse("");
+
+
+                Integer carNum = Optional.ofNullable(matchedStorageBills)
+                        .filter(list4 -> !list4.isEmpty())
+                        .flatMap(list4 -> list4.stream()
+                                .map(StorageBill::getCarNum)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse(1);
+
+                Date createTime = Optional.ofNullable(matchedStorageBills)
+                        .filter(list5 -> !list5.isEmpty())
+                        .flatMap(list5 -> list5.stream()
+                                .map(StorageBill::getCreateTime)
+                                .filter(Objects::nonNull)
+                                .findFirst())
+                        .orElse(new Date());
+
+                StorageCenterHeatNoInvoicingVO.RollChargeDetail rollChargeDetail = new StorageCenterHeatNoInvoicingVO.RollChargeDetail();
+                rollChargeDetail.setSize(size);
+                rollChargeDetail.setSpec(spec);
+                rollChargeDetail.setWeight(totalWeight);
+                rollChargeDetail.setAmount(billets.size());
+                rollChargeDetail.setLicensePlate(licensePlate);
+                rollChargeDetail.setBtype(btype);
+                rollChargeDetail.setHeatNo(heatNo);
+                rollChargeDetail.setCarNum(carNum);
+                rollChargeDetail.setBrandNum(brandNum);
+                rollChargeDetail.setCreateTime(createTime);
+
+                rollChargeDetails.add(rollChargeDetail);
+            }
+
+            // 按 licensePlate 分组并累加 amount 和 weight
+            Map<String, StorageCenterHeatNoInvoicingVO.RollChargeDetail> groupedByLicensePlate = rollChargeDetails.stream()
+                    .collect(Collectors.toMap(
+                            StorageCenterHeatNoInvoicingVO.RollChargeDetail::getLicensePlate,
+                            detail -> {
+                                StorageCenterHeatNoInvoicingVO.RollChargeDetail newDetail = new StorageCenterHeatNoInvoicingVO.RollChargeDetail();
+                                newDetail.setSize(detail.getSize());  // 这里可以选择合适的 size 逻辑
+                                newDetail.setSpec(detail.getSpec());
+                                newDetail.setWeight(detail.getWeight());
+                                newDetail.setAmount(detail.getAmount());
+                                newDetail.setLicensePlate(detail.getLicensePlate());
+                                newDetail.setBtype(detail.getBtype());
+                                newDetail.setHeatNo(detail.getHeatNo());
+                                newDetail.setCarNum(detail.getCarNum());
+                                newDetail.setBrandNum(detail.getBrandNum());
+                                newDetail.setCreateTime(detail.getCreateTime());
+                                return newDetail;
+                            },
+                            (existing, newDetail) -> {
+                                existing.setAmount(existing.getAmount() + newDetail.getAmount());
+                                existing.setWeight(existing.getWeight().add(newDetail.getWeight())); // BigDecimal 累加
+                                return existing;
+                            }
+                    ));
+
+            // 转换为 List 并赋值
+            List<StorageCenterHeatNoInvoicingVO.RollChargeDetail> mergedRollChargeDetails = new ArrayList<>(groupedByLicensePlate.values());
+            mergedRollChargeDetails.sort(Comparator.comparing(StorageCenterHeatNoInvoicingVO.RollChargeDetail::getCarNum));
+
+            rollOutHeatNo.setRollChargeDetails(mergedRollChargeDetails);
+            rollOutHeatNo.setSizeDetails(sizeDetailsList);
+            storageCenterHeatNoInvoicingVO.setRollOutShippDetails(rollOutHeatNo);
+        }
+
+        return storageCenterHeatNoInvoicingVO;
+    }
+
     public static String getTransportUnitNameByCarNumber(String carNumber) {
         if (StringUtils.isBlank(carNumber)) return "";