src/main/java/com/zy/asrs/controller/MobileController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/controller/ReviewController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/entity/ReviewDetl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/importexcle/ImportReviewDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/importexcle/ImportReviewListener.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/static/js/review/review.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/views/review/review.html | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/zy/asrs/controller/MobileController.java
@@ -16,12 +16,15 @@ import com.zy.asrs.service.*; import com.zy.common.model.WrkDto; import com.zy.common.web.BaseController; import com.zy.system.entity.User; import com.zy.system.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; /** * 移动端接口控制器 @@ -64,6 +67,14 @@ @Resource private OrderDetlMapper orderDetlMapper; @Resource private ReviewService reviewService; @Resource private ReviewDetlService reviewDetlService; @Resource private UserService userService; // 商品上架 @RequestMapping("/mat/onSale/auth") @@ -72,6 +83,7 @@ mobileService.onSale(combParam); return R.ok("上架成功"); } // 商品下架 @RequestMapping("/mat/offSale/auth") //@ManagerAuth @@ -90,7 +102,6 @@ } return R.ok(rgvOneSign.getRgvOneSign()); } // 组托 ---------------------------------------------------------------------------------------------------- @@ -638,4 +649,53 @@ } @GetMapping("/getReviewList/{orderNo}") public synchronized R getReviewList(@PathVariable("orderNo") String orderNo) { List<Review> reviewList = reviewService.selectList(new EntityWrapper<Review>().like("order_no", orderNo)); List<String> collect = reviewList.stream().map(Review::getOrderNo).collect(Collectors.toList()); return R.ok(collect); } @GetMapping("/getReviewDetlByOrderNo/{orderNo}") public synchronized R getReviewDetlByOrderNo(@PathVariable("orderNo") String orderNo) { List<ReviewDetl> reviewList = reviewDetlService.selectList(new EntityWrapper<ReviewDetl>().eq("order_no", orderNo).ne("inspect", 1)); return R.ok(reviewList); } @PostMapping("/reviewCheck") @ManagerAuth(memo = "单据复核") public synchronized R reviewCheck(@RequestBody List<ReviewDetl> param) { System.out.println(JSONObject.toJSONString(param)); if (Cools.isEmpty(param)) { return R.parse("参数有误,请检查参数"); } for (ReviewDetl reviewDetl : param) { if (!Cools.isEmpty(reviewDetl.getInspect()) && reviewDetl.getInspect() == 1) { ReviewDetl reviewDetl1 = reviewDetlService.selectById(reviewDetl.getId()); reviewDetl1.setInspect(reviewDetl.getInspect()); reviewDetl1.setMemo(reviewDetl.getMemo()); reviewDetl1.setThreeCode(reviewDetl.getThreeCode()); reviewDetl1.setUpdateTime(new Date()); reviewDetlService.updateById(reviewDetl1); Review review = reviewService.selectById(reviewDetl1.getOrderId()); review.setSettle(2L); reviewService.updateById(review); } } return R.ok(); } @GetMapping("/getCheckUser") public R getCheckUser() { Set set = new HashSet<String>(); List<User> userList = userService.selectList(new EntityWrapper<User>().eq("status", 1).eq("role_id", 18L)); for (User user : userList) { set.add(user.getUsername()); } return R.ok(set); } } src/main/java/com/zy/asrs/controller/ReviewController.java
@@ -19,6 +19,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -41,6 +42,9 @@ @Autowired private SnowflakeIdWorker snowflakeIdWorker; @Autowired private PlatformTransactionManager transactionManager; @Resource private ReviewDetlMapper reviewDetlMapper; @@ -61,7 +65,7 @@ public void importOrder(MultipartFile multipartFile) throws IOException { // 考核数据的判重使用order_id,check_type的组合唯一索引解决 EasyExcel.read(multipartFile.getInputStream(), ImportReviewDto.class, new ImportReviewListener(snowflakeIdWorker, getUserId())).sheet().doReadSync(); new ImportReviewListener(transactionManager,reviewService, reviewDetlService, snowflakeIdWorker, getUserId())).sheet().doReadSync(); } src/main/java/com/zy/asrs/entity/ReviewDetl.java
@@ -8,7 +8,6 @@ import com.core.common.Cools; import com.core.common.SpringUtils; import com.zy.asrs.service.BasBoxTypeService; import com.zy.asrs.service.OrderService; import com.zy.common.utils.Synchro; import com.zy.system.entity.User; import com.zy.system.service.UserService; @@ -56,7 +55,7 @@ /** * 作业数量 * * <p> * 入库 : 组托完成,组托档、工作档、入库完成数量 * 出库 : 工作档、出库完成数量 */ @@ -66,7 +65,7 @@ /** * 完成数量 * * <p> * 入库 : qty 👆 * 出库 : qty 👆 */ @@ -310,7 +309,9 @@ public String getStatus$(){ if (null == this.status){ return null; } if (null == this.status) { return null; } switch (this.status){ case 1: return "正常"; @@ -360,6 +361,17 @@ return "未完成"; } public String getInspect$() { if (Cools.isEmpty(this.inspect)) { return "未复核"; } if (this.inspect == 1) { return "已复核"; } else { return "未复核"; } } public Double getEnableQty() { if (null != this.anfme && this.workQty != null) { return this.anfme - this.workQty; src/main/java/com/zy/asrs/importexcle/ImportReviewDto.java
@@ -11,18 +11,37 @@ @Data public class ImportReviewDto { @ExcelProperty(value = "包装组号/源库位",index = 0) private Long orderId; @ExcelProperty(value = "单据编号", index = 0) private String column1; @ExcelProperty(value = "出库单号/单据类型/客户名称/备注/目标库位",index = 1) @ExcelProperty(value = "物料编号", index = 1) private String column2; @ExcelProperty(value = "目标巷道/客户名称",index = 2) @ExcelProperty(value = "物料名称", index = 2) private String column3; @ExcelProperty(value = "备注",index = 3) @ExcelProperty(value = "规格", index = 3) private String column4; @ExcelProperty(value = "单位", index = 4) private String column5; @ExcelProperty(value = "品级", index = 5) private String column6; @ExcelProperty(value = "批次号", index = 6) private String column7; @ExcelProperty(value = "卷号", index = 7) private String column8; @ExcelProperty(value = "出库数量", index = 8) private Double column9; @ExcelProperty(value = "出库日期", index = 9) private String column10; } src/main/java/com/zy/asrs/importexcle/ImportReviewListener.java
@@ -3,13 +3,19 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.common.DateUtils; import com.core.common.SnowflakeIdWorker; import com.zy.asrs.entity.OrderDetl; import com.core.exception.CoolException; import com.zy.asrs.entity.Review; import com.zy.asrs.entity.ReviewDetl; import com.zy.asrs.service.ReviewDetlService; import com.zy.asrs.service.ReviewService; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import java.util.*; @@ -23,29 +29,32 @@ /** * 每隔1000条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 400; private static final int BATCH_COUNT = 2000; private int count = 0; private String orderNo; private long orderId; private long docTypeId; List<ImportReviewDto> list = new ArrayList<>(); /** * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 */ private final PlatformTransactionManager transactionManager; private ReviewService reviewService; private ReviewDetlService reviewDetlService; private final SnowflakeIdWorker snowflakeIdWorker; private final Long userId; private TransactionStatus transactionStatus; /** * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 */ public ImportReviewListener(SnowflakeIdWorker snowflakeIdWorker, Long userId) { public ImportReviewListener(PlatformTransactionManager transactionManager, ReviewService reviewService, ReviewDetlService reviewDetlService, SnowflakeIdWorker snowflakeIdWorker, Long userId) { this.transactionManager = transactionManager; this.reviewService = reviewService; this.reviewDetlService = reviewDetlService; this.snowflakeIdWorker = snowflakeIdWorker; this.userId = userId; } @@ -57,28 +66,42 @@ public void invoke(ImportReviewDto data, AnalysisContext context) { log.info("解析到第 {} 条数据:{}", ++count, JSON.toJSONString(data)); // 获取包装组号(column1) String packNo = data.getColumn1(); if (Cools.isEmpty(packNo)) { log.warn("包装组号为空,跳过该行!"); if (Cools.isEmpty(data.getColumn2())) { log.warn("规格型号,跳过该行!"); return; } // 如果已经处理过该包装组号,则跳过 if (uniquePackNos.contains(packNo)) { log.info("重复的包装组号:{},跳过", packNo); if (Cools.isEmpty(data.getColumn4())) { log.info("重复的包装组号:{},跳过", data.getColumn5()); return; } if (Cools.isEmpty(data.getColumn7())) { log.info("重复的包装组号:{},跳过", data.getColumn7()); return; } // 首次出现,记录并处理 uniquePackNos.add(packNo); list.add(data); uniquePackNos.add(data.getColumn1()); if (context.getCurrentRowNum() == 3) { String time = DateUtils.convert(new Date(), DateUtils.yyyyMMddHHmmss_F); Review review = reviewService.selectOne(new EntityWrapper<Review>().eq("order_no", data.getColumn1())); if (review == null) { review = new Review(); review.setUuid(String.valueOf(snowflakeIdWorker.nextId())); review.setOrderNo(data.getColumn1()); review.setOrderTime(time); review.setSettle(1L); review.setStatus(1); review.setCreateBy(userId); review.setCreateTime(new Date()); return; reviewService.insert(review); review = reviewService.selectOne(new EntityWrapper<Review>().eq("order_no", data.getColumn1())); }else { log.info("已存在该订单:{},", data.getColumn1()); throw new CoolException("订单已存在!"); } data.setOrderId(review.getId()); list.add(data); if (list.size() >= BATCH_COUNT) { saveData(); list.clear(); @@ -106,47 +129,37 @@ */ private void saveData() { log.info("{}条数据,开始存储数据库!", list.size()); log.info("单据号:{},数据:{},", orderNo, JSON.toJSONString(list)); log.info("数据:{},", JSON.toJSONString(list)); List<OrderDetl> orderDetlList = new ArrayList<>(); List<ReviewDetl> orderDetlList = new ArrayList<>(); for (ImportReviewDto importOrderDto : list) { OrderDetl orderDetl = new OrderDetl(); ReviewDetl orderDetl = new ReviewDetl(); 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.setOrderNo(importOrderDto.getColumn1()); orderDetl.setMatnr(importOrderDto.getColumn2()); orderDetl.setMaktx(importOrderDto.getColumn3()); orderDetl.setSpecs(importOrderDto.getColumn4()); orderDetl.setUnit(importOrderDto.getColumn5()); //orderDetl.set(importOrderDto.getColumn6()); orderDetl.setBatch(importOrderDto.getColumn7()); orderDetl.setModel(importOrderDto.getColumn8()); orderDetl.setAnfme(importOrderDto.getColumn9()); orderDetl.setDeadTime(importOrderDto.getColumn10()); orderDetl.setBatch(""); orderDetl.setOrderId(orderId); orderDetl.setOrderNo(orderNo); orderDetl.setOrderId(importOrderDto.getOrderId()); 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); } // ✅ 关键点:分批提交 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); //reviewDetlService.batchDetls(batch); for (ReviewDetl d : orderDetlList) { reviewDetlService.insert(d); } log.info("存储数据库成功!"); } src/main/webapp/static/js/review/review.js
@@ -32,7 +32,7 @@ {type: 'numbers'}, {field: 'orderNo', title: '单据编号'}, {field: 'cstmrName', align: 'center',title: '客户名称'}, {align: 'center', title: '明细', toolbar: '#tbLook', minWidth: 160, width: 160}, {align: 'center', title: '明细', toolbar: '#tbLook', minWidth: 250, width: 250}, {field: 'createTime$', title: '创建时间', minWidth: 200, width: 200}, {field: 'settle$', align: 'center', title: '状态', templet: '#settleTpl', minWidth: 160, width: 160}, //{field: 'memo', align: 'center',title: '备注'}, @@ -207,7 +207,7 @@ layer.open({ type: 1, title: false, area: '1020px', area: '1220px', offset: [top + 'px', (left - 530 + $a.outerWidth()) + 'px'], shade: .01, shadeClose: true, @@ -229,10 +229,11 @@ {field: 'maktx', title: '产品名称'}, {field: 'specs', title: '规格型号'}, {field: 'batch', title: '批次号'}, {field: 'color', title: '卷号'}, {field: 'qty', title: '出库数量'}, {field: 'model', title: '卷号'}, {field: 'anfme', title: '出库数量'}, {field: 'deadTime', title: '出库日期'}, {field: 'source', title: '复核状态'}, {field: 'inspect$', title: '复核状态'}, {field: 'threeCode', title: '复核人'}, {field: 'memo', title: '复核备注'} ]], request: { src/main/webapp/views/review/review.html
@@ -114,7 +114,7 @@ var formData = new FormData(); formData.append('file', file); fetch(baseUrl+'/importOrder', { fetch(baseUrl+'/importReview', { method: 'POST', headers: {'token': localStorage.getItem('token')}, body: formData @@ -162,6 +162,7 @@ <!-- <a class="layui-btn layui-btn-primary layui-border-blue layui-btn-xs btn-complete" lay-event="labelUp">上传标签</a>--> {{# } }} {{# if (d.settle == 2) { }} <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a> <!-- <a class="layui-btn layui-btn-primary layui-border-blue layui-btn-xs btn-complete" lay-event="labelUp">上传标签</a>--> <a class="layui-btn layui-btn-primary layui-border-blue layui-btn-xs btn-edit" lay-event="complete">完结</a> {{# } }}