自动化立体仓库 - WMS系统
pang.jiabao
2024-09-02 35313ffe430ad0ef6799c60316ce2d7bdfa8b855
excel导入单据
2个文件已添加
5个文件已修改
299 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/OrderController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/importexcle/ImportOrderDto.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/importexcle/ImportOrderListener.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/OrderDetlMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/DocTypeServiceImpl.java 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/OrderDetlMapper.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/order/order.html 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OrderController.java
@@ -1,5 +1,6 @@
package com.zy.asrs.controller;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
@@ -11,16 +12,23 @@
import com.zy.asrs.entity.param.OrderDomainParam;
import com.zy.asrs.entity.result.WrkTraceVo;
import com.zy.asrs.importexcle.ImportOrderDto;
import com.zy.asrs.importexcle.ImportOrderListener;
import com.zy.asrs.mapper.OrderDetlMapper;
import com.zy.asrs.service.*;
import com.zy.asrs.utils.FileSaveExampleUtil;
import com.zy.common.model.DetlDto;
import com.zy.common.web.BaseController;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
@RestController
@@ -45,6 +53,29 @@
    @Autowired
    private WrkMastLogService wrkMastLogService;
    @Resource
    private OrderDetlMapper orderDetlMapper;
    @PostMapping("/importOrder")
    @ManagerAuth(memo = "单据导入")
    @ApiOperation(value = "单据导入", produces = MediaType.APPLICATION_JSON_VALUE)
    public R importOrderData(@RequestParam("file") MultipartFile multipartFile) {
        try {
            importOrder(multipartFile);
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }
        return R.ok("导入成功");
    }
    @Transactional(rollbackFor = Exception.class)
    public void importOrder(MultipartFile multipartFile) throws IOException {
        // 考核数据的判重使用order_id,check_type的组合唯一索引解决
        EasyExcel.read(multipartFile.getInputStream(), ImportOrderDto.class,
                new ImportOrderListener(orderService, orderDetlMapper,docTypeService, snowflakeIdWorker,getUserId())).sheet().doReadSync();
    }
    @RequestMapping(value = "/order/nav/list/auth")
    @ManagerAuth
    public R navList(@RequestParam(required = false) String orderNo){
src/main/java/com/zy/asrs/importexcle/ImportOrderDto.java
New file
@@ -0,0 +1,20 @@
package com.zy.asrs.importexcle;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
 * @author pang.jiabao
 * @description 导入订单dto
 * @createDate 2024/9/2 9:55
 */
@Data
public class ImportOrderDto {
    @ExcelProperty(value = "包装组号",index = 0)
    private String column1;
    @ExcelProperty(value = "出库单号/单据类型",index = 1)
    private String column2;
}
src/main/java/com/zy/asrs/importexcle/ImportOrderListener.java
New file
@@ -0,0 +1,150 @@
package com.zy.asrs.importexcle;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.core.common.SnowflakeIdWorker;
import com.zy.asrs.entity.DocType;
import com.zy.asrs.entity.Order;
import com.zy.asrs.entity.OrderDetl;
import com.zy.asrs.mapper.OrderDetlMapper;
import com.zy.asrs.service.DocTypeService;
import com.zy.asrs.service.OrderService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * @author pang.jiabao
 * @description 导入订单监听器
 * @createDate 2024/9/2 9:56
 */
@Slf4j
public class ImportOrderListener extends AnalysisEventListener<ImportOrderDto> {
    /**
     * 每隔1000条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 400;
    private int count = 0;
    private String orderNo;
    private long orderId;
    List<ImportOrderDto> list = new ArrayList<>();
    /**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private final OrderService orderService;
    private final OrderDetlMapper orderDetlMapper;
    private final DocTypeService docTypeService;
    private final SnowflakeIdWorker snowflakeIdWorker;
    private final Long userId;
    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     */
    public ImportOrderListener(OrderService orderService, OrderDetlMapper orderDetlMapper,DocTypeService docTypeService, SnowflakeIdWorker snowflakeIdWorker, Long userId) {
        this.orderService = orderService;
        this.orderDetlMapper = orderDetlMapper;
        this.docTypeService = docTypeService;
        this.snowflakeIdWorker = snowflakeIdWorker;
        this.userId = userId;
    }
    /**
     * 这个每一条数据解析都会来调用
     */
    @SneakyThrows
    @Override
    public void invoke(ImportOrderDto data, AnalysisContext context) {
        log.info("解析到第 {} 条数据:{}", ++count, JSON.toJSONString(data));
        list.add(data);
        if (context.getCurrentRowNum() == 3) {
            String time = DateUtils.convert(new Date(),DateUtils.yyyyMMddHHmmss_F);
            Order order2 = orderService.selectByNo(list.get(0).getColumn2());
            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();
            Order order = new Order();
            order.setUuid(String.valueOf(snowflakeIdWorker.nextId()));
            order.setOrderNo(orderNo);
            order.setOrderTime(time);
            order.setDocType(docType.getDocId());
            order.setSettle(1L);
            order.setStatus(1);
            order.setCreateBy(userId);
            order.setCreateTime(new Date());
            orderService.insert(order);
            Order order1 = orderService.selectByNo(orderNo);
            orderId = order1.getId();
            list.clear();
            return;
        }
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }
    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        if (list.size() > 0) {
            saveData();
        }
        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();
            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("存储数据库成功!");
    }
    /**
     *解析出现错误会进入该方法 具体看源代码或文档
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        log.error("处理异常:" + exception.getMessage());
        throw exception;
    }
}
src/main/java/com/zy/asrs/mapper/OrderDetlMapper.java
@@ -13,6 +13,11 @@
@Repository
public interface OrderDetlMapper extends BaseMapper<OrderDetl> {
    /**
     * 批量存储单据明细
     */
    int batchDetls(@Param("list") List<OrderDetl> list);
    OrderDetl selectItem(@Param("orderId") Long orderId, @Param("matnr") String matnr, @Param("batch") String batch);
    OrderDetl selectItemByOrderNo(@Param("orderNo") String orderNo, @Param("matnr") String matnr, @Param("batch") String batch);
src/main/java/com/zy/asrs/service/impl/DocTypeServiceImpl.java
@@ -1,15 +1,12 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.mapper.DocTypeMapper;
import com.zy.asrs.entity.DocType;
import com.zy.asrs.service.DocTypeService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.core.common.Cools;
import com.zy.asrs.entity.DocType;
import com.zy.asrs.mapper.DocTypeMapper;
import com.zy.asrs.service.DocTypeService;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service("docTypeService")
public class DocTypeServiceImpl extends ServiceImpl<DocTypeMapper, DocType> implements DocTypeService {
@@ -21,24 +18,25 @@
        }
        DocType docType = this.selectOne(new EntityWrapper<DocType>().eq("doc_name", docName));
        if (docType == null) {
            long docId = 1L;
            DocType last = this.selectOne(new EntityWrapper<DocType>().orderBy("doc_id", false));
            if (last != null) {
                docId = last.getDocId() + 1;
            }
            docType = new DocType();
            docType.setDocId(docId);
            docType.setDocName(docName);
            if (null != pakin) {
                docType.setPakin(pakin ? 1 : 0);
                docType.setPakout(pakin ? 0 : 1);
            }
            docType.setStatus(1);
            docType.setCreateTime(new Date());
            docType.setUpdateTime(new Date());
            if (!this.insert(docType)) {
                throw new CoolException("单据类型错误");
            }
            return null;
//            long docId = 1L;
//            DocType last = this.selectOne(new EntityWrapper<DocType>().orderBy("doc_id", false));
//            if (last != null) {
//                docId = last.getDocId() + 1;
//            }
//            docType = new DocType();
//            docType.setDocId(docId);
//            docType.setDocName(docName);
//            if (null != pakin) {
//                docType.setPakin(pakin ? 1 : 0);
//                docType.setPakout(pakin ? 0 : 1);
//            }
//            docType.setStatus(1);
//            docType.setCreateTime(new Date());
//            docType.setUpdateTime(new Date());
//            if (!this.insert(docType)) {
//                throw new CoolException("单据类型错误");
//            }
        }
        return docType;
    }
src/main/resources/mapper/OrderDetlMapper.xml
@@ -169,6 +169,23 @@
    <insert id="addToLogTable">
        INSERT INTO man_order_detl_log SELECT * FROM man_order_detl WHERE id = #{id}
    </insert>
    <insert id="batchDetls">
        INSERT INTO
        man_order_detl(brand,batch,order_id,order_no,create_by,create_time,status,qty,anfme)
        VALUES
        <foreach collection="list" item="item" index="index" separator=",">
            (
            #{item.brand},
            #{item.batch},
            #{item.orderId},
            #{item.orderNo},
            #{item.createBy},
            #{item.createTime},
            #{item.status},
            #{item.qty},
            #{item.anfme}
            )</foreach>
    </insert>
    <update id="increaseQtyByOrderNo">
        update man_order_detl
src/main/webapp/views/order/order.html
@@ -82,6 +82,8 @@
                        </button>
<!--                        <button id="orderAddBtn" class="layui-btn icon-btn btn-add"><i class="layui-icon">&#xe654;</i>添加-->
<!--                        </button>-->
                        <input type="file" id="fileInput" accept=".xlsx, .xls">
                        <button onclick="exportExc()">导入订单</button>
                    </div>
                </div>
            </div>
@@ -96,7 +98,31 @@
        </div>
    </div>
</div>
<script>
    function exportExc() {
        var fileInput = document.getElementById('fileInput');
        var file = fileInput.files[0];
        if (file === undefined) {
            alert('请先选择文件')
            return
        }
        var formData = new FormData();
        formData.append('file', file);
        fetch(baseUrl+'/importOrder', {
            method: 'POST',
            headers: {'token': localStorage.getItem('token')},
            body: formData
        }).then(response => {
            response.text().then(data => {
                var res = JSON.parse(data)
                alert(res.msg)
            })
        }).catch(error => {
            alert('导入异常');
        });
    }
</script>
<div id="myModal"  style="display: none">
    <div style="padding: 10px">
        <div class="layui-upload">
@@ -134,7 +160,7 @@
    <a class="layui-btn layui-btn-primary layui-border-blue layui-btn-xs btn-complete" lay-event="complete">完结</a>
    {{# } }}
    {{# if (d.settle == 4 && d.tkType=='1') { }}
        <a class="layui-btn layui-btn-danger layui-btn-xs btn-delete" lay-event="refundLoc">退库</a>
<!--        <a class="layui-btn layui-btn-danger layui-btn-xs btn-delete" lay-event="refundLoc">退库</a>-->
    {{# } }}
</script>
<!-- 表格操作列 -->