src/main/java/com/zy/asrs/controller/OrderController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/importexcle/ImportOrderDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/importexcle/ImportOrderListener.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/mapper/OrderDetlMapper.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/service/impl/DocTypeServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/resources/mapper/OrderDetlMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/views/order/order.html | ●●●●● 补丁 | 查看 | 原始文档 | 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"></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> <!-- 表格操作列 -->