测试环境库存查询报错;
This commit is contained in:
+8
@@ -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;
|
||||
}
|
||||
+8
@@ -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;
|
||||
|
||||
}
|
||||
+11
@@ -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<ReservationSto
|
||||
|
||||
List<ReservationStockInOrderPO> queryNoticePrint(ReservationStockInOrderDO stockInOrderDO);
|
||||
List<ReservationInMaterialDetailPO> queryNoticePrintDetail(ReservationStockInOrderDO stockInOrderDTO);
|
||||
|
||||
/**
|
||||
* 解析Excel文件并获取出库数据
|
||||
* @param file Excel文件
|
||||
* @param sheetName 工作表名称(出库导入/参考数据)
|
||||
* @return 出库数据DTO
|
||||
* @throws Exception 解析异常
|
||||
*/
|
||||
DeliveryDataDTO parseExcelFile(MultipartFile file, String sheetName) throws Exception;
|
||||
}
|
||||
+210
@@ -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<Object> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DeliveryExcelListener.class);
|
||||
|
||||
// 数据存储
|
||||
private DeliveryHeader deliveryHeader = new DeliveryHeader();
|
||||
private List<ProductDetail> productDetailList = new ArrayList<>();
|
||||
private List<CustomerDeliveryDetail> 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<ProductDetail> getProductDetailList() { return productDetailList; }
|
||||
public List<CustomerDeliveryDetail> getCustomerDeliveryDetailList() { return customerDeliveryDetailList; }
|
||||
}
|
||||
+36
@@ -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<ReservationStockInO
|
||||
return stockInOrderMapper.queryNoticePrintDetail(stockInOrderDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeliveryDataDTO parseExcelFile(MultipartFile file, String sheetName) throws Exception {
|
||||
// 校验文件
|
||||
if (file.isEmpty()) {
|
||||
throw new IllegalArgumentException("上传的Excel文件不能为空");
|
||||
}
|
||||
|
||||
// 校验工作表名称
|
||||
if (!"出库导入".equals(sheetName) && !"参考数据".equals(sheetName)) {
|
||||
throw new IllegalArgumentException("工作表名称必须为'出库导入'或'参考数据'");
|
||||
}
|
||||
|
||||
// 使用EasyExcel解析Excel
|
||||
DeliveryExcelListener listener = new DeliveryExcelListener();
|
||||
try (InputStream inputStream = file.getInputStream()) {
|
||||
EasyExcel.read(inputStream, listener)
|
||||
.sheet(sheetName) // 指定工作表
|
||||
.headRowNumber(0) // 无固定表头,从第1行开始解析
|
||||
.doRead();
|
||||
}
|
||||
|
||||
// 封装DTO返回
|
||||
DeliveryDataDTO deliveryDataDTO = new DeliveryDataDTO();
|
||||
deliveryDataDTO.setDeliveryHeader(listener.getDeliveryHeader());
|
||||
deliveryDataDTO.setProductDetailList(listener.getProductDetailList());
|
||||
deliveryDataDTO.setCustomerDeliveryDetailList(listener.getCustomerDeliveryDetailList());
|
||||
|
||||
return deliveryDataDTO;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.mhd.oms.domain.reservationStockInOrder.repository.vo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 客户配送明细实体类
|
||||
*/
|
||||
@Data
|
||||
public class CustomerDeliveryDetail {
|
||||
// 类别
|
||||
private String category;
|
||||
// 发票编号
|
||||
private String invoiceNo;
|
||||
// 客户编号
|
||||
private String customerCode;
|
||||
// 客户名称
|
||||
private String customerName;
|
||||
// 箱数
|
||||
private Integer boxCount;
|
||||
// 包数
|
||||
private Integer packageCount;
|
||||
// 金额
|
||||
private BigDecimal amount;
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.mhd.oms.domain.reservationStockInOrder.repository.vo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 出库数据DTO(包含表头、货品明细、客户配送明细)
|
||||
*/
|
||||
@Data
|
||||
public class DeliveryDataDTO {
|
||||
// 表头信息
|
||||
private DeliveryHeader deliveryHeader;
|
||||
// 货品明细列表
|
||||
private List<ProductDetail> productDetailList;
|
||||
// 客户配送明细列表
|
||||
private List<CustomerDeliveryDetail> customerDeliveryDetailList;
|
||||
|
||||
}
|
||||
+33
@@ -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;
|
||||
|
||||
}
|
||||
+19
@@ -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;
|
||||
|
||||
}
|
||||
+27
@@ -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<DeliveryDataDTO> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user