diff --git a/src/main/java/com/zg/project/Inventory/AutoInventory/service/impl/InventoryMatchScanServiceImpl.java b/src/main/java/com/zg/project/Inventory/AutoInventory/service/impl/InventoryMatchScanServiceImpl.java index d5bcc92..fd40a69 100644 --- a/src/main/java/com/zg/project/Inventory/AutoInventory/service/impl/InventoryMatchScanServiceImpl.java +++ b/src/main/java/com/zg/project/Inventory/AutoInventory/service/impl/InventoryMatchScanServiceImpl.java @@ -66,8 +66,9 @@ public class InventoryMatchScanServiceImpl implements InventoryMatchScanService } // 状态=1:查询指定仓库下未被扫描的库位 else if ("1".equals(param.getStatus())) { - String wh = taskMapper.getWhByTaskId(param.getTaskId()); // 根据任务ID获取仓库ID - return rkInfoMapper.getUnscannedPcodeByWh(wh, param.getTaskId()); + // ✅ 根据任务ID取 sceneId,再按 scene 查询“未被扫描”的库位 + String sceneId = taskMapper.getSceneByTaskId(param.getTaskId()); + return rkInfoMapper.getUnscannedPcodeByScene(sceneId, param.getTaskId()); } // 其它情况:返回扫描表和库存表的关联数据 else { diff --git a/src/main/java/com/zg/project/Inventory/Task/mapper/InventoryTaskMapper.java b/src/main/java/com/zg/project/Inventory/Task/mapper/InventoryTaskMapper.java index 98fc512..b14edca 100644 --- a/src/main/java/com/zg/project/Inventory/Task/mapper/InventoryTaskMapper.java +++ b/src/main/java/com/zg/project/Inventory/Task/mapper/InventoryTaskMapper.java @@ -74,6 +74,13 @@ public interface InventoryTaskMapper */ String getWhByTaskId(String taskId); + /** + * 根据任务ID查询场景ID + * @param taskId + * @return + */ + String getSceneByTaskId(@Param("taskId") String taskId); + /** * 更新任务状态 * @param taskId diff --git a/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java b/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java index 38e81de..7c3a282 100644 --- a/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java +++ b/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java @@ -2,6 +2,7 @@ package com.zg.project.information.mapper; import java.util.List; import com.zg.project.information.domain.PcdeDetail; +import org.apache.ibatis.annotations.Param; /** * 库位明细Mapper接口 @@ -66,4 +67,11 @@ public interface PcdeDetailMapper * @return */ PcdeDetail selectByPcode(String pcode); + + /** + * 根据仓库编码查询库位编码 + * @param pcode + * @return + */ + String selectEncodedIdByPcode(@Param("pcode") String pcode);; } diff --git a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java index d4621ae..589420d 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java @@ -153,10 +153,11 @@ public interface RkInfoMapper /** * 根据所属仓库查询所有的库位号和库位对应的货物数量 - * @param wh + * @param * @return */ - List getUnscannedPcodeByWh(@Param("wh") String wh, @Param("taskId") String taskId); + List getUnscannedPcodeByScene(@Param("sceneId") String sceneId, + @Param("taskId") String taskId); /** * 图表统计:每个库位有多少个货物 diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java index 487e6c5..adc73aa 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java @@ -18,6 +18,7 @@ import com.zg.project.Inventory.domain.dto.QueryDTO; import com.zg.project.Inventory.domain.entity.InventoryMatchScan; import com.zg.project.Inventory.domain.vo.ChartDataVO; import com.zg.project.Inventory.domain.vo.PcdeCntVO; +import com.zg.project.information.mapper.PcdeDetailMapper; import com.zg.project.system.service.ISysConfigService; import com.zg.project.wisdom.domain.AuditSignature; import com.zg.project.wisdom.domain.GysJh; @@ -63,6 +64,10 @@ public class RkInfoServiceImpl implements IRkInfoService @Autowired private ISysConfigService configService; + @Autowired + private PcdeDetailMapper pcdeDetailMapper; + + /** * 查询库存单据主 * @@ -326,6 +331,8 @@ public class RkInfoServiceImpl implements IRkInfoService for (PcRkInfoItemDTO item : list) { RkInfo rk = new RkInfo(); BeanUtils.copyProperties(item, rk); + String encodedId = pcdeDetailMapper.selectEncodedIdByPcode(item.getPcode()); + rk.setPcodeId(encodedId); rk.setBillNo(billNo); rk.setRkType(dto.getRkType()); rk.setWlType(dto.getWlType()); @@ -738,37 +745,44 @@ public class RkInfoServiceImpl implements IRkInfoService } @Override - @Transactional(rollbackFor = Exception.class) + @Transactional(rollbackFor = Exception.class) // 开启事务,异常时回滚 public void matchWithStatus(QueryDTO dto) { + // 从 DTO 获取待比对的库位 ID 列表 List pcdeIds = dto.getIds(); - if (pcdeIds == null || pcdeIds.isEmpty()) return; + if (pcdeIds == null || pcdeIds.isEmpty()) return; // 如果为空,直接返回 - // 场景ID:优先取 DTO;没有就通过任务查 + // 通过任务 ID 获取场景 ID(优先取 DTO 中的,若无则从任务表查) String sceneId = taskMapper.selectSceneIdById(dto.getTaskId()); if (sceneId == null || sceneId.trim().isEmpty()) { throw new ServiceException("匹配失败:缺少场景ID"); } - // 自动盘点必须要设备ID + // 自动盘点必须有设备 ID String deviceId = dto.getDeviceId(); - int scanType = dto.getScanType() != null ? dto.getScanType() : 0; + int scanType = dto.getScanType() != null ? dto.getScanType() : 0; // 扫描类型:0=手动盘点,1=自动盘点 String taskId = dto.getTaskId(); + // 校验:若是自动盘点(scanType=1),但未传设备 ID,则报错 if (scanType == 1 && (deviceId == null || deviceId.trim().isEmpty())) { throw new ServiceException("自动盘点必须传递设备ID"); } - // 三类数据(限定在 sceneId 内) + // ====================== 分类匹配三类数据 ====================== + + // 1. 正常匹配的数据(库位 ID 存在于库存表中,且属于当前场景 sceneId) List matchedAll = rkInfoMapper.getByPcodeIdList(pcdeIds, sceneId); - matchedAll.forEach(r -> r.setStatus("0")); + matchedAll.forEach(r -> r.setStatus("0")); // 标记状态 0:匹配成功 + // 2. 未盘点的数据(存在于库存表,但未出现在传入的 pcdeIds 中) List missedAll = rkInfoMapper.getMissedPcodeIds(pcdeIds, sceneId); - missedAll.forEach(r -> r.setStatus("1")); + missedAll.forEach(r -> r.setStatus("1")); // 标记状态 1:未盘点 + // 3. 异常数据(传入的库位 ID 在库存中不存在) List errorIds = pcdeIds.stream() - .filter(id -> rkInfoMapper.existsByPcodeId(id, sceneId) == 0) + .filter(id -> rkInfoMapper.existsByPcodeId(id, sceneId) == 0) // 判断库位是否存在 .collect(Collectors.toList()); + // 将异常库位 ID 封装成 RkInfo 对象,状态设为 2:错误 List errorAll = errorIds.stream().map(id -> { RkInfo r = new RkInfo(); r.setPcodeId(id); @@ -776,29 +790,47 @@ public class RkInfoServiceImpl implements IRkInfoService return r; }).collect(Collectors.toList()); - // 统一落表 + // ====================== 扫描结果落库 ====================== + + // 当前时间字符串 String tmeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); List toSave = new ArrayList<>(); + // 将匹配成功的数据封装成扫描记录 for (RkInfo r : matchedAll) { - toSave.add(buildScanRecord(taskId, r.getPcodeId(), "0", deviceId, tmeStr, scanType)); + toSave.add(buildScanRecord(taskId, r.getPcode(), "0", deviceId, tmeStr, scanType)); } + // 将未盘点的数据封装成扫描记录 for (RkInfo r : missedAll) { - toSave.add(buildScanRecord(taskId, r.getPcodeId(), "1", deviceId, tmeStr, scanType)); + toSave.add(buildScanRecord(taskId, r.getPcode(), "1", deviceId, tmeStr, scanType)); } + // 将异常数据封装成扫描记录 for (RkInfo r : errorAll) { toSave.add(buildScanRecord(taskId, r.getPcodeId(), "2", deviceId, tmeStr, scanType)); } + // 批量插入数据库 if (!toSave.isEmpty()) { matchScanMapper.insertBatch(toSave); } + // 更新任务状态为“已完成”(状态=1) if (taskId != null && !taskId.trim().isEmpty()) { - taskMapper.updateStatus(taskId, "1"); // 已完成 + taskMapper.updateStatus(taskId, "1"); } } + /** + * 封装一个盘点扫描记录 + * + * @param taskId 任务 ID + * @param pcode 库位编码 ID + * @param status 盘点状态(0=匹配成功,1=未盘点,2=错误) + * @param deviceId 设备 ID(自动盘点时才有) + * @param tme 扫描时间 + * @param scanType 扫描类型(0=手动盘点,1=自动盘点) + * @return 封装好的 InventoryMatchScan 对象 + */ private InventoryMatchScan buildScanRecord(String taskId, String pcode, String status, String deviceId, String tme, int scanType) { InventoryMatchScan record = new InventoryMatchScan(); @@ -806,6 +838,7 @@ public class RkInfoServiceImpl implements IRkInfoService record.setTaskId(taskId); record.setStatus(status); + // 自动盘点时才保存设备 ID if (scanType == 1 && deviceId != null) { record.setDeviceId(deviceId); } diff --git a/src/main/resources/mybatis/Inventory/AutoInventory/InventoryMatchScanMapper.xml b/src/main/resources/mybatis/Inventory/AutoInventory/InventoryMatchScanMapper.xml index e244560..d03cac0 100644 --- a/src/main/resources/mybatis/Inventory/AutoInventory/InventoryMatchScanMapper.xml +++ b/src/main/resources/mybatis/Inventory/AutoInventory/InventoryMatchScanMapper.xml @@ -196,10 +196,10 @@ parameterType="InventoryMatchScan" resultType="com.zg.project.Inventory.domain.vo.RkInfoMatchVO"> SELECT - r.pcode AS rkPcode, - COALESCE(SUM(r.real_qty), 0) AS realQty + r.pcode AS rkPcode, + COALESCE(SUM(r.real_qty), 0) AS realQty FROM rk_info r - WHERE r.pcode_id IN ( + WHERE r.pcode IN ( SELECT DISTINCT i.pcode FROM inventory_match_scan i diff --git a/src/main/resources/mybatis/Inventory/Task/InventoryTaskMapper.xml b/src/main/resources/mybatis/Inventory/Task/InventoryTaskMapper.xml index d754284..681da65 100644 --- a/src/main/resources/mybatis/Inventory/Task/InventoryTaskMapper.xml +++ b/src/main/resources/mybatis/Inventory/Task/InventoryTaskMapper.xml @@ -85,6 +85,13 @@ where id = #{taskId} + + + + insert into pcde_detail @@ -134,4 +141,5 @@ #{id} + diff --git a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml index 9cd330d..23f84b8 100644 --- a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml +++ b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml @@ -653,19 +653,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND is_chuku = '0' - SELECT - r.pcode AS rkPcode, - r.real_qty AS realQty - FROM rk_info r - WHERE r.cangku = #{wh} - AND r.pcode_id NOT IN ( - SELECT i.pcode - FROM inventory_match_scan i - WHERE i.task_id = #{taskId} - AND i.status = '0' - ) - ORDER BY r.create_time DESC + r.pcode AS rkPcode, + COALESCE(SUM(r.real_qty), 0) AS realQty + FROM pcde_detail d + JOIN rk_info r + ON r.pcode = d.pcode + LEFT JOIN ( + SELECT DISTINCT pcode + FROM inventory_match_scan + WHERE task_id = #{taskId} + AND status = '0' + ) s + ON s.pcode = r.pcode + WHERE (d.is_delete IS NULL OR d.is_delete = '0') + AND d.scene = #{sceneId} + AND r.is_chuku = '0' + AND s.pcode IS NULL + GROUP BY r.pcode + ORDER BY MAX(r.create_time) DESC