cl
12 小时以前 8943a4e9f5ee1455c56ac4af60d941fa23731051
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
@@ -51,6 +51,8 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -140,6 +142,11 @@
        // 验证设备站点
        DeviceSite deviceSite = validateDeviceSite(param);
        // 空板入库:与非空板同一入口,仅不校验组托,只做分配库位、建任务、更新库位
        if (param.getIoType() != null && param.getIoType().equals(TaskType.TASK_TYPE_EMPITY_IN.type)) {
            return createInTaskForEmptyPallet(param);
        }
        // 提前定义 waitPakin / waitPakinItems,供后续其他入库逻辑使用
        WaitPakin waitPakin = null;
@@ -257,6 +264,12 @@
                    log.warn("更新拣料入库任务的入库站点失败 - 任务编码:{}", pickInTask.getTaskCode());
                }
            }
            if (param.getWeight() != null) {
                pickInTask.setWeight(param.getWeight());
                if (!taskService.updateById(pickInTask)) {
                    log.warn("更新拣料入库任务重量失败 - 任务编码:{}", pickInTask.getTaskCode());
                }
            }
            // 返回拣料入库任务的信息
            InTaskMsgDto msgDto = new InTaskMsgDto();
@@ -308,6 +321,12 @@
                checkInTask.setOrgSite(param.getSourceStaNo());
                if (!taskService.updateById(checkInTask)) {
                    log.warn("更新盘点入库任务的入库站点失败 - 任务编码:{}", checkInTask.getTaskCode());
                }
            }
            if (param.getWeight() != null) {
                checkInTask.setWeight(param.getWeight());
                if (!taskService.updateById(checkInTask)) {
                    log.warn("更新盘点入库任务重量失败 - 任务编码:{}", checkInTask.getTaskCode());
                }
            }
@@ -390,6 +409,12 @@
                    log.warn("更新入库任务的入库站点失败 - 任务编码:{}", existingInTask.getTaskCode());
                }
            }
            if (param.getWeight() != null) {
                existingInTask.setWeight(param.getWeight());
                if (!taskService.updateById(existingInTask)) {
                    log.warn("更新入库任务重量失败 - 任务编码:{}", existingInTask.getTaskCode());
                }
            }
            // 直接返回已有任务信息,不再新建任务
            InTaskMsgDto msgDto = new InTaskMsgDto();
@@ -419,10 +444,11 @@
        }
        // 创建并保存任务
        Task task = createTask(ruleCode, locNo.getLocNo(), waitPakin.getBarcode(),
                deviceSite.getDeviceSite(), param.getSourceStaNo().toString(), param.getUser());
                deviceSite.getDeviceSite(), param.getSourceStaNo().toString(), param.getUser(),
                TaskType.TASK_TYPE_IN.type, param.getWeight());
        // 更新库位状态
        updateLocStatus(task.getTargLoc(), waitPakin.getBarcode());
        updateLocStatus(task.getTargLoc(), waitPakin.getBarcode(), param.getWeight());
        // 获取并验证组拖明细
        waitPakinItems = getWaitPakinItems(waitPakin.getId());
@@ -579,16 +605,16 @@
    /**
     * 创建并保存任务
     */
    private Task createTask(String ruleCode, String targetLoc, String barcode,
                            String targetSite, String sourceSiteNo, Long loginUserId) {
        return createTask(ruleCode, targetLoc, barcode, targetSite, sourceSiteNo, loginUserId, TaskType.TASK_TYPE_IN.type);
    }
//    private Task createTask(String ruleCode, String targetLoc, String barcode,
//                            String targetSite, String sourceSiteNo, Long loginUserId) {
//        return createTask(ruleCode, targetLoc, barcode, targetSite, sourceSiteNo, loginUserId, TaskType.TASK_TYPE_IN.type, null);
//    }
    /**
     * 创建并保存任务(支持指定任务类型,如空板入库)
     */
    private Task createTask(String ruleCode, String targetLoc, String barcode,
                            String targetSite, String sourceSiteNo, Long loginUserId, Integer taskType) {
                            String targetSite, String sourceSiteNo, Long loginUserId, Integer taskType, BigDecimal weight) {
        Task task = new Task();
        task.setTaskCode(ruleCode)
                .setTaskStatus(TaskStsType.GENERATE_IN.id)
@@ -600,6 +626,9 @@
                .setCreateBy(loginUserId)
                .setUpdateBy(loginUserId)
                .setOrgSite(sourceSiteNo);
        if (weight != null) {
            task.setWeight(weight);
        }
        if (!taskService.save(task)) {
            throw new CoolException("任务保存失败!!");
@@ -610,27 +639,32 @@
    /**
     * 更新库位状态
     */
    private void updateLocStatus(String locCode, String barcode) {
        boolean updated = locService.update(new LambdaUpdateWrapper<Loc>()
    private void updateLocStatus(String locCode, String barcode, BigDecimal weight) {
        LambdaUpdateWrapper<Loc> uw = new LambdaUpdateWrapper<Loc>()
                .eq(Loc::getCode, locCode)
                .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type)
                .set(Loc::getBarcode, barcode));
                .set(Loc::getBarcode, barcode)
                .set(Loc::getWeight, weight);
        boolean updated = locService.update(uw);
        if (!updated) {
            throw new CoolException("库位预约失败!!");
        }
    }
    /**
     * 空板入库:RCS 申请时 full=true,无需组托,分配库位并创建 TASK_TYPE_EMPITY_IN 任务。
     * 需在设备站点中配置 type=10(空板入库)的站点路径。
     * 空板入库:与非空板同一流程(校验站点、分配库位、建任务、更新库位),仅不校验组托、不写任务明细、不更新组托状态。
     * 由 createInTask 在 ioType=空板时调用;需在设备站点中配置 type=10(空板入库)的站点路径。
     */
    private InTaskMsgDto createInTaskForEmptyPallet(String barcode, String staNo, Integer type) {
    private InTaskMsgDto createInTaskForEmptyPallet(TaskInParam sourceParam) {
        TaskInParam param = new TaskInParam();
        String barcode = sourceParam.getBarcode();
        String staNo = sourceParam.getSourceStaNo();
        param.setBarcode(barcode);
        param.setSourceStaNo(staNo);
        param.setLocType1(type != null ? type : 1);
        param.setLocType1(sourceParam.getLocType1() != null ? sourceParam.getLocType1() : 1);
        param.setIoType(TaskType.TASK_TYPE_EMPITY_IN.type);
        param.setUser(1L);
        param.setUser(sourceParam.getUser() != null ? sourceParam.getUser() : 1L);
        param.setWeight(sourceParam.getWeight());
        // 校验设备站点(需配置 type=10 空板入库的站点)
        DeviceSite deviceSite = validateDeviceSite(param);
@@ -645,6 +679,10 @@
            log.info("找到该托盘号已有空板入库任务,复用 - 任务编码:{},箱号:{}", existingInTask.getTaskCode(), barcode);
            if (StringUtils.isNotBlank(staNo) && !staNo.equals(existingInTask.getOrgSite())) {
                existingInTask.setOrgSite(staNo);
                taskService.updateById(existingInTask);
            }
            if (param.getWeight() != null) {
                existingInTask.setWeight(param.getWeight());
                taskService.updateById(existingInTask);
            }
            InTaskMsgDto msgDto = new InTaskMsgDto();
@@ -681,8 +719,8 @@
        }
        String ruleCode = generateTaskCode();
        String targetSite = StringUtils.isNotBlank(deviceSite.getDeviceSite()) ? deviceSite.getDeviceSite() : staNo;
        Task task = createTask(ruleCode, locNo.getLocNo(), barcode, targetSite, staNo, param.getUser(), TaskType.TASK_TYPE_EMPITY_IN.type);
        updateLocStatus(task.getTargLoc(), barcode);
        Task task = createTask(ruleCode, locNo.getLocNo(), barcode, targetSite, staNo, param.getUser(), TaskType.TASK_TYPE_EMPITY_IN.type, param.getWeight());
        updateLocStatus(task.getTargLoc(), barcode, param.getWeight());
        locNo.setWorkNo(ruleCode);
        locNo.setTaskId(task.getId());
        log.info("[空板入库] 已创建任务: {}, 库位: {}, 料箱: {}", ruleCode, locNo.getLocNo(), barcode);
@@ -1556,40 +1594,24 @@
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R allocateLocation(String barcode, String staNo, Integer type, Boolean full) {
    public R allocateLocation(String barcode, String staNo, Integer type, Boolean full, BigDecimal weight) {
        log.info("========== 开始申请入库任务,分配库位 ==========");
        log.info("料箱码:{},入库站点:{},入库类型:{},空板:{}", barcode, staNo, type, full);
        log.info("料箱码:{},入库站点:{},入库类型:{},空板:{},重量:{}", barcode, staNo, type, full, weight);
        // full=true 时走空板入库(无需组托);否则走普通入库(需组托或自动组托)
        if (Boolean.TRUE.equals(full)) {
            InTaskMsgDto msgDto = createInTaskForEmptyPallet(barcode, staNo, type);
            JSONObject result = new JSONObject();
            result.put("locNo", msgDto.getLocNo());
            result.put("batchNo", msgDto.getWorkNo());
            result.put("taskNo", msgDto.getWorkNo());
            return R.ok(result);
        BigDecimal weightScaled = null;
        if (weight != null) {
            weightScaled = weight.setScale(4, RoundingMode.HALF_UP);
        }
        // 构建 TaskInParam 参数,与 /wcs/create/in/task 接口参数一致
        // 统一走 createInTask:空板(full=true)仅不校验组托,仍校验站点、分配库位、建任务;非空板需组托
        TaskInParam param = new TaskInParam();
        param.setBarcode(barcode);
        param.setSourceStaNo(staNo);
        param.setIoType(TaskType.TASK_TYPE_IN.type); // 入库类型
        param.setLocType1(type); // 库位类型(高低检测信号)
        param.setUser(1L); // 默认用户ID,可以根据实际需求调整
        param.setLocType1(type != null ? type : 1);
        param.setUser(1L);
        param.setIoType(Boolean.TRUE.equals(full) ? TaskType.TASK_TYPE_EMPITY_IN.type : TaskType.TASK_TYPE_IN.type);
        param.setWeight(weightScaled);
        // 调用 createInTask 方法,创建完整的入库任务
        // 该方法会执行以下流程:
        // 1. 验证设备站点
        // 2. 验证组拖状态
        // 3. 检查是否有匹配的入库任务(拣料/盘点入库会匹配状态199并更新为2)
        // 4. 生成任务编码(如果需要创建新任务)
        // 5. 获取库位号
        // 6. 创建并保存任务(如果需要创建新任务)
        // 7. 更新库位状态
        // 8. 获取并验证组拖明细
        // 9. 创建并保存任务明细
        // 10. 更新组托状态
        InTaskMsgDto msgDto = createInTask(param);
        // 查询任务当前状态
@@ -1619,10 +1641,12 @@
                    .set(Task::getUpdateTime, new Date()));
            if (statusUpdated) {
                log.info("新创建的入库任务状态已更新为2(RCS任务已下发) - 任务编码:{}", task.getTaskCode());
                task = taskService.getById(task.getId());
                log.info("新创建的入库任务状态已更新为2(RCS任务已下发) - 任务编码:{},当前状态:{}", task.getTaskCode(), task != null ? task.getTaskStatus() : null);
            } else {
                task = taskService.getById(task.getId());
                log.warn("新创建的入库任务状态更新为2失败,可能状态已变更 - 任务编码:{},当前状态:{}",
                        task.getTaskCode(), task.getTaskStatus());
                        task.getTaskCode(), task != null ? task.getTaskStatus() : null);
            }
        } else if (taskStatus != null && taskStatus.equals(TaskStsType.WCS_EXECUTE_IN.id)) {
            log.info("入库任务状态已经是2(RCS任务已下发),无需更新 - 任务编码:{}", task.getTaskCode());