ソースを参照

重构储运中心列表查询以及导出

lingpeng.li 1 ヶ月 前
コミット
bab2d03da8

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

@@ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -37,7 +36,6 @@ import org.jeecg.modules.billet.billetHotsendChangeShift.service.IBilletHotsendC
 import org.jeecg.modules.billet.billetHotsendConfig.entity.BilletHotsendTypeConfig;
 import org.jeecg.modules.billet.billetHotsendConfig.service.IBilletHotsendTypeConfigService;
 import org.jeecg.modules.billet.operateLog.service.IOperateLogService;
-import org.jeecg.modules.billet.rollClubOne.entity.RollClubOne;
 import org.jeecg.modules.billet.rollClubOne.entity.RollClubOneDetails;
 import org.jeecg.modules.billet.rollClubOne.service.IRollClubOneDetailsService;
 import org.jeecg.modules.billet.rollClubThree.entity.RollClubThree;
@@ -63,6 +61,7 @@ import org.jeecg.modules.billet.storageBill.service.IStorageBillService;
 import org.jeecg.modules.billet.storageBill.vo.*;
 import org.jeecg.modules.billet.storageCarLog.entity.StorageCarLog;
 import org.jeecg.modules.billet.storageCarLog.service.IStorageCarLogService;
+import org.jeecg.modules.carUnit.service.ICarUnitService;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -78,12 +77,8 @@ import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.function.Function;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 /**
@@ -156,6 +151,9 @@ public class StorageBillController extends JeecgController<StorageBill, IStorage
 
 	@Autowired
 	private IBilletRulerConfigService billetRulerConfigService;
+
+	@Autowired
+	private ICarUnitService carUnitService;
 	/**
 	 * 分页列表查询
 	 *
@@ -2387,10 +2385,10 @@ public class StorageBillController extends JeecgController<StorageBill, IStorage
 
 	@ApiOperation(value = "储运中心根据炉号展示开票信息", notes = "储运中心根据炉号展示开票信息")
 	@GetMapping(value = "/storageCenterInvoicingInfo")
-	public Result<Page<StorageCenterInvoicingVO>> storageCenterInvoicingInfo(StorageCenterQueryDTO queryDTO) {
+	public Result<List<StorageCenterInvoicingVO>> storageCenterInvoicingInfo(StorageCenterQueryDTO queryDTO) {
 
-		Page<StorageCenterInvoicingVO> storageCenterInvoicingVOPage = storageBillService.storageCenterInvoicingInfo(queryDTO);
-		return Result.OK(storageCenterInvoicingVOPage);
+		List<StorageCenterInvoicingVO> invoicingVOList = carUnitService.storageCenterInvoicingList(queryDTO);
+		return Result.OK(invoicingVOList);
 	}
 
 	@ApiOperation(value = "根据炉号查询储运中心开票信息", notes = "根据炉号查询储运中心开票信息")

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

@@ -159,12 +159,12 @@ public class StorageCenterHeatNoInvoicingVO {
         @ApiModelProperty(value = "重量")
         private BigDecimal weight;
 
-        @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+        @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
         @DateTimeFormat(pattern = "yyyy-MM-dd")
         @ApiModelProperty(value = "创建日期")
         private Date createTime;
 
-        @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+        @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
         @DateTimeFormat(pattern = "yyyy-MM-dd")
         @ApiModelProperty(value = "修改日期")
         private Date updateTime;

+ 1 - 1
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/carUnit/controller/CarUnitController.java

@@ -178,7 +178,7 @@ public class CarUnitController extends JeecgController<CarUnit, ICarUnitService>
 	 @ApiOperation(value = "导出储运中心车次信息", notes = "导出储运中心车次信息")
 	 @GetMapping("/exportStorageCenterInfo")
 	 public void exportStorageCenterInfo(HttpServletResponse response, StorageCenterQueryDTO queryDTO) throws IOException {
-		 List<StorageCenterInvoicingVO> invoicingVOList = storageBillService.storageCenterInvoicingInfoList(queryDTO);
+		 List<StorageCenterInvoicingVO> invoicingVOList = carUnitService.storageCenterInvoicingList(queryDTO);
 
 		 // 数据处理
 		 List<StorageCenterExportRow> exportList = carUnitService.buildExportData(invoicingVOList);

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

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

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

@@ -3,12 +3,16 @@ package org.jeecg.modules.carUnit.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.jeecg.common.util.DateUtils;
 import org.jeecg.common.util.SpringContextUtils;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletBasicInfo;
 import org.jeecg.modules.actualControl.billetActual.billetActual.service.IBilletBasicInfoService;
+import org.jeecg.modules.billet.billetHotsend.entity.BilletHotsend;
+import org.jeecg.modules.billet.billetHotsend.mapper.BilletHotsendBaseMapper;
+import org.jeecg.modules.billet.rollClubOne.entity.RollClubOneDetails;
 import org.jeecg.modules.billet.rollClubOne.service.IRollClubOneDetailsService;
 import org.jeecg.modules.billet.rollClubThree.entity.RollClubThreeDetails;
 import org.jeecg.modules.billet.rollClubThree.service.IRollClubThreeDetailsService;
@@ -17,7 +21,6 @@ import org.jeecg.modules.billet.rollClubTwo.service.IRollClubTwoDetailsService;
 import org.jeecg.modules.billet.rollHeight.service.IRollHeightDetailsService;
 import org.jeecg.modules.billet.rollOutShipp.entity.RollOutShippDetails;
 import org.jeecg.modules.billet.rollOutShipp.service.IRollOutShippDetailsService;
-import org.jeecg.modules.billet.shiftConfiguration.entity.ShiftConfiguration;
 import org.jeecg.modules.billet.shiftConfiguration.mapper.ShiftConfigurationMapper;
 import org.jeecg.modules.billet.storageBill.dto.StorageCenterQueryDTO;
 import org.jeecg.modules.billet.storageBill.entity.StorageBill;
@@ -41,6 +44,8 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -92,6 +97,9 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
     @Autowired
     public RedisTemplate redisTemplate;
 
+    @Autowired
+    private BilletHotsendBaseMapper billetHotsendBaseMapper;
+
 
     @Override
     public List<StorageCenterExportRow> buildExportData(List<StorageCenterInvoicingVO> records) {
@@ -484,7 +492,6 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
         }
 
 
-
         if (groupedByBelongTableAndLength.containsKey("roll_club_three")) {
             Map<Integer, List<BilletBasicInfo>> lengthMap = groupedByBelongTableAndLength.get("roll_club_three");
 
@@ -736,7 +743,7 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
 
 
     @Override
-    public StorageCenterHeatNoInvoicingVO storageCenterInvoicingByHeatNo(String heatNo,StorageCenterQueryDTO queryDTO) {
+    public StorageCenterHeatNoInvoicingVO storageCenterInvoicingByHeatNo(String heatNo, StorageCenterQueryDTO queryDTO) {
         StorageCenterHeatNoInvoicingVO storageCenterHeatNoInvoicingVO = new StorageCenterHeatNoInvoicingVO();
 
         StorageCenterHeatNoInvoicingVO.RollOneHeatNo rollOneHeatNo = new StorageCenterHeatNoInvoicingVO.RollOneHeatNo();
@@ -1506,6 +1513,751 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
         return storageCenterHeatNoInvoicingVO;
     }
 
+    @Override
+    public List<StorageCenterInvoicingVO> storageCenterInvoicingList(StorageCenterQueryDTO queryDTO) {
+
+        LambdaQueryWrapper<RollClubOneDetails> oneQueryWrapper = new LambdaQueryWrapper<>();
+        if (StringUtils.isNotBlank(queryDTO.getCcmNo())) {
+            oneQueryWrapper.eq(RollClubOneDetails::getCcmNo, queryDTO.getCcmNo());
+        }
+        if (StringUtils.isNotBlank(queryDTO.getHeatsCode())) {
+            oneQueryWrapper.eq(RollClubOneDetails::getHeatNo, queryDTO.getHeatsCode());
+        }
+        if (StringUtils.isNotBlank(queryDTO.getShift())) {
+            oneQueryWrapper.eq(RollClubOneDetails::getShift, queryDTO.getShift());
+        }
+        if (StringUtils.isNotBlank(queryDTO.getShiftGroup())) {
+            oneQueryWrapper.eq(RollClubOneDetails::getShiftGroup, queryDTO.getShiftGroup());
+        }
+        // 获取当天零点和当天23:59:59
+        LocalDate today = LocalDate.now();
+        LocalDateTime startOfDay = today.atStartOfDay();
+        LocalDateTime endOfDay = today.atTime(LocalTime.MAX);  // 23:59:59.999999999
+
+        // 转为 Date(注意时区,这里使用系统默认时区)
+        ZoneId zoneId = ZoneId.systemDefault();
+        Date defaultBeginDate = Date.from(startOfDay.atZone(zoneId).toInstant());
+        Date defaultEndDate = Date.from(endOfDay.atZone(zoneId).toInstant());
+        Date beginDate = queryDTO.getStorageTimeBegin();
+        Date endDate = queryDTO.getStorageTimeEnd();
+
+        if (beginDate == null) {
+            beginDate = defaultBeginDate;
+        }
+        if (endDate == null) {
+            endDate = defaultEndDate;
+        }
+
+        if (beginDate != null) {
+            oneQueryWrapper.ge(RollClubOneDetails::getCreateTime, beginDate);
+        }
+        if (endDate != null) {
+            oneQueryWrapper.le(RollClubOneDetails::getCreateTime, endDate);
+        }
+
+        oneQueryWrapper.orderByDesc(RollClubOneDetails::getCreateTime);
+
+        List<RollClubOneDetails> oneList = rollClubOneDetailsService.list(oneQueryWrapper);
+
+
+        LambdaQueryWrapper<StorageBill> billQueryWrapper = new LambdaQueryWrapper<>();
+        if (StringUtils.isNotBlank(queryDTO.getCcmNo())) {
+            billQueryWrapper.eq(StorageBill::getCcmNo, queryDTO.getCcmNo());
+        }
+        if (StringUtils.isNotBlank(queryDTO.getHeatsCode())) {
+            billQueryWrapper.eq(StorageBill::getHeatNo, queryDTO.getHeatsCode());
+        }
+        if (StringUtils.isNotBlank(queryDTO.getShift())) {
+            billQueryWrapper.eq(StorageBill::getShift, queryDTO.getShift());
+        }
+        if (StringUtils.isNotBlank(queryDTO.getShiftGroup())) {
+            billQueryWrapper.eq(StorageBill::getShiftGroup, queryDTO.getShiftGroup());
+        }
+        if (beginDate != null) {
+            billQueryWrapper.ge(StorageBill::getArrivalTime, beginDate);
+        }
+        if (endDate != null) {
+            billQueryWrapper.le(StorageBill::getArrivalTime, endDate);
+        }
+        billQueryWrapper.orderByDesc(StorageBill::getArrivalTime);
+
+        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);
+
+
+        // 1. 按炉号聚合棒一和棒二数据到 StorageCenterHeatNoInvoicingVO
+        Map<String, StorageCenterHeatNoInvoicingVO> heatNoVOMap = new HashMap<>();
+        for (String heatNo : rollOneMap.keySet()) {
+            StorageCenterHeatNoInvoicingVO vo = heatNoVOMap.computeIfAbsent(heatNo, k -> new StorageCenterHeatNoInvoicingVO());
+            StorageCenterHeatNoInvoicingVO.RollOneHeatNo rollOne = rollOneMap.get(heatNo);
+            vo.setRollClubOneDetails(rollOne);
+
+        }
+        for (String heatNo : rollTwoMap.keySet()) {
+            StorageCenterHeatNoInvoicingVO vo = heatNoVOMap.computeIfAbsent(heatNo, k -> new StorageCenterHeatNoInvoicingVO());
+            StorageCenterHeatNoInvoicingVO.RollTwoHeatNo rollTwo = rollTwoMap.get(heatNo);
+            vo.setRollClubTwoDetails(rollTwo);
+
+        }
+        for (String heatNo : rollThreeMap.keySet()) {
+            StorageCenterHeatNoInvoicingVO vo = heatNoVOMap.computeIfAbsent(heatNo, k -> new StorageCenterHeatNoInvoicingVO());
+            StorageCenterHeatNoInvoicingVO.RollThreeHeatNo rollThree = rollThreeMap.get(heatNo);
+            vo.setRollClubThreeDetails(rollThree);
+
+        }
+        for (String heatNo : rollOutMap.keySet()) {
+            StorageCenterHeatNoInvoicingVO vo = heatNoVOMap.computeIfAbsent(heatNo, k -> new StorageCenterHeatNoInvoicingVO());
+            StorageCenterHeatNoInvoicingVO.RollOutHeatNo rollOut = rollOutMap.get(heatNo);
+            vo.setRollOutShippDetails(rollOut);
+
+        }
+
+        // 2. 遍历所有炉号,构建最终返回列表
+        List<StorageCenterInvoicingVO> resultList = new ArrayList<>();
+        Set<String> allHeatNos = new HashSet<>();
+        allHeatNos.addAll(rollOneMap.keySet());
+        allHeatNos.addAll(rollTwoMap.keySet());
+        allHeatNos.addAll(rollThreeMap.keySet());
+        allHeatNos.addAll(rollOutMap.keySet());
+
+        Map<String, StorageCenterInvoicingVO.HeatNoDetail> heatNoDetailMap = new HashMap<>();
+
+
+        if (CollectionUtils.isNotEmpty(allHeatNos)) {
+            LambdaQueryWrapper<BilletHotsend> hotsendWrapper = new LambdaQueryWrapper<>();
+            hotsendWrapper.in(BilletHotsend::getHeatNo, allHeatNos); // 只查用到的炉号
+            List<BilletHotsend> hotsendList = billetHotsendBaseMapper.selectList(hotsendWrapper);
+
+            if (CollectionUtils.isNotEmpty(hotsendList)) {
+                Map<String, List<BilletHotsend>> hotsendGroupMap = hotsendList.stream()
+                        .collect(Collectors.groupingBy(BilletHotsend::getHeatNo));
+
+                for (Map.Entry<String, List<BilletHotsend>> entry : hotsendGroupMap.entrySet()) {
+                    String heatNo = entry.getKey();
+                    List<BilletHotsend> hotsends = entry.getValue();
+
+                    if (CollectionUtils.isEmpty(hotsends)) {
+                        continue;
+                    }
+
+                    // 先定义 rollOne, rollTwo, rollThree, rollOut,初始值为 null
+                    StorageCenterHeatNoInvoicingVO.RollOneHeatNo rollOne = null;
+                    StorageCenterHeatNoInvoicingVO.RollTwoHeatNo rollTwo = null;
+                    StorageCenterHeatNoInvoicingVO.RollThreeHeatNo rollThree = null;
+                    StorageCenterHeatNoInvoicingVO.RollOutHeatNo rollOut = null;
+
+                    StorageCenterHeatNoInvoicingVO vo = heatNoVOMap.get(heatNo);
+                    if (vo != null) {
+                        rollOne = vo.getRollClubOneDetails();
+                        rollTwo = vo.getRollClubTwoDetails();
+                        rollThree = vo.getRollClubThreeDetails();
+                        rollOut = vo.getRollOutShippDetails();
+                    }
+
+                    // 初始化累计值
+                    int totalAmount = 0;
+                    BigDecimal totalWeight = BigDecimal.ZERO;
+
+                    if (rollOne != null && rollOne.getTotalAmount() != null) {
+                        totalAmount += rollOne.getTotalAmount();
+                    }
+                    if (rollOne != null && rollOne.getTotalWeight() != null) {
+                        totalWeight = totalWeight.add(rollOne.getTotalWeight());
+                    }
+                    if (rollTwo != null && rollTwo.getTotalAmount() != null) {
+                        totalAmount += rollTwo.getTotalAmount();
+                    }
+                    if (rollTwo != null && rollTwo.getTotalWeight() != null) {
+                        totalWeight = totalWeight.add(rollTwo.getTotalWeight());
+                    }
+                    if (rollThree != null && rollThree.getTotalAmount() != null) {
+                        totalAmount += rollThree.getTotalAmount();
+                    }
+                    if (rollThree != null && rollThree.getTotalWeight() != null) {
+                        totalWeight = totalWeight.add(rollThree.getTotalWeight());
+                    }
+                    if (rollOut != null && rollOut.getTotalAmount() != null) {
+                        totalAmount += rollOut.getTotalAmount();
+                    }
+                    if (rollOut != null && rollOut.getTotalWeight() != null) {
+                        totalWeight = totalWeight.add(rollOut.getTotalWeight());
+                    }
+
+                    StorageCenterInvoicingVO.HeatNoDetail detail = new StorageCenterInvoicingVO.HeatNoDetail();
+                    detail.setHeatNo(heatNo);
+
+                    // 按 createTime 降序,选最新记录
+                    hotsends.sort(Comparator.comparing(BilletHotsend::getCreateTime, Comparator.nullsLast(Date::compareTo)).reversed());
+                    BilletHotsend latest = hotsends.get(0);
+
+                    // 这里用优先级取 createTime
+                    Date finalCreateTime = null;
+                    if (rollOne != null && rollOne.getRollSendDetails() != null && rollOne.getRollSendDetails().get(0).getCreateTime() != null) {
+                        finalCreateTime = rollOne.getRollSendDetails().get(0).getCreateTime();
+                    } else if (rollTwo != null && rollTwo.getRollChargeDetails() != null && rollTwo.getRollChargeDetails().get(0).getCreateTime() != null) {
+                        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 (rollOut != null && rollOut.getRollChargeDetails() != null && rollOut.getRollChargeDetails().get(0).getCreateTime() != null) {
+                        finalCreateTime = rollOut.getRollChargeDetails().get(0).getCreateTime();
+                    } else {
+                        finalCreateTime = latest.getCreateTime();
+                    }
+                    detail.setCreateTime(finalCreateTime);
+
+                    detail.setHeatNoAmount(totalAmount);
+                    detail.setHeatNoWeight(totalWeight);
+
+                    // ccmNo 可能为空或非数字,需要校验
+                    try {
+                        if (StringUtils.isNotBlank(latest.getCcmNo())) {
+                            detail.setCcmNo(Integer.valueOf(latest.getCcmNo()));
+                        }
+                    } catch (NumberFormatException e) {
+                        log.warn("炉号 {} 的 ccmNo 非法值:{}", heatNo, latest.getCcmNo(), e);
+                    }
+
+                    detail.setShift(latest.getShift());
+                    detail.setShiftGroup(latest.getShiftGroup());
+
+                    heatNoDetailMap.put(heatNo, detail);
+                }
+            } else {
+                log.warn("未查询到 billet_hotsend 记录,heatNo 列表为:{}", allHeatNos);
+            }
+        } else {
+            log.warn("heatNo 集合为空,跳过 billet_hotsend 查询");
+        }
+
+        if (CollectionUtils.isNotEmpty(allHeatNos)) {
+            for (String heatNo : allHeatNos) {
+                StorageCenterInvoicingVO invoicingVO = new StorageCenterInvoicingVO();
+
+                // 设置基础详情
+                StorageCenterInvoicingVO.HeatNoDetail detail = heatNoDetailMap.get(heatNo);
+                invoicingVO.setHeatNoDetails(detail == null ? Collections.emptyList() : Collections.singletonList(detail));
+
+                // 设置聚合的棒一棒二数据
+                StorageCenterHeatNoInvoicingVO heatNoInvoicing = heatNoVOMap.get(heatNo);
+                invoicingVO.setStorageCenterHeatNoInvoicing(heatNoInvoicing);
+
+                resultList.add(invoicingVO);
+            }
+        } else {
+            log.warn("allHeatNos 为空,未生成任何开票信息结果");
+        }
+
+        return resultList;
+
+    }
+
+    public Map<String, StorageCenterHeatNoInvoicingVO.RollOneHeatNo> buildRollOneHeatNoMap(List<RollClubOneDetails> oneList) {
+        // 1. 按 heatNo 字段进行分组
+        Map<String, List<RollClubOneDetails>> groupedByHeatNo = oneList.stream()
+                .filter(item -> item.getHeatNo() != null) // 避免空指针
+                .collect(Collectors.groupingBy(RollClubOneDetails::getHeatNo));
+
+        Map<String, StorageCenterHeatNoInvoicingVO.RollOneHeatNo> resultMap = new HashMap<>();
+
+        // 2. 遍历每个分组
+        for (Map.Entry<String, List<RollClubOneDetails>> entry : groupedByHeatNo.entrySet()) {
+            String heatNo = entry.getKey();
+            List<RollClubOneDetails> heatNoList = entry.getValue();
+
+            StorageCenterHeatNoInvoicingVO.RollOneHeatNo rollOneHeatNo = new StorageCenterHeatNoInvoicingVO.RollOneHeatNo();
+
+
+            // 总重量
+            BigDecimal totalBlankOutput = heatNoList.stream()
+                    .map(RollClubOneDetails::getBlankOutput)
+                    .filter(Objects::nonNull)
+                    .map(BigDecimal::valueOf)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            rollOneHeatNo.setTotalAmount(heatNoList.size());
+            rollOneHeatNo.setTotalWeight(totalBlankOutput);
+
+            Map<String, List<RollClubOneDetails>> groupedBySize = heatNoList.stream()
+                    .filter(item -> item.getSize() != null)
+                    .collect(Collectors.groupingBy(RollClubOneDetails::getSize));
+
+            List<StorageCenterHeatNoInvoicingVO.SizeDetail> sizeDetailsList = new ArrayList<>();
+            List<StorageCenterHeatNoInvoicingVO.RollSendDetail> rollSendDetailList = new ArrayList<>();
+
+            for (Map.Entry<String, List<RollClubOneDetails>> sizeEntry : groupedBySize.entrySet()) {
+                String size = sizeEntry.getKey();
+                List<RollClubOneDetails> sameSizeList = sizeEntry.getValue();
+
+
+                Date latestCreateTime = sameSizeList.stream()
+                        .filter(Objects::nonNull)
+                        .map(RollClubOneDetails::getCreateTime)
+                        .filter(Objects::nonNull)
+                        .max(Date::compareTo)
+                        .orElse(null);
+
+
+                BigDecimal sizeWeight = sameSizeList.stream()
+                        .map(RollClubOneDetails::getBlankOutput)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                String spec = Optional.ofNullable(sameSizeList.get(0).getSpec()).orElse("Unknown");
+
+                StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                sizeDetail.setSize(Integer.valueOf(size));
+                sizeDetail.setSizeAmount(sameSizeList.size());
+                sizeDetail.setSizeWeight(sizeWeight);
+                sizeDetailsList.add(sizeDetail);
+
+                StorageCenterHeatNoInvoicingVO.RollSendDetail rollSendDetail = new StorageCenterHeatNoInvoicingVO.RollSendDetail();
+                rollSendDetail.setSize(Integer.valueOf(size));
+                rollSendDetail.setAmount(sameSizeList.size());
+                rollSendDetail.setWeight(sizeWeight);
+                rollSendDetail.setSpec(spec);
+                rollSendDetail.setCreateTime(latestCreateTime);
+                rollSendDetailList.add(rollSendDetail);
+            }
+
+            rollOneHeatNo.setSizeDetails(sizeDetailsList);
+            rollOneHeatNo.setRollSendDetails(rollSendDetailList);
+
+            resultMap.put(heatNo, rollOneHeatNo);
+        }
+
+        return resultMap;
+    }
+
+
+    private Map<String, StorageCenterHeatNoInvoicingVO.RollTwoHeatNo> buildRollTwoHeatNoGroupByHeatNo(List<StorageBill> billList) {
+        Map<String, StorageCenterHeatNoInvoicingVO.RollTwoHeatNo> 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<RollClubTwoDetails> detailList = rollClubTwoDetailsService.list(
+                new LambdaQueryWrapper<RollClubTwoDetails>()
+                        .in(RollClubTwoDetails::getStorageBillId, billIdSet)
+        );
+
+        // 按 heatNo -> storageBillId -> List 分组
+        Map<String, Map<String, List<RollClubTwoDetails>>> grouped = detailList.stream()
+                .filter(d -> d.getHeatNo() != null && d.getStorageBillId() != null)
+                .collect(Collectors.groupingBy(
+                        RollClubTwoDetails::getHeatNo,
+                        Collectors.groupingBy(RollClubTwoDetails::getStorageBillId)
+                ));
+
+        for (Map.Entry<String, Map<String, List<RollClubTwoDetails>>> heatNoEntry : grouped.entrySet()) {
+            String heatNo = heatNoEntry.getKey();
+            Map<String, List<RollClubTwoDetails>> billGroupMap = heatNoEntry.getValue();
+
+            StorageCenterHeatNoInvoicingVO.RollTwoHeatNo rollTwoHeatNo = resultMap.computeIfAbsent(heatNo, k -> {
+                StorageCenterHeatNoInvoicingVO.RollTwoHeatNo r = new StorageCenterHeatNoInvoicingVO.RollTwoHeatNo();
+                r.setSizeDetails(new ArrayList<>());
+                r.setRollChargeDetails(new ArrayList<>());
+                return r;
+            });
+
+            for (Map.Entry<String, List<RollClubTwoDetails>> billEntry : billGroupMap.entrySet()) {
+                String billId = billEntry.getKey();
+                List<RollClubTwoDetails> heatNoList = billEntry.getValue();
+
+                StorageBill bill = billMap.get(billId);
+                if (bill == null) continue;
+
+                // 计算重量(仅根据明细的 blankOutput)
+                BigDecimal heatWeight = heatNoList.stream()
+                        .map(RollClubTwoDetails::getBlankOutput)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                // 累加总支数与重量
+                rollTwoHeatNo.setTotalAmount(
+                        Optional.ofNullable(rollTwoHeatNo.getTotalAmount()).orElse(0) + heatNoList.size()
+                );
+                rollTwoHeatNo.setTotalWeight(
+                        Optional.ofNullable(rollTwoHeatNo.getTotalWeight()).orElse(BigDecimal.ZERO).add(heatWeight)
+                );
+
+                // 获取 billetNo 列表(不去重)
+                List<String> billetNoList = heatNoList.stream()
+                        .map(RollClubTwoDetails::getBilletNo)
+                        .filter(StringUtils::isNotBlank)
+                        .flatMap(s -> Arrays.stream(s.split(",")))
+                        .map(String::trim)
+                        .filter(StringUtils::isNotBlank)
+                        .collect(Collectors.toList());
+
+                if (billetNoList.isEmpty()) continue;
+
+                // 统计 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);
+
+                    // 添加尺寸明细
+                    StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                    sizeDetail.setSize(size);
+                    sizeDetail.setSizeWeight(totalWeight);
+                    sizeDetail.setSizeAmount(sizeList.size());
+                    rollTwoHeatNo.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.getCreateTime()).orElse(new Date()));
+                    rollTwoHeatNo.getRollChargeDetails().add(chargeDetail);
+                }
+            }
+        }
+
+        return resultMap;
+    }
+
+
+    private Map<String, StorageCenterHeatNoInvoicingVO.RollThreeHeatNo> buildRollThreeHeatNoGroupByHeatNo(List<StorageBill> billList) {
+        Map<String, StorageCenterHeatNoInvoicingVO.RollThreeHeatNo> 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<RollClubThreeDetails> detailList = rollClubThreeDetailsService.list(
+                new LambdaQueryWrapper<RollClubThreeDetails>()
+                        .in(RollClubThreeDetails::getStorageBillId, billIdSet)
+        );
+
+        // 按 heatNo -> storageBillId -> List 分组
+        Map<String, Map<String, List<RollClubThreeDetails>>> grouped = detailList.stream()
+                .filter(d -> d.getHeatNo() != null && d.getStorageBillId() != null)
+                .collect(Collectors.groupingBy(
+                        RollClubThreeDetails::getHeatNo,
+                        Collectors.groupingBy(RollClubThreeDetails::getStorageBillId)
+                ));
+
+        for (Map.Entry<String, Map<String, List<RollClubThreeDetails>>> heatNoEntry : grouped.entrySet()) {
+            String heatNo = heatNoEntry.getKey();
+            Map<String, List<RollClubThreeDetails>> billGroupMap = heatNoEntry.getValue();
+
+            StorageCenterHeatNoInvoicingVO.RollThreeHeatNo rollThreeHeatNo = resultMap.computeIfAbsent(heatNo, k -> {
+                StorageCenterHeatNoInvoicingVO.RollThreeHeatNo r = new StorageCenterHeatNoInvoicingVO.RollThreeHeatNo();
+                r.setSizeDetails(new ArrayList<>());
+                r.setRollChargeDetails(new ArrayList<>());
+                return r;
+            });
+
+            for (Map.Entry<String, List<RollClubThreeDetails>> billEntry : billGroupMap.entrySet()) {
+                String billId = billEntry.getKey();
+                List<RollClubThreeDetails> heatNoList = billEntry.getValue();
+
+                StorageBill bill = billMap.get(billId);
+                if (bill == null) continue;
+
+                // 计算重量(仅根据明细的 blankOutput)
+                BigDecimal heatWeight = heatNoList.stream()
+                        .map(RollClubThreeDetails::getBlankOutput)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                // 累加总支数与重量
+                rollThreeHeatNo.setTotalAmount(
+                        Optional.ofNullable(rollThreeHeatNo.getTotalAmount()).orElse(0) + heatNoList.size()
+                );
+                rollThreeHeatNo.setTotalWeight(
+                        Optional.ofNullable(rollThreeHeatNo.getTotalWeight()).orElse(BigDecimal.ZERO).add(heatWeight)
+                );
+
+                // 获取 billetNo 列表(不去重)
+                List<String> billetNoList = heatNoList.stream()
+                        .map(RollClubThreeDetails::getBilletNo)
+                        .filter(StringUtils::isNotBlank)
+                        .flatMap(s -> Arrays.stream(s.split(",")))
+                        .map(String::trim)
+                        .filter(StringUtils::isNotBlank)
+                        .collect(Collectors.toList());
+
+                if (billetNoList.isEmpty()) continue;
+
+                // 统计 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);
+
+                    // 添加尺寸明细
+                    StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                    sizeDetail.setSize(size);
+                    sizeDetail.setSizeWeight(totalWeight);
+                    sizeDetail.setSizeAmount(sizeList.size());
+                    rollThreeHeatNo.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.getCreateTime()).orElse(new Date()));
+                    rollThreeHeatNo.getRollChargeDetails().add(chargeDetail);
+                }
+            }
+        }
+
+        return resultMap;
+    }
+
+
+    private Map<String, StorageCenterHeatNoInvoicingVO.RollOutHeatNo> buildRollOutHeatNoGroupByHeatNo(List<StorageBill> billList) {
+        Map<String, StorageCenterHeatNoInvoicingVO.RollOutHeatNo> 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<RollOutShippDetails> detailList = rollOutShippDetailsService.list(
+                new LambdaQueryWrapper<RollOutShippDetails>()
+                        .in(RollOutShippDetails::getStorageBillId, billIdSet)
+        );
+
+        // 按 heatNo -> storageBillId -> List 分组
+        Map<String, Map<String, List<RollOutShippDetails>>> grouped = detailList.stream()
+                .filter(d -> d.getHeatNo() != null && d.getStorageBillId() != null)
+                .collect(Collectors.groupingBy(
+                        RollOutShippDetails::getHeatNo,
+                        Collectors.groupingBy(RollOutShippDetails::getStorageBillId)
+                ));
+
+        for (Map.Entry<String, Map<String, List<RollOutShippDetails>>> heatNoEntry : grouped.entrySet()) {
+            String heatNo = heatNoEntry.getKey();
+            Map<String, List<RollOutShippDetails>> billGroupMap = heatNoEntry.getValue();
+
+            StorageCenterHeatNoInvoicingVO.RollOutHeatNo rollOutHeatNo = resultMap.computeIfAbsent(heatNo, k -> {
+                StorageCenterHeatNoInvoicingVO.RollOutHeatNo r = new StorageCenterHeatNoInvoicingVO.RollOutHeatNo();
+                r.setSizeDetails(new ArrayList<>());
+                r.setRollChargeDetails(new ArrayList<>());
+                return r;
+            });
+
+            for (Map.Entry<String, List<RollOutShippDetails>> billEntry : billGroupMap.entrySet()) {
+                String billId = billEntry.getKey();
+                List<RollOutShippDetails> heatNoList = billEntry.getValue();
+
+                StorageBill bill = billMap.get(billId);
+                if (bill == null) continue;
+
+                // 计算重量(仅根据明细的 blankOutput)
+                BigDecimal heatWeight = heatNoList.stream()
+                        .map(RollOutShippDetails::getBlankOutput)
+                        .filter(Objects::nonNull)
+                        .map(BigDecimal::valueOf)
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                // 累加总支数与重量
+                rollOutHeatNo.setTotalAmount(
+                        Optional.ofNullable(rollOutHeatNo.getTotalAmount()).orElse(0) + heatNoList.size()
+                );
+                rollOutHeatNo.setTotalWeight(
+                        Optional.ofNullable(rollOutHeatNo.getTotalWeight()).orElse(BigDecimal.ZERO).add(heatWeight)
+                );
+
+                // 获取 billetNo 列表(不去重)
+                List<String> billetNoList = heatNoList.stream()
+                        .map(RollOutShippDetails::getBilletNo)
+                        .filter(StringUtils::isNotBlank)
+                        .flatMap(s -> Arrays.stream(s.split(",")))
+                        .map(String::trim)
+                        .filter(StringUtils::isNotBlank)
+                        .collect(Collectors.toList());
+
+                if (billetNoList.isEmpty()) continue;
+
+                // 统计 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);
+
+                    // 添加尺寸明细
+                    StorageCenterHeatNoInvoicingVO.SizeDetail sizeDetail = new StorageCenterHeatNoInvoicingVO.SizeDetail();
+                    sizeDetail.setSize(size);
+                    sizeDetail.setSizeWeight(totalWeight);
+                    sizeDetail.setSizeAmount(sizeList.size());
+                    rollOutHeatNo.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.getCreateTime()).orElse(new Date()));
+                    rollOutHeatNo.getRollChargeDetails().add(chargeDetail);
+                }
+            }
+        }
+
+        return resultMap;
+    }
+
+
     public static String getTransportUnitNameByCarNumber(String carNumber) {
         if (StringUtils.isBlank(carNumber)) return "";
 
@@ -1601,9 +2353,9 @@ public class CarUnitServiceImpl extends ServiceImpl<CarUnitMapper, CarUnit> impl
             row.setSize("170*170*" + result.toPlainString());
         }
         row.setSpec(detail.getSpec());
-        if (detail != null && detail.getUpdateTime() != null) {
+        if (detail != null && detail.getCreateTime() != null) {
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-            row.setFactoryDate(sdf.format(detail.getUpdateTime()));
+            row.setFactoryDate(sdf.format(detail.getCreateTime()));
         } else {
             row.setFactoryDate("");
         }