From e7a061942f7ebcda0fbb1c6f2f223c3ab480ede0 Mon Sep 17 00:00:00 2001 From: liangzhou <594755172@qq.com> Date: Tue, 6 Aug 2024 16:21:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0=EF=BC=9A?= =?UTF-8?q?=201.=E5=A2=9E=E5=8A=A0excel=E7=9A=84=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=202.=E5=A2=9E=E5=8A=A0=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 11 +- .../wms/constants/enums/ConfigMapKeyEnum.java | 1 + .../com/wms/controller/ConfigController.java | 17 + .../com/wms/controller/ExcelController.java | 193 +++- .../java/com/wms/controller/JobComponent.java | 7 +- .../com/wms/controller/TaskController.java | 12 +- .../java/com/wms/entity/app/dto/StockDto.java | 3 - .../entity/app/request/UploadRecordQuery.java | 59 + .../java/com/wms/entity/app/vo/FileVo.java | 21 + .../java/com/wms/entity/app/vo/StockVo.java | 113 ++ .../com/wms/entity/app/vo/UploadRecordVo.java | 49 + .../wms/entity/table/InventoryHistory.java | 28 + .../com/wms/entity/table/InventoryList.java | 57 + .../com/wms/entity/table/UploadRecord.java | 46 + .../java/com/wms/entity/test/ExcelTest.java | 7 - .../wms/mapper/InventoryHistoryMapper.java | 12 + .../com/wms/mapper/InventoryListMapper.java | 12 + .../com/wms/mapper/UploadRecordMapper.java | 13 + .../wms/service/InventoryHistoryService.java | 10 + .../com/wms/service/InventoryListService.java | 10 + .../com/wms/service/TaskRecordService.java | 8 +- .../com/wms/service/UploadRecordService.java | 11 + .../WmsJobServiceImplements.java | 15 +- .../WmsTaskServiceImplements.java | 3 +- .../WorkServiceImplements.java | 1 + .../InventoryHistoryServiceImpl.java | 17 + .../InventoryListServiceImpl.java | 17 + .../TaskRecordServiceImplements.java | 10 +- .../UploadRecordServiceImpl.java | 20 + src/main/java/com/wms/utils/HttpUtils.java | 2 - .../com/wms/utils/excel/ExcelClassField.java | 71 -- .../java/com/wms/utils/excel/ExcelExport.java | 22 - .../java/com/wms/utils/excel/ExcelImport.java | 25 - .../java/com/wms/utils/excel/ExcelUtils.java | 1026 ----------------- .../excel/convertor/TaskStatusConvertor.java | 83 ++ .../excel/convertor/TaskTypeConvertor.java | 62 + .../excel/listener/UploadStocksListener.java | 107 ++ .../utils/excel/style/ExcelContentStyle.java | 31 + .../wms/utils/excel/vo/LocationExcelVo.java | 74 ++ .../com/wms/utils/excel/vo/StockExcelVo.java | 122 ++ .../wms/utils/excel/vo/TaskRecordExcelVo.java | 151 +++ .../wms/utils/excel/vo/VehicleExcelVo.java | 48 + src/main/resources/application.yml | 5 + .../mapper/InventoryHistoryMapper.xml | 6 + .../resources/mapper/InventoryListMapper.xml | 6 + .../resources/mapper/UploadRecordMapper.xml | 6 + 46 files changed, 1394 insertions(+), 1236 deletions(-) create mode 100644 src/main/java/com/wms/entity/app/request/UploadRecordQuery.java create mode 100644 src/main/java/com/wms/entity/app/vo/FileVo.java create mode 100644 src/main/java/com/wms/entity/app/vo/UploadRecordVo.java create mode 100644 src/main/java/com/wms/entity/table/InventoryHistory.java create mode 100644 src/main/java/com/wms/entity/table/InventoryList.java create mode 100644 src/main/java/com/wms/entity/table/UploadRecord.java create mode 100644 src/main/java/com/wms/mapper/InventoryHistoryMapper.java create mode 100644 src/main/java/com/wms/mapper/InventoryListMapper.java create mode 100644 src/main/java/com/wms/mapper/UploadRecordMapper.java create mode 100644 src/main/java/com/wms/service/InventoryHistoryService.java create mode 100644 src/main/java/com/wms/service/InventoryListService.java create mode 100644 src/main/java/com/wms/service/UploadRecordService.java create mode 100644 src/main/java/com/wms/service/serviceImplements/InventoryHistoryServiceImpl.java create mode 100644 src/main/java/com/wms/service/serviceImplements/InventoryListServiceImpl.java create mode 100644 src/main/java/com/wms/service/serviceImplements/UploadRecordServiceImpl.java delete mode 100644 src/main/java/com/wms/utils/excel/ExcelClassField.java delete mode 100644 src/main/java/com/wms/utils/excel/ExcelExport.java delete mode 100644 src/main/java/com/wms/utils/excel/ExcelImport.java delete mode 100644 src/main/java/com/wms/utils/excel/ExcelUtils.java create mode 100644 src/main/java/com/wms/utils/excel/convertor/TaskStatusConvertor.java create mode 100644 src/main/java/com/wms/utils/excel/convertor/TaskTypeConvertor.java create mode 100644 src/main/java/com/wms/utils/excel/listener/UploadStocksListener.java create mode 100644 src/main/java/com/wms/utils/excel/style/ExcelContentStyle.java create mode 100644 src/main/java/com/wms/utils/excel/vo/LocationExcelVo.java create mode 100644 src/main/java/com/wms/utils/excel/vo/StockExcelVo.java create mode 100644 src/main/java/com/wms/utils/excel/vo/TaskRecordExcelVo.java create mode 100644 src/main/java/com/wms/utils/excel/vo/VehicleExcelVo.java create mode 100644 src/main/resources/mapper/InventoryHistoryMapper.xml create mode 100644 src/main/resources/mapper/InventoryListMapper.xml create mode 100644 src/main/resources/mapper/UploadRecordMapper.xml diff --git a/pom.xml b/pom.xml index 128400b..af7ee12 100644 --- a/pom.xml +++ b/pom.xml @@ -109,12 +109,12 @@ org.apache.poi poi-ooxml - 5.2.5 + 5.3.0 org.apache.poi poi - 5.2.3 + 5.3.0 org.projectlombok @@ -173,7 +173,12 @@ org.springframework.boot spring-boot-starter-websocket - + + + com.alibaba + easyexcel + 4.0.1 + diff --git a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java index eaf7fcf..f943505 100644 --- a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java +++ b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java @@ -10,6 +10,7 @@ public enum ConfigMapKeyEnum { START_WORK("START_WORK"), SEND_TASK("SEND_TASK"), MAX_VEHICLE_NUMS("MAX_VEHICLE_NUMS"), + MAX_WCS_ACCEPT_NUMS("MAX_WCS_ACCEPT_NUMS"), SLOC_FILTER_STRING("SLOC_FILTER_STRING"), URL_WCS_CHANGE_TASK("URL_WCS_CHANGE_TASK"); private final String configKey; diff --git a/src/main/java/com/wms/controller/ConfigController.java b/src/main/java/com/wms/controller/ConfigController.java index 8c7ed9d..18a2243 100644 --- a/src/main/java/com/wms/controller/ConfigController.java +++ b/src/main/java/com/wms/controller/ConfigController.java @@ -13,6 +13,7 @@ import com.wms.entity.app.request.ConfigQuery; import com.wms.entity.app.vo.ConfigVo; import com.wms.entity.table.Config; import com.wms.service.ConfigService; +import com.wms.system_service.ISystemService; import com.wms.utils.HttpUtils; import com.wms.utils.StringUtils; import jakarta.servlet.http.HttpServletRequest; @@ -51,6 +52,10 @@ public class ConfigController { * 请求头部信息 */ private final HttpServletRequest servletRequest; + /** + * 系统服务 + */ + private final ISystemService systemService; /** * 查找所有配置 @@ -122,12 +127,24 @@ public class ConfigController { rsp.setMessage("更新系统配置时配置id为必须项"); return JSON.toJSONString(rsp); } + // 更新配置 configService.update(new LambdaUpdateWrapper() .set(StringUtils.isNotEmpty(configQuery.getConfigKey()), Config::getConfigKey, configQuery.getConfigKey()) .set(StringUtils.isNotEmpty(configQuery.getConfigType()), Config::getConfigType, configQuery.getConfigType()) .set(StringUtils.isNotEmpty(configQuery.getConfigValue()), Config::getConfigValue, configQuery.getConfigValue()) .set(StringUtils.isNotEmpty(configQuery.getConfigName()), Config::getConfigName, configQuery.getConfigName()) .eq(Config::getConfigId, configQuery.getConfigId())); + // 更新Map + try { + systemService.reloadConfig(); + // 返回成功 + rsp.setCode(ResponseCode.OK.getCode()); + rsp.setMessage("更新系统配置成功!"); + } catch (Exception e) { + // 返回成功 + rsp.setCode(ResponseCode.OK.getCode()); + rsp.setMessage("重载系统配置错误,请手动重载配置。"); + } // 返回成功 rsp.setCode(ResponseCode.OK.getCode()); rsp.setMessage("更新系统配置成功!"); diff --git a/src/main/java/com/wms/controller/ExcelController.java b/src/main/java/com/wms/controller/ExcelController.java index 37d4977..773e00f 100644 --- a/src/main/java/com/wms/controller/ExcelController.java +++ b/src/main/java/com/wms/controller/ExcelController.java @@ -1,23 +1,25 @@ package com.wms.controller; -import cn.hutool.core.bean.BeanUtil; -import com.alibaba.fastjson2.JSON; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.wms.constants.enums.*; import com.wms.entity.app.ResponseEntity; -import com.wms.entity.app.dto.LocationDto; -import com.wms.entity.app.dto.StockDto; -import com.wms.entity.app.dto.TaskRecordDto; -import com.wms.entity.app.dto.VehicleDto; import com.wms.entity.app.request.LocationQuery; import com.wms.entity.app.request.StockQuery; import com.wms.entity.app.request.TaskRecordQuery; import com.wms.entity.app.request.VehicleQuery; -import com.wms.entity.table.Location; -import com.wms.entity.table.Vehicle; +import com.wms.entity.app.vo.FileVo; +import com.wms.entity.table.*; import com.wms.service.*; import com.wms.utils.StringUtils; -import com.wms.utils.excel.ExcelUtils; +import com.wms.utils.excel.listener.UploadStocksListener; +import com.wms.utils.excel.style.ExcelContentStyle; +import com.wms.utils.excel.vo.LocationExcelVo; +import com.wms.utils.excel.vo.StockExcelVo; +import com.wms.utils.excel.vo.TaskRecordExcelVo; +import com.wms.utils.excel.vo.VehicleExcelVo; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -32,11 +34,14 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import java.util.Collections; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.List; import static com.wms.utils.HttpUtils.getIpAddr; import static com.wms.utils.StringUtils.convertJsonString; +import static com.wms.utils.WmsUtils.generateId; /** * @@ -52,6 +57,7 @@ public class ExcelController { private final TaskRecordService taskRecordService;// 任务记录服务 private final VehicleService vehicleService;// 载具服务 private final LocationService locationService;// 库位服务 + private final UploadRecordService uploadRecordService;// 上传服务 /** * 导入库存信息 @@ -62,22 +68,27 @@ public class ExcelController { @PostMapping("/uploadStocks") @ResponseBody @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) - public String uploadStocks(@RequestPart("file") MultipartFile file) { + public String uploadStocks(@RequestPart("file") MultipartFile file, @RequestPart("obj") FileVo fileVo) { logger.info("导入库存,请求ip:{}", getIpAddr(servletRequest)); ResponseEntity response = new ResponseEntity(); try { - List stocksDto = ExcelUtils.readMultipartFile(file, StockDto.class); + // 导入excel + EasyExcel.read(file.getInputStream(), StockExcelVo.class, new UploadStocksListener(stockService)).sheet().doRead(); + // 添加导入记录 + UploadRecord uploadRecord = new UploadRecord(); + uploadRecord.setUploadId(generateId("UPLOAD_")); + uploadRecord.set + uploadRecordService.save(uploadRecord); response.setCode(ResponseCode.OK.getCode()); - response.setMessage("导入库存成功"); - response.setReturnData(file); + response.setMessage("导入库存成功。"); } catch (Exception e) { - convertJsonString(e); + logger.error("导入库存异常:{}", convertJsonString(e)); // 回滚事务 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage(e.getMessage()); + response.setMessage("导入库存异常。"); } - return JSON.toJSONString(response); + return convertJsonString(response); } /** @@ -85,12 +96,31 @@ public class ExcelController { * * @param response 请求 */ - @GetMapping("/downloadStockExcel") + @PostMapping("/downloadStockExcel") @ResponseBody - public void downloadStockExcel(@RequestParam("stockQuery") StockQuery query, HttpServletResponse response) { - logger.info("导出库存记录,请求ip:{}", getIpAddr(servletRequest)); - List stocks = stockService.selectStocks(query.toStockPO()); - ExcelUtils.export(response, "库存报表", stocks, StockDto.class); + public void downloadStockExcel(@RequestBody StockQuery stockQuery, HttpServletResponse response) throws IOException { + logger.info("导出库存记录,筛选参数:{},请求ip:{}", convertJsonString(stockQuery), getIpAddr(servletRequest)); + //设置响应格式 +// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName = URLEncoder.encode("库存报表", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + // 内容样式 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); + // 查询参数 + List stockPoList = stockService.list(new LambdaQueryWrapper() + .like(StringUtils.isNotEmpty(stockQuery.getVehicleId()), Stock::getVehicleId, stockQuery.getVehicleId()) + .eq(StringUtils.isNotEmpty(stockQuery.getLocationId()), Stock::getLocationId, stockQuery.getLocationId()) + .eq(stockQuery.getStockStatus() != null, Stock::getStockStatus, stockQuery.getStockStatus()) + .apply(StringUtils.isNotEmpty(stockQuery.getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')", stockQuery.getGoodsId()) + .apply(StringUtils.isNotEmpty(stockQuery.getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", stockQuery.getGoodsName())); + EasyExcel.write(response.getOutputStream(), StockExcelVo.class) + .excelType(ExcelTypeEnum.XLSX) + .registerWriteHandler(horizontalCellStyleStrategy) + .sheet("库存") + .doWrite(stockPoList.stream().map(StockExcelVo::of).toList()); } /** @@ -98,12 +128,25 @@ public class ExcelController { * * @param response 请求 */ - @GetMapping("/downloadInRecordExcel") + @PostMapping("/downloadInRecordExcel") @ResponseBody - public void downloadInRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) { - logger.info("导出入库记录,请求ip:{}", getIpAddr(servletRequest)); - List inRecord = taskRecordService.selectInTaskRecord(query.toTaskRecordPO()); - ExcelUtils.export(response, "入库记录报表", inRecord, TaskRecordDto.class); + public void downloadInRecordExcel(@RequestBody TaskRecordQuery query, HttpServletResponse response) throws IOException { + logger.info("导出入库记录,筛选参数:{},请求ip:{}", convertJsonString(query), getIpAddr(servletRequest)); + //设置响应格式 + response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName = URLEncoder.encode("入库记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + // 内容样式 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); + // 查询参数 + List inRecord = taskRecordService.selectInTaskRecord(query.toTaskRecordPO()); + EasyExcel.write(response.getOutputStream(), TaskRecordExcelVo.class) + .excelType(ExcelTypeEnum.XLSX) + .registerWriteHandler(horizontalCellStyleStrategy) + .sheet("入库记录") + .doWrite(inRecord.stream().map(TaskRecordExcelVo::of).toList()); } /** @@ -111,12 +154,25 @@ public class ExcelController { * * @param response 请求 */ - @GetMapping("/downloadOutRecordExcel") + @PostMapping("/downloadOutRecordExcel") @ResponseBody - public void downloadOutRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) { - logger.info("导出出库记录,请求ip:{}", getIpAddr(servletRequest)); - List outRecord = taskRecordService.selectOutTaskRecord(query.toTaskRecordPO()); - ExcelUtils.export(response, "出库记录报表", outRecord, TaskRecordDto.class); + public void downloadOutRecordExcel(@RequestBody TaskRecordQuery query, HttpServletResponse response) throws IOException { + logger.info("导出出库记录,筛选参数:{},请求ip:{}", convertJsonString(query), getIpAddr(servletRequest)); + //设置响应格式 + response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName = URLEncoder.encode("出库记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + // 内容样式 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); + // 查询参数 + List inRecord = taskRecordService.selectOutTaskRecord(query.toTaskRecordPO()); + EasyExcel.write(response.getOutputStream(), TaskRecordExcelVo.class) + .excelType(ExcelTypeEnum.XLSX) + .registerWriteHandler(horizontalCellStyleStrategy) + .sheet("出库记录") + .doWrite(inRecord.stream().map(TaskRecordExcelVo::of).toList()); } /** @@ -124,12 +180,25 @@ public class ExcelController { * * @param response 请求 */ - @GetMapping("/downloadInventoryRecordExcel") + @PostMapping("/downloadInventoryRecordExcel") @ResponseBody - public void downloadInventoryRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) { - logger.info("导出盘点记录,请求ip:{}", getIpAddr(servletRequest)); - List inventoryRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO()); - ExcelUtils.export(response, "盘点记录报表", inventoryRecord, TaskRecordDto.class); + public void downloadInventoryRecordExcel(@RequestBody TaskRecordQuery query, HttpServletResponse response) throws IOException { + logger.info("导出盘点记录,筛选参数:{},请求ip:{}", convertJsonString(query), getIpAddr(servletRequest)); + //设置响应格式 + response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName = URLEncoder.encode("盘点记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + // 内容样式 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); + // 查询参数 + List inRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO()); + EasyExcel.write(response.getOutputStream(), TaskRecordExcelVo.class) + .excelType(ExcelTypeEnum.XLSX) + .registerWriteHandler(horizontalCellStyleStrategy) + .sheet("盘点记录") + .doWrite(inRecord.stream().map(TaskRecordExcelVo::of).toList()); } /** @@ -137,20 +206,29 @@ public class ExcelController { * * @param response 请求 */ - @GetMapping("/downloadVehicleExcel") + @PostMapping("/downloadVehicleExcel") @ResponseBody - public void downloadVehicleExcel(@RequestParam("vehicleQuery") VehicleQuery vehicleQuery, HttpServletResponse response) { - logger.info("导出载具记录,查询参数:{},请求ip:{}", convertJsonString(vehicleQuery), getIpAddr(servletRequest)); + public void downloadVehicleExcel(@RequestBody VehicleQuery vehicleQuery, HttpServletResponse response) throws IOException { + logger.info("导出料箱报表,筛选参数:{},请求ip:{}", convertJsonString(vehicleQuery), getIpAddr(servletRequest)); + //设置响应格式 + response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName = URLEncoder.encode("盘点记录", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + // 内容样式 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); + // 查询参数 List vehicles = vehicleService.list(new LambdaQueryWrapper() .like(StringUtils.isNotEmpty(vehicleQuery.getVehicleId()), Vehicle::getVehicleId, vehicleQuery.getVehicleId()) .like(StringUtils.isNotEmpty(vehicleQuery.getCurrentLocation()), Vehicle::getCurrentLocation, vehicleQuery.getCurrentLocation()) .eq(vehicleQuery.getIsEmpty() != null, Vehicle::getIsEmpty, vehicleQuery.getIsEmpty()) .eq(vehicleQuery.getVehicleStatus() != null, Vehicle::getVehicleStatus, vehicleQuery.getVehicleStatus())); - if (vehicles == null || vehicles.isEmpty()) { - ExcelUtils.export(response, "载具报表", Collections.emptyList(), VehicleDto.class); - } else { - ExcelUtils.export(response, "载具报表", BeanUtil.copyToList(vehicles, VehicleDto.class), VehicleDto.class); - } + EasyExcel.write(response.getOutputStream(), VehicleExcelVo.class) + .excelType(ExcelTypeEnum.XLSX) + .registerWriteHandler(horizontalCellStyleStrategy) + .sheet("料箱报表") + .doWrite(vehicles.stream().map(VehicleExcelVo::of).toList()); } /** @@ -158,19 +236,28 @@ public class ExcelController { * * @param response 请求 */ - @GetMapping("/downloadLocationsExcel") + @PostMapping("/downloadLocationsExcel") @ResponseBody - public void downloadLocationsExcel(@RequestParam("locationQuery") LocationQuery locationQuery, HttpServletResponse response) { - logger.info("导出库位详情,查询参数:{},请求ip:{}", convertJsonString(locationQuery), getIpAddr(servletRequest)); + public void downloadLocationsExcel(@RequestBody LocationQuery locationQuery, HttpServletResponse response) throws IOException { + logger.info("导出库位报表,筛选参数:{},请求ip:{}", convertJsonString(locationQuery), getIpAddr(servletRequest)); + //设置响应格式 + response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName = URLEncoder.encode("库位报表", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + // 内容样式 + HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); + // 查询参数 List locations = locationService.list(new LambdaQueryWrapper() .like(StringUtils.isNotEmpty(locationQuery.getLocationId()), Location::getLocationId, locationQuery.getLocationId()) .eq(locationQuery.getAreaId() != null, Location::getAreaId, locationQuery.getAreaId()) .eq(locationQuery.getIsLock() != null, Location::getIsLock, locationQuery.getIsLock()) .eq(locationQuery.getLocationStatus() != null, Location::getLocationStatus, locationQuery.getLocationStatus())); - if (locations == null || locations.isEmpty()) { - ExcelUtils.export(response, "库位报表", Collections.emptyList(), LocationDto.class); - } else { - ExcelUtils.export(response, "库位报表", BeanUtil.copyToList(locations, LocationDto.class), LocationDto.class); - } + EasyExcel.write(response.getOutputStream(), LocationExcelVo.class) + .excelType(ExcelTypeEnum.XLSX) + .registerWriteHandler(horizontalCellStyleStrategy) + .sheet("库位报表") + .doWrite(locations.stream().map(LocationExcelVo::of).toList()); } } \ No newline at end of file diff --git a/src/main/java/com/wms/controller/JobComponent.java b/src/main/java/com/wms/controller/JobComponent.java index 514c94a..f32c1ca 100644 --- a/src/main/java/com/wms/controller/JobComponent.java +++ b/src/main/java/com/wms/controller/JobComponent.java @@ -50,12 +50,11 @@ public class JobComponent { * 每2秒执行一次 */ @Async -// @Scheduled(fixedDelay = 2000) + @Scheduled(fixedDelay = 2000) @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void executeTasks() { String sendTask = configMap.get(ConfigMapKeyEnum.SEND_TASK.getConfigKey()); if (StringUtils.isEmpty(sendTask) || !sendTask.equals("1")) { - logger.info("暂停发送任务,跳过..."); return; } try { @@ -85,12 +84,11 @@ public class JobComponent { * 检测工作 */ @Async -// @Scheduled(fixedDelay = 2000) + @Scheduled(fixedDelay = 2000) @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void detectWork() { String startWork = configMap.get(ConfigMapKeyEnum.START_WORK.getConfigKey()); if (StringUtils.isEmpty(startWork) || !startWork.equals("1")) { - logger.info("未开始工作,跳过..."); return; } // 轮询工作站台,判断是否需要下发任务 @@ -117,7 +115,6 @@ public class JobComponent { } } -// // /** // * 每天查询一次是否有入库后长期未使用的库存 // * 每天晚上9点执行一次 diff --git a/src/main/java/com/wms/controller/TaskController.java b/src/main/java/com/wms/controller/TaskController.java index 903e27f..0c4a7b4 100644 --- a/src/main/java/com/wms/controller/TaskController.java +++ b/src/main/java/com/wms/controller/TaskController.java @@ -157,7 +157,8 @@ public class TaskController { Task sameVehicleTempTask = taskService.getOne(new LambdaQueryWrapper() .eq(Task::getVehicleId, taskInRequest.getVehicleId()) .eq(Task::getTaskStatus, WmsTaskStatus.TEMP.getCode()) - .eq(Task::getTaskType, TaskType.IN.getCode())); + .eq(Task::getTaskType, TaskType.IN.getCode()) + .last("limit 1")); // 生成入库任务 String saveTaskResult; if (sameVehicleTempTask != null) {// 有相同的箱子任务 @@ -301,7 +302,8 @@ public class TaskController { // TODO 查询条件根据项目要求调整 Stock existStock = stockService.getOne(new LambdaQueryWrapper() .apply("goods_related -> '$.goodsId' = {0}", inTask.getGoodsRelated().getGoodsId()) - .eq(Stock::getVehicleId, inTask.getVehicleId())); + .eq(Stock::getVehicleId, inTask.getVehicleId()) + .last("limit 1")); if (existStock != null) { // 已有库存,直接更新数量 existStock.getGoodsRelated().setRemainNum(existStock.getGoodsRelated().getRemainNum().add(inTask.getGoodsRelated().getOpNum())); @@ -859,7 +861,8 @@ public class TaskController { } // 查一下物料信息 Goods goodsInfo = goodsService.getOne(new LambdaQueryWrapper() - .eq(Goods::getGoodsId, workQuery.getGoodsId())); + .eq(Goods::getGoodsId, workQuery.getGoodsId()) + .last("limit 1")); // 查找工作流 List workFlows = workFlowService.list(new LambdaQueryWrapper() .eq(WorkFlow::getWorkStation, standId) @@ -1721,7 +1724,8 @@ public class TaskController { .eq(StringUtils.isNotEmpty(callEmptyVehicleRequest.getVehicleType1()), Vehicle::getVehicleType, callEmptyVehicleRequest.getVehicleType1()) .eq(Vehicle::getIsEmpty, 1) .eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode()) - .orderByAsc(Vehicle::getLastInTime)); + .orderByAsc(Vehicle::getLastInTime) + .last("limit 1")); if (emptyVehicle != null) {// 有可用的空箱 // 创建一个空箱出库任务 Task emptyVehicleTask = new Task(); diff --git a/src/main/java/com/wms/entity/app/dto/StockDto.java b/src/main/java/com/wms/entity/app/dto/StockDto.java index b7dfaf6..9e9bbb3 100644 --- a/src/main/java/com/wms/entity/app/dto/StockDto.java +++ b/src/main/java/com/wms/entity/app/dto/StockDto.java @@ -1,10 +1,7 @@ package com.wms.entity.app.dto; -import com.fasterxml.jackson.annotation.JsonFormat; import com.wms.entity.app.dto.extend.StockDetailInfo; -import com.wms.utils.excel.ExcelExport; import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDateTime; diff --git a/src/main/java/com/wms/entity/app/request/UploadRecordQuery.java b/src/main/java/com/wms/entity/app/request/UploadRecordQuery.java new file mode 100644 index 0000000..bc20aeb --- /dev/null +++ b/src/main/java/com/wms/entity/app/request/UploadRecordQuery.java @@ -0,0 +1,59 @@ +package com.wms.entity.app.request; + +import cn.hutool.core.bean.BeanUtil; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wms.entity.table.UploadRecord; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +/** + * 上传记录查询 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class UploadRecordQuery extends PageQuery { + /** + * 上传id + */ + @JsonProperty("upload_id") + private String uploadId; + /** + * 文件id + */ + @JsonProperty("file_id") + private String fileId; + /** + * 文件名 + */ + @JsonProperty("file_name") + private String fileName; + /** + * 文件类型 + */ + @JsonProperty("file_type") + private String fileType; + /** + * 上传时间 + */ + @JsonProperty("uploadTime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uploadTime; + /** + * 上传人员 + */ + @JsonProperty("uploadUser") + private String uploadUser; + + /** + * 将UploadRecordQuery转化为UploadRecordPo + * @return UploadRecordPo结果 + */ + public UploadRecord toUploadRecordPO() { + return BeanUtil.copyProperties(this, UploadRecord.class); + } +} diff --git a/src/main/java/com/wms/entity/app/vo/FileVo.java b/src/main/java/com/wms/entity/app/vo/FileVo.java new file mode 100644 index 0000000..a2405f4 --- /dev/null +++ b/src/main/java/com/wms/entity/app/vo/FileVo.java @@ -0,0 +1,21 @@ +package com.wms.entity.app.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * 文件Vo + */ +@Data +public class FileVo { + @JsonProperty("fileId") + private String fileId; + @JsonProperty("name") + private String name; + @JsonProperty("type") + private String type; + @JsonProperty("size") + private String size; + @JsonProperty("userName") + private String userName; +} diff --git a/src/main/java/com/wms/entity/app/vo/StockVo.java b/src/main/java/com/wms/entity/app/vo/StockVo.java index 3789d88..54aab96 100644 --- a/src/main/java/com/wms/entity/app/vo/StockVo.java +++ b/src/main/java/com/wms/entity/app/vo/StockVo.java @@ -1,14 +1,127 @@ package com.wms.entity.app.vo; +import com.alibaba.excel.annotation.ExcelProperty; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wms.entity.table.Stock; +import com.wms.utils.excel.vo.StockExcelVo; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; +import java.math.BigDecimal; import java.time.LocalDateTime; @Data public class StockVo { + /** + * 库存编号 + */ + @JsonProperty("stockId") + private String stockId; + /** + * 库位ID + */ + @JsonProperty("locationId") + private String locationId; + /** + * 托盘号 + */ + @JsonProperty("vehicleId") + private String vehicleId; + /** + * 重量 + */ + @JsonProperty("weight") + private BigDecimal weight; + /** + * 库存状态 + * 正常、出库中、锁定 等 + */ + @JsonProperty("stockStatus") + private Integer stockStatus; + /** + * 创建时间 + */ + @JsonProperty("createTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; + /** + * 最后更新时间 + */ + @JsonProperty("lastUpdateTime") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime lastUpdateTime; + /** + * 最后更新用户 + */ + @JsonProperty("lastUpdateUser") + private String lastUpdateUser; + /** + * 是否盘点 + */ + @JsonProperty("isInventory") + private Integer isInventory; + /** + * 盘点任务号 盘点出库和盘点入库同样 + */ + @JsonProperty("inventoryTaskId") + private String inventoryTaskId; + /** + * 呆滞天数 + */ + @JsonProperty("noUseDays") + private Integer noUseDays; + /** + * 物料编号 + */ + @JsonProperty("goodsId") + private String goodsId; + /** + * 物料名称 + */ + @JsonProperty("goodsName") + private String goodsName; + /** + * 物料状态 + */ + @JsonProperty("goodsStatus") + private Integer goodsStatus; + /** + * 剩余数量 + */ + @JsonProperty("remainNum") + private BigDecimal remainNum; + /** + * 入库库存总数 + */ + @JsonProperty("totalNum") + private BigDecimal totalNum; + + /** + * 从数据库实体转换为excel对象 + * @param stockPo 数据库实体 + * @return excel对象 + */ + public static StockExcelVo of(Stock stockPo) { + StockExcelVo stockExcelVo = new StockExcelVo(); + stockExcelVo.setStockId(stockPo.getStockId()); + stockExcelVo.setLocationId(stockPo.getLocationId()); + stockExcelVo.setVehicleId(stockPo.getVehicleId()); + stockExcelVo.setWeight(stockPo.getWeight()); + stockExcelVo.setStockStatus(stockPo.getStockStatus()); + stockExcelVo.setCreateTime(stockPo.getCreateTime()); + stockExcelVo.setLastUpdateTime(stockPo.getLastUpdateTime()); + stockExcelVo.setLastUpdateUser(stockPo.getLastUpdateUser()); + stockExcelVo.setIsInventory(stockPo.getIsInventory()); + stockExcelVo.setInventoryTaskId(stockPo.getInventoryTaskId()); + stockExcelVo.setNoUseDays(stockPo.getNoUseDays()); + stockExcelVo.setGoodsId(stockPo.getGoodsRelated().getGoodsId()); + stockExcelVo.setGoodsName(stockPo.getGoodsRelated().getGoodsName()); + stockExcelVo.setGoodsStatus(stockPo.getGoodsRelated().getGoodsStatus()); + stockExcelVo.setRemainNum(stockPo.getGoodsRelated().getRemainNum()); + stockExcelVo.setTotalNum(stockPo.getGoodsRelated().getTotalNum()); + return stockExcelVo; + } } diff --git a/src/main/java/com/wms/entity/app/vo/UploadRecordVo.java b/src/main/java/com/wms/entity/app/vo/UploadRecordVo.java new file mode 100644 index 0000000..4d58499 --- /dev/null +++ b/src/main/java/com/wms/entity/app/vo/UploadRecordVo.java @@ -0,0 +1,49 @@ +package com.wms.entity.app.vo; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +/** + * 上传记录Vo + */ +@Data +public class UploadRecordVo { + /** + * 上传id + */ + @JsonProperty("upload_id") + private String uploadId; + /** + * 文件id + */ + @JsonProperty("file_id") + private String fileId; + /** + * 文件名 + */ + @JsonProperty("file_name") + private String fileName; + /** + * 文件类型 + */ + @JsonProperty("file_type") + private String fileType; + /** + * 上传时间 + */ + @JsonProperty("uploadTime") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime uploadTime; + /** + * 上传人员 + */ + @JsonProperty("uploadUser") + private String uploadUser; +} diff --git a/src/main/java/com/wms/entity/table/InventoryHistory.java b/src/main/java/com/wms/entity/table/InventoryHistory.java new file mode 100644 index 0000000..878dfaa --- /dev/null +++ b/src/main/java/com/wms/entity/table/InventoryHistory.java @@ -0,0 +1,28 @@ +package com.wms.entity.table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +@TableName(value = "tbl_app_inventory_history", autoResultMap = true) +public class InventoryHistory { + @TableId("inventory_id") + private String inventoryId; + @TableField("goods_id") + private String goodsId; + @TableField("stock_num") + private BigDecimal stockNum; + @TableField("real_num") + private BigDecimal realNum; + @TableField("inventory_status") + private Integer inventoryStatus; + @TableField("inventory_user") + private String inventoryUser; + @TableField("inventory_date") + private LocalDateTime inventoryDate; +} diff --git a/src/main/java/com/wms/entity/table/InventoryList.java b/src/main/java/com/wms/entity/table/InventoryList.java new file mode 100644 index 0000000..694ec9b --- /dev/null +++ b/src/main/java/com/wms/entity/table/InventoryList.java @@ -0,0 +1,57 @@ +package com.wms.entity.table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 盘点清单 + */ +@Data +@TableName(value = "tbl_app_inventory_list", autoResultMap = true) +public class InventoryList { + /** + * 盘点id + */ + @TableId("inventory_id") + private String inventoryId; + /** + * 料号 + */ + @TableField("goods_id") + private String goodsId; + /** + * 库存数量 + */ + @TableField("stock_num") + private BigDecimal stockNum; + /** + * 实际数量 + */ + @TableField("real_num") + private BigDecimal realNum; + /** + * 盘点状态 + */ + @TableField("inventory_status") + private Integer inventoryStatus; + /** + * 盘点用户 + */ + @TableField("inventory_user") + private String inventoryUser; + /** + * 盘点日期 + */ + @TableField("inventory_date") + private LocalDateTime inventoryDate; + /** + * 清单id + */ + @TableField("list_id") + private String listId; +} diff --git a/src/main/java/com/wms/entity/table/UploadRecord.java b/src/main/java/com/wms/entity/table/UploadRecord.java new file mode 100644 index 0000000..a493ad1 --- /dev/null +++ b/src/main/java/com/wms/entity/table/UploadRecord.java @@ -0,0 +1,46 @@ +package com.wms.entity.table; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 上传历史 + */ +@Data +@TableName(value = "tbl_app_upload_record", autoResultMap = true) +public class UploadRecord { + /** + * 上传id + */ + @TableId("upload_id") + private String uploadId; + /** + * 文件id + */ + @TableField("file_id") + private String fileId; + /** + * 文件名 + */ + @TableField("file_name") + private String fileName; + /** + * 文件类型 + */ + @TableField("file_type") + private String fileType; + /** + * 上传时间 + */ + @TableField("upload_time") + private LocalDateTime uploadTime; + /** + * 上传人员 + */ + @TableField("upload_user") + private String uploadUser; +} diff --git a/src/main/java/com/wms/entity/test/ExcelTest.java b/src/main/java/com/wms/entity/test/ExcelTest.java index 03bead4..2ca5c11 100644 --- a/src/main/java/com/wms/entity/test/ExcelTest.java +++ b/src/main/java/com/wms/entity/test/ExcelTest.java @@ -1,14 +1,7 @@ package com.wms.entity.test; -import com.wms.utils.excel.ExcelExport; -import com.wms.utils.excel.ExcelImport; - public class ExcelTest { - @ExcelImport("库位") - @ExcelExport("库位") private String locationId; - @ExcelImport("箱号") - @ExcelExport("箱号") private String vehicleId; public ExcelTest(){}; diff --git a/src/main/java/com/wms/mapper/InventoryHistoryMapper.java b/src/main/java/com/wms/mapper/InventoryHistoryMapper.java new file mode 100644 index 0000000..36d30ec --- /dev/null +++ b/src/main/java/com/wms/mapper/InventoryHistoryMapper.java @@ -0,0 +1,12 @@ +package com.wms.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.wms.entity.table.InventoryHistory; +import org.apache.ibatis.annotations.Mapper; + +/** + * 盘点清单历史记录Mapper + */ +@Mapper +public interface InventoryHistoryMapper extends BaseMapper { +} diff --git a/src/main/java/com/wms/mapper/InventoryListMapper.java b/src/main/java/com/wms/mapper/InventoryListMapper.java new file mode 100644 index 0000000..438444d --- /dev/null +++ b/src/main/java/com/wms/mapper/InventoryListMapper.java @@ -0,0 +1,12 @@ +package com.wms.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.wms.entity.table.InventoryList; +import org.apache.ibatis.annotations.Mapper; + +/** + * 盘点清单Mapper + */ +@Mapper +public interface InventoryListMapper extends BaseMapper { +} diff --git a/src/main/java/com/wms/mapper/UploadRecordMapper.java b/src/main/java/com/wms/mapper/UploadRecordMapper.java new file mode 100644 index 0000000..4bd4e6f --- /dev/null +++ b/src/main/java/com/wms/mapper/UploadRecordMapper.java @@ -0,0 +1,13 @@ +package com.wms.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.wms.entity.table.InventoryList; +import com.wms.entity.table.UploadRecord; +import org.apache.ibatis.annotations.Mapper; + +/** + * 盘点清单Mapper + */ +@Mapper +public interface UploadRecordMapper extends BaseMapper { +} diff --git a/src/main/java/com/wms/service/InventoryHistoryService.java b/src/main/java/com/wms/service/InventoryHistoryService.java new file mode 100644 index 0000000..374c051 --- /dev/null +++ b/src/main/java/com/wms/service/InventoryHistoryService.java @@ -0,0 +1,10 @@ +package com.wms.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.wms.entity.table.InventoryHistory; + +/** + * 盘点记录服务接口 + */ +public interface InventoryHistoryService extends IService { +} diff --git a/src/main/java/com/wms/service/InventoryListService.java b/src/main/java/com/wms/service/InventoryListService.java new file mode 100644 index 0000000..ef145fe --- /dev/null +++ b/src/main/java/com/wms/service/InventoryListService.java @@ -0,0 +1,10 @@ +package com.wms.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.wms.entity.table.InventoryList; + +/** + * 盘点清单服务接口 + */ +public interface InventoryListService extends IService { +} diff --git a/src/main/java/com/wms/service/TaskRecordService.java b/src/main/java/com/wms/service/TaskRecordService.java index 897a26c..833310d 100644 --- a/src/main/java/com/wms/service/TaskRecordService.java +++ b/src/main/java/com/wms/service/TaskRecordService.java @@ -12,24 +12,24 @@ public interface TaskRecordService extends IService { * @param query 查询参数 * @return 查询结果 */ - List selectInTaskRecord(TaskRecord query); + List selectInTaskRecord(TaskRecord query); /** * 查找出库任务记录 * @param query 查询参数 * @return 查询结果 */ - List selectOutTaskRecord(TaskRecord query); + List selectOutTaskRecord(TaskRecord query); /** * 查找盘点任务记录 * @param query 查询参数 * @return 查询结果 */ - List selectInventoryTaskRecord(TaskRecord query); + List selectInventoryTaskRecord(TaskRecord query); /** * 查找任务记录 * @param query 查询参数 * @return 查询结果 */ - List selectTaskRecord(TaskRecord query); + List selectTaskRecord(TaskRecord query); } diff --git a/src/main/java/com/wms/service/UploadRecordService.java b/src/main/java/com/wms/service/UploadRecordService.java new file mode 100644 index 0000000..fdb55ce --- /dev/null +++ b/src/main/java/com/wms/service/UploadRecordService.java @@ -0,0 +1,11 @@ +package com.wms.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.wms.entity.table.InventoryList; +import com.wms.entity.table.UploadRecord; + +/** + * 盘点清单服务接口 + */ +public interface UploadRecordService extends IService { +} diff --git a/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java index 833794e..b157272 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java @@ -7,7 +7,6 @@ import com.wms.constants.enums.*; import com.wms.entity.app.ResponseEntity; import com.wms.entity.app.wcs.WcsStandTaskRequest; import com.wms.entity.app.wcs.WcsTaskRequest; -import com.wms.entity.table.OutsideVehicles; import com.wms.entity.table.PickTask; import com.wms.entity.table.Task; import com.wms.entity.table.WmsLog; @@ -48,14 +47,20 @@ public class WmsJobServiceImplements implements IWmsJobService { public void sendCommonTasks() throws Exception { try { String max_vehicle_nums = configMap.get(ConfigMapKeyEnum.MAX_VEHICLE_NUMS.getConfigKey()); - if (StringUtils.isEmpty(max_vehicle_nums)) { + String max_wcs_accept_nums = configMap.get(ConfigMapKeyEnum.MAX_WCS_ACCEPT_NUMS.getConfigKey()); + if (StringUtils.isEmpty(max_vehicle_nums) || StringUtils.isEmpty(max_wcs_accept_nums)) { logger.error("配置未生成"); return; } int maxVehicleNums = Integer.parseInt(max_vehicle_nums); + int maxWcsAcceptNums = Integer.parseInt(max_wcs_accept_nums); List outsideVehicles = outsideVehiclesService.selectDistinctVehicles(); - if (outsideVehicles == null || outsideVehicles.size() >= maxVehicleNums) { - return; + if (outsideVehicles == null) { + outsideVehicles = Collections.emptyList(); + } else { + if (outsideVehicles.size() >= maxVehicleNums) { + return; + } } int remainVehicleNums = maxVehicleNums - outsideVehicles.size(); @@ -69,7 +74,7 @@ public class WmsJobServiceImplements implements IWmsJobService { List taskGroupIds = new ArrayList<>(); if (!allTasks.isEmpty()) { for (Task task : allTasks) { - if (taskGroupIds.size() >= remainVehicleNums) { + if (taskGroupIds.size() >= remainVehicleNums || taskGroupIds.size() >= maxWcsAcceptNums) { break; } if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 diff --git a/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java index 52a3682..7f71519 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java @@ -253,7 +253,8 @@ public class WmsTaskServiceImplements implements IWmsTaskService { } else if (Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) { // 查询到当前当前载具对应的任务,并同步 Task sameVehicleTask = taskService.getOne(new LambdaQueryWrapper() - .eq(Task::getVehicleId, stock.getVehicleId())); + .eq(Task::getVehicleId, stock.getVehicleId()) + .last("limit 1")); // 创建出库任务 Task vehicleOutTask = new Task(); vehicleOutTask.setTaskId(generateId("CK_")); diff --git a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java index cadb5cd..beba9c9 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java @@ -169,6 +169,7 @@ public class WorkServiceImplements implements IWorkService { workDoingStations.add(workStation); } try { + // TODO 分配任务 // 查找当前站台未开始的工作流 List currentWorkFlowList = workFlowService.list(new LambdaQueryWrapper() .eq(WorkFlow::getWorkStation, workStation) diff --git a/src/main/java/com/wms/service/serviceImplements/InventoryHistoryServiceImpl.java b/src/main/java/com/wms/service/serviceImplements/InventoryHistoryServiceImpl.java new file mode 100644 index 0000000..99ae01f --- /dev/null +++ b/src/main/java/com/wms/service/serviceImplements/InventoryHistoryServiceImpl.java @@ -0,0 +1,17 @@ +package com.wms.service.serviceImplements; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wms.entity.table.InventoryHistory; +import com.wms.mapper.InventoryHistoryMapper; +import com.wms.service.InventoryHistoryService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 盘点记录服务实现 + */ +@Service +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class InventoryHistoryServiceImpl extends ServiceImpl implements InventoryHistoryService { +} diff --git a/src/main/java/com/wms/service/serviceImplements/InventoryListServiceImpl.java b/src/main/java/com/wms/service/serviceImplements/InventoryListServiceImpl.java new file mode 100644 index 0000000..43cbdbc --- /dev/null +++ b/src/main/java/com/wms/service/serviceImplements/InventoryListServiceImpl.java @@ -0,0 +1,17 @@ +package com.wms.service.serviceImplements; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wms.entity.table.InventoryList; +import com.wms.mapper.InventoryListMapper; +import com.wms.service.InventoryListService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 盘点清单服务实现 + */ +@Service +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class InventoryListServiceImpl extends ServiceImpl implements InventoryListService { +} diff --git a/src/main/java/com/wms/service/serviceImplements/TaskRecordServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/TaskRecordServiceImplements.java index 9358a36..d342167 100644 --- a/src/main/java/com/wms/service/serviceImplements/TaskRecordServiceImplements.java +++ b/src/main/java/com/wms/service/serviceImplements/TaskRecordServiceImplements.java @@ -22,25 +22,25 @@ public class TaskRecordServiceImplements extends ServiceImpl selectInTaskRecord(TaskRecord query) { + public List selectInTaskRecord(TaskRecord query) { query.setTaskType(TaskType.IN.getCode());// 设置为入库 return selectTaskRecord(query); } @Override - public List selectOutTaskRecord(TaskRecord query) { + public List selectOutTaskRecord(TaskRecord query) { query.setTaskType(TaskType.OUT.getCode());// 设置为出库 return selectTaskRecord(query); } @Override - public List selectInventoryTaskRecord(TaskRecord query) { + public List selectInventoryTaskRecord(TaskRecord query) { query.setTaskType(TaskType.INVENTORY.getCode());// 设置为盘点 return selectTaskRecord(query); } @Override - public List selectTaskRecord(TaskRecord query) { + public List selectTaskRecord(TaskRecord query) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() .eq(TaskRecord::getTaskType, query.getTaskType()) .like(StringUtils.isNotEmpty(query.getVehicleId()), TaskRecord::getVehicleId, query.getVehicleId()); @@ -51,6 +51,6 @@ public class TaskRecordServiceImplements extends ServiceImpl> '$.goodsName' like concat('%', {0}, '%')", query.getGoodsRelated().getGoodsName()); } - return BeanUtil.copyToList(super.list(queryWrapper), TaskRecordDto.class); + return super.list(queryWrapper); } } diff --git a/src/main/java/com/wms/service/serviceImplements/UploadRecordServiceImpl.java b/src/main/java/com/wms/service/serviceImplements/UploadRecordServiceImpl.java new file mode 100644 index 0000000..2905fd4 --- /dev/null +++ b/src/main/java/com/wms/service/serviceImplements/UploadRecordServiceImpl.java @@ -0,0 +1,20 @@ +package com.wms.service.serviceImplements; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wms.entity.table.InventoryList; +import com.wms.entity.table.UploadRecord; +import com.wms.mapper.InventoryListMapper; +import com.wms.mapper.UploadRecordMapper; +import com.wms.service.InventoryListService; +import com.wms.service.UploadRecordService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 盘点清单服务实现 + */ +@Service +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class UploadRecordServiceImpl extends ServiceImpl implements UploadRecordService { +} diff --git a/src/main/java/com/wms/utils/HttpUtils.java b/src/main/java/com/wms/utils/HttpUtils.java index 99c1d3c..6a8b3af 100644 --- a/src/main/java/com/wms/utils/HttpUtils.java +++ b/src/main/java/com/wms/utils/HttpUtils.java @@ -1,8 +1,6 @@ package com.wms.utils; import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.nio.charset.Charset; import java.util.Base64; import java.util.Map; diff --git a/src/main/java/com/wms/utils/excel/ExcelClassField.java b/src/main/java/com/wms/utils/excel/ExcelClassField.java deleted file mode 100644 index 008be2b..0000000 --- a/src/main/java/com/wms/utils/excel/ExcelClassField.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.wms.utils.excel; - -import java.util.LinkedHashMap; - -public class ExcelClassField { - /** 字段名称 */ - private String fieldName; - - /** 表头名称 */ - private String name; - - /** 映射关系 */ - private LinkedHashMap kvMap; - - /** 示例值 */ - private Object example; - - /** 排序 */ - private int sort; - - /** 是否为注解字段:0-否,1-是 */ - private int hasAnnotation; - - public String getFieldName() { - return fieldName; - } - - public void setFieldName(String fieldName) { - this.fieldName = fieldName; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public LinkedHashMap getKvMap() { - return kvMap; - } - - public void setKvMap(LinkedHashMap kvMap) { - this.kvMap = kvMap; - } - - public Object getExample() { - return example; - } - - public void setExample(Object example) { - this.example = example; - } - - public int getSort() { - return sort; - } - - public void setSort(int sort) { - this.sort = sort; - } - - public int getHasAnnotation() { - return hasAnnotation; - } - - public void setHasAnnotation(int hasAnnotation) { - this.hasAnnotation = hasAnnotation; - } -} diff --git a/src/main/java/com/wms/utils/excel/ExcelExport.java b/src/main/java/com/wms/utils/excel/ExcelExport.java deleted file mode 100644 index 431d99e..0000000 --- a/src/main/java/com/wms/utils/excel/ExcelExport.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.wms.utils.excel; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface ExcelExport { - /** 字段名称 */ - String value(); - - /** 导出排序先后: 数字越小越靠前(默认按Java类字段顺序导出) */ - int sort() default 0; - - /** 导出映射,格式如:0-未知;1-男;2-女 */ - String kv() default ""; - - /** 导出模板示例值(有值的话,直接取该值,不做映射) */ - String example() default ""; -} diff --git a/src/main/java/com/wms/utils/excel/ExcelImport.java b/src/main/java/com/wms/utils/excel/ExcelImport.java deleted file mode 100644 index 58c7b52..0000000 --- a/src/main/java/com/wms/utils/excel/ExcelImport.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.wms.utils.excel; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface ExcelImport { - /** 字段名称 */ - String value(); - - /** 导出映射,格式如:0-未知;1-男;2-女 */ - String kv() default ""; - - /** 是否为必填字段(默认为非必填) */ - boolean required() default false; - - /** 最大长度(默认255) */ - int maxLength() default 255; - - /** 导入唯一性验证(多个字段则取联合验证) */ - boolean unique() default false; -} diff --git a/src/main/java/com/wms/utils/excel/ExcelUtils.java b/src/main/java/com/wms/utils/excel/ExcelUtils.java deleted file mode 100644 index 28c81d1..0000000 --- a/src/main/java/com/wms/utils/excel/ExcelUtils.java +++ /dev/null @@ -1,1026 +0,0 @@ -package com.wms.utils.excel; - - -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; -import jakarta.servlet.ServletOutputStream; -import jakarta.servlet.http.HttpServletResponse; -import org.apache.poi.hssf.usermodel.HSSFDataFormatter; -import org.apache.poi.hssf.usermodel.HSSFDataValidation; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.*; -import org.springframework.web.multipart.MultipartFile; -import org.apache.poi.ss.usermodel.DateUtil; - -import java.io.*; -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.net.URL; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.*; - -/** - * Excel工具类 - */ -@SuppressWarnings("unused") -public class ExcelUtils { - private static final String XLSX = ".xlsx"; - private static final String XLS = ".xls"; - public static final String ROW_MERGE = "row_merge"; - public static final String COLUMN_MERGE = "column_merge"; - private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; - private static final String ROW_NUM = "rowNum"; - private static final String ROW_DATA = "rowData"; - private static final String ROW_TIPS = "rowTips"; - private static final int CELL_OTHER = 0; - private static final int CELL_ROW_MERGE = 1; - private static final int CELL_COLUMN_MERGE = 2; - private static final int IMG_HEIGHT = 30; - private static final int IMG_WIDTH = 30; - private static final char LEAN_LINE = '/'; - private static final int BYTES_DEFAULT_LENGTH = 10240; - private static final NumberFormat NUMBER_FORMAT = NumberFormat.getNumberInstance(); - - public static List readFile(File file, Class clazz) throws Exception { - JSONArray array = readFile(file); - return getBeanList(array, clazz); - } - - public static List readMultipartFile(MultipartFile mFile, Class clazz) throws Exception { - JSONArray array = readMultipartFile(mFile); - return getBeanList(array, clazz); - } - public static JSONArray readFile(File file) throws Exception { - return readExcel(null, file); - } - - public static JSONArray readMultipartFile(MultipartFile mFile) throws Exception { - return readExcel(mFile, null); - } - - public static Map readFileManySheet(File file) throws Exception { - return readExcelManySheet(null, file); - } - - public static Map readFileManySheet(MultipartFile file) throws Exception { - return readExcelManySheet(file, null); - } - - private static List getBeanList(JSONArray array, Class clazz) throws Exception { - List list = new ArrayList<>(); - Map uniqueMap = new HashMap<>(16); - for (int i = 0; i < array.size(); i++) { - list.add(getBean(clazz, array.getJSONObject(i), uniqueMap)); - } - return list; - } - - - /** - * 获取每个对象的数据 - */ - private static T getBean(Class c, JSONObject obj, Map uniqueMap) throws Exception { - T t = c.getDeclaredConstructor().newInstance(); - Field[] fields = c.getDeclaredFields(); - List errMsgList = new ArrayList<>(); - boolean hasRowTipsField = false; - StringBuilder uniqueBuilder = new StringBuilder(); - int rowNum = 0; - for (Field field : fields) { - // 行号 - if (field.getName().equals(ROW_NUM)) { - rowNum = obj.getInteger(ROW_NUM); - field.setAccessible(true); - field.set(t, rowNum); - continue; - } - // 是否需要设置异常信息 - if (field.getName().equals(ROW_TIPS)) { - hasRowTipsField = true; - continue; - } - // 原始数据 - if (field.getName().equals(ROW_DATA)) { - field.setAccessible(true); - field.set(t, obj.toString()); - continue; - } - // 设置对应属性值 - setFieldValue(t, field, obj, uniqueBuilder, errMsgList); - } - // 数据唯一性校验 - if (uniqueBuilder.length() > 0) { - if (uniqueMap.containsValue(uniqueBuilder.toString())) { - Set rowNumKeys = uniqueMap.keySet(); - for (Integer num : rowNumKeys) { - if (uniqueMap.get(num).equals(uniqueBuilder.toString())) { - errMsgList.add(String.format("数据唯一性校验失败,(%s)与第%s行重复)", uniqueBuilder, num)); - } - } - } else { - uniqueMap.put(rowNum, uniqueBuilder.toString()); - } - } - // 失败处理 - if (errMsgList.isEmpty() && !hasRowTipsField) { - return t; - } - StringBuilder sb = new StringBuilder(); - int size = errMsgList.size(); - for (int i = 0; i < size; i++) { - if (i == size - 1) { - sb.append(errMsgList.get(i)); - } else { - sb.append(errMsgList.get(i)).append(";"); - } - } - // 设置错误信息 - for (Field field : fields) { - if (field.getName().equals(ROW_TIPS)) { - field.setAccessible(true); - field.set(t, sb.toString()); - } - } - return t; - } - - private static void setFieldValue(T t, Field field, JSONObject obj, StringBuilder uniqueBuilder, List errMsgList) { - // 获取 ExcelImport 注解属性 - ExcelImport annotation = field.getAnnotation(ExcelImport.class); - if (annotation == null) { - return; - } - String cname = annotation.value(); - if (cname.trim().length() == 0) { - return; - } - // 获取具体值 - String val = null; - if (obj.containsKey(cname)) { - val = getString(obj.getString(cname)); - } - if (val == null) { - return; - } - field.setAccessible(true); - // 判断是否必填 - boolean require = annotation.required(); - if (require && val.isEmpty()) { - errMsgList.add(String.format("[%s]不能为空", cname)); - return; - } - // 数据唯一性获取 - boolean unique = annotation.unique(); - if (unique) { - if (uniqueBuilder.length() > 0) { - uniqueBuilder.append("--").append(val); - } else { - uniqueBuilder.append(val); - } - } - // 判断是否超过最大长度 - int maxLength = annotation.maxLength(); - if (maxLength > 0 && val.length() > maxLength) { - errMsgList.add(String.format("[%s]长度不能超过%s个字符(当前%s个字符)", cname, maxLength, val.length())); - } - // 判断当前属性是否有映射关系 - LinkedHashMap kvMap = getKvMap(annotation.kv()); - if (!kvMap.isEmpty()) { - boolean isMatch = false; - for (String key : kvMap.keySet()) { - if (kvMap.get(key).equals(val)) { - val = key; - isMatch = true; - break; - } - } - if (!isMatch) { - errMsgList.add(String.format("[%s]的值不正确(当前值为%s)", cname, val)); - return; - } - } - // 其余情况根据类型赋值 - String fieldClassName = field.getType().getSimpleName(); - try { - if ("String".equalsIgnoreCase(fieldClassName)) { - field.set(t, val); - } else if ("boolean".equalsIgnoreCase(fieldClassName)) { - field.set(t, Boolean.valueOf(val)); - } else if ("int".equalsIgnoreCase(fieldClassName) || "Integer".equals(fieldClassName)) { - try { - field.set(t, Integer.valueOf(val)); - } catch (NumberFormatException e) { - errMsgList.add(String.format("[%s]的值格式不正确(当前值为%s)", cname, val)); - } - } else if ("double".equalsIgnoreCase(fieldClassName)) { - field.set(t, Double.valueOf(val)); - } else if ("long".equalsIgnoreCase(fieldClassName)) { - field.set(t, Long.valueOf(val)); - } else if ("BigDecimal".equalsIgnoreCase(fieldClassName)) { - field.set(t, new BigDecimal(val)); - } else if ("Date".equalsIgnoreCase(fieldClassName)) { - try { - field.set(t, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(val)); - } catch (Exception e) { - field.set(t, new SimpleDateFormat("yyyy-MM-dd").parse(val)); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static Map readExcelManySheet(MultipartFile mFile, File file) throws IOException { - Workbook book = getWorkbook(mFile, file); - if (book == null) { - return Collections.emptyMap(); - } - Map map = new LinkedHashMap<>(); - for (int i = 0; i < book.getNumberOfSheets(); i++) { - Sheet sheet = book.getSheetAt(i); - JSONArray arr = readSheet(sheet); - map.put(sheet.getSheetName(), arr); - } - book.close(); - return map; - } - - private static JSONArray readExcel(MultipartFile mFile, File file) throws IOException { - Workbook book = getWorkbook(mFile, file); - if (book == null) { - return new JSONArray(); - } - JSONArray array = readSheet(book.getSheetAt(0)); - book.close(); - return array; - } - - private static Workbook getWorkbook(MultipartFile mFile, File file) throws IOException { - boolean fileNotExist = (file == null || !file.exists()); - if (mFile == null && fileNotExist) { - return null; - } - // 解析表格数据 - InputStream in; - String fileName; - if (mFile != null) { - // 上传文件解析 - in = mFile.getInputStream(); - fileName = getString(mFile.getOriginalFilename()).toLowerCase(); - } else { - // 本地文件解析 - in = new FileInputStream(file); - fileName = file.getName().toLowerCase(); - } - Workbook book; - if (fileName.endsWith(XLSX)) { - book = new XSSFWorkbook(in); - } else if (fileName.endsWith(XLS)) { - POIFSFileSystem poifsFileSystem = new POIFSFileSystem(in); - book = new HSSFWorkbook(poifsFileSystem); - } else { - return null; - } - in.close(); - return book; - } - - private static JSONArray readSheet(Sheet sheet) { - // 首行下标 - int rowStart = sheet.getFirstRowNum(); - // 尾行下标 - int rowEnd = sheet.getLastRowNum(); - // 获取表头行 - Row headRow = sheet.getRow(rowStart); - if (headRow == null) { - return new JSONArray(); - } - int cellStart = headRow.getFirstCellNum(); - int cellEnd = headRow.getLastCellNum(); - Map keyMap = new HashMap<>(); - for (int j = cellStart; j < cellEnd; j++) { - // 获取表头数据 - String val = getCellValue(headRow.getCell(j)); - if (val != null && val.trim().length() != 0) { - keyMap.put(j, val); - } - } - // 如果表头没有数据则不进行解析 - if (keyMap.isEmpty()) { - return (JSONArray) Collections.emptyList(); - } - // 获取每行JSON对象的值 - JSONArray array = new JSONArray(); - // 如果首行与尾行相同,表明只有一行,返回表头数据 - if (rowStart == rowEnd) { - JSONObject obj = new JSONObject(); - // 添加行号 - obj.put(ROW_NUM, 1); - for (int i : keyMap.keySet()) { - obj.put(keyMap.get(i), ""); - } - array.add(obj); - return array; - } - for (int i = rowStart + 1; i <= rowEnd; i++) { - Row eachRow = sheet.getRow(i); - JSONObject obj = new JSONObject(); - // 添加行号 - obj.put(ROW_NUM, i + 1); - StringBuilder sb = new StringBuilder(); - for (int k = cellStart; k < cellEnd; k++) { - if (eachRow != null) { - String val = getCellValue(eachRow.getCell(k)); - // 所有数据添加到里面,用于判断该行是否为空 - sb.append(val); - obj.put(keyMap.get(k), val); - } - } - if (sb.length() > 0) { - array.add(obj); - } - } - return array; - } - - private static String getCellValue(Cell cell) { - // 空白或空 - if (cell == null || cell.getCellType() == CellType.BLANK) { - return ""; - } - // String类型 - if (cell.getCellType() == CellType.STRING) { - String val = cell.getStringCellValue(); - if (val == null || val.trim().length() == 0) { - return ""; - } - return val.trim(); - } - // 数字类型 - if (cell.getCellType() == CellType.NUMERIC) { - if (DateUtil.isCellDateFormatted(cell)) {// 日期类型 - // 短日期转化为字符串 - Date date = cell.getDateCellValue(); - if (date != null) { - // 标准0点 1970/01/01 08:00:00 - if (date.getTime() % 86400000 == 16 * 3600 * 1000 && cell.getCellStyle().getDataFormat() == 14) { - return new SimpleDateFormat("yyyy-MM-dd").format(date); - } else { - return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); - } - } - } else {// 数值 - //System.out.println("Value:"+cell.getNumericCellValue()); - String numberStr = new HSSFDataFormatter().formatCellValue(cell); - // 货币格式,如:1,200.00 - if (numberStr.contains(",")) { - numberStr = numberStr.replace(",", ""); - } - if (numberStr.contains("E")) { // 科学计算法 - numberStr = new DecimalFormat("0").format(cell.getNumericCellValue()); //4.89481368464913E14还原为长整数 - return numberStr; - } else { - if (numberStr.contains(".")) { // 小数 - return numberStr; - } else { // 转换为整数 - return numberStr; - } - } - } -// String s = cell.getNumericCellValue() + ""; -// // 去掉尾巴上的小数点0 -// if (Pattern.matches(".*\\.0*", s)) { -// return s.split("\\.")[0]; -// } else { -// return s; -// } - } - // 布尔值类型 - if (cell.getCellType() == CellType.BOOLEAN) { - return String.valueOf(cell.getBooleanCellValue()); - } - // 错误类型 - return cell.getCellFormula(); - } - - public static void exportTemplate(HttpServletResponse response, String fileName, Class clazz) { - exportTemplate(response, fileName, fileName, clazz, false); - } - - public static void exportTemplate(HttpServletResponse response, String fileName, String sheetName, - Class clazz) { - exportTemplate(response, fileName, sheetName, clazz, false); - } - - public static void exportTemplate(HttpServletResponse response, String fileName, Class clazz, - boolean isContainExample) { - exportTemplate(response, fileName, fileName, clazz, isContainExample); - } - - public static void exportTemplate(HttpServletResponse response, String fileName, String sheetName, - Class clazz, boolean isContainExample) { - // 获取表头字段 - List headFieldList = getExcelClassFieldList(clazz); - // 获取表头数据和示例数据 - List> sheetDataList = new ArrayList<>(); - List headList = new ArrayList<>(); - List exampleList = new ArrayList<>(); - Map> selectMap = new LinkedHashMap<>(); - for (int i = 0; i < headFieldList.size(); i++) { - ExcelClassField each = headFieldList.get(i); - headList.add(each.getName()); - exampleList.add(each.getExample()); - LinkedHashMap kvMap = each.getKvMap(); - if (kvMap != null && kvMap.size() > 0) { - selectMap.put(i, new ArrayList<>(kvMap.values())); - } - } - sheetDataList.add(headList); - if (isContainExample) { - sheetDataList.add(exampleList); - } - // 导出数据 - export(response, fileName, sheetName, sheetDataList, selectMap); - } - - private static List getExcelClassFieldList(Class clazz) { - // 解析所有字段 - Field[] fields = clazz.getDeclaredFields(); - boolean hasExportAnnotation = false; - Map> map = new LinkedHashMap<>(); - List sortList = new ArrayList<>(); - for (Field field : fields) { - ExcelClassField cf = getExcelClassField(field); - if (cf.getHasAnnotation() == 1) { - hasExportAnnotation = true; - } - int sort = cf.getSort(); - if (map.containsKey(sort)) { - map.get(sort).add(cf); - } else { - List list = new ArrayList<>(); - list.add(cf); - sortList.add(sort); - map.put(sort, list); - } - } - Collections.sort(sortList); - // 获取表头 - List headFieldList = new ArrayList<>(); - if (hasExportAnnotation) { - for (Integer sort : sortList) { - for (ExcelClassField cf : map.get(sort)) { - if (cf.getHasAnnotation() == 1) { - headFieldList.add(cf); - } - } - } - } else { - headFieldList.addAll(map.get(0)); - } - return headFieldList; - } - - private static ExcelClassField getExcelClassField(Field field) { - ExcelClassField cf = new ExcelClassField(); - String fieldName = field.getName(); - cf.setFieldName(fieldName); - ExcelExport annotation = field.getAnnotation(ExcelExport.class); - // 无 ExcelExport 注解情况 - if (annotation == null) { - cf.setHasAnnotation(0); - cf.setName(fieldName); - cf.setSort(0); - return cf; - } - // 有 ExcelExport 注解情况 - cf.setHasAnnotation(1); - cf.setName(annotation.value()); - String example = getString(annotation.example()); - if (!example.isEmpty()) { - if (isNumeric(example) && example.length() < 8) { - cf.setExample(Double.valueOf(example)); - } else { - cf.setExample(example); - } - } else { - cf.setExample(""); - } - cf.setSort(annotation.sort()); - // 解析映射 - String kv = getString(annotation.kv()); - cf.setKvMap(getKvMap(kv)); - return cf; - } - - private static LinkedHashMap getKvMap(String kv) { - LinkedHashMap kvMap = new LinkedHashMap<>(); - if (kv.isEmpty()) { - return kvMap; - } - String[] kvs = kv.split(";"); - for (String each : kvs) { - String[] eachKv = getString(each).split("-"); - if (eachKv.length != 2) { - continue; - } - String k = eachKv[0]; - String v = eachKv[1]; - if (k.isEmpty() || v.isEmpty()) { - continue; - } - kvMap.put(k, v); - } - return kvMap; - } - - /** - * 导出表格到本地 - * - * @param file 本地文件对象 - * @param sheetData 导出数据 - */ - public static void exportFile(File file, List> sheetData) { - if (file == null) { - System.out.println("文件创建失败"); - return; - } - if (sheetData == null) { - sheetData = new ArrayList<>(); - } - Map>> map = new HashMap<>(); - map.put(file.getName(), sheetData); - export(null, file, file.getName(), map, null); - } - - /** - * 导出表格到本地 - * - * @param 导出数据类似,和K类型保持一致 - * @param filePath 文件父路径(如:D:/doc/excel/) - * @param fileName 文件名称(不带尾缀,如:学生表) - * @param list 导出数据 - * @throws IOException IO异常 - */ - public static File exportFile(String filePath, String fileName, List list) throws IOException { - File file = getFile(filePath, fileName); - List> sheetData = getSheetData(list); - exportFile(file, sheetData); - return file; - } - - /** - * 获取文件 - * - * @param filePath filePath 文件父路径(如:D:/doc/excel/) - * @param fileName 文件名称(不带尾缀,如:用户表) - * @return 本地File文件对象 - */ - private static File getFile(String filePath, String fileName) throws IOException { - String dirPath = getString(filePath); - String fileFullPath; - if (dirPath.isEmpty()) { - fileFullPath = fileName; - } else { - // 判定文件夹是否存在,如果不存在,则级联创建 - File dirFile = new File(dirPath); - if (!dirFile.exists()) { - boolean mkdirs = dirFile.mkdirs(); - if (!mkdirs) { - return null; - } - } - // 获取文件夹全名 - if (dirPath.endsWith(String.valueOf(LEAN_LINE))) { - fileFullPath = dirPath + fileName + XLSX; - } else { - fileFullPath = dirPath + LEAN_LINE + fileName + XLSX; - } - } - System.out.println(fileFullPath); - File file = new File(fileFullPath); - if (!file.exists()) { - boolean result = file.createNewFile(); - if (!result) { - return null; - } - } - return file; - } - - private static List> getSheetData(List list) { - // 获取表头字段 - List excelClassFieldList = getExcelClassFieldList(list.get(0).getClass()); - List headFieldList = new ArrayList<>(); - List headList = new ArrayList<>(); - Map headFieldMap = new HashMap<>(); - for (ExcelClassField each : excelClassFieldList) { - String fieldName = each.getFieldName(); - headFieldList.add(fieldName); - headFieldMap.put(fieldName, each); - headList.add(each.getName()); - } - // 添加表头名称 - List> sheetDataList = new ArrayList<>(); - sheetDataList.add(headList); - // 获取表数据 - for (T t : list) { - Map fieldDataMap = getFieldDataMap(t); - Set fieldDataKeys = fieldDataMap.keySet(); - List rowList = new ArrayList<>(); - for (String headField : headFieldList) { - if (!fieldDataKeys.contains(headField)) { - continue; - } - Object data = fieldDataMap.get(headField); - if (data == null) { - rowList.add(""); - continue; - } - ExcelClassField cf = headFieldMap.get(headField); - // 判断是否有映射关系 - LinkedHashMap kvMap = cf.getKvMap(); - if (kvMap == null || kvMap.isEmpty()) { - rowList.add(data); - continue; - } - String val = kvMap.get(data.toString()); - if (isNumeric(val)) { - rowList.add(Double.valueOf(val)); - } else { - rowList.add(val); - } - } - sheetDataList.add(rowList); - } - return sheetDataList; - } - - private static Map getFieldDataMap(T t) { - Map map = new HashMap<>(); - Field[] fields = t.getClass().getDeclaredFields(); - try { - for (Field field : fields) { - String fieldName = field.getName(); - field.setAccessible(true); - Object object = field.get(t); - map.put(fieldName, object); - } - } catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - return map; - } - - public static void exportEmpty(HttpServletResponse response, String fileName) { - List> sheetDataList = new ArrayList<>(); - List headList = new ArrayList<>(); - headList.add("导出无数据"); - sheetDataList.add(headList); - export(response, fileName, sheetDataList); - } - - public static void export(HttpServletResponse response, String fileName, List> sheetDataList) { - export(response, fileName, fileName, sheetDataList, null); - } - - public static void exportManySheet(HttpServletResponse response, String fileName, Map>> sheetMap) { - export(response, null, fileName, sheetMap, null); - } - - - public static void export(HttpServletResponse response, String fileName, String sheetName, - List> sheetDataList) { - export(response, fileName, sheetName, sheetDataList, null); - } - - public static void export(HttpServletResponse response, String fileName, String sheetName, - List> sheetDataList, Map> selectMap) { - - Map>> map = new HashMap<>(); - map.put(sheetName, sheetDataList); - export(response, null, fileName, map, selectMap); - } - - public static void export(HttpServletResponse response, String fileName, List list, Class template) { - // list 是否为空 - boolean lisIsEmpty = list == null || list.isEmpty(); - // 如果模板数据为空,且导入的数据为空,则导出空文件 - if (template == null && lisIsEmpty) { - exportEmpty(response, fileName); - return; - } - // 如果 list 数据,则导出模板数据 - if (lisIsEmpty) { - exportTemplate(response, fileName, template); - return; - } - // 导出数据 - List> sheetDataList = getSheetData(list); - export(response, fileName, sheetDataList); - } - - public static void export(HttpServletResponse response, String fileName, List> sheetDataList, Map> selectMap) { - export(response, fileName, fileName, sheetDataList, selectMap); - } - - private static void export(HttpServletResponse response, File file, String fileName, - Map>> sheetMap, Map> selectMap) { - // 整个 Excel 表格 book 对象 - SXSSFWorkbook book = new SXSSFWorkbook(); - // 每个 Sheet 页 - Set>>> entries = sheetMap.entrySet(); - for (Map.Entry>> entry : entries) { - List> sheetDataList = entry.getValue(); - Sheet sheet = book.createSheet(entry.getKey()); - Drawing patriarch = sheet.createDrawingPatriarch(); - // 设置表头背景色(灰色) - CellStyle headStyle = book.createCellStyle(); - headStyle.setFillForegroundColor(IndexedColors.GREY_80_PERCENT.index); - headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - headStyle.setAlignment(HorizontalAlignment.CENTER); - headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index); - // 设置表身背景色(默认色) - CellStyle rowStyle = book.createCellStyle(); - rowStyle.setAlignment(HorizontalAlignment.CENTER); - rowStyle.setVerticalAlignment(VerticalAlignment.CENTER); - // 设置表格列宽度(默认为15个字节) - sheet.setDefaultColumnWidth(15); - // 创建合并算法数组 - int rowLength = sheetDataList.size(); - int columnLength = sheetDataList.get(0).size(); - int[][] mergeArray = new int[rowLength][columnLength]; - for (int i = 0; i < sheetDataList.size(); i++) { - // 每个 Sheet 页中的行数据 - Row row = sheet.createRow(i); - List rowList = sheetDataList.get(i); - for (int j = 0; j < rowList.size(); j++) { - // 每个行数据中的单元格数据 - Object o = rowList.get(j); - int v = 0; - if (o instanceof URL) { - // 如果要导出图片的话, 链接需要传递 URL 对象 - setCellPicture(book, row, patriarch, i, j, (URL) o); - } else { - Cell cell = row.createCell(j); - if (i == 0) { - // 第一行为表头行,采用灰色底背景 - v = setCellValue(cell, o, headStyle); - } else { - // 其他行为数据行,默认白底色 - v = setCellValue(cell, o, rowStyle); - } - } - mergeArray[i][j] = v; - } - } - // 合并单元格 - mergeCells(sheet, mergeArray); - // 设置下拉列表 - setSelect(sheet, selectMap); - } - // 写数据 - if (response != null) { - // 前端导出 - try { - write(response, book, fileName); - } catch (IOException e) { - e.printStackTrace(); - } - } else { - // 本地导出 - FileOutputStream fos; - try { - fos = new FileOutputStream(file); - ByteArrayOutputStream ops = new ByteArrayOutputStream(); - book.write(ops); - fos.write(ops.toByteArray()); - fos.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - /** - * 合并当前Sheet页的单元格 - * - * @param sheet 当前 sheet 页 - * @param mergeArray 合并单元格算法 - */ - private static void mergeCells(Sheet sheet, int[][] mergeArray) { - // 横向合并 - for (int x = 0; x < mergeArray.length; x++) { - int[] arr = mergeArray[x]; - boolean merge = false; - int y1 = 0; - int y2 = 0; - for (int y = 0; y < arr.length; y++) { - int value = arr[y]; - if (value == CELL_COLUMN_MERGE) { - if (!merge) { - y1 = y; - } - y2 = y; - merge = true; - } else { - merge = false; - if (y1 > 0) { - sheet.addMergedRegion(new CellRangeAddress(x, x, (y1 - 1), y2)); - } - y1 = 0; - y2 = 0; - } - } - if (y1 > 0) { - sheet.addMergedRegion(new CellRangeAddress(x, x, (y1 - 1), y2)); - } - } - // 纵向合并 - int xLen = mergeArray.length; - int yLen = mergeArray[0].length; - for (int y = 0; y < yLen; y++) { - boolean merge = false; - int x1 = 0; - int x2 = 0; - for (int x = 0; x < xLen; x++) { - int value = mergeArray[x][y]; - if (value == CELL_ROW_MERGE) { - if (!merge) { - x1 = x; - } - x2 = x; - merge = true; - } else { - merge = false; - if (x1 > 0) { - sheet.addMergedRegion(new CellRangeAddress((x1 - 1), x2, y, y)); - } - x1 = 0; - x2 = 0; - } - } - if (x1 > 0) { - sheet.addMergedRegion(new CellRangeAddress((x1 - 1), x2, y, y)); - } - } - } - - private static void write(HttpServletResponse response, SXSSFWorkbook book, String fileName) throws IOException { - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - response.setCharacterEncoding("utf-8"); - String name = new String(fileName.getBytes("GBK"), "ISO8859_1") + XLSX; - response.addHeader("Content-Disposition", "attachment;filename=" + name); - ServletOutputStream out = response.getOutputStream(); - book.write(out); - out.flush(); - out.close(); - } - - private static int setCellValue(Cell cell, Object o, CellStyle style) { - // 设置样式 - cell.setCellStyle(style); - // 数据为空时 - if (o == null) { -// cell.setCellType(CellType.STRING); - cell.setCellValue(""); - return CELL_OTHER; - } - // 是否为字符串 - if (o instanceof String) { - String s = o.toString(); - // 当数字类型长度超过8位时,改为字符串类型显示(Excel数字超过一定长度会显示为科学计数法) -// if (isNumeric(s) && s.length() < 8) { -//// cell.setCellType(CellType.NUMERIC); -// cell.setCellValue(Double.parseDouble(s)); -// return CELL_OTHER; -// } else { -//// cell.setCellType(CellType.STRING); -// cell.setCellValue(s); -// } - cell.setCellValue(s); - if (s.equals(ROW_MERGE)) { - return CELL_ROW_MERGE; - } else if (s.equals(COLUMN_MERGE)) { - return CELL_COLUMN_MERGE; - } else { - return CELL_OTHER; - } - } - // 是否为字符串 - if (o instanceof Integer || o instanceof Long || o instanceof Double || o instanceof Float) { -// cell.setCellType(CellType.NUMERIC); - cell.setCellValue(Double.parseDouble(o.toString())); - return CELL_OTHER; - } - // 是否为Boolean - if (o instanceof Boolean) { -// cell.setCellType(CellType.BOOLEAN); - cell.setCellValue((Boolean) o); - return CELL_OTHER; - } - // 如果是BigDecimal,则默认3位小数 - if (o instanceof BigDecimal) { -// cell.setCellType(CellType.NUMERIC); - cell.setCellValue(((BigDecimal) o).setScale(3, RoundingMode.HALF_UP).doubleValue()); - return CELL_OTHER; - } - // 如果是Date数据,则显示格式化数据 - if (o instanceof Date) { -// cell.setCellType(CellType.STRING); - cell.setCellValue(formatDate((Date) o)); - return CELL_OTHER; - } - // 如果是其他,则默认字符串类型 -// cell.setCellType(CellType.STRING); - cell.setCellValue(o.toString()); - return CELL_OTHER; - } - - private static void setCellPicture(SXSSFWorkbook wb, Row sr, Drawing patriarch, int x, int y, URL url) { - // 设置图片宽高 - sr.setHeight((short) (IMG_WIDTH * IMG_HEIGHT)); - // (jdk1.7版本try中定义流可自动关闭) - try (InputStream is = url.openStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { - byte[] buff = new byte[BYTES_DEFAULT_LENGTH]; - int rc; - while ((rc = is.read(buff, 0, BYTES_DEFAULT_LENGTH)) > 0) { - outputStream.write(buff, 0, rc); - } - // 设置图片位置 - XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, y, x, y + 1, x + 1); - // 设置这个,图片会自动填满单元格的长宽 - anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); - patriarch.createPicture(anchor, wb.addPicture(outputStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG)); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static String formatDate(Date date) { - if (date == null) { - return ""; - } - SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT); - return format.format(date); - } - - private static void setSelect(Sheet sheet, Map> selectMap) { - if (selectMap == null || selectMap.isEmpty()) { - return; - } - Set>> entrySet = selectMap.entrySet(); - for (Map.Entry> entry : entrySet) { - int y = entry.getKey(); - List list = entry.getValue(); - if (list == null || list.isEmpty()) { - continue; - } - String[] arr = new String[list.size()]; - for (int i = 0; i < list.size(); i++) { - arr[i] = list.get(i); - } - DataValidationHelper helper = sheet.getDataValidationHelper(); - CellRangeAddressList addressList = new CellRangeAddressList(1, 65000, y, y); - DataValidationConstraint dvc = helper.createExplicitListConstraint(arr); - DataValidation dv = helper.createValidation(dvc, addressList); - if (dv instanceof HSSFDataValidation) { - dv.setSuppressDropDownArrow(false); - } else { - dv.setSuppressDropDownArrow(true); - dv.setShowErrorBox(true); - } - sheet.addValidationData(dv); - } - } - - private static boolean isNumeric(String str) { - if (Objects.nonNull(str) && "0.0".equals(str)) { - return true; - } - for (int i = str.length(); --i >= 0; ) { - if (!Character.isDigit(str.charAt(i))) { - return false; - } - } - return true; - } - - private static String getString(String s) { - if (s == null) { - return ""; - } - if (s.isEmpty()) { - return s; - } - return s.trim(); - } -} diff --git a/src/main/java/com/wms/utils/excel/convertor/TaskStatusConvertor.java b/src/main/java/com/wms/utils/excel/convertor/TaskStatusConvertor.java new file mode 100644 index 0000000..9cd41c9 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/convertor/TaskStatusConvertor.java @@ -0,0 +1,83 @@ +package com.wms.utils.excel.convertor; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.WriteConverterContext; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * excel任务状态转换 + */ +public class TaskStatusConvertor implements Converter { + @Override + public Class supportJavaTypeKey() { + return Integer.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + /** + * 这里是读的时候会调用 + * + * @return 转换后的任务状态 + */ + @Override + public Integer convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String cellValue = cellData.getStringValue(); + return switch (cellValue.trim()) { + case "重复入库" -> -2; + case "暂存任务" -> -1; + case "任务新建,待下发" -> 0; + case "任务已下发" -> 1; + case "任务开始执行" -> 2; + case "出库完成" -> 3; + case "环线运输" -> 4; + case "拣选中" -> 8; + case "盘点中" -> 9; + case "任务完成" -> 100; + case "任务取消" -> 998; + default -> 999; + }; + } + + /** + * 这里是写的时候会调用 + * + * @return 转换后的任务状态 + */ + @Override + public WriteCellData convertToExcelData(WriteConverterContext context) { + Integer value = context.getValue(); + if (value == -2) { + return new WriteCellData<>("重复入库"); + } else if (value == -1) { + return new WriteCellData<>("暂存任务"); + } else if (value == 0) { + return new WriteCellData<>("任务新建,待下发"); + } else if (value == 1) { + return new WriteCellData<>("任务已下发"); + } else if (value == 2) { + return new WriteCellData<>("任务开始执行"); + } else if (value == 3) { + return new WriteCellData<>("出库完成"); + } else if (value == 4) { + return new WriteCellData<>("环线运输"); + } else if (value == 8) { + return new WriteCellData<>("拣选中"); + } else if (value == 9) { + return new WriteCellData<>("盘点中"); + } else if (value == 100) { + return new WriteCellData<>("任务完成"); + } else if (value == 998) { + return new WriteCellData<>("任务取消"); + } else { + return new WriteCellData<>("任务异常"); + } + } +} diff --git a/src/main/java/com/wms/utils/excel/convertor/TaskTypeConvertor.java b/src/main/java/com/wms/utils/excel/convertor/TaskTypeConvertor.java new file mode 100644 index 0000000..437c089 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/convertor/TaskTypeConvertor.java @@ -0,0 +1,62 @@ +package com.wms.utils.excel.convertor; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.WriteConverterContext; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * excel任务类型转换 + */ +public class TaskTypeConvertor implements Converter { + @Override + public Class supportJavaTypeKey() { + return Integer.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + /** + * 这里是读的时候会调用 + * + * @return 转换后的任务类型 + */ + @Override + public Integer convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + String cellValue = cellData.getStringValue(); + return switch (cellValue.trim()) { + case "入库" -> 1; + case "出库" -> 2; + case "盘点" -> 10; + case "移库" -> 9; + default -> -1; + }; + } + + /** + * 这里是写的时候会调用 + * + * @return 转换后的任务类型 + */ + @Override + public WriteCellData convertToExcelData(WriteConverterContext context) { + Integer value = context.getValue(); + if (value == 1) { + return new WriteCellData<>("入库"); + } else if (value == 2) { + return new WriteCellData<>("出库"); + } else if (value == 10) { + return new WriteCellData<>("盘点"); + } else if (value == 9) { + return new WriteCellData<>("移库"); + } else { + return new WriteCellData<>("未知"); + } + } +} diff --git a/src/main/java/com/wms/utils/excel/listener/UploadStocksListener.java b/src/main/java/com/wms/utils/excel/listener/UploadStocksListener.java new file mode 100644 index 0000000..d427cd7 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/listener/UploadStocksListener.java @@ -0,0 +1,107 @@ +package com.wms.utils.excel.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.excel.util.ListUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.wms.entity.app.dto.extend.StockDetailInfo; +import com.wms.entity.table.Stock; +import com.wms.service.StockService; +import com.wms.utils.excel.vo.StockExcelVo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +import static com.wms.utils.StringUtils.convertJsonString; +import static com.wms.utils.WmsUtils.generateId; + +/** + * 上传库存监听 + */ +public class UploadStocksListener implements ReadListener { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + /** + * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 + */ + private static final int BATCH_COUNT = 100; + private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + private final StockService stockService; + public UploadStocksListener(StockService stockService) { + this.stockService = stockService; + } + + @Override + public void onException(Exception exception, AnalysisContext context) throws Exception { + logger.error("处理数据发生异常:{}", convertJsonString(exception)); + ReadListener.super.onException(exception, context); + } + + /** + * 这个每一条数据解析都会来调用 + * + * @param stockExcelVo one row value. It is same as {@link AnalysisContext#readRowHolder()} + * @param analysisContext context + */ + @Override + public void invoke(StockExcelVo stockExcelVo, AnalysisContext analysisContext) { + cachedDataList.add(stockExcelVo); + // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM + if (cachedDataList.size() >= BATCH_COUNT) { + logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size()); + saveData(); + // 存储完成清理 list + cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + } + } + + /** + * 所有数据解析完成了 都会来调用 + * + * @param analysisContext context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + saveData(); + } + + /** + * 存储数据 + */ + private void saveData() { + List stockList = new ArrayList<>(); + for (StockExcelVo stockExcelVo : cachedDataList) { + if (stockService.exists(new LambdaQueryWrapper() + .eq(Stock::getVehicleId, stockExcelVo.getVehicleId()) + .eq(Stock::getLocationId, stockExcelVo.getLocationId()) + .apply("goods_related ->> '$.goodsId' = {0}", stockExcelVo.getGoodsId()))) { + // 重复库存 + cachedDataList.remove(stockExcelVo); + continue; + } + Stock stock = new Stock(); + stock.setStockId(generateId("ST_")); + stock.setLocationId(stockExcelVo.getLocationId()); + stock.setVehicleId(stockExcelVo.getVehicleId()); + stock.setWeight(stockExcelVo.getWeight()); + stock.setStockStatus(stockExcelVo.getStockStatus()); + stock.setCreateTime(stockExcelVo.getCreateTime()); + stock.setLastUpdateTime(stockExcelVo.getLastUpdateTime()); + stock.setLastUpdateUser(stockExcelVo.getLastUpdateUser()); + stock.setIsInventory(stockExcelVo.getIsInventory()); + stock.setInventoryTaskId(stockExcelVo.getInventoryTaskId()); + stock.setNoUseDays(stockExcelVo.getNoUseDays()); + // 物料信息 + StockDetailInfo goodsRelated = new StockDetailInfo(); + goodsRelated.setGoodsId(stockExcelVo.getGoodsId()); + goodsRelated.setGoodsName(stockExcelVo.getGoodsName()); + goodsRelated.setGoodsStatus(stockExcelVo.getGoodsStatus()); + goodsRelated.setTotalNum(stockExcelVo.getTotalNum()); + goodsRelated.setRemainNum(stockExcelVo.getRemainNum()); + stock.setGoodsRelated(goodsRelated); + stockList.add(stock); + } + stockService.saveBatch(stockList); + } +} diff --git a/src/main/java/com/wms/utils/excel/style/ExcelContentStyle.java b/src/main/java/com/wms/utils/excel/style/ExcelContentStyle.java new file mode 100644 index 0000000..59ed251 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/style/ExcelContentStyle.java @@ -0,0 +1,31 @@ +package com.wms.utils.excel.style; + +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.VerticalAlignment; + +public class ExcelContentStyle { + //设置excel内容格式 + public static HorizontalCellStyleStrategy getContentStyle(){ + //内容策略 + WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); + //设置样式 + contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框; + contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色; + contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); //设置左边框; + contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色; + contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框; + contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色; + contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框; + contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色; + + contentWriteCellStyle.setWrapped(true); //设置自动换行; + contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中 + contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中 + + return new HorizontalCellStyleStrategy(contentWriteCellStyle, contentWriteCellStyle); + } +} diff --git a/src/main/java/com/wms/utils/excel/vo/LocationExcelVo.java b/src/main/java/com/wms/utils/excel/vo/LocationExcelVo.java new file mode 100644 index 0000000..f030bee --- /dev/null +++ b/src/main/java/com/wms/utils/excel/vo/LocationExcelVo.java @@ -0,0 +1,74 @@ +package com.wms.utils.excel.vo; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.excel.annotation.ExcelProperty; +import com.wms.entity.table.Location; +import lombok.Data; + +@Data +public class LocationExcelVo { + /** + * 库位编号 + */ + @ExcelProperty("库位") + private String locationId; + /** + * 库区编号 + */ + @ExcelProperty("库区") + private Integer areaId; + /** + * 设备编号 + */ + @ExcelProperty("设备号") + private Integer equipmentId; + /** + * 库位类型 + */ + @ExcelProperty("库位类型") + private Integer locationType; + /** + * 排 + */ + @ExcelProperty("排") + private Integer wRow; + /** + * 列 + */ + @ExcelProperty("列") + private Integer wCol; + /** + * 层 + */ + @ExcelProperty("层") + private Integer wLayer; + /** + * 深度 + */ + @ExcelProperty("深度") + private Integer wDepth; + /** + * 是否锁定 + */ + @ExcelProperty("锁定") + private Integer isLock; + /** + * 库位状态 + */ + @ExcelProperty("状态") + private Integer locationStatus; + /** + * 载具号 + */ + @ExcelProperty("料箱号") + private String vehicleId; + + /** + * 从数据库实体转换为excel对象 + * @param locationPo 数据库实体 + * @return excel对象 + */ + public static LocationExcelVo of(Location locationPo) { + return BeanUtil.copyProperties(locationPo, LocationExcelVo.class); + } +} diff --git a/src/main/java/com/wms/utils/excel/vo/StockExcelVo.java b/src/main/java/com/wms/utils/excel/vo/StockExcelVo.java new file mode 100644 index 0000000..df23022 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/vo/StockExcelVo.java @@ -0,0 +1,122 @@ +package com.wms.utils.excel.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.wms.entity.table.Stock; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class StockExcelVo { + /** + * 库存编号 + */ + @ExcelProperty("库存编号") + private String stockId; + /** + * 库位ID + */ + @ExcelProperty("库位") + private String locationId; + /** + * 托盘号 + */ + @ExcelProperty("箱号") + private String vehicleId; + /** + * 重量 + */ + @ExcelProperty("重量") + private BigDecimal weight; + /** + * 库存状态 + * 正常、出库中、锁定 等 + */ + @ExcelProperty("库存状态") + private Integer stockStatus; + /** + * 创建时间 + */ + @ExcelProperty("入库时间") + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + /** + * 最后更新时间 + */ + @ExcelProperty("最近使用时间") + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + private LocalDateTime lastUpdateTime; + /** + * 最后更新用户 + */ + @ExcelProperty("最近更新用户") + private String lastUpdateUser; + /** + * 是否盘点 + */ + @ExcelProperty("是否盘点") + private Integer isInventory; + /** + * 盘点任务号 盘点出库和盘点入库同样 + */ + @ExcelProperty("盘点任务号") + private String inventoryTaskId; + /** + * 呆滞天数 + */ + @ExcelProperty("未使用天数") + private Integer noUseDays; + /** + * 物料编号 + */ + @ExcelProperty("料号") + private String goodsId; + /** + * 物料名称 + */ + @ExcelProperty("物料描述") + private String goodsName; + /** + * 物料状态 + */ + @ExcelProperty("物料状态") + private Integer goodsStatus; + /** + * 剩余数量 + */ + @ExcelProperty("剩余数量") + private BigDecimal remainNum; + /** + * 入库库存总数 + */ + @ExcelProperty("入库数量") + private BigDecimal totalNum; + + /** + * 从数据库实体转换为excel对象 + * @param stockPo 数据库实体 + * @return excel对象 + */ + public static StockExcelVo of(Stock stockPo) { + StockExcelVo stockExcelVo = new StockExcelVo(); + stockExcelVo.setStockId(stockPo.getStockId()); + stockExcelVo.setLocationId(stockPo.getLocationId()); + stockExcelVo.setVehicleId(stockPo.getVehicleId()); + stockExcelVo.setWeight(stockPo.getWeight()); + stockExcelVo.setStockStatus(stockPo.getStockStatus()); + stockExcelVo.setCreateTime(stockPo.getCreateTime()); + stockExcelVo.setLastUpdateTime(stockPo.getLastUpdateTime()); + stockExcelVo.setLastUpdateUser(stockPo.getLastUpdateUser()); + stockExcelVo.setIsInventory(stockPo.getIsInventory()); + stockExcelVo.setInventoryTaskId(stockPo.getInventoryTaskId()); + stockExcelVo.setNoUseDays(stockPo.getNoUseDays()); + stockExcelVo.setGoodsId(stockPo.getGoodsRelated().getGoodsId()); + stockExcelVo.setGoodsName(stockPo.getGoodsRelated().getGoodsName()); + stockExcelVo.setGoodsStatus(stockPo.getGoodsRelated().getGoodsStatus()); + stockExcelVo.setRemainNum(stockPo.getGoodsRelated().getRemainNum()); + stockExcelVo.setTotalNum(stockPo.getGoodsRelated().getTotalNum()); + return stockExcelVo; + } +} diff --git a/src/main/java/com/wms/utils/excel/vo/TaskRecordExcelVo.java b/src/main/java/com/wms/utils/excel/vo/TaskRecordExcelVo.java new file mode 100644 index 0000000..aeadd20 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/vo/TaskRecordExcelVo.java @@ -0,0 +1,151 @@ +package com.wms.utils.excel.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.wms.entity.table.Stock; +import com.wms.entity.table.TaskRecord; +import com.wms.utils.excel.convertor.TaskStatusConvertor; +import com.wms.utils.excel.convertor.TaskTypeConvertor; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 任务记录Excel对象 + */ +@Data +public class TaskRecordExcelVo { + /** + * 任务号 + */ + @ExcelProperty("任务id") + private String taskId; + /** + * 任务类型 + */ + @ExcelProperty(value = "任务类型", converter = TaskTypeConvertor.class) + private Integer taskType; + /** + * 任务状态 + */ + @ExcelProperty(value = "任务类型", converter = TaskStatusConvertor.class) + private Integer taskStatus; + /** + * 起点 + */ + @ExcelProperty("起点") + private String origin; + /** + * 终点 + */ + @ExcelProperty("终点") + private String destination; + /** + * 任务优先级 + */ + @ExcelProperty("优先级") + private Integer taskPriority; + /** + * 任务组 + */ + @ExcelProperty("任务组") + private String taskGroup; + /** + * 载具号 + */ + @ExcelProperty("料箱号") + private String vehicleId; + /** + * 重量 + */ + @ExcelProperty("重量") + private BigDecimal weight; + /** + * 载具尺寸 + */ + @ExcelProperty("载具尺寸") + private Integer vehicleSize; + /** + * 创建时间 + */ + @ExcelProperty("创建时间") + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + /** + * 完成时间 + */ + @ExcelProperty("完成时间") + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + private LocalDateTime finishTime; + /** + * 用户名 + */ + @ExcelProperty("用户名") + private String userName; + /** + * 物料编号 + */ + @ExcelProperty("物料编号") + private String goodsId; + /** + * 物料名称 + */ + @ExcelProperty("物料描述") + private String goodsName; + /** + * 操作数量 + */ + @ExcelProperty("操作数量") + private BigDecimal opNum; + /** + * 原库存剩余数量 + */ + @ExcelProperty("库存数量") + private BigDecimal originNum; + /** + * 前置任务号 + */ + @ExcelProperty("前置任务") + private String preTask; + /** + * 是否拣选 + */ + @ExcelProperty("是否拣选") + private Integer isPicking; + /** + * 拣选站台 + */ + @ExcelProperty("拣选站台") + private String pickStand; + + /** + * 从数据库实体转换为excel对象 + * @param recordPo 数据库实体 + * @return excel对象 + */ + public static TaskRecordExcelVo of(TaskRecord recordPo) { + TaskRecordExcelVo recordExcelVo = new TaskRecordExcelVo(); + recordExcelVo.setTaskId(recordPo.getTaskId()); + recordExcelVo.setTaskType(recordPo.getTaskType()); + recordExcelVo.setTaskStatus(recordPo.getTaskStatus()); + recordExcelVo.setOrigin(recordPo.getOrigin()); + recordExcelVo.setDestination(recordPo.getDestination()); + recordExcelVo.setTaskPriority(recordPo.getTaskPriority()); + recordExcelVo.setTaskGroup(recordPo.getTaskGroup()); + recordExcelVo.setVehicleId(recordPo.getVehicleId()); + recordExcelVo.setWeight(recordPo.getWeight()); + recordExcelVo.setVehicleSize(recordPo.getVehicleSize()); + recordExcelVo.setCreateTime(recordPo.getCreateTime()); + recordExcelVo.setFinishTime(recordPo.getFinishTime()); + recordExcelVo.setUserName(recordPo.getUserName()); + recordExcelVo.setGoodsId(recordPo.getGoodsRelated().getGoodsId()); + recordExcelVo.setGoodsName(recordPo.getGoodsRelated().getGoodsName()); + recordExcelVo.setOpNum(recordPo.getGoodsRelated().getOpNum()); + recordExcelVo.setOriginNum(recordPo.getGoodsRelated().getOriginNum()); + recordExcelVo.setPreTask(recordPo.getPreTask()); + recordExcelVo.setIsPicking(recordPo.getIsPicking()); + recordExcelVo.setPickStand(recordPo.getPickStand()); + return recordExcelVo; + } +} diff --git a/src/main/java/com/wms/utils/excel/vo/VehicleExcelVo.java b/src/main/java/com/wms/utils/excel/vo/VehicleExcelVo.java new file mode 100644 index 0000000..729e688 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/vo/VehicleExcelVo.java @@ -0,0 +1,48 @@ +package com.wms.utils.excel.vo; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.wms.entity.table.Vehicle; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class VehicleExcelVo { + /** + * 载具编号 + */ + @ExcelProperty("箱号") + private String vehicleId; + /** + * 当前所在位置 + */ + @ExcelProperty("库位") + private String currentLocation; + /** + * 载具状态 + */ + @ExcelProperty("料箱状态") + private Integer vehicleStatus; + /** + * 是否是空箱 + */ + @ExcelProperty("是否空箱") + private Integer isEmpty; + /** + * 上次入库时间 + */ + @ExcelProperty("上次入库时间") + @DateTimeFormat("yyyy-MM-dd HH:mm:ss") + private LocalDateTime lastInTime; + + /** + * 从数据库实体转换为excel对象 + * @param vehiclePo 数据库实体 + * @return excel对象 + */ + public static VehicleExcelVo of(Vehicle vehiclePo) { + return BeanUtil.copyProperties(vehiclePo, VehicleExcelVo.class); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 99d07ce..d8c8423 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -30,6 +30,11 @@ spring: driver-class-name: com.mysql.cj.jdbc.Driver profiles: active: online + servlet: + multipart: + max-file-size: 100MB #设置允许单个文件上传的大小 + max-request-size: 1000MB #设置允许上传的总的文件的大小 + server: # 服务端配置 port: 12315 diff --git a/src/main/resources/mapper/InventoryHistoryMapper.xml b/src/main/resources/mapper/InventoryHistoryMapper.xml new file mode 100644 index 0000000..1441ecc --- /dev/null +++ b/src/main/resources/mapper/InventoryHistoryMapper.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/InventoryListMapper.xml b/src/main/resources/mapper/InventoryListMapper.xml new file mode 100644 index 0000000..8678a08 --- /dev/null +++ b/src/main/resources/mapper/InventoryListMapper.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UploadRecordMapper.xml b/src/main/resources/mapper/UploadRecordMapper.xml new file mode 100644 index 0000000..1ca287d --- /dev/null +++ b/src/main/resources/mapper/UploadRecordMapper.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file