chen.lin
昨天 ed170766d35e68256f60ab48e3fd7071326455a9
pda确认流程优化
3个文件已修改
237 ■■■■ 已修改文件
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java 158 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/PdaOutStockServiceImpl.java
@@ -93,6 +93,8 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    @Synchronized
    public R saveOutTaskSts(String barcode) {
        LambdaQueryWrapper<Task> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Task::getBarcode, barcode);
@@ -103,20 +105,38 @@
        if (!task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
            return R.error("任务状态不是等待确认");
        }
        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
        Map<Long, List<TaskItem>> maps = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource));
        maps.keySet().forEach(key -> {
            WkOrderItem orderItem = asnOrderItemService.getById(key);
            if (Objects.isNull(orderItem)) {
                throw new CoolException("单据明细不存在!!");
            }
        });
        task.setTaskStatus(TaskStsType.COMPLETE_OUT.id);
        if (!taskService.updateById(task)) {
            return R.error("更新任务状态失败");
        Long loginUserId = SystemAuthUtils.getLoginUserId();
        if (loginUserId == null) {
            loginUserId = 1L; // 使用默认值
        }
        return R.ok("确认成功");
        try {
            if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
                // 拣料出库:创建拣料入库任务(形成闭环)
                taskService.pickOrCheckTask(task.getId(), "");
                return R.ok("确认成功,已创建拣料入库任务");
            } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
                // 盘点出库:创建盘点入库任务(形成闭环)
                taskService.pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
                return R.ok("确认成功,已创建盘点入库任务");
            } else if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
                // 全版出库:更新为200(最终完成,不闭环)
                taskService.completeFullOutStock(task.getId(), loginUserId);
                return R.ok("确认成功,全版出库已完成");
            } else {
                // 其他出库类型:直接更新为200
                task.setTaskStatus(TaskStsType.UPDATED_OUT.id)
                        .setUpdateBy(loginUserId)
                        .setUpdateTime(new Date());
                if (!taskService.updateById(task)) {
                    return R.error("更新任务状态失败");
                }
                return R.ok("确认成功");
            }
        } catch (Exception e) {
            throw new CoolException("快速拣货确认失败:" + e.getMessage());
        }
    }
    @Override
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
@@ -150,11 +150,11 @@
            if (!batchList.isEmpty()) {
                log.info("检查组托明细批号 - 批号列表:{}", batchList);
                
                // 查询拣料入库任务:箱号匹配且状态为1或2
                // 查询拣料入库任务:箱号匹配且状态为1、2或199(RCS申请入库时,状态199需要变成2)
                List<Task> pickInTasks = taskService.list(new LambdaQueryWrapper<Task>()
                        .eq(Task::getBarcode, param.getBarcode())
                        .eq(Task::getTaskType, TaskType.TASK_TYPE_PICK_IN.type)
                        .in(Task::getTaskStatus, TaskStsType.GENERATE_IN.id, TaskStsType.WCS_EXECUTE_IN.id)
                        .in(Task::getTaskStatus, TaskStsType.GENERATE_IN.id, TaskStsType.WAVE_SEED.id)
                        .orderByDesc(Task::getCreateTime));
                
                // 通过TaskItem的batch字段匹配批号
@@ -171,11 +171,11 @@
                    }
                }
                
                // 查询盘点入库任务:箱号匹配且状态为1或2
                // 查询盘点入库任务:箱号匹配且状态为1、2或199(RCS申请入库时,状态199需要变成2)
                List<Task> checkInTasks = taskService.list(new LambdaQueryWrapper<Task>()
                        .eq(Task::getBarcode, param.getBarcode())
                        .eq(Task::getTaskType, TaskType.TASK_TYPE_CHECK_IN.type)
                        .in(Task::getTaskStatus, TaskStsType.GENERATE_IN.id, TaskStsType.WCS_EXECUTE_IN.id)
                        .in(Task::getTaskStatus, TaskStsType.GENERATE_IN.id, TaskStsType.WCS_EXECUTE_IN.id, TaskStsType.WAVE_SEED.id)
                        .orderByDesc(Task::getCreateTime));
                
                // 通过TaskItem的batch字段匹配批号
@@ -196,7 +196,35 @@
        
        // 如果是拣料入库任务,直接返回,不校验组托
        if (Objects.nonNull(pickInTask)) {
            log.info("拣料入库任务,直接返回,不校验组托 - 任务编码:{}", pickInTask.getTaskCode());
            log.info("拣料入库任务,直接返回,不校验组托 - 任务编码:{},当前状态:{}",
                    pickInTask.getTaskCode(), pickInTask.getTaskStatus());
            // 如果状态是199,RCS申请入库时应该变成状态2(RCS任务已下发)
            if (pickInTask.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
                log.info("拣料入库任务状态为199,RCS申请入库时更新为状态2 - 任务编码:{}", pickInTask.getTaskCode());
                Long loginUserId = SystemAuthUtils.getLoginUserId();
                if (loginUserId == null) {
                    log.warn("无法获取系统用户ID,使用默认值1");
                    loginUserId = 1L;
                }
                // 更新状态为2(RCS任务已下发)
                boolean statusUpdated = taskService.update(new LambdaUpdateWrapper<Task>()
                        .eq(Task::getId, pickInTask.getId())
                        .eq(Task::getTaskStatus, TaskStsType.WAVE_SEED.id)
                        .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_IN.id)
                        .set(Task::getUpdateBy, loginUserId)
                        .set(Task::getUpdateTime, new Date()));
                if (statusUpdated) {
                    log.info("拣料入库任务状态已更新为2(RCS任务已下发) - 任务编码:{}", pickInTask.getTaskCode());
                    // 重新查询任务以获取最新状态
                    pickInTask = taskService.getById(pickInTask.getId());
                } else {
                    log.warn("拣料入库任务状态更新为2失败,可能状态已变更 - 任务编码:{},当前状态:{}",
                            pickInTask.getTaskCode(), pickInTask.getTaskStatus());
                }
            }
            
            // 更新入库站点信息(如果与当前申请的站点不同)
            if (StringUtils.isNotBlank(param.getSourceStaNo()) && 
@@ -221,7 +249,35 @@
        
        // 如果是盘点入库任务,直接返回,不校验组托
        if (Objects.nonNull(checkInTask)) {
            log.info("盘点入库任务,直接返回,不校验组托 - 任务编码:{}", checkInTask.getTaskCode());
            log.info("盘点入库任务,直接返回,不校验组托 - 任务编码:{},当前状态:{}",
                    checkInTask.getTaskCode(), checkInTask.getTaskStatus());
            // 如果状态是199,RCS申请入库时应该变成状态2(RCS任务已下发)
            if (checkInTask.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
                log.info("盘点入库任务状态为199,RCS申请入库时更新为状态2 - 任务编码:{}", checkInTask.getTaskCode());
                Long loginUserId = SystemAuthUtils.getLoginUserId();
                if (loginUserId == null) {
                    log.warn("无法获取系统用户ID,使用默认值1");
                    loginUserId = 1L;
                }
                // 更新状态为2(RCS任务已下发)
                boolean statusUpdated = taskService.update(new LambdaUpdateWrapper<Task>()
                        .eq(Task::getId, checkInTask.getId())
                        .eq(Task::getTaskStatus, TaskStsType.WAVE_SEED.id)
                        .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_IN.id)
                        .set(Task::getUpdateBy, loginUserId)
                        .set(Task::getUpdateTime, new Date()));
                if (statusUpdated) {
                    log.info("盘点入库任务状态已更新为2(RCS任务已下发) - 任务编码:{}", checkInTask.getTaskCode());
                    // 重新查询任务以获取最新状态
                    checkInTask = taskService.getById(checkInTask.getId());
                } else {
                    log.warn("盘点入库任务状态更新为2失败,可能状态已变更 - 任务编码:{},当前状态:{}",
                            checkInTask.getTaskCode(), checkInTask.getTaskStatus());
                }
            }
            
            // 更新入库站点信息(如果与当前申请的站点不同)
            if (StringUtils.isNotBlank(param.getSourceStaNo()) && 
@@ -854,9 +910,9 @@
                    }
                    log.info("出库任务状态更新成功 - 任务编码:{}", task.getTaskCode());
                    
                    // 全版出库在RCS回调后直接处理并设置为200
                    // 全版出库在RCS回调后处理库存并设置为199,等待PDA快速拣货确认后更新为200
                    if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
                        log.info("全版出库任务,开始处理库存并更新状态为200 - 任务编码:{}", task.getTaskCode());
                        log.info("全版出库任务,开始处理库存并更新状态为199 - 任务编码:{}", task.getTaskCode());
                        try {
                            // 重新查询任务以获取最新状态(198)
                            task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode()));
@@ -869,34 +925,10 @@
                            // 重新查询任务以获取最新状态(199)
                            task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode()));
                            
                            // 如果状态已经是199,继续处理并设置为200
                            if (task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
                                Long loginUserId = SystemAuthUtils.getLoginUserId();
                                if (loginUserId == null) {
                                    log.warn("无法获取系统用户ID,使用默认值1");
                                    loginUserId = 1L;
                                }
                                // 删除作业中库存记录(LocItemWorking)
                                locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>()
                                        .eq(LocItemWorking::getTaskId, task.getId()));
                                // 更新任务状态为库存更新完成(200)
                                boolean finalUpdated = taskService.update(new LambdaUpdateWrapper<Task>()
                                        .eq(Task::getTaskCode, task.getTaskCode())
                                        .eq(Task::getTaskStatus, TaskStsType.WAVE_SEED.id)
                                        .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id)
                                        .set(Task::getUpdateBy, loginUserId)
                                        .set(Task::getUpdateTime, new Date()));
                                if (!finalUpdated) {
                                    log.warn("全版出库任务状态更新为200失败,可能状态已变更 - 任务编码:{},当前状态:{}",
                                            task.getTaskCode(), task.getTaskStatus());
                                } else {
                                    log.info("全版出库任务状态已更新为200(库存更新完成) - 任务编码:{}", task.getTaskCode());
                                }
                                log.info("全版出库任务状态已更新为199(等待PDA快速拣货确认后更新为200) - 任务编码:{}", task.getTaskCode());
                            } else {
                                log.warn("全版出库任务状态不是199,无法更新为200 - 任务编码:{},当前状态:{}",
                                log.warn("全版出库任务状态更新为199失败 - 任务编码:{},当前状态:{}",
                                        task.getTaskCode(), task.getTaskStatus());
                            }
                        } catch (Exception e) {
@@ -1324,18 +1356,56 @@
        // 该方法会执行以下流程:
        // 1. 验证设备站点
        // 2. 验证组拖状态
        // 3. 生成任务编码
        // 4. 获取库位号
        // 5. 创建并保存任务
        // 6. 更新库位状态
        // 7. 获取并验证组拖明细
        // 8. 创建并保存任务明细
        // 9. 更新组托状态
        // 3. 检查是否有匹配的入库任务(拣料/盘点入库会匹配状态199并更新为2)
        // 4. 生成任务编码(如果需要创建新任务)
        // 5. 获取库位号
        // 6. 创建并保存任务(如果需要创建新任务)
        // 7. 更新库位状态
        // 8. 获取并验证组拖明细
        // 9. 创建并保存任务明细
        // 10. 更新组托状态
        InTaskMsgDto msgDto = createInTask(param);
        //RCS已经在输送线上,所以不需要下发任务
        taskService.updateById(new Task(){{setId(msgDto.getTaskId());setTaskStatus(2);}});
        // 查询任务当前状态
        Task task = taskService.getById(msgDto.getTaskId());
        if (Objects.isNull(task)) {
            throw new CoolException("任务不存在,任务ID:" + msgDto.getTaskId());
        }
        // RCS申请入库时,需要将任务状态更新为2(RCS任务已下发)
        // 情况1:如果是拣料/盘点入库任务,状态199已经在createInTask中更新为2了
        // 情况2:如果是新创建的任务(无订单号组托),状态是1,需要更新为2
        // 情况3:如果状态已经是2,不需要更新
        if (task.getTaskStatus().equals(TaskStsType.GENERATE_IN.id)) {
            log.info("新创建的入库任务(无订单号组托),RCS申请入库时更新为状态2 - 任务编码:{}", task.getTaskCode());
            Long loginUserId = SystemAuthUtils.getLoginUserId();
            if (loginUserId == null) {
                log.warn("无法获取系统用户ID,使用默认值1");
                loginUserId = 1L;
            }
            boolean statusUpdated = taskService.update(new LambdaUpdateWrapper<Task>()
                    .eq(Task::getId, task.getId())
                    .eq(Task::getTaskStatus, TaskStsType.GENERATE_IN.id)
                    .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_IN.id)
                    .set(Task::getUpdateBy, loginUserId)
                    .set(Task::getUpdateTime, new Date()));
            if (statusUpdated) {
                log.info("新创建的入库任务状态已更新为2(RCS任务已下发) - 任务编码:{}", task.getTaskCode());
            } else {
                log.warn("新创建的入库任务状态更新为2失败,可能状态已变更 - 任务编码:{},当前状态:{}",
                        task.getTaskCode(), task.getTaskStatus());
            }
        } else if (task.getTaskStatus().equals(TaskStsType.WCS_EXECUTE_IN.id)) {
            log.info("入库任务状态已经是2(RCS任务已下发),无需更新 - 任务编码:{}", task.getTaskCode());
        } else {
            log.info("入库任务当前状态:{},RCS申请入库时保持当前状态 - 任务编码:{}",
                    task.getTaskStatus(), task.getTaskCode());
        }
        log.info("========== RCS-申请入库任务成功 ==========");
        log.info("RCS-返回 任务编码:{},库位号:{}", msgDto.getWorkNo(), msgDto.getLocNo());
        log.info("RCS-返回 任务编码:{},库位号:{},任务状态:{}", msgDto.getWorkNo(), msgDto.getLocNo(), task.getTaskStatus());
        // 返回结果,只返回库位号(根据接口文档要求)
        JSONObject result = new JSONObject();
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -1450,8 +1450,8 @@
            try {
                // 根据任务类型更新库位明细
                if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
                    // 全版出库:删除所有库位明细
                    subtractLocItem(loc);
                    // 全版出库:不删除库位明细,等待PDA快速拣货确认时再删除
                    // subtractLocItem(loc); // 已移除,改为在completeFullOutStock中删除
                } else {
                    // 部分出库(如拣料出库):根据TaskItem数量扣减库位明细
                    subtractLocItemByTaskItems(loc, taskItems, loginUserId);
@@ -1513,6 +1513,8 @@
                throw new CoolException(e.getMessage());
            }
        }
        // 根据任务类型更新库位状态
        if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
            /**修改为库位状态为S.预约入库,保留原有库位*/
            if (!locService.update(new LambdaUpdateWrapper<Loc>()
@@ -1523,6 +1525,9 @@
                    .eq(Loc::getId, loc.getId()))) {
                throw new CoolException("库位状态修改失败!!");
            }
        } else if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
            // 全版出库:不更新库位状态为O,等待PDA快速拣货确认时再更新
            // 库位状态保持原样(R.出库预约状态)
        } else {
            /**修改为库位状态为O.空库*/
            if (!locService.update(new LambdaUpdateWrapper<Loc>()
@@ -2184,12 +2189,26 @@
                throw new CoolException("库位不存在!!");
            }
            LocItem item = new LocItem();
            LocItem locItem = locItemService.getOne(new LambdaQueryWrapper<LocItem>()
            // 构建查询条件:需要同时匹配物料ID、库位ID、批次和票号
            LambdaQueryWrapper<LocItem> locItemWrapper = new LambdaQueryWrapper<LocItem>()
                    .eq(LocItem::getMatnrId, taskItem.getMatnrId())
                    .eq(LocItem::getLocId, loc.getId())
                    .eq(StringUtils.isNotBlank(taskItem.getBatch()), LocItem::getBatch, taskItem.getBatch())
                    .eq(StringUtils.isNotBlank(taskItem.getFieldsIndex()), LocItem::getFieldsIndex, taskItem.getFieldsIndex())
            );
                    .eq(LocItem::getLocId, loc.getId());
            // 批次匹配:如果taskItem有批次,则必须匹配;如果taskItem没有批次,则查询批次为null或空字符串的记录
            if (StringUtils.isNotBlank(taskItem.getBatch())) {
                locItemWrapper.eq(LocItem::getBatch, taskItem.getBatch());
            } else {
                locItemWrapper.and(wrapper -> wrapper.isNull(LocItem::getBatch).or().eq(LocItem::getBatch, ""));
            }
            // 票号匹配:如果taskItem有票号,则必须匹配;如果taskItem没有票号,则查询票号为null或空字符串的记录
            if (StringUtils.isNotBlank(taskItem.getFieldsIndex())) {
                locItemWrapper.eq(LocItem::getFieldsIndex, taskItem.getFieldsIndex());
            } else {
                locItemWrapper.and(wrapper -> wrapper.isNull(LocItem::getFieldsIndex).or().eq(LocItem::getFieldsIndex, ""));
            }
            LocItem locItem = locItemService.getOne(locItemWrapper);
            if (Objects.isNull(locItem)) {
                // 库位明细不存在,创建新的库位明细
                BeanUtils.copyProperties(taskItem, item);