自动化立体仓库 - WMS系统
lty
2025-06-24 dcae969ee04f67b6dc46f3ca061116f44558307a
src/main/java/com/zy/asrs/importexcle/ImportOrderListener.java
@@ -4,6 +4,7 @@
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.fastjson.JSON;
import com.core.common.Cools;
import com.core.common.DateUtils;
import com.core.common.SnowflakeIdWorker;
import com.zy.asrs.entity.DocType;
@@ -15,9 +16,7 @@
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * @author pang.jiabao
@@ -36,6 +35,8 @@
    private String orderNo;
    private long orderId;
    private long docTypeId;
    List<ImportOrderDto> list = new ArrayList<>();
    /**
@@ -58,25 +59,44 @@
        this.userId = userId;
    }
    /**
     * 这个每一条数据解析都会来调用
     */
    private Set<String> uniquePackNos = new HashSet<>(); // 用于去重包装组号
    @SneakyThrows
    @Override
    public void invoke(ImportOrderDto data, AnalysisContext context) {
        log.info("解析到第 {} 条数据:{}", ++count, JSON.toJSONString(data));
        // 获取包装组号(column1)
        String packNo = data.getColumn1();
        if (Cools.isEmpty(packNo)) {
            log.warn("包装组号为空,跳过该行!");
            return;
        }
        // 如果已经处理过该包装组号,则跳过
        if (uniquePackNos.contains(packNo)) {
            log.info("重复的包装组号:{},跳过", packNo);
            return;
        }
        // 首次出现,记录并处理
        uniquePackNos.add(packNo);
        list.add(data);
        if (context.getCurrentRowNum() == 3) {
            String time = DateUtils.convert(new Date(),DateUtils.yyyyMMddHHmmss_F);
            String time = DateUtils.convert(new Date(), DateUtils.yyyyMMddHHmmss_F);
            Order order2 = orderService.selectByNo(list.get(0).getColumn2());
            if(order2 != null) {
            if (order2 != null) {
                throw new ExcelAnalysisException("单据已存在!");
            }
            DocType docType = docTypeService.selectOrAdd(list.get(1).getColumn2(), Boolean.FALSE);
            if (docType == null) {
                throw new ExcelAnalysisException("单据类型错误:" + list.get(1).getColumn2());
            }
            orderNo = list.get(0).getColumn2();
            docTypeId = docType.getDocId();
            Order order = new Order();
            order.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
            order.setOrderNo(orderNo);
@@ -86,6 +106,7 @@
            order.setStatus(1);
            order.setCreateBy(userId);
            order.setCreateTime(new Date());
            orderService.insert(order);
            Order order1 = orderService.selectByNo(orderNo);
            orderId = order1.getId();
@@ -93,13 +114,12 @@
            return;
        }
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }
    /**
     * 所有数据解析完成了 都会来调用
@@ -113,16 +133,69 @@
        log.info("所有数据解析完成!");
    }
//    /**
//     * 加上存储数据库
//     */
//    private void saveData() {
//        log.info("{}条数据,开始存储数据库!", list.size());
//        log.info("单据号:{},数据:{},",orderNo, JSON.toJSONString(list));
//        List<OrderDetl> orderDetlList = new ArrayList<>();
//        list.forEach(importOrderDto -> {
//            OrderDetl orderDetl = new OrderDetl();
//            if (docTypeId == 24) {
//                orderDetl.setSpecs(String.format("%07d",Integer.parseInt(importOrderDto.getColumn1()))); // 源库位
//                if (importOrderDto.getColumn2() != null) {
//                    orderDetl.setModel(String.format("%07d",Integer.parseInt(importOrderDto.getColumn2()))); // 目标库位
//                }
//                if (importOrderDto.getColumn3() != null) {
//                    orderDetl.setBeBatch(Integer.parseInt(importOrderDto.getColumn3())); //巷道
//                }
//            } else {
//                orderDetl.setBrand(importOrderDto.getColumn1());
//            }
//            orderDetl.setBatch("");
//            orderDetl.setOrderId(orderId);
//            orderDetl.setOrderNo(orderNo);
//            orderDetl.setCreateBy(9527L);
//            orderDetl.setCreateTime(new Date());
//            orderDetl.setUpdateBy(9527L);
//            orderDetl.setUpdateTime(new Date());
//            orderDetl.setStatus(1);
//            orderDetl.setQty(0.0D);
//            orderDetl.setAnfme(1.0);
//            orderDetlList.add(orderDetl);
//        });
//        orderDetlMapper.batchDetls(orderDetlList);
//
//        log.info("存储数据库成功!");
//    }
private static final int MAX_BATCH_SIZE = 50; // 建议 100~200,根据字段数控制
    /**
     * 加上存储数据库
     * 分批存储数据库,避免SQL Server参数上限(2100)错误
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", list.size());
        log.info("单据号:{},数据:{},",orderNo, JSON.toJSONString(list));
        log.info("单据号:{},数据:{},", orderNo, JSON.toJSONString(list));
        List<OrderDetl> orderDetlList = new ArrayList<>();
        list.forEach(importOrderDto -> {
        for (ImportOrderDto importOrderDto : list) {
            OrderDetl orderDetl = new OrderDetl();
            orderDetl.setBrand(importOrderDto.getColumn1());
            if (docTypeId == 24) {
                orderDetl.setSpecs(String.format("%07d", Integer.parseInt(importOrderDto.getColumn1()))); // 源库位
                if (importOrderDto.getColumn2() != null) {
                    orderDetl.setModel(String.format("%07d", Integer.parseInt(importOrderDto.getColumn2()))); // 目标库位
                }
                if (importOrderDto.getColumn3() != null) {
                    orderDetl.setBeBatch(Integer.parseInt(importOrderDto.getColumn3())); // 巷道
                }
            } else {
                orderDetl.setBrand(importOrderDto.getColumn1());
                orderDetl.setSupp(importOrderDto.getColumn3());
                orderDetl.setMemo(importOrderDto.getColumn4());
            }
            orderDetl.setBatch("");
            orderDetl.setOrderId(orderId);
            orderDetl.setOrderNo(orderNo);
@@ -133,12 +206,21 @@
            orderDetl.setStatus(1);
            orderDetl.setQty(0.0D);
            orderDetl.setAnfme(1.0);
            orderDetlList.add(orderDetl);
        });
        orderDetlMapper.batchDetls(orderDetlList);
        }
        // ✅ 关键点:分批提交
        for (int i = 0; i < orderDetlList.size(); i += MAX_BATCH_SIZE) {
            int end = Math.min(i + MAX_BATCH_SIZE, orderDetlList.size());
            List<OrderDetl> batch = orderDetlList.subList(i, end);
            orderDetlMapper.batchDetls(batch);
        }
        log.info("存储数据库成功!");
    }
    /**
     *解析出现错误会进入该方法 具体看源代码或文档
     */