diff --git a/pom.xml b/pom.xml index 86a262f..7e05899 100644 --- a/pom.xml +++ b/pom.xml @@ -295,6 +295,12 @@ <version>1.1.1</version> </dependency> + <!--解析excel--> + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>easyexcel</artifactId> + <version>3.1.1</version> + </dependency> </dependencies> diff --git a/src/main/java/com/glxp/udi/admin/controller/product/StackOrderController.java b/src/main/java/com/glxp/udi/admin/controller/product/StackOrderController.java index e37a42d..33d2fde 100644 --- a/src/main/java/com/glxp/udi/admin/controller/product/StackOrderController.java +++ b/src/main/java/com/glxp/udi/admin/controller/product/StackOrderController.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.glxp.udi.admin.annotation.AuthRuleAnnotation; import com.glxp.udi.admin.common.res.BaseResponse; import com.glxp.udi.admin.req.info.DeleteRequest; +import com.glxp.udi.admin.req.product.ImportStackOrderRequest; import com.glxp.udi.admin.req.product.StackUploadRequest; import com.glxp.udi.admin.res.product.StackOrderResponse; import com.glxp.udi.admin.service.auth.CustomerService; @@ -18,18 +19,21 @@ import com.glxp.udi.admin.service.product.StackCodeService; import com.glxp.udi.admin.service.product.StackOrderService; import com.glxp.udi.admin.common.enums.ResultEnum; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.List; +import java.io.File; +import java.util.*; @Slf4j @RestController public class StackOrderController { + @Value("${file_path}") + private String filePath; @Resource StackOrderService stackOrderService; @Resource @@ -117,9 +121,8 @@ public class StackOrderController { * @param file * @return */ - @AuthRuleAnnotation("") - @PostMapping("/udims/stack/order/importStackOrder") - public BaseResponse importStackOrder(@RequestParam("file") MultipartFile file) { + @PostMapping("/udims/stack/order/uploadStackFile") + public BaseResponse uploadStackFile(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return ResultVOUtils.error(ResultEnum.DATA_ERROR, "上传文件不能为空"); } @@ -127,10 +130,60 @@ public class StackOrderController { String fileName = file.getOriginalFilename(); String fileType = fileName.substring(fileName.lastIndexOf(".")); //文件类型判断 - if (StrUtil.isBlank(fileType) || (!fileType.equals(".xls") || !fileType.equals(".xlsx"))) { + if (StrUtil.isBlank(fileType) || (!fileType.equals(".xls") && !fileType.equals(".xlsx"))) { return ResultVOUtils.error(ResultEnum.DATA_ERROR, "只能上传 xlx 或 xlsx 格式文件"); } - return ResultVOUtils.success(); + + //生成新文件名 + String newName = UUID.randomUUID() + fileType; + String savePath = filePath + "/stack/files"; + + File file1 = new File(savePath); + //判断目录是否存在 + if (!file1.exists()) { + //创建多层目录 + file1.mkdirs(); + } + String filePath = savePath + "/" + newName; + file1 = new File(filePath); + try { + file.transferTo(file1); + Map<String, String> map = new HashMap<>(2); + map.put("msg", "上传成功"); + map.put("path", filePath); + return ResultVOUtils.success(map); + } catch (Exception e) { + log.error("上传失败", e); + } + + return ResultVOUtils.error(ResultEnum.DATA_NOT, "上传失败"); } + + /** + * 导入excel文件建垛 + * + * @param importStackOrderRequest + * @param bindingResult + * @return + */ + @AuthRuleAnnotation("") + @PostMapping("/udims/stack/order/importStackOrder") + public BaseResponse importStackOrder(@RequestBody ImportStackOrderRequest importStackOrderRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL, bindingResult.getFieldError().getDefaultMessage()); + } + if (StrUtil.isBlank(importStackOrderRequest.getFilePath())) { + return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL, "请上传文件!"); + } + try { + stackOrderService.importStackOrder(importStackOrderRequest.getFilePath()); + return ResultVOUtils.success(); + } catch (Exception e) { + log.error("导入建垛失败", e); + } + return ResultVOUtils.error(500, "建垛失败"); + } + + } diff --git a/src/main/java/com/glxp/udi/admin/dao/product/StackCodeDao.java b/src/main/java/com/glxp/udi/admin/dao/product/StackCodeDao.java index 5bb06a3..370878c 100644 --- a/src/main/java/com/glxp/udi/admin/dao/product/StackCodeDao.java +++ b/src/main/java/com/glxp/udi/admin/dao/product/StackCodeDao.java @@ -22,4 +22,12 @@ public interface StackCodeDao extends BaseMapper<StackCode> { * @return */ Long countByOrderId(@Param("orderId") String orderId); + + /** + * 查询码在表中的数量 + * + * @param code + * @return + */ + long countByCode(@Param("code") String code); } diff --git a/src/main/java/com/glxp/udi/admin/entity/product/StackCode.java b/src/main/java/com/glxp/udi/admin/entity/product/StackCode.java index 655479c..a562e86 100644 --- a/src/main/java/com/glxp/udi/admin/entity/product/StackCode.java +++ b/src/main/java/com/glxp/udi/admin/entity/product/StackCode.java @@ -17,4 +17,12 @@ public class StackCode { private Integer id; private String code; private String orderIdFk; + + public StackCode() { + } + + public StackCode(String orderIdFk, String code) { + this.orderIdFk = orderIdFk; + this.code = code; + } } diff --git a/src/main/java/com/glxp/udi/admin/req/product/ImportStackOrderRequest.java b/src/main/java/com/glxp/udi/admin/req/product/ImportStackOrderRequest.java new file mode 100644 index 0000000..38bfaef --- /dev/null +++ b/src/main/java/com/glxp/udi/admin/req/product/ImportStackOrderRequest.java @@ -0,0 +1,16 @@ +package com.glxp.udi.admin.req.product; + +import lombok.Data; + +/** + * 导入建垛请求参数 + */ +@Data +public class ImportStackOrderRequest { + + /** + * 文件路径 + */ + private String filePath; + +} diff --git a/src/main/java/com/glxp/udi/admin/service/product/StackOrderService.java b/src/main/java/com/glxp/udi/admin/service/product/StackOrderService.java index 62f4b8b..c355080 100644 --- a/src/main/java/com/glxp/udi/admin/service/product/StackOrderService.java +++ b/src/main/java/com/glxp/udi/admin/service/product/StackOrderService.java @@ -1,7 +1,11 @@ package com.glxp.udi.admin.service.product; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.poi.excel.ExcelReader; +import cn.hutool.poi.excel.ExcelUtil; +import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -11,7 +15,9 @@ import com.glxp.udi.admin.entity.product.StackCode; import com.glxp.udi.admin.entity.product.StackOrder; import com.glxp.udi.admin.req.product.StackOrderFilterRequest; import com.glxp.udi.admin.req.product.StackUploadRequest; +import com.glxp.udi.admin.service.auth.CustomerService; import com.glxp.udi.admin.util.IdUtil; +import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; @@ -20,9 +26,15 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.io.File; +import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; +@Slf4j @Service @Transactional(rollbackFor = Exception.class) public class StackOrderService { @@ -35,6 +47,8 @@ public class StackOrderService { private StackCodeDao stackCodeDao; @Resource private SqlSessionFactory sqlSessionFactory; + @Resource + private CustomerService customerService; public IPage<StackOrder> filterList(StackOrderFilterRequest stackOrderFilterRequest) { @@ -107,4 +121,80 @@ public class StackOrderService { Long codeNum = stackCodeDao.countByOrderId(orderId); return codeNum; } + + /** + * 读取excel文件,建垛 + * + * @param filePath + */ + public void importStackOrder(String filePath) throws Exception { + long t1 = System.currentTimeMillis(); + + List<Object> objects = EasyExcel.read(filePath).sheet().doReadSync(); + + + ExcelReader reader = ExcelUtil.getReader(new File(filePath)); + List<List<Object>> read = reader.read(1); + if (CollUtil.isEmpty(read)) { + log.error("解析垛码excel文件数据为空"); + throw new RuntimeException("垛码excel文件数据为空"); + } + + List<StackCode> stackCodes = new ArrayList<>(read.size()); + for (List<Object> list : read) { + //流水号 + String serialNum = String.valueOf(list.get(0)); + String code = String.valueOf(list.get(1)); + if (StrUtil.isBlank(serialNum) || StrUtil.isBlank(code)) { + log.error("数据为空,数据不规范"); + throw new RuntimeException("垛码数据格式错误,解析失败"); + } + + StackCode stackCode = new StackCode(serialNum, code); + stackCodes.add(stackCode); + } + + long t2 = System.currentTimeMillis(); + log.info("解析构造数据用时:{}", t2 - t1); + + Map<String, List<StackCode>> stacks = stackCodes.stream().collect(Collectors.groupingBy(StackCode::getOrderIdFk)); + //根据每一个流水号,创建单据,生成条码 + String customerId = String.valueOf(customerService.getCustomerId()); + SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); + StackCodeDao mapper = sqlSession.getMapper(StackCodeDao.class); + for (String serialNum : stacks.keySet()) { + StackOrder stackOrder = new StackOrder(); + String stackId = idUtil.getStackId(customerId); + stackOrder.setOrderId(stackId); + stackOrder.setCreateTime(new Date()); + stackOrder.setExportStatus(0); + stackOrder.setCustomerId(customerId); + //插入垛数据 + stackOrderDao.insert(stackOrder); + List<StackCode> data = stacks.get(serialNum); + List<StackCode> saveDataList = new CopyOnWriteArrayList<>(data); + saveDataList.parallelStream().forEach(stackCode -> { + stackCode.setOrderIdFk(stackId); + //检查此码是否已经被添加过 + long count = stackCodeDao.countByCode(stackCode.getCode()); + if (count > 0) { + log.error("重复条码"); + throw new RuntimeException("重复条码"); + } + + mapper.insert(stackCode); + }); + + sqlSession.commit(); + } + + sqlSession.close(); + + long t3 = System.currentTimeMillis(); + log.info("插入数据用时:{}", t3 - t2); + log.info("全程用时:{}", t3 - t1); + + //导入成功,删除数据文件 + FileUtil.del(filePath); + } } diff --git a/src/main/java/com/glxp/udi/admin/vo/StackCodeVo.java b/src/main/java/com/glxp/udi/admin/vo/StackCodeVo.java new file mode 100644 index 0000000..11e0338 --- /dev/null +++ b/src/main/java/com/glxp/udi/admin/vo/StackCodeVo.java @@ -0,0 +1,21 @@ +package com.glxp.udi.admin.vo; + +import lombok.Data; + +/** + * 垛码excel数据解析对象 + */ +@Data +public class StackCodeVo { + + /** + * 流水号 + */ + private String orderId; + + /** + * 条码 + */ + private String code; + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 71d3028..09f529f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,6 +4,10 @@ server: spring: profiles: active: dev + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB mybatis-plus: diff --git a/src/main/resources/mybatis/mapper/product/StackCodeDao.xml b/src/main/resources/mybatis/mapper/product/StackCodeDao.xml index bd25a00..6b70825 100644 --- a/src/main/resources/mybatis/mapper/product/StackCodeDao.xml +++ b/src/main/resources/mybatis/mapper/product/StackCodeDao.xml @@ -11,4 +11,7 @@ select count(*) from stack_code where orderIdFk = #{orderId} </select> + <select id="countByCode" resultType="long"> + select count(*) from stack_code where code = #{code} + </select> </mapper> \ No newline at end of file