diff --git a/src/main/java/com/gaotao/modules/notify/controller/NewIssureController.java b/src/main/java/com/gaotao/modules/notify/controller/NewIssureController.java index 578c4c0..fb48de3 100644 --- a/src/main/java/com/gaotao/modules/notify/controller/NewIssureController.java +++ b/src/main/java/com/gaotao/modules/notify/controller/NewIssureController.java @@ -51,10 +51,12 @@ public class NewIssureController { */ @PostMapping(value="/uploadNotifyExcel") @ResponseBody - public R uploadNotifyExcel(@RequestParam("file") MultipartFile file) throws Exception { + public R uploadNotifyExcel(@RequestParam("file") MultipartFile file, + @RequestParam("site") String site, + @RequestParam("notifyNo") String notifyNo) throws Exception { try { - newIssureService.uploadNotifyExcel(file); - return R.ok(); + newIssureService.uploadNotifyExcel(file, site, notifyNo); + return R.ok("Excel文件上传并处理成功"); } catch (Exception e) { System.err.println("Excel文件处理异常: " + e.getMessage()); e.printStackTrace(); diff --git a/src/main/java/com/gaotao/modules/notify/mapper/NewIssureMapper.java b/src/main/java/com/gaotao/modules/notify/mapper/NewIssureMapper.java index 0ce40b8..c52f156 100644 --- a/src/main/java/com/gaotao/modules/notify/mapper/NewIssureMapper.java +++ b/src/main/java/com/gaotao/modules/notify/mapper/NewIssureMapper.java @@ -1,13 +1,34 @@ package com.gaotao.modules.notify.mapper; import com.gaotao.modules.base.entity.SOScheduledRoutingData; +import com.gaotao.modules.notify.entity.SOIssueNotifyOrderList; import com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListData; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import java.math.BigDecimal; import java.util.List; @Mapper public interface NewIssureMapper { + /** + * 批量保存申请单物料明细(Excel导入专用) + */ + void batchSaveSOIssueNotifyOrderMaterialListDataForExcel(@Param("data") List data); + + /** + * 保存申请单工单明细(Excel导入专用) + */ + int saveSOIssueNotifyOrderListForExcel(SOIssueNotifyOrderList data); + + /** + * 删除申请单物料明细(Excel导入专用) + */ + void deleteSOIssueNotifyOrderMaterialListDataForExcel(SOIssueNotifyOrderMaterialListData data); + + /** + * 获取已保存的申请单物料明细(用于回显) + */ List getSOSBOMForIssureNew(SOScheduledRoutingData data); } diff --git a/src/main/java/com/gaotao/modules/notify/service/NewIssureService.java b/src/main/java/com/gaotao/modules/notify/service/NewIssureService.java index 10a8d7e..06ac47b 100644 --- a/src/main/java/com/gaotao/modules/notify/service/NewIssureService.java +++ b/src/main/java/com/gaotao/modules/notify/service/NewIssureService.java @@ -16,10 +16,12 @@ public interface NewIssureService { * @Description Excel文件上传并解析 * @Title uploadNotifyExcel * @param file Excel文件 + * @param site 工厂编码 + * @param notifyNo 申请单号 * @author system * @date 2024/12/19 - * @return List + * @return void * @throws Exception */ - void uploadNotifyExcel(MultipartFile file) throws Exception; + void uploadNotifyExcel(MultipartFile file, String site, String notifyNo) throws Exception; } diff --git a/src/main/java/com/gaotao/modules/notify/service/impl/NewIssureServiceImpl.java b/src/main/java/com/gaotao/modules/notify/service/impl/NewIssureServiceImpl.java index 6526e5d..059bc60 100644 --- a/src/main/java/com/gaotao/modules/notify/service/impl/NewIssureServiceImpl.java +++ b/src/main/java/com/gaotao/modules/notify/service/impl/NewIssureServiceImpl.java @@ -6,13 +6,16 @@ import com.gaotao.modules.api.entity.IfsShopOrder; import com.gaotao.modules.api.service.IfsApiService; import com.gaotao.modules.base.entity.SOScheduledRoutingData; import com.gaotao.modules.notify.entity.NotifyExcelData; +import com.gaotao.modules.notify.entity.SOIssueNotifyOrderList; import com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListData; import com.gaotao.modules.notify.entity.vo.ShopOrderMaterialVo; import com.gaotao.modules.notify.mapper.NewIssureMapper; +import com.gaotao.modules.notify.mapper.IssureNotifyMapper; import com.gaotao.modules.notify.service.NewIssureService; import org.apache.commons.lang.StringUtils; 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.math.BigDecimal; @@ -22,12 +25,15 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Service public class NewIssureServiceImpl implements NewIssureService { @Autowired private NewIssureMapper newIssureMapper; @Autowired + private IssureNotifyMapper issureNotifyMapper; + @Autowired private IfsApiService ifsApiService; @@ -73,7 +79,8 @@ public class NewIssureServiceImpl implements NewIssureService { } @Override - public void uploadNotifyExcel(MultipartFile file) throws Exception { + @Transactional + public void uploadNotifyExcel(MultipartFile file, String site, String notifyNo) throws Exception { // 校验文件格式 if (file == null || file.isEmpty()) { throw new RuntimeException("请选择要上传的文件"); @@ -112,6 +119,9 @@ public class NewIssureServiceImpl implements NewIssureService { if (siteObj == null || StringUtils.isBlank(siteObj.toString())) { throw new RuntimeException("第" + rowIndex + "行的工厂编码(site)不能为空"); } + if (!siteObj.toString().trim().equals(site)){ + throw new RuntimeException("第" + rowIndex + "行的工厂编码(site)与当前工厂不一致"); + } notifyData.setSite(siteObj.toString().trim()); // 第二列:orderNo @@ -207,6 +217,153 @@ public class NewIssureServiceImpl implements NewIssureService { } System.out.println("=== 解析完成 ==="); - + // 按 site+orderNo+releaseNo+sequenceNo 分组 + Map> groupedDataMap = notifyExcelDataList.stream() + .collect(Collectors.groupingBy(data -> + data.getSite() + "|" + data.getOrderNo() + "|" + data.getReleaseNo() + "|" + data.getSequenceNo() + )); + + System.out.println("=== 分组处理开始 ==="); + System.out.println("共分为 " + groupedDataMap.size() + " 个工单组:"); + + // 遍历每个分组,进行业务处理 + for (Map.Entry> entry : groupedDataMap.entrySet()) { + String groupKey = entry.getKey(); + List groupData = entry.getValue(); + + // 解析分组key + String[] keyParts = groupKey.split("\\|"); + String site2 = keyParts[0]; + String orderNo = keyParts[1]; + String releaseNo = keyParts[2]; + String sequenceNo = keyParts[3]; + + System.out.println("处理工单组: site=" + site2 + ", orderNo=" + orderNo + + ", releaseNo=" + releaseNo + ", sequenceNo=" + sequenceNo + + ", 包含物料数量=" + groupData.size()); + + // TODO: 在这里添加你自己的业务逻辑代码 + // 参数说明: + // - site: 工厂编码 + // - orderNo: 订单号 + // - releaseNo: 发布号 + // - sequenceNo: 序列号 + // - groupData: 该工单下的所有物料列表 + processWorkOrderGroup(site2, orderNo, releaseNo, sequenceNo, groupData, notifyNo); + } + + System.out.println("=== 分组处理完成 ==="); + } + + /** + * 处理单个工单组的业务逻辑 + * @param site 工厂编码 + * @param orderNo 订单号 + * @param releaseNo 发布号 + * @param sequenceNo 序列号 + * @param materialList 该工单下的物料列表 + * @param notifyNo 申请单号 + */ + private void processWorkOrderGroup(String site, String orderNo, String releaseNo, + String sequenceNo, List materialList, String notifyNo) { + try { + System.out.println(" 开始处理工单: " + orderNo + "-" + releaseNo + "-" + sequenceNo); + + // 1. 校验工单是否存在 + IfsShopOrder shopOrderQuery = new IfsShopOrder(); + shopOrderQuery.setSite(site); + shopOrderQuery.setOrderNo(orderNo); + shopOrderQuery.setReleaseNo(releaseNo); + shopOrderQuery.setSequenceNo(sequenceNo); + + List shopOrders = ifsApiService.getShopOrderFromIFSWithOrderNo(shopOrderQuery); + if (shopOrders == null || shopOrders.isEmpty()) { + throw new RuntimeException("工单不存在: " + site + "-" + orderNo + "-" + releaseNo + "-" + sequenceNo); + } + + IfsShopOrder shopOrder = shopOrders.get(0); + System.out.println(" 工单校验通过: " + shopOrder.getPartNo() + " - " + shopOrder.getPartDesc()); + + // 2. 获取工单BOM信息 + List bomMaterials = ifsApiService.getSoBomWithOrderNo(shopOrderQuery); + if (bomMaterials == null || bomMaterials.isEmpty()) { + throw new RuntimeException("工单BOM为空: " + site + "-" + orderNo + "-" + releaseNo + "-" + sequenceNo); + } + + // 3. 校验Excel中的物料是否在BOM中存在 + for (NotifyExcelData excelMaterial : materialList) { + boolean found = false; + for (ShopOrderMaterialVo bomMaterial : bomMaterials) { + if (excelMaterial.getBomLineNo().equals(bomMaterial.getLineItemNo()) && + excelMaterial.getMaterialPartNo().equals(bomMaterial.getComponentPartNo())) { + found = true; + break; + } + } + if (!found) { + throw new RuntimeException("Excel中的物料在IFS工单BOM中不存在: 工单=" + orderNo + "-" + releaseNo + "-" + sequenceNo + + ", BOM行号=" + excelMaterial.getBomLineNo() + + ", 物料编码=" + excelMaterial.getMaterialPartNo()); + } + } + System.out.println(" 物料校验通过,Excel中" + materialList.size() + "个物料均在BOM中存在"); + + // 4. 保存SOIssueNotifyOrderList记录 + SOIssueNotifyOrderList orderListRecord = new SOIssueNotifyOrderList(); + orderListRecord.setNotifyNo(notifyNo); + orderListRecord.setSite(site); + orderListRecord.setFgPartNo(shopOrder.getPartNo()); + orderListRecord.setSoorderNo(orderNo); + orderListRecord.setReleaseNo(releaseNo); + orderListRecord.setSequenceNo(sequenceNo); + orderListRecord.setOutWorkOrderFlag("N"); + orderListRecord.setNeedDate(materialList.get(0).getNeedDate()); // 使用第一个物料的需求日期 + + // 获取下一个item_no(使用原有的IssureNotifyMapper) + BigDecimal nextItemNo = issureNotifyMapper.getNextItemForSOIssueNotifyOrderList(orderListRecord); + orderListRecord.setItemNo(nextItemNo); + + // 保存工单记录(使用Excel专用方法) + newIssureMapper.saveSOIssueNotifyOrderListForExcel(orderListRecord); + System.out.println(" 保存工单记录成功,itemNo=" + nextItemNo); + + // 5. 删除该工单下的旧物料明细(如果存在) + SOIssueNotifyOrderMaterialListData deleteParam = new SOIssueNotifyOrderMaterialListData(); + deleteParam.setSite(site); + deleteParam.setNotifyNo(notifyNo); + deleteParam.setItemNo(nextItemNo); + newIssureMapper.deleteSOIssueNotifyOrderMaterialListDataForExcel(deleteParam); + + // 6. 准备物料明细数据 + List materialDetails = new ArrayList<>(); + for (int i = 0; i < materialList.size(); i++) { + NotifyExcelData excelMaterial = materialList.get(i); + + SOIssueNotifyOrderMaterialListData materialDetail = new SOIssueNotifyOrderMaterialListData(); + materialDetail.setNotifyNo(notifyNo); + materialDetail.setSite(site); + materialDetail.setItemNo(nextItemNo); + materialDetail.setBOMItemNo(excelMaterial.getBomLineNo().toString()); + materialDetail.setComponentPartNo(excelMaterial.getMaterialPartNo()); + materialDetail.setQtyToIssue(excelMaterial.getQty()); + materialDetail.setQtyToIssueOriginal(BigDecimal.ZERO); + materialDetail.setIssueType("BOM物料"); + materialDetail.setRemark(""); + + materialDetails.add(materialDetail); + } + + // 7. 批量保存物料明细 + if (!materialDetails.isEmpty()) { + newIssureMapper.batchSaveSOIssueNotifyOrderMaterialListDataForExcel(materialDetails); + System.out.println(" 保存物料明细成功,共" + materialDetails.size() + "条记录"); + } + + System.out.println(" 工单处理完成: " + orderNo + "-" + releaseNo + "-" + sequenceNo); + + } catch (Exception e) { + System.err.println(" 工单处理失败: " + orderNo + "-" + releaseNo + "-" + sequenceNo + ", 错误: " + e.getMessage()); + throw new RuntimeException("工单处理失败: " + orderNo + "-" + releaseNo + "-" + sequenceNo + ", 原因: " + e.getMessage(), e); + } } } diff --git a/src/main/resources/mapper/notify/NewIssureMapper.xml b/src/main/resources/mapper/notify/NewIssureMapper.xml index c5bfe73..bb48771 100644 --- a/src/main/resources/mapper/notify/NewIssureMapper.xml +++ b/src/main/resources/mapper/notify/NewIssureMapper.xml @@ -1,14 +1,33 @@ + - + select a.notify_no,a.site,a.item_no,a.BOM_item_no as BOMItemNo,a.component_part_no as ComponentPartNo, + a.qty_to_issue as QtyToIssue,a.qty_to_issue_original as QtyToIssueOriginal,a.remark from SOIssueNotifyOrderMaterialList a - where a.notify_no = #{notifyNo} - and a.site = #{site} - and a.item_no = #{itemNo} + inner join SOIssueNotifyOrderList b on a.site=b.site and a.notify_no=b.notify_no and a.item_no=b.item_no + where a.notify_no=#{notifyNo} and a.site=#{site} and b.soorder_no=#{orderNo} + and b.release_no=#{releaseNo} and b.sequence_no=#{sequenceNo} + \ No newline at end of file