From 5478605ca0b502f10f9d4b0d0df49f159a0e034e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=B8=E7=86=9F=E5=90=B4=E5=BD=A6=E7=A5=96?= Date: Thu, 25 Dec 2025 10:36:54 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=98=E7=82=B9=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PhysicalInventoryController.java | 24 +++ .../check/mapper/PhysicalInventoryMapper.java | 21 ++- .../service/PhysicalInventoryService.java | 16 ++ .../impl/PhysicalInventoryServiceImpl.java | 161 ++++++++++++++++++ .../mapper/check/PhysicalInventoryMapper.xml | 18 +- 5 files changed, 238 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gaotao/modules/check/controller/PhysicalInventoryController.java b/src/main/java/com/gaotao/modules/check/controller/PhysicalInventoryController.java index d89fa9e..f14a78a 100644 --- a/src/main/java/com/gaotao/modules/check/controller/PhysicalInventoryController.java +++ b/src/main/java/com/gaotao/modules/check/controller/PhysicalInventoryController.java @@ -111,6 +111,30 @@ public class PhysicalInventoryController { int result = physicalInventoryService.addMaterialToCount(query); return R.ok().put("result", result); } + + /** + * @Description 一键添加物料 - 根据物料号精确查询所有标签并添加到盘点单 - rqrq + * @param query 包含site、countNo、searchPartNo、username + * @return R + * @author rqrq + */ + @PostMapping("/quickAddMaterialByPartNo") + public R quickAddMaterialByPartNo(@RequestBody CountHeaderData query) { + int result = physicalInventoryService.quickAddMaterialByPartNo(query); + return R.ok().put("result", result); + } + + /** + * @Description 一键删除物料 - 根据物料号删除盘点单中该物料的所有标签 - rqrq + * @param query 包含site、countNo、searchPartNo + * @return R + * @author rqrq + */ + @PostMapping("/deleteMaterialByPartNo") + public R deleteMaterialByPartNo(@RequestBody CountHeaderData query) { + int result = physicalInventoryService.deleteMaterialByPartNo(query); + return R.ok().put("result", result); + } /** * @Description 下达盘点单 - rqrq diff --git a/src/main/java/com/gaotao/modules/check/mapper/PhysicalInventoryMapper.java b/src/main/java/com/gaotao/modules/check/mapper/PhysicalInventoryMapper.java index b451e50..330a299 100644 --- a/src/main/java/com/gaotao/modules/check/mapper/PhysicalInventoryMapper.java +++ b/src/main/java/com/gaotao/modules/check/mapper/PhysicalInventoryMapper.java @@ -497,7 +497,7 @@ public interface PhysicalInventoryMapper extends BaseMapper { */ int deleteCountLabel(@Param("site") String site, @Param("countNo") String countNo); - /** +/** * @Description 删除盘点栈板子表 - rqrq * @param site 工厂编码 * @param countNo 盘点单号 @@ -506,6 +506,25 @@ public interface PhysicalInventoryMapper extends BaseMapper { */ int deleteCountPallet(@Param("site") String site, @Param("countNo") String countNo); + /** + * @Description 根据物料号删除盘点标签 - rqrq + * @param site 工厂编码 + * @param countNo 盘点单号 + * @param partNo 物料号 + * @return int 删除数量 + * @author rqrq + */ + int deleteCountLabelByPartNo(@Param("site") String site, @Param("countNo") String countNo, @Param("partNo") String partNo); + + /** + * @Description 清理没有标签的栈板记录 - rqrq + * @param site 工厂编码 + * @param countNo 盘点单号 + * @return int 删除数量 + * @author rqrq + */ + int deleteEmptyCountPallets(@Param("site") String site, @Param("countNo") String countNo); + // ==================== 推送WCS相关 ==================== /** diff --git a/src/main/java/com/gaotao/modules/check/service/PhysicalInventoryService.java b/src/main/java/com/gaotao/modules/check/service/PhysicalInventoryService.java index db119ae..24ea6ee 100644 --- a/src/main/java/com/gaotao/modules/check/service/PhysicalInventoryService.java +++ b/src/main/java/com/gaotao/modules/check/service/PhysicalInventoryService.java @@ -74,6 +74,22 @@ public interface PhysicalInventoryService { */ int addMaterialToCount(CountHeaderData query); + /** + * @Description 一键添加物料 - 根据物料号精确查询所有标签并添加到盘点单 - rqrq + * @param query 包含site、countNo、searchPartNo、username + * @return int 新增标签数量 + * @author rqrq + */ + int quickAddMaterialByPartNo(CountHeaderData query); + + /** + * @Description 一键删除物料 - 根据物料号删除盘点单中该物料的所有标签 - rqrq + * @param query 包含site、countNo、searchPartNo + * @return int 删除标签数量 + * @author rqrq + */ + int deleteMaterialByPartNo(CountHeaderData query); + /** * @Description 下达盘点单 - rqrq * @param query 包含site、countNo、username diff --git a/src/main/java/com/gaotao/modules/check/service/impl/PhysicalInventoryServiceImpl.java b/src/main/java/com/gaotao/modules/check/service/impl/PhysicalInventoryServiceImpl.java index c6d6cc1..b33038f 100644 --- a/src/main/java/com/gaotao/modules/check/service/impl/PhysicalInventoryServiceImpl.java +++ b/src/main/java/com/gaotao/modules/check/service/impl/PhysicalInventoryServiceImpl.java @@ -553,6 +553,167 @@ public class PhysicalInventoryServiceImpl extends ServiceImpl existingLabels = baseMapper.searchCountLabelList(labelQuery); + Set existingUnitIds = existingLabels.stream() + .map(CountLabelData::getUnitId) + .collect(Collectors.toSet()); + + // 4. 根据物料号精确查询所有标签(在立库中的)- rqrq + CountMaterialSummary labelQueryParam = new CountMaterialSummary(); + labelQueryParam.setSite(query.getSite()); + labelQueryParam.setSearchPartNo(query.getSearchPartNo()); // 精确匹配 + + List allLabels = baseMapper.queryLabelsByMaterial(labelQueryParam); + + // 5. 过滤出未在盘点单中的标签 - rqrq + List newLabels = allLabels.stream() + .filter(label -> query.getSearchPartNo().equals(label.getPartNo())) // 精确匹配物料号 + .filter(label -> !existingUnitIds.contains(label.getUnitId())) + .collect(Collectors.toList()); + + if (newLabels.isEmpty()) { + throw new RuntimeException("没有找到新的可添加标签(物料号: " + query.getSearchPartNo() + ")"); + } + + // 6. 收集涉及的栈板 - rqrq + Set newPallets = new LinkedHashSet<>(); + for (CountLabelInfo label : newLabels) { + if (label.getPalletId() != null) { + newPallets.add(label.getPalletId()); + } + } + + log.info("新增标签数: {},涉及托盘数: {}", newLabels.size(), newPallets.size()); + + // 7. 创建盘点标签子表 - rqrq + List countLabels = new ArrayList<>(); + for (CountLabelInfo labelInfo : newLabels) { + CountLabel countLabel = createCountLabel(query.getSite(), query.getCountNo(), labelInfo, + CountLabel.LABEL_TYPE_ASSIGNED, query.getUsername()); + countLabels.add(countLabel); + } + + if (!countLabels.isEmpty()) { + baseMapper.batchInsertCountLabel(countLabels); + } + + // 8. 创建/更新盘点栈板子表 - rqrq + Integer maxSeqNo = baseMapper.getMaxSeqNo(query.getSite(), query.getCountNo()); + int seqNo = (maxSeqNo == null ? 0 : maxSeqNo) + 1; + + List countPallets = new ArrayList<>(); + for (String palletId : newPallets) { + int exists = baseMapper.checkCountPalletExists(query.getSite(), query.getCountNo(), palletId); + if (exists == 0) { + int labelCount = (int) countLabels.stream() + .filter(l -> palletId.equals(l.getPalletId())) + .count(); + + Integer locationZ = 1; + CountLabelInfo firstLabel = newLabels.stream() + .filter(l -> palletId.equals(l.getPalletId())) + .findFirst() + .orElse(null); + if (firstLabel != null && firstLabel.getLocationZ() != null) { + locationZ = firstLabel.getLocationZ().intValue(); + } + + CountPallet countPallet = new CountPallet(); + countPallet.setSite(query.getSite()); + countPallet.setCountNo(query.getCountNo()); + countPallet.setSeqNo(seqNo++); + countPallet.setPalletId(palletId); + countPallet.setCountFlag(CountPallet.COUNT_FLAG_NO); + countPallet.setLabelCount(labelCount); + countPallet.setCheckedCount(0); + countPallet.setLocationZ(locationZ); + countPallet.setCreatedBy(query.getUsername()); + countPallets.add(countPallet); + } + } + + if (!countPallets.isEmpty()) { + baseMapper.batchInsertCountPallet(countPallets); + } + + log.info("quickAddMaterialByPartNo 结束,新增标签数: {}", countLabels.size()); + return countLabels.size(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteMaterialByPartNo(CountHeaderData query) { + log.info("deleteMaterialByPartNo 开始,site: {}, countNo: {}, partNo: {}", + query.getSite(), query.getCountNo(), query.getSearchPartNo()); + + // 1. 参数校验 - rqrq + if (!StringUtils.hasText(query.getSite())) { + throw new RuntimeException("工厂编码不能为空"); + } + if (!StringUtils.hasText(query.getCountNo())) { + throw new RuntimeException("盘点单号不能为空"); + } + if (!StringUtils.hasText(query.getSearchPartNo())) { + throw new RuntimeException("物料号不能为空"); + } + + // 2. 校验盘点单状态 - rqrq + CountHeaderData header = getCountHeaderByNo(query.getSite(), query.getCountNo()); + if (header == null) { + throw new RuntimeException("盘点单不存在"); + } + if (!CountHeader.STATUS_DRAFT.equals(header.getStatus())) { + throw new RuntimeException("只有草稿状态的盘点单才能删除物料"); + } + if (!CountHeader.COUNT_TYPE_MANUAL.equals(header.getCountType())) { + throw new RuntimeException("只有手工盘点单才能删除物料"); + } + + // 3. 删除该物料的所有标签 - rqrq + int deleteCount = baseMapper.deleteCountLabelByPartNo(query.getSite(), query.getCountNo(), query.getSearchPartNo()); + log.info("已删除标签数: {}", deleteCount); + + // 4. 清理没有标签的栈板 - rqrq + int cleanedPallets = baseMapper.deleteEmptyCountPallets(query.getSite(), query.getCountNo()); + log.info("已清理空栈板数: {}", cleanedPallets); + + log.info("deleteMaterialByPartNo 结束,删除标签数: {}", deleteCount); + return deleteCount; + } @Override @Transactional(rollbackFor = Exception.class) diff --git a/src/main/resources/mapper/check/PhysicalInventoryMapper.xml b/src/main/resources/mapper/check/PhysicalInventoryMapper.xml index dfcb917..908cc6b 100644 --- a/src/main/resources/mapper/check/PhysicalInventoryMapper.xml +++ b/src/main/resources/mapper/check/PhysicalInventoryMapper.xml @@ -810,7 +810,7 @@ LEFT JOIN agv_station s ON p.location_code = s.station_code WHERE h.site = #{query.site} AND p.pallet_id IS NOT NULL and p.wcs_location is not null - AND h.part_no LIKE '%' + #{query.searchPartNo} + '%' + AND h.part_no LIKE #{query.searchPartNo} AND h.batch_no LIKE '%' + #{query.searchBatchNo} + '%' @@ -898,6 +898,22 @@ DELETE FROM count_pallet WHERE site = #{site} AND count_no = #{countNo} + + + + DELETE FROM count_label + WHERE site = #{site} AND count_no = #{countNo} AND part_no = #{partNo} + + + + + DELETE FROM count_pallet + WHERE site = #{site} AND count_no = #{countNo} + AND pallet_id NOT IN ( + SELECT DISTINCT pallet_id FROM count_label + WHERE site = #{site} AND count_no = #{countNo} + ) +