From 6ef4713bb11c30b5a5f14d91c88d45700e2dbc06 Mon Sep 17 00:00:00 2001 From: fengyuan_yang <1976974459@qq.com> Date: Mon, 3 Nov 2025 14:05:53 +0800 Subject: [PATCH] =?UTF-8?q?2025-11-03=20pda=E8=B0=83=E6=95=B4=E6=89=AB?= =?UTF-8?q?=E6=8F=8F=E3=80=81=E6=9F=A5=E8=AF=A2=E3=80=81=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=88=E7=94=9F=E4=BA=A7=E9=A2=86=E6=96=99?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProductionPickingController.java | 84 ++++++++-- .../dao/ProductionPickingMapper.java | 8 + .../service/ProductionPickingService.java | 36 +++- .../impl/ProductionPickingServiceImpl.java | 156 ++++++++++++++---- .../mapper/orderIssure/IssureNotifyMapper.xml | 8 +- .../ProductionPickingMapper.xml | 20 ++- 6 files changed, 261 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/gaotao/modules/productionPicking/controller/ProductionPickingController.java b/src/main/java/com/gaotao/modules/productionPicking/controller/ProductionPickingController.java index a46ec93..d0b0589 100644 --- a/src/main/java/com/gaotao/modules/productionPicking/controller/ProductionPickingController.java +++ b/src/main/java/com/gaotao/modules/productionPicking/controller/ProductionPickingController.java @@ -2,8 +2,10 @@ package com.gaotao.modules.productionPicking.controller; import com.gaotao.common.utils.R; import com.gaotao.modules.productionPicking.service.ProductionPickingService; +import com.gaotao.modules.sys.entity.SysUserEntity; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import org.apache.shiro.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -84,7 +86,7 @@ public class ProductionPickingController { } /** - * 验证标签与出库单是否匹配 + * 验证标签(通过存储过程) */ @PostMapping("/outbound/validateLabel") @ApiOperation("验证标签与出库单是否匹配") @@ -92,13 +94,30 @@ public class ProductionPickingController { try { String labelCode = (String) params.get("labelCode"); String outboundNo = (String) params.get("outboundNo"); - String warehouseId = (String) params.get("warehouseId"); + String relatedNo = (String) params.get("relatedNo"); String site = (String) params.get("site"); String buNo = (String) params.get("buNo"); - String relatedNo = (String) params.get("relatedNo"); + String operationType = (String) params.get("operationType"); + + if (labelCode == null || labelCode.trim().isEmpty()) { + return R.error("标签条码不能为空"); + } + + if (outboundNo == null || outboundNo.trim().isEmpty()) { + return R.error("出库单号不能为空"); + } + + if (operationType == null || operationType.trim().isEmpty()) { + operationType = "I"; // 默认为添加 + } - logger.info("验证标签,标签码: {}, 出库单号: {}, 仓库: {}, 站点: {}, 业务单元: {}", labelCode, outboundNo, warehouseId, site, buNo); - List> result = productionPickingService.validateLabelWithOutbound(labelCode, outboundNo, warehouseId, site, buNo, relatedNo); + // 获取当前登录用户 + SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); + String userName = sysUserEntity.getUsername(); + + logger.info("验证生产领料标签,标签码: {}, 出库单号: {}, 关联单号: {}, 操作类型: {}", labelCode, outboundNo, relatedNo, operationType); + Map result = productionPickingService.validateLabelWithOutbound( + site, buNo, outboundNo, relatedNo, labelCode, operationType, userName); return R.ok().put("data", result); } catch (Exception e) { logger.error("标签验证失败", e); @@ -107,7 +126,7 @@ public class ProductionPickingController { } /** - * 确认生产领料 + * 确认生产领料(通过存储过程) */ @PostMapping("/outbound/confirm") @ApiOperation("确认生产领料") @@ -116,13 +135,24 @@ public class ProductionPickingController { String site = (String) params.get("site"); String buNo = (String) params.get("buNo"); String outboundNo = (String) params.get("outboundNo"); - String warehouseId = (String) params.get("warehouseId"); String relatedNo = (String) params.get("relatedNo"); - List> labels = (List>) params.get("labels"); + String locationCode = (String) params.get("locationCode"); + + if (outboundNo == null || outboundNo.trim().isEmpty()) { + return R.error("出库单号不能为空"); + } + if (locationCode == null || locationCode.trim().isEmpty()) { + return R.error("库位号不能为空"); + } + + // 获取当前登录用户 + SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); + String userName = sysUserEntity.getUsername(); - logger.info("确认生产领料,出库单号: {}, 业务单元: {}, 仓库: {}, 标签数量: {}", outboundNo, buNo, warehouseId, labels != null ? labels.size() : 0); + logger.info("确认生产领料,出库单号: {}, 业务单元: {}, 关联单号: {}", outboundNo, buNo, relatedNo); - boolean success = productionPickingService.confirmProductionPicking(site, buNo, outboundNo, warehouseId, labels, relatedNo); + boolean success = productionPickingService.confirmProductionPicking( + site, buNo, outboundNo, relatedNo, locationCode, userName); if (success) { return R.ok("领料成功"); } else { @@ -185,4 +215,38 @@ public class ProductionPickingController { return R.error("获取物料明细失败: " + e.getMessage()); } } + + /** + * 获取已扫描标签列表(从缓存表) + */ + @PostMapping("/outbound/getScannedLabelList") + @ApiOperation("获取已扫描标签列表") + public R getScannedLabelList(@RequestBody Map params) { + try { + String site = (String) params.get("site"); + String buNo = (String) params.get("buNo"); + String outboundNo = (String) params.get("outboundNo"); + String relatedNo = (String) params.get("relatedNo"); + + if (site == null || site.trim().isEmpty()) { + return R.error("站点不能为空"); + } + + if (buNo == null || buNo.trim().isEmpty()) { + return R.error("业务单元不能为空"); + } + + if (outboundNo == null || outboundNo.trim().isEmpty()) { + return R.error("出库单号不能为空"); + } + + List> labelList = productionPickingService.getScannedLabelList( + site, buNo, outboundNo, relatedNo); + + return R.ok().put("data", labelList); + } catch (Exception e) { + logger.error("获取已扫描标签列表失败", e); + return R.error("获取已扫描标签列表失败: " + e.getMessage()); + } + } } diff --git a/src/main/java/com/gaotao/modules/productionPicking/dao/ProductionPickingMapper.java b/src/main/java/com/gaotao/modules/productionPicking/dao/ProductionPickingMapper.java index 18f27cf..1f76fb7 100644 --- a/src/main/java/com/gaotao/modules/productionPicking/dao/ProductionPickingMapper.java +++ b/src/main/java/com/gaotao/modules/productionPicking/dao/ProductionPickingMapper.java @@ -76,4 +76,12 @@ public interface ProductionPickingMapper { void updateSoBomPickedQty(@Param("site") String site, @Param("relatedNo") String relatedNo, @Param("partNo") String partno, @Param("transQty") BigDecimal transqty); + + /** + * 获取已扫描标签列表(从缓存表) + */ + List> getScannedLabelList(@Param("site") String site, + @Param("buNo") String buNo, + @Param("outboundNo") String outboundNo, + @Param("relatedNo") String relatedNo); } diff --git a/src/main/java/com/gaotao/modules/productionPicking/service/ProductionPickingService.java b/src/main/java/com/gaotao/modules/productionPicking/service/ProductionPickingService.java index cb9ace8..16d18e6 100644 --- a/src/main/java/com/gaotao/modules/productionPicking/service/ProductionPickingService.java +++ b/src/main/java/com/gaotao/modules/productionPicking/service/ProductionPickingService.java @@ -20,16 +20,32 @@ public interface ProductionPickingService { Map getOutboundDetails(String outboundNo, String buNo, String warehouseId, String site, String relatedNo); /** - * 验证标签与出库单是否匹配,并检查库存 + * 验证标签(通过存储过程) + * @param site 站点 + * @param buNo 业务单元 + * @param outboundNo 出库单号 + * @param relatedNo 关联单号 + * @param labelCode 标签条码 + * @param operationType 操作类型 I-添加 D-移除 + * @param userName 当前登录人 + * @return 标签信息 */ - List> validateLabelWithOutbound(String labelCode, String outboundNo, - String warehouseId, String site, String buNo, String relatedNo); + Map validateLabelWithOutbound(String site, String buNo, String outboundNo, + String relatedNo, String labelCode, + String operationType, String userName); /** - * 确认生产领料 + * 确认生产领料(通过存储过程) + * @param site 站点 + * @param buNo 业务单元 + * @param outboundNo 出库单号 + * @param relatedNo 关联单号 + * @param locationCode 库位号 + * @param userName 当前登录人 + * @return 处理结果 */ boolean confirmProductionPicking(String site, String buNo, String outboundNo, - String warehouseId, List> labels, String relatedNo); + String relatedNo, String locationCode, String userName); /** * 获取出库单物料清单 @@ -40,4 +56,14 @@ public interface ProductionPickingService { * 获取出库单物料明细列表 */ List> getOutboundMaterialDetails(String site, String outboundNo); + + /** + * 获取已扫描标签列表(从缓存表) + * @param site 站点 + * @param buNo 业务单元 + * @param outboundNo 出库单号 + * @param relatedNo 关联单号 + * @return 已扫描标签列表 + */ + List> getScannedLabelList(String site, String buNo, String outboundNo, String relatedNo); } diff --git a/src/main/java/com/gaotao/modules/productionPicking/service/impl/ProductionPickingServiceImpl.java b/src/main/java/com/gaotao/modules/productionPicking/service/impl/ProductionPickingServiceImpl.java index 18a9947..ad8a23a 100644 --- a/src/main/java/com/gaotao/modules/productionPicking/service/impl/ProductionPickingServiceImpl.java +++ b/src/main/java/com/gaotao/modules/productionPicking/service/impl/ProductionPickingServiceImpl.java @@ -6,6 +6,7 @@ import com.gaotao.modules.productionPicking.service.ProductionPickingService; import com.gaotao.modules.inventoryStock.entity.InventoryStock; import com.gaotao.modules.inventoryStock.service.InventoryStockService; import com.gaotao.modules.productionPicking.service.StockTransactionLogService; +import com.gaotao.modules.schedule.mapper.ProcedureMapper; import com.gaotao.modules.sys.entity.SysUserEntity; import com.gaotao.modules.trans.entity.TransDetail; import com.gaotao.modules.trans.entity.TransDetailDto; @@ -50,6 +51,8 @@ public class ProductionPickingServiceImpl implements ProductionPickingService { @Autowired private StockTransactionLogService stockTransactionLogService; + @Autowired + private ProcedureMapper procedureMapper; @Override public List> getOutboundList(String site, String warehouseId, String searchCode, String status) { @@ -65,48 +68,120 @@ public class ProductionPickingServiceImpl implements ProductionPickingService { } @Override - public List> validateLabelWithOutbound(String labelCode, String outboundNo, String warehouseId, String site, String buNo, String relatedNo) { - logger.info("验证标签与出库单匹配,标签码: {}, 出库单号: {}, 仓库: {}, 站点: {}, 业务单元: {}", labelCode, outboundNo, warehouseId, site, buNo); - // 1. 验证标签与出库单物料是否匹配 - List> labelInfos = pickingMapper.validateLabelWithOutbound(labelCode, outboundNo, site, buNo, warehouseId, relatedNo); - if (labelInfos == null || labelInfos.isEmpty()) { - throw new RuntimeException("该标签与出库单不符,请检查"); + public Map validateLabelWithOutbound(String site, String buNo, String outboundNo, + String relatedNo, String labelCode, + String operationType, String userName) { + logger.info("验证生产领料标签,site: {}, buNo: {}, 出库单号: {}, 关联单号: {}, 标签: {}, 操作类型: {}", + site, buNo, outboundNo, relatedNo, labelCode, operationType); + + try { + // 调用存储过程 GetScanLabelVerification + List params = new ArrayList<>(); + params.add(site); // 参数1: site + params.add(buNo); // 参数2: buNo + params.add(outboundNo); // 参数3: 出库单号 + params.add(relatedNo); // 参数4: 关联单号 + params.add(""); // 参数5: 空字符串 + params.add(""); // 参数6: 空字符串 + params.add(""); // 参数7: 空字符串 + params.add(labelCode); // 参数8: 扫描的标签条码 + params.add(""); // 参数9: 空字符串 + params.add("生产领料"); // 参数10: 生产领料 + params.add(operationType); // 参数11: 操作类型 I或D + params.add(userName); // 参数12: 当前登陆人 + + List> resultList = procedureMapper.getProcedureData("GetScanLabelVerification", params); + + // 判断返回结果 + if (resultList == null || resultList.isEmpty()) { + throw new RuntimeException("存储过程调用失败"); + } + + Map result = resultList.get(0); + String code = String.valueOf(result.get("code")); + + if (!"200".equals(code)) { + String msg = String.valueOf(result.get("message")); + throw new RuntimeException(msg); + } + + logger.info("标签验证成功,标签: {}, 操作类型: {}", labelCode, operationType); + return result; + } catch (Exception e) { + logger.error("标签验证失败,标签: {}, 错误: {}", labelCode, e.getMessage(), e); + throw new RuntimeException(e.getMessage(), e); } - return labelInfos; } @Override @Transactional(rollbackFor = Exception.class) - public boolean confirmProductionPicking(String site, String buNo, String outboundNo, String warehouseId, List> labels, String relatedNo) { - logger.info("开始确认生产领料,出库单号: {}, 业务单元: {}, 仓库: {}, 标签数量: {}", outboundNo, buNo, warehouseId, labels.size()); - SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); - String userName = sysUserEntity.getUsername(); - + public boolean confirmProductionPicking(String site, String buNo, String outboundNo, + String relatedNo, String locationCode, String userName) { + logger.info("开始确认生产领料,site: {}, buNo: {}, 出库单号: {}, 关联单号: {}, 库位: {}", + site, buNo, outboundNo, relatedNo, locationCode); + try { - // 1. 提取标签条码列表 - List labelCodes = labels.stream() - .map(label -> (String) label.get("labelCode")) - .collect(Collectors.toList()); - - // 2. 更新WMS库存表中的标签状态(生产领料直接操作库存) - updateInventoryStockStatus(labels, site, buNo, warehouseId, outboundNo); - -// // 3. 更新出库单状态 -// int updatedHead = pickingMapper.updateOutboundStatus(outboundNo, buNo, "已出库", site); -// if (updatedHead == 0) { -// throw new RuntimeException("出库单状态更新失败"); -// } - - // 4. 生成WMS出库记录 - generateOutboundTransaction(outboundNo, warehouseId, labels, site, buNo, relatedNo, userName); - logger.info("生产领料确认完成,出库单号: {}, 处理标签数: {}", outboundNo, labels.size()); + // 调用存储过程 GetSaveLabelVerification + List params = new ArrayList<>(); + params.add(site); // 参数1: site + params.add(buNo); // 参数2: buNo + params.add(outboundNo); // 参数3: 出库单号 + params.add(relatedNo); // 参数4: 关联单号 + params.add(""); // 参数5: 空字符串 + params.add(""); // 参数6: 空字符串 + params.add(""); // 参数7: 空字符串 + params.add(locationCode); // 参数8: 库位 + params.add("生产领料"); // 参数9: 生产领料 + params.add(userName); // 参数10: 当前登陆人 + + List> resultList = procedureMapper.getProcedureData("GetSaveLabelVerification", params); + + // 判断返回结果 + if (resultList == null || resultList.isEmpty()) { + throw new RuntimeException("存储过程调用失败"); + } + + Map result = resultList.get(0); + String code = String.valueOf(result.get("code")); + + if (!"200".equals(code)) { + String msg = String.valueOf(result.get("message")); + throw new RuntimeException(msg); + } + + logger.info("生产领料确认成功,出库单号: {}", outboundNo); return true; } catch (Exception e) { - logger.error("生产领料确认失败,出库单号: {}, 错误信息: {}", outboundNo, e.getMessage(), e); + logger.error("生产领料确认失败,出库单号: {}, 错误: {}", outboundNo, e.getMessage(), e); throw new RuntimeException(e.getMessage(), e); } } + // 保留原有的实现方法作为注释,以防需要 + // private boolean confirmProductionPickingOld(String site, String buNo, String outboundNo, String warehouseId, List> labels, String relatedNo) { + // logger.info("开始确认生产领料(旧方法),出库单号: {}, 业务单元: {}, 仓库: {}, 标签数量: {}", outboundNo, buNo, warehouseId, labels.size()); + // SysUserEntity sysUserEntity = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); + // String userName = sysUserEntity.getUsername(); + // + // try { + // // 1. 提取标签条码列表 + // List labelCodes = labels.stream() + // .map(label -> (String) label.get("labelCode")) + // .collect(Collectors.toList()); + // + // // 2. 更新WMS库存表中的标签状态(生产领料直接操作库存) + // updateInventoryStockStatus(labels, site, buNo, warehouseId, outboundNo); + // + // // 3. 生成WMS出库记录 + // generateOutboundTransaction(outboundNo, warehouseId, labels, site, buNo, relatedNo, userName); + // logger.info("生产领料确认完成,出库单号: {}, 处理标签数: {}", outboundNo, labels.size()); + // return true; + // } catch (Exception e) { + // logger.error("生产领料确认失败,出库单号: {}, 错误信息: {}", outboundNo, e.getMessage(), e); + // throw new RuntimeException(e.getMessage(), e); + // } + // } + @Override public List> getMaterialList(String site, String buNo, String outboundNo, String warehouseId, String relatedNo) { logger.info("获取出库单物料清单,站点: {}, 业务单元: {}, 出库单号: {}", site, buNo, outboundNo); @@ -385,4 +460,25 @@ public class ProductionPickingServiceImpl implements ProductionPickingService { } } } + + @Override + public List> getScannedLabelList(String site, String buNo, String outboundNo, String relatedNo) { + logger.info("获取已扫描标签列表,site: {}, buNo: {}, 出库单号: {}, 关联单号: {}", + site, buNo, outboundNo, relatedNo); + + try { + List> labelList = pickingMapper.getScannedLabelList( + site, buNo, outboundNo, relatedNo); + + if (labelList == null) { + labelList = new ArrayList<>(); + } + + logger.info("获取已扫描标签列表成功,共 {} 条记录", labelList.size()); + return labelList; + } catch (Exception e) { + logger.error("获取已扫描标签列表失败,错误: {}", e.getMessage(), e); + throw new RuntimeException("获取已扫描标签列表失败: " + e.getMessage(), e); + } + } } diff --git a/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml b/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml index 76879b8..777cc4b 100644 --- a/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml +++ b/src/main/resources/mapper/orderIssure/IssureNotifyMapper.xml @@ -347,18 +347,18 @@ RecordVersion,OutWorkOrderFlag,ProjectID,OrderType,AuthRuleID,bu) A.NotifyNo, a.ComponentPartNo, sum(a.QtyToIssue) QtyToIssue, - dbo.Get_InboundQty(a.site, B.bu, a.NotifyNo, a.ComponentPartNo, 'SI') as QtyToIssue_Original, + dbo.Get_InboundQty(a.site, B.bu, a.NotifyNo, SOOrderNo,SeqNo, 'soi') as QtyToIssue_Original, dbo.Get_PartDesc(a.site,a.ComponentPartNo) partDesc, a.issueType, a.warehouse_id, W.WareHouseName AS warehouseName from SOIssueNotifyHeader B - INNER JOIN SOIssueNotifyOrderMaterialList a ON A.SITE = B.SITE AND A.NotifyNo = B.NotifyNo + INNER JOIN SOIssueNotifyOrderList C ON B.SITE = C.SITE AND B.NotifyNo = C.NotifyNo + INNER JOIN SOIssueNotifyOrderMaterialList a ON A.SITE = C.SITE AND A.NotifyNo = C.NotifyNo AND A.ItemNo = C.ItemNo left join WareHouse w on a.site = w.site and a.warehouse_id = w.WareHouseID where a.NotifyNo = #{notifyNo} and a.site = #{site} and b.bu = #{bu} - group by a.site, a.ComponentPartNo, a.issueType , b.BU ,a.warehouse_id ,wareHouseName, a.site, b.bu, A.NotifyNo + group by a.site, a.ComponentPartNo, a.issueType , b.BU ,a.warehouse_id ,wareHouseName, a.site, b.bu, A.NotifyNo,SOOrderNo,SeqNo order by a.issueType - @@ -169,4 +169,20 @@ AND OrderNo = #{relatedNo} AND ComponentPartNo = #{partNo} + + +