diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDO.java index fcd0afe63..8903744e3 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDO.java @@ -243,4 +243,12 @@ public class ReservationMaterialInventoryDO extends MaterialBaseDO { @ApiModelProperty("LOT编号") @Excel(name = "LOT编号") private String lotNumber; + + @ApiModelProperty("入库时间 ") + @Excel(name = "入库时间 ") + private String createTimeStart; + + @ApiModelProperty("入库时间 ") + @Excel(name = "入库时间 ") + private String createTimeEnd; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDTO.java index 1a5521eaa..7f152c98b 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDTO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationMaterialInventory/repository/todo/ReservationMaterialInventoryDTO.java @@ -184,4 +184,12 @@ public class ReservationMaterialInventoryDTO extends MaterialBaseDTO { @Excel(name = "冻结数量大于0条件") private String greaterThanFreezeQuantity; + @ApiModelProperty("入库时间 ") + @Excel(name = "入库时间 ") + private String createTimeStart; + + @ApiModelProperty("入库时间 ") + @Excel(name = "入库时间 ") + private String createTimeEnd; + } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/facade/IReservationStockInOrderService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/facade/IReservationStockInOrderService.java index 1f19dc33e..eca6f3453 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/facade/IReservationStockInOrderService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/facade/IReservationStockInOrderService.java @@ -5,6 +5,8 @@ import com.mhd.oms.domain.reservationInMaterialDetail.repository.po.ReservationI import com.mhd.oms.domain.reservationStockInOrder.entity.ReservationStockInOrder; import com.mhd.oms.domain.reservationStockInOrder.repository.po.ReservationStockInOrderPO; import com.mhd.oms.domain.reservationStockInOrder.repository.todo.ReservationStockInOrderDO; +import com.mhd.oms.domain.reservationStockInOrder.repository.vo.DeliveryDataDTO; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -45,4 +47,13 @@ public interface IReservationStockInOrderService extends IService queryNoticePrint(ReservationStockInOrderDO stockInOrderDO); List queryNoticePrintDetail(ReservationStockInOrderDO stockInOrderDTO); + + /** + * 解析Excel文件并获取出库数据 + * @param file Excel文件 + * @param sheetName 工作表名称(出库导入/参考数据) + * @return 出库数据DTO + * @throws Exception 解析异常 + */ + DeliveryDataDTO parseExcelFile(MultipartFile file, String sheetName) throws Exception; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/listener/DeliveryExcelListener.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/listener/DeliveryExcelListener.java new file mode 100644 index 000000000..cd905cc84 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/listener/DeliveryExcelListener.java @@ -0,0 +1,210 @@ +package com.mhd.oms.domain.reservationStockInOrder.repository.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelDataConvertException; +import com.mhd.oms.domain.reservationStockInOrder.repository.vo.CustomerDeliveryDetail; +import com.mhd.oms.domain.reservationStockInOrder.repository.vo.DeliveryHeader; +import com.mhd.oms.domain.reservationStockInOrder.repository.vo.ProductDetail; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Excel解析监听器 + */ +public class DeliveryExcelListener extends AnalysisEventListener { + private static final Logger LOGGER = LoggerFactory.getLogger(DeliveryExcelListener.class); + + // 数据存储 + private DeliveryHeader deliveryHeader = new DeliveryHeader(); + private List productDetailList = new ArrayList<>(); + private List customerDeliveryDetailList = new ArrayList<>(); + + // 解析状态标记 + private boolean isProductDetail = false; // 是否在解析货品明细 + private boolean isCustomerDetail = false; // 是否在解析客户配送明细 + + @Override + public void invoke(Object data, AnalysisContext context) { + try { + // 将数据转为数组(Excel行数据) + Object[] rowData = (Object[]) data; + + // 1. 解析表头信息(第1行) + if (context.readRowHolder().getRowIndex() == 0) { + parseHeaderInfo(rowData); + } + // 2. 识别数据区域(根据关键字判断) + else if (context.readRowHolder().getRowIndex() == 1) { + if (rowData[0] != null && "货品明细".equals(rowData[0].toString().trim())) { + isProductDetail = true; + isCustomerDetail = false; + } + } + else if (context.readRowHolder().getRowIndex() == 7) { + // 解析纪录合共(第8行,索引为7) + parseTotalRecord(rowData); + } + else if (context.readRowHolder().getRowIndex() == 8) { + if (rowData[0] != null && "客户配送明细".equals(rowData[0].toString().trim())) { + isProductDetail = false; + isCustomerDetail = true; + } + } + else if (context.readRowHolder().getRowIndex() == 30) { + // 解析发票张数(第31行,索引为30) + parseInvoiceCount(rowData); + } + // 3. 解析货品明细(第4-7行,索引3-6) + else if (isProductDetail && context.readRowHolder().getRowIndex() >= 3 && context.readRowHolder().getRowIndex() <= 6) { + parseProductDetail(rowData); + } + // 4. 解析客户配送明细(第11-30行,索引10-29) + else if (isCustomerDetail && context.readRowHolder().getRowIndex() >= 10 && context.readRowHolder().getRowIndex() <= 29) { + parseCustomerDeliveryDetail(rowData); + } + + } catch (ExcelDataConvertException e) { + LOGGER.error("Excel数据转换异常,行号:{},列号:{}", + context.readRowHolder().getRowIndex() + 1, + e.getColumnIndex() + 1); + } catch (Exception e) { + LOGGER.error("Excel解析异常,行号:{}", + context.readRowHolder().getRowIndex() + 1, e); + } + } + + /** + * 解析表头信息(第1行) + */ + private void parseHeaderInfo(Object[] rowData) { + // 送货日期(第2列,索引1) + if (rowData[1] != null) { + deliveryHeader.setDeliveryDate((Date) rowData[1]); + } + // 送货线号(第4列,索引3) + if (rowData[3] != null) { + deliveryHeader.setDeliveryLineNo(Integer.parseInt(rowData[3].toString())); + } + // 车次(第6列,索引5) + if (rowData[5] != null) { + deliveryHeader.setTrainNumber(Integer.parseInt(rowData[5].toString())); + } + } + + /** + * 解析纪录合共(第8行) + */ + private void parseTotalRecord(Object[] rowData) { + // 纪录合共-货品总数量(第2列,索引1) + if (rowData[1] != null) { + deliveryHeader.setTotalRecordCount(Integer.parseInt(rowData[1].toString())); + } + // 总箱数(第5列,索引4) + if (rowData[4] != null) { + deliveryHeader.setTotalBoxCount(Integer.parseInt(rowData[4].toString())); + } + // 总支数(第6列,索引5) + if (rowData[5] != null) { + deliveryHeader.setTotalPieceCount(Integer.parseInt(rowData[5].toString())); + } + } + + /** + * 解析发票张数(第31行) + */ + private void parseInvoiceCount(Object[] rowData) { + // 发票张数(第2列,索引1) + if (rowData[1] != null) { + deliveryHeader.setInvoiceCount(Integer.parseInt(rowData[1].toString())); + } + // 小计-总箱数(第5列,索引4) + if (rowData[4] != null) { + deliveryHeader.setSubtotalBoxCount(Integer.parseInt(rowData[4].toString())); + } + // 小计-总支数(第6列,索引5) + if (rowData[5] != null) { + deliveryHeader.setSubtotalPieceCount(Integer.parseInt(rowData[5].toString())); + } + // 小计-总金额(第7列,索引6) + if (rowData[6] != null) { + deliveryHeader.setSubtotalAmount(new BigDecimal(rowData[6].toString())); + } + } + + /** + * 解析货品明细 + */ + private void parseProductDetail(Object[] rowData) { + ProductDetail productDetail = new ProductDetail(); + // 货品编号(第1列,索引0) + if (rowData[0] != null) { + productDetail.setProductCode(rowData[0].toString().trim()); + } + // 货品简称(第2列,索引1) + if (rowData[1] != null) { + productDetail.setProductName(rowData[1].toString().trim()); + } + // 箱数(第5列,索引4) + if (rowData[4] != null) { + productDetail.setBoxCount(Integer.parseInt(rowData[4].toString())); + } + // 支数(第6列,索引5) + if (rowData[5] != null) { + productDetail.setPieceCount(Integer.parseInt(rowData[5].toString())); + } + productDetailList.add(productDetail); + } + + /** + * 解析客户配送明细 + */ + private void parseCustomerDeliveryDetail(Object[] rowData) { + CustomerDeliveryDetail customerDetail = new CustomerDeliveryDetail(); + // 类别(第1列,索引0) + if (rowData[0] != null) { + customerDetail.setCategory(rowData[0].toString().trim()); + } + // 发票编号(第2列,索引1) + if (rowData[1] != null) { + customerDetail.setInvoiceNo(rowData[1].toString().trim()); + } + // 客户编号(第3列,索引2) + if (rowData[2] != null) { + customerDetail.setCustomerCode(rowData[2].toString().trim()); + } + // 客户名称(第4列,索引3) + if (rowData[3] != null) { + customerDetail.setCustomerName(rowData[3].toString().trim()); + } + // 箱数(第5列,索引4) + if (rowData[4] != null) { + customerDetail.setBoxCount(Integer.parseInt(rowData[4].toString())); + } + // 包数(第6列,索引5) + if (rowData[5] != null) { + customerDetail.setPackageCount(Integer.parseInt(rowData[5].toString())); + } + // 金额(第7列,索引6) + if (rowData[6] != null) { + customerDetail.setAmount(new BigDecimal(rowData[6].toString())); + } + customerDeliveryDetailList.add(customerDetail); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + LOGGER.info("Excel解析完成,共解析货品明细:{}条,客户配送明细:{}条", + productDetailList.size(), customerDeliveryDetailList.size()); + } + + // Getter方法(供Service层获取解析后的数据) + public DeliveryHeader getDeliveryHeader() { return deliveryHeader; } + public List getProductDetailList() { return productDetailList; } + public List getCustomerDeliveryDetailList() { return customerDeliveryDetailList; } +} \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/persistence/ReservationStockInOrderImpl.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/persistence/ReservationStockInOrderImpl.java index 12698bdcc..c84825059 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/persistence/ReservationStockInOrderImpl.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/persistence/ReservationStockInOrderImpl.java @@ -1,17 +1,22 @@ package com.mhd.oms.domain.reservationStockInOrder.repository.persistence; +import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mhd.oms.domain.reservationInMaterialDetail.repository.po.ReservationInMaterialDetailPO; import com.mhd.oms.domain.reservationStockInOrder.entity.ReservationStockInOrder; import com.mhd.oms.domain.reservationStockInOrder.repository.facade.IReservationStockInOrderService; +import com.mhd.oms.domain.reservationStockInOrder.repository.listener.DeliveryExcelListener; import com.mhd.oms.domain.reservationStockInOrder.repository.mapper.ReservationStockInOrderMapper; import com.mhd.oms.domain.reservationStockInOrder.repository.po.ReservationStockInOrderPO; import com.mhd.oms.domain.reservationStockInOrder.repository.todo.ReservationStockInOrderDO; +import com.mhd.oms.domain.reservationStockInOrder.repository.vo.DeliveryDataDTO; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -93,4 +98,35 @@ public class ReservationStockInOrderImpl extends ServiceImpl productDetailList; + // 客户配送明细列表 + private List customerDeliveryDetailList; + +} \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/vo/DeliveryHeader.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/vo/DeliveryHeader.java new file mode 100644 index 000000000..40a12dcfc --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/vo/DeliveryHeader.java @@ -0,0 +1,33 @@ +package com.mhd.oms.domain.reservationStockInOrder.repository.vo; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 出库表头信息(包含送货日期、纪录合共、发票张数等) + */ +@Data +public class DeliveryHeader { + // 送货日期 + private Date deliveryDate; + // 送货线号 + private Integer deliveryLineNo; + // 车次 + private Integer trainNumber; + // 纪录合共-货品总数量 + private Integer totalRecordCount; + // 纪录合共-总箱数 + private Integer totalBoxCount; + // 纪录合共-总支数 + private Integer totalPieceCount; + // 发票张数 + private Integer invoiceCount; + // 小计-总箱数 + private Integer subtotalBoxCount; + // 小计-总支数 + private Integer subtotalPieceCount; + // 小计-总金额 + private BigDecimal subtotalAmount; + +} \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/vo/ProductDetail.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/vo/ProductDetail.java new file mode 100644 index 000000000..7fa7d8937 --- /dev/null +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/vo/ProductDetail.java @@ -0,0 +1,19 @@ +package com.mhd.oms.domain.reservationStockInOrder.repository.vo; + +import lombok.Data; + +/** + * 货品明细实体类 + */ +@Data +public class ProductDetail { + // 货品编号 + private String productCode; + // 货品简称 + private String productName; + // 箱数 + private Integer boxCount; + // 支数 + private Integer pieceCount; + +} \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java index a77bf2ea1..7030310d2 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java @@ -4,9 +4,11 @@ import com.mhd.common.core.web.controller.BaseController; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.core.web.page.TableDataInfo; import com.mhd.oms.domain.reservationInMaterialDetail.repository.po.ReservationInMaterialDetailPO; +import com.mhd.oms.domain.reservationStockInOrder.repository.facade.IReservationStockInOrderService; import com.mhd.oms.domain.reservationStockInOrder.repository.po.ReservationStockInOrderPO; import com.mhd.oms.domain.reservationStockInOrder.repository.todo.ReservationStockInOrderDO; import com.mhd.oms.domain.reservationStockInOrder.repository.todo.ReservationStockInOrderDTO; +import com.mhd.oms.domain.reservationStockInOrder.repository.vo.DeliveryDataDTO; import com.mhd.oms.domain.reservationStockInOrder.service.ReservationStockInOrderApplicationService; import com.mhd.oms.domain.reservationStockInOrder.service.ReservationStockInOrderAssembler; import com.mhd.system.api.domain.InMaterialDetail; @@ -15,6 +17,8 @@ import com.mhd.system.api.domain.StockInOrder; import com.mhd.system.api.domain.StockInOrderTZPD; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -37,6 +41,8 @@ public class ReservationStockInOrderApi extends BaseController { @Resource private ReservationStockInOrderAssembler stockInOrderAssembler; + @Autowired + private IReservationStockInOrderService reservationStockInOrderService; /** * 分页查询入库单列表 @@ -183,4 +189,25 @@ public class ReservationStockInOrderApi extends BaseController { return AjaxResult.success(result); } + + /** + * 上传并解析Excel文件 + * @param file Excel文件 + * @param sheetName 工作表名称(出库导入/参考数据) + * @return 解析后的出库数据 + */ + @PostMapping("/parseExcel") + public ResponseEntity parseExcel( + @RequestParam("file") MultipartFile file, + @RequestParam("sheetName") String sheetName) { + try { + DeliveryDataDTO deliveryDataDTO = reservationStockInOrderService.parseExcelFile(file, sheetName); + return new ResponseEntity<>(deliveryDataDTO, HttpStatus.OK); + } catch (IllegalArgumentException e) { + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } catch (Exception e) { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + } \ No newline at end of file