package com.wms_main.service.controller.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms_main.app.AppCommon;
import com.wms_main.constant.AppConstant;
import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums;
import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums;
import com.wms_main.constant.enums.wms.*;
import com.wms_main.dao.*;
import com.wms_main.model.bo.wcs.WcsStackerTask;
import com.wms_main.model.bo.wms.GoodsInfoForTask;
import com.wms_main.model.bo.wms.StockConfirmEntity;
import com.wms_main.model.bo.wms.TaskConfirmEntity;
import com.wms_main.model.bo.wms.WmsPickTask;
import com.wms_main.model.dto.request.wcs.WcsBoxArriveRequest;
import com.wms_main.model.dto.request.wcs.WcsTaskResultRequest;
import com.wms_main.model.dto.request.wcs.WcsVehicleInRequest;
import com.wms_main.model.dto.request.wms.*;
import com.wms_main.model.dto.response.wcs.BaseWcsApiResponse;
import com.wms_main.model.dto.response.wcs.WcsApiResponse;
import com.wms_main.model.dto.response.wms.BaseWmsApiResponse;
import com.wms_main.model.dto.response.wms.WmsApiResponse;
import com.wms_main.model.po.*;
import com.wms_main.model.vo.wms.InventoryConfirmVo;
import com.wms_main.model.vo.wms.TaskConfirmVo;
import com.wms_main.model.vo.wms.WorkConfirmVo;
import com.wms_main.repository.utils.ConvertUtils;
import com.wms_main.repository.utils.StringUtils;
import com.wms_main.repository.utils.UUIDUtils;
import com.wms_main.service.business.IConveyTaskService;
import com.wms_main.service.business.IStackerTaskService;
import com.wms_main.service.business.IStockDataService;
import com.wms_main.service.controller.ITaskControllerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 任务控制类 服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TaskControllerServiceImpl implements ITaskControllerService {
    private final ITAppWcsTaskService appWcsTaskService;// wcs任务服务
    private final ITAppWcsTaskBakService appWcsTaskBakService;// wcs任务备份服务
    private final ITAppTaskService appWmsTaskService;// wms任务服务
    private final IStackerTaskService stackerTaskService;// 堆垛机任务服务
    private final ITAppLocationService appLocationService;// 库位服务
    private final ITAppPickTaskService appPickTaskService;// 拣选任务服务
    private final ITAppVehicleService appVehicleService;// 载具服务
    private final ITAppStockService appStockService;// 库存服务
    private final IConveyTaskService conveyTaskService;// 输送线任务服务
    private final ITAppStandService appStandService;// 站台服务
    private final ITAppOutsService appOutsService;// 出库单服务
    private final IStockDataService stockDataService;// 库存数据服务
    private final ITAppOutsRecordService appOutsRecordService;// 出库单记录服务
    private final ITAppPickPlanService appPickPlanService;// 拣选计划服务
    private final ITAppInventoryService appInventoryService;// 盘点任务服务
    private final ITAppInventoryRecordService appInventoryRecordService;// 盘点记录服务
    private final AppCommon appCommon;

    /**
     * 实现
     *
     * @param stockInRequest 请求信息
     * @return 响应结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse requireStockIn(StockInRequest stockInRequest) {
        // 判断请求信息的正确性。
        if (stockInRequest == null || StringUtils.isEmpty(stockInRequest.getVehicleId())) {
            return BaseWmsApiResponse.error("请求参数不完整，缺少载具号。");
        }
        // 校验当前是否在库
        if (appVehicleService.exists(new LambdaQueryWrapper<TAppVehicle>()
                .eq(TAppVehicle::getVehicleId, stockInRequest.getVehicleId())
                .eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode()))) {
            return BaseWmsApiResponse.error("当前载具显示已在库中，无法再次入库。");
        }
        // 判断这个箱子是否有其他的wcs任务
        if (appWcsTaskService.exists(new LambdaQueryWrapper<TAppWcsTask>()
                .eq(TAppWcsTask::getVehicleId, stockInRequest.getVehicleId()))) {
            return BaseWmsApiResponse.error("当前载具仍有未完成的WCS任务，无法创建新的入库任务。");
        }
        // 判断这个箱子是否有其他的wms任务
        if (appWmsTaskService.exists(new LambdaQueryWrapper<TAppTask>()
                .eq(TAppTask::getVehicleId, stockInRequest.getVehicleId()))) {
            return BaseWmsApiResponse.error("当前载具仍有未完成的WMS任务，无法创建新的入库任务。");
        }
        // 非空载具入库，但是未包含物料信息，设置为空
        if (!stockInRequest.isEmptyTask() && (stockInRequest.getGoodsInfo() == null || stockInRequest.getGoodsInfo().isEmpty())) {
            stockInRequest.setEmptyTask(true);
        }
        // 空载具入库但是请求包含物料信息，设置为非空
        if (stockInRequest.isEmptyTask() && stockInRequest.getGoodsInfo() != null && !stockInRequest.getGoodsInfo().isEmpty()) {
            stockInRequest.setEmptyTask(false);
        }
        // 判断是否同种类料入库
        String thisTimeInGoodsId = "";// 本次入库物料
        if (stockInRequest.getGoodsInfo() != null && !stockInRequest.getGoodsInfo().isEmpty()) {
            for (GoodsInfoForTask goodsInfoForTask : stockInRequest.getGoodsInfo()) {
                if (StringUtils.isEmpty(thisTimeInGoodsId)) {
                    thisTimeInGoodsId = goodsInfoForTask.getGoodsId();
                } else {
                    if (!thisTimeInGoodsId.equals(goodsInfoForTask.getGoodsId())) {
                        return BaseWmsApiResponse.error("一个载具中只能入一种料。");
                    }
                }
            }
        }
        if (stockInRequest.isEmptyTask()) {
            // 创建空载具入库任务
            TAppTask task = new TAppTask(
                    UUIDUtils.getNewUUID(),
                    WmsTaskTypeEnums.IN.getCode(),
                    WmsStackerTaskStatusEnums.TEMP.getCode(),
                    1,
                    stockInRequest.getVehicleId(),
                    stockInRequest.getOrigin(),
                    null,
                    null,
                    LocalDateTime.now(),
                    null,
                    AppConstant.EMPTY_GOODS_ID,
                    0,
                    0,
                    stockInRequest.getUserName(),
                    "",
                    stockInRequest.getStandId(),
                    ""
            );
            try {
                // 保存任务
                appWmsTaskService.save(task);
            } catch (Exception e) {
                return BaseWmsApiResponse.error("创建空载具入库任务失败。");
            }
        } else {
            // 查询当前载具的库存信息
            List<TAppStock> thisVehicleStocks = appStockService.list(
                    new LambdaQueryWrapper<TAppStock>()
                            .eq(TAppStock::getVehicleId, stockInRequest.getVehicleId()));
            // 判断入库物料是否在库存中
            if (StringUtils.isNotEmpty(thisTimeInGoodsId) && thisVehicleStocks != null && !thisVehicleStocks.isEmpty()) {
                for (TAppStock stock : thisVehicleStocks) {
                    if (!Objects.equals(stock.getGoodsId(), thisTimeInGoodsId)) {
                        return BaseWmsApiResponse.error("当前载具已经绑定其他种类物料。");
                    }
                }
            }
            Map<String, TAppTask> goodsIdTaskMap = new HashMap<>();
            Map<String, TAppGoods> goodsMap = new HashMap<>();
            // 循环物料生成入库任务
            for (GoodsInfoForTask goodsInfoForTask : stockInRequest.getGoodsInfo()) {
                if (goodsIdTaskMap.containsKey(goodsInfoForTask.getGoodsId())) {
                    // 如果同一物料，则数量叠加。
                    TAppTask task = goodsIdTaskMap.get(goodsInfoForTask.getGoodsId());
                    task.setOpNum(task.getOpNum() + goodsInfoForTask.getOpNum());
                    goodsIdTaskMap.replace(goodsInfoForTask.getGoodsId(), task);
                } else {
                    // 判断当前料号是否存在于立库信息中
                    TAppGoods goods = appCommon.getInstantGoodsByGoodsId(goodsInfoForTask.getGoodsId());
                    if (goods == null) {
                        return BaseWmsApiResponse.error("入库物料列表中有物料不在立库维护信息中。物料号：" + goodsInfoForTask.getGoodsId() + "。");
                    }
                    if (!Objects.equals(goods.getPutArea(), "ASRS")) {
                        return BaseWmsApiResponse.error("非库内料不允许入库。物料号：" + goodsInfoForTask.getGoodsId() + "。");
                    }
                    // 创建入库任务
                    TAppTask task = new TAppTask(
                            UUIDUtils.getNewUUID(),
                            WmsTaskTypeEnums.IN.getCode(),
                            WmsStackerTaskStatusEnums.TEMP.getCode(),
                            1,
                            stockInRequest.getVehicleId(),
                            stockInRequest.getOrigin(),
                            null,
                            null,
                            LocalDateTime.now(),
                            null,
                            goodsInfoForTask.getGoodsId(),
                            goodsInfoForTask.getOpNum(),
                            0,
                            stockInRequest.getUserName(),
                            goodsInfoForTask.getRemark(),
                            stockInRequest.getStandId(),
                            goods.getGoodsDescription()
                    );
                    goodsIdTaskMap.put(goodsInfoForTask.getGoodsId(), task);
                    goodsMap.put(goodsInfoForTask.getGoodsId(), goods);
                }
                if (goodsMap.containsKey(goodsInfoForTask.getGoodsId())) {
                    // 判断数量是否超载
                    TAppGoods thisGoods = goodsMap.get(goodsInfoForTask.getGoodsId());
                    int maxQty1Vehicle = thisGoods.getBoxQty() * thisGoods.getMaxBoxNum();
                    int oldStockNum = 0;
                    if (thisVehicleStocks != null && !thisVehicleStocks.isEmpty()) {
                        // 计算出该物料的库存数量
                        oldStockNum = thisVehicleStocks.stream()
                                .filter(stock -> stock.getGoodsId().equals(goodsInfoForTask.getGoodsId()))
                                .mapToInt(TAppStock::getRealNum)
                                .sum();
                    }
                    if (goodsIdTaskMap.get(goodsInfoForTask.getGoodsId()).getOpNum() + oldStockNum > maxQty1Vehicle) {
                        return BaseWmsApiResponse.error("物料号：" + goodsInfoForTask.getGoodsId() + "数量超过阈值" + maxQty1Vehicle + "，不允许入库。");
                    }
                }
            }
            try {
                appWmsTaskService.saveBatch(goodsIdTaskMap.values());
            } catch (Exception e) {
                // 回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return BaseWmsApiResponse.error("创建入库任务失败。");
            }
        }

        return BaseWmsApiResponse.success("生成入库任务成功。");
    }

    /**
     * 请求出库---实现
     *
     * @param stockOutRequest 请求信息
     * @return 处理结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse requireStockOut(StockOutRequest stockOutRequest) {
        // 保存
        if (stockOutRequest == null || stockOutRequest.getOutType() == null || stockOutRequest.getNeedNum() == null
                || stockOutRequest.getNeedNum() <= 0 || StringUtils.isEmpty(stockOutRequest.getDestination())) {
            return BaseWmsApiResponse.error("请求参数不完整。");
        }
        // 判断终点对不对
        if (!appStandService.exists(new LambdaQueryWrapper<TAppStand>().eq(TAppStand::getStandId, stockOutRequest.getDestination()))) {
            return BaseWmsApiResponse.error("请求的终点站台不存在。");
        }
        // 针对不同的出库类型验证请求
        if (stockOutRequest.getOutType().equals(WmsOutTypeEnums.EMPTY.getCode())) {
            // 如果指定了载具号，则验证该载具是否为空载具
            if (StringUtils.isNotEmpty(stockOutRequest.getVehicleId())) {
                // 查询这个载具号
                boolean haveThisEmptyVehicleFlag = appVehicleService.exists(new LambdaQueryWrapper<TAppVehicle>()
                        .eq(TAppVehicle::getVehicleId, stockOutRequest.getVehicleId())
                                .eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode())
                        .eq(TAppVehicle::getIsEmpty, 1)
                );
                if (!haveThisEmptyVehicleFlag) {
                    return BaseWmsApiResponse.error("请求错误：目标不存在。");
                }
            } else {
                // 判断空载具数量够不够
                List<TAppVehicle> emptyVehicles = appVehicleService.list(new LambdaQueryWrapper<TAppVehicle>()
                        .eq(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.ON.getCode())
                        .eq(TAppVehicle::getIsEmpty, 1)
                );
                if (emptyVehicles == null || emptyVehicles.isEmpty()) {
                    return BaseWmsApiResponse.error("请求错误：库内无空箱。");
                }
                if (emptyVehicles.size() < stockOutRequest.getNeedNum()) {
                    return BaseWmsApiResponse.error("请求错误：库内空箱数量" + emptyVehicles.size() + "，小于请求数量" + stockOutRequest.getNeedNum() + "。");
                }
            }
        } else if (stockOutRequest.getOutType().equals(WmsOutTypeEnums.EMERGE.getCode())) {
            if (!appStandService.exists(new LambdaQueryWrapper<TAppStand>().eq(TAppStand::getStandId, stockOutRequest.getDestination())
                    .eq(TAppStand::getStandType, 1))) {
                return BaseWmsApiResponse.error("非拣选站台不允许紧急出库。");
            }
            // 判断理由是否输入
            if (StringUtils.isEmpty(stockOutRequest.getReason())) {
                return BaseWmsApiResponse.error("请求错误：紧急出库必须输入原因。");
            }
            // 判断料号数量是否输入
            if (StringUtils.isEmpty(stockOutRequest.getGoodsId())) {
                return BaseWmsApiResponse.error("请求错误：紧急出库必须输入料号。");
            }
            if (stockOutRequest.getNeedNum() == null || stockOutRequest.getNeedNum() <= 0) {
                return BaseWmsApiResponse.error("请求错误：紧急出库必须输入有效数量。");
            }
            // 判断请求的料号是不是库外料
            TAppGoods thisGoods = appCommon.getInstantGoodsByGoodsId(stockOutRequest.getGoodsId());
            if (thisGoods == null || !thisGoods.getPutArea().contains("ASRS")) {
                return BaseWmsApiResponse.error("请求错误：库外料或未在系统中维护的料不允许紧急出库。");
            }
            // 判断库存是否足够
            List<TAppStock> stockList = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                    .eq(TAppStock::getGoodsId, stockOutRequest.getGoodsId())
                    .gt(TAppStock::getRemainNum, 0));
            // 生成物料数量map
            Map<String, Integer> stockByGoodsMap = new HashMap<>();
            for (TAppStock stock : stockList) {
                if (stockByGoodsMap.containsKey(stock.getGoodsId())) {
                    stockByGoodsMap.replace(stock.getGoodsId(), stockByGoodsMap.get(stock.getGoodsId()) + stock.getRemainNum());
                } else {
                    stockByGoodsMap.put(stock.getGoodsId(), stock.getRemainNum());
                }
            }
            if (!stockByGoodsMap.containsKey(stockOutRequest.getGoodsId())) {
                return BaseWmsApiResponse.error("请求错误：库内无该料库存。");
            }
            if (stockByGoodsMap.get(stockOutRequest.getGoodsId()) < stockOutRequest.getNeedNum()) {
                return BaseWmsApiResponse.error("请求错误：库内该料库存不足，库内数量：" + stockByGoodsMap.get(stockOutRequest.getGoodsId()) + "，需求数量: " + stockOutRequest.getNeedNum() + "。");
            }
        } else {
            return BaseWmsApiResponse.error("请求错误：未知的出库类型。");
        }
        // 添加任务
        TAppOuts task = new TAppOuts(
                UUIDUtils.getNewUUID(),
                stockOutRequest.getGoodsId(),
                stockOutRequest.getVehicleId(),
                stockOutRequest.getNeedNum(),
                0,
                0,
                stockOutRequest.getOutType(),
                stockOutRequest.getDestination(),
                stockOutRequest.getUserName(),
                stockOutRequest.getReason(),
                LocalDateTime.now()
        );
        appOutsService.save(task);
        return BaseWmsApiResponse.success("添加出库请求成功。");
    }

    /**
     * 入库用出库---实现
     * @param voiRequest 请求信息
     * @return 处理结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse requireVehiclesForIn(VehicleOutForInRequest voiRequest) {
        // 验证请求正确性
        if (voiRequest == null || voiRequest.getGoodsIds() == null || voiRequest.getGoodsIds().isEmpty()) {
            return WmsApiResponse.error("请求错误：请求信息为空。", null);
        }
        // 结果
        List<TAppOuts> outsList = new ArrayList<>();
        // 筛选出料号
        List<String> distinctGoodsIdList = voiRequest.getGoodsIds().stream().distinct().toList();
        // 获取数据map
        Map<String, Map<String, Integer>> goodsQtyMap = stockDataService.getCanPutGoodsMap(distinctGoodsIdList);
        // 迭代处理需求
        List<String> nonVehicleGoodsIds = new ArrayList<>();
        for (String goodsId : voiRequest.getGoodsIds()) {
            TAppGoods thisGoods = appCommon.getInstantGoodsByGoodsId(goodsId);
            if (thisGoods == null || !thisGoods.getPutArea().contains("ASRS")) {
                nonVehicleGoodsIds.add(goodsId);
                continue;
            }
            // 判断需求是否能满足
            if (!goodsQtyMap.containsKey(goodsId)) {
                nonVehicleGoodsIds.add(goodsId);
                continue;
            }
            Map<String, Integer> qtyByVehicleMap = goodsQtyMap.get(goodsId);
            if (qtyByVehicleMap.isEmpty()) {
                nonVehicleGoodsIds.add(goodsId);
                goodsQtyMap.remove(goodsId);
                continue;
            }
            // 当前料的载具号列表
            List<String> vehicleIdsOfThisGoods = new ArrayList<>(qtyByVehicleMap.keySet());
            for (String vehicleId : vehicleIdsOfThisGoods) {
                qtyByVehicleMap.remove(vehicleId);
                if (qtyByVehicleMap.isEmpty()) {
                    goodsQtyMap.remove(goodsId);
                } else {
                    goodsQtyMap.replace(goodsId, qtyByVehicleMap);
                }
                break;
            }
            // 添加任务
            outsList.add(new TAppOuts(
                    UUIDUtils.getNewUUID(),
                    goodsId,
                    "",
                    1,
                    0,
                    0,
                    WmsOutTypeEnums.FOR_IN.getCode(),
                    "R1",
                    voiRequest.getUserName(),
                    "",
                    LocalDateTime.now()
            ));
        }

        if (!outsList.isEmpty()) {
            StringBuilder message = new StringBuilder("以下料号无料箱：\n");
            for (String nonVehicleGoodsId : nonVehicleGoodsIds) {
                message.append(nonVehicleGoodsId).append("；\n");
            }
            appOutsService.saveBatch(outsList);
            return BaseWmsApiResponse.success("添加请求成功。" + message);
        } else {
            return BaseWmsApiResponse.error("符合条件的料号数量为0。");
        }
    }

    /**
     * 实现
     *
     * @param wcsTaskResultRequest 请求信息
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWcsApiResponse sendTaskResult(WcsTaskResultRequest wcsTaskResultRequest) {
        if (StringUtils.isEmpty(wcsTaskResultRequest.getTaskId()) || wcsTaskResultRequest.getTaskStatus() == null) {
            return BaseWcsApiResponse.error("请求缺少关键信息：任务号、任务状态。");
        }
        // 查询对应的wcs任务
        TAppWcsTask wcsTask = appWcsTaskService.getOne(
                new LambdaQueryWrapper<TAppWcsTask>()
                        .eq(TAppWcsTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
        );
        if (wcsTask == null) {
            return BaseWcsApiResponse.error("未找到对应的wcs任务。");
        }
        // 转换堆垛机任务状态
        int wmsTaskStatus = ConvertUtils.convertWcsStackerTaskStatusToWmsTaskStatus(wcsTaskResultRequest.getTaskStatus());
        if (wmsTaskStatus == -1) {
            return BaseWcsApiResponse.error("反馈的任务状态值无效。");
        }
        // 判断反馈的任务状态是否是「已完成」
        if (Objects.equals(wcsTaskResultRequest.getTaskStatus(), WcsStackerTaskStatusEnums.FINISH.getCode())) {
            // 更新wms任务状态
            appWmsTaskService.update(
                    new LambdaUpdateWrapper<TAppTask>()
                            .set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.FINISH.getCode())
                            .set(TAppTask::getFinishTime, LocalDateTime.now())
                            .eq(TAppTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
            );
            // 移除wcs任务，并向wcs备份表添加记录
            TAppWcsTaskBak wcsTaskBak = new TAppWcsTaskBak(
                    wcsTask.getWcsTaskId(),
                    wcsTask.getWcsTaskStatus(),
                    wcsTask.getWcsTaskType(),
                    wcsTask.getTaskPriority(),
                    wcsTask.getVehicleId(),
                    wcsTask.getOrigin(),
                    wcsTask.getDestination(),
                    wcsTask.getCreateTime(),
                    wcsTask.getSendTime(),
                    wcsTask.getFinishTime(),
                    wcsTask.getRemark()
            );
            appWcsTaskService.removeById(wcsTask.getWcsTaskId());
            appWcsTaskBakService.save(wcsTaskBak);
        } else {
            // 更新wms任务状态
            appWmsTaskService.update(
                    new LambdaUpdateWrapper<TAppTask>()
                            .set(TAppTask::getTaskStatus, wmsTaskStatus)
                            .eq(TAppTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
            );
            // 更新wcs任务状态
            appWcsTaskService.update(
                    new LambdaUpdateWrapper<TAppWcsTask>()
                            .set(TAppWcsTask::getWcsTaskStatus, wcsTaskResultRequest.getTaskStatus())
                            .eq(TAppWcsTask::getWcsTaskId, wcsTaskResultRequest.getTaskId())
            );
        }
        return BaseWcsApiResponse.success("处理任务状态反馈成功。");
    }

    /**
     * 实现
     *
     * @param wcsVehicleInRequest 载具请求
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WcsApiResponse<WcsStackerTask> wcsRequestVehicleIn(WcsVehicleInRequest wcsVehicleInRequest) {
        if (StringUtils.isEmpty(wcsVehicleInRequest.getVehicleNo())) {
            return WcsApiResponse.error("请求缺少关键信息：载具号。", null);
        }
        // 查询该载具对应的wms任务
        List<TAppTask> wmsTasks = appWmsTaskService.list(
                new LambdaQueryWrapper<TAppTask>()
                        .eq(TAppTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
                        .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
                        .eq(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.TEMP.getCode())
        );
        if (wmsTasks == null || wmsTasks.isEmpty()) {
            return WcsApiResponse.error("当前载具不存在任务或者任务已经下发。", null);
        }
        // 查询是否已经有对应wcs任务
        List<TAppWcsTask> wcsTasks = appWcsTaskService.list(
                new LambdaQueryWrapper<TAppWcsTask>()
                        .eq(TAppWcsTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
                        .eq(TAppWcsTask::getWcsTaskType, WcsStackerTaskTypeEnums.IN.getCode())
                        .ne(TAppWcsTask::getWcsTaskStatus, WcsStackerTaskStatusEnums.FINISH.getCode()));
        if (wcsTasks != null && !wcsTasks.isEmpty()) {
            WcsStackerTask wcsStackerTask = new WcsStackerTask(
                    wcsTasks.getFirst().getWcsTaskId(),
                    wcsTasks.getFirst().getWcsTaskType(),
                    wcsTasks.getFirst().getVehicleId(),
                    wcsTasks.getFirst().getOrigin(),
                    wcsTasks.getFirst().getDestination(),
                    "WMS"
            );
            return WcsApiResponse.success("载具请求入库成功。", wcsStackerTask);
        }
        // 判断是否已经分配库位
        String locationId = "";
        List<String> goodsIds = new ArrayList<>();
        for (TAppTask wmsTask : wmsTasks) {
            if (StringUtils.isNotEmpty(wmsTask.getDestination())) {
                locationId = wmsTask.getDestination();
                break;
            }
            if (!goodsIds.contains(wmsTask.getGoodsId())) {
                goodsIds.add(wmsTask.getGoodsId());
            }
        }
        if (StringUtils.isEmpty(locationId)) {
            // 如果只有一个料号，那么分配优先存放区域
            TAppLocation locationFilter = new TAppLocation();
            if (goodsIds.size() == 1) {
                TAppGoods thisGoods = appCommon.getInstantGoodsByGoodsId(goodsIds.getFirst());
                if (thisGoods != null && StringUtils.isNotEmpty(thisGoods.getPutArea())) {
                    locationFilter.setSubArea(thisGoods.getPutArea());
                }
            }
            // 需要申请库位
            TAppLocation targetLocation = stackerTaskService.requestOneLocation(null, wcsVehicleInRequest.getVehicleNo());
            locationId = targetLocation.getLocationId();
        }
        // 解析wms任务以获得wcs任务
        TAppWcsTask wcsInTask = new TAppWcsTask();
        wcsInTask.setWcsTaskId(UUIDUtils.getNewUUID());
        wcsInTask.setWcsTaskType(WcsStackerTaskTypeEnums.IN.getCode());
        wcsInTask.setWcsTaskStatus(WcsStackerTaskStatusEnums.WAIT.getCode());
        wcsInTask.setTaskPriority(wmsTasks.getFirst().getTaskPriority());
        wcsInTask.setOrigin(wmsTasks.getFirst().getOrigin());
        wcsInTask.setDestination(locationId);
        wcsInTask.setVehicleId(wmsTasks.getFirst().getVehicleId());
        wcsInTask.setCreateTime(LocalDateTime.now());
        wcsInTask.setSendTime(LocalDateTime.now());
        // 实时返回的任务
        WcsStackerTask wcsStackerTask = new WcsStackerTask(
                wcsInTask.getWcsTaskId(),
                wcsInTask.getWcsTaskType(),
                wcsInTask.getVehicleId(),
                wcsInTask.getOrigin(),
                wcsInTask.getDestination(),
                "WMS"
        );
        try {
            // 载具设置状态入库中
            appVehicleService.update(new LambdaUpdateWrapper<TAppVehicle>()
                    .set(TAppVehicle::getVehicleStatus, WmsVehicleStatusEnums.IN.getCode())
                    .eq(TAppVehicle::getVehicleId, wcsVehicleInRequest.getVehicleNo()));
            // 如果有库存的话，更新库存状态为回库中
            appStockService.update(new LambdaUpdateWrapper<TAppStock>()
                    .set(TAppStock::getStockStatus, WmsStockStatusEnums.BACK.getCode())
                    .eq(TAppStock::getVehicleId, wcsVehicleInRequest.getVehicleNo()));
            // 更新wmsTask
            appWmsTaskService.update(
                    new LambdaUpdateWrapper<TAppTask>()
                            .set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.SEND.getCode())
                            .set(TAppTask::getWcsTaskId, wcsInTask.getWcsTaskId())
                            .set(TAppTask::getDestination, locationId)
                            .eq(TAppTask::getVehicleId, wcsVehicleInRequest.getVehicleNo())
                            .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())
                            .eq(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.TEMP.getCode())
            );
            // 存储wcsTask
            appWcsTaskService.save(wcsInTask);
            return WcsApiResponse.success("载具请求入库成功。", wcsStackerTask);
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            // 恢复库位空闲
            appLocationService.update(new LambdaUpdateWrapper<TAppLocation>()
                    .set(TAppLocation::getIsOccupy, 0)
                    .set(TAppLocation::getVehicleId, "")
                    .eq(TAppLocation::getLocationId, locationId));
            return WcsApiResponse.error("载具请求入库发生异常。", null);
        }
    }

    /**
     * 实现
     *
     * @param boxArriveRequest 请求信息
     * @return 响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWcsApiResponse boxArrive(WcsBoxArriveRequest boxArriveRequest) {
        if (boxArriveRequest == null
                || StringUtils.isEmpty(boxArriveRequest.getVehicleNo())
                || StringUtils.isEmpty(boxArriveRequest.getLocation())) {
            return BaseWcsApiResponse.error("请求信息不完整，缺少载具号或者点位。");
        }
        // 更新当前载具到达当前点位的拣选任务为已到达
        boolean isUpdateSuccess = appPickTaskService.update(new LambdaUpdateWrapper<TAppPickTask>()
                .set(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode())
                .set(TAppPickTask::getArriveTime, LocalDateTime.now())
                .eq(TAppPickTask::getVehicleId, boxArriveRequest.getVehicleNo())
                .eq(TAppPickTask::getPickStand, boxArriveRequest.getLocation())
                .ne(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.FOR_IN.getCode()));
        if (isUpdateSuccess) {
            // 更新成功，返回成功
            return BaseWcsApiResponse.success("处理成功。");
        } else {
            // 更新失败，返回失败
            return BaseWcsApiResponse.error("处理失败。");
        }
    }

    /**
     * 取消拣选任务实现
     *
     * @param pickTaskRequest 请求信息
     * @return 处理结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse cancelPickTasks(PickTaskRequest pickTaskRequest) {
        if (pickTaskRequest == null || pickTaskRequest.getPickTasks() == null || pickTaskRequest.getPickTasks().isEmpty()) {
            // 更新失败，返回失败
            return BaseWmsApiResponse.error("空请求。");
        }
        // 获得需要取消的拣选任务列表
        Map<String, WmsPickTask> vehicleStandMap = new HashMap<>();
        for (WmsPickTask pickTask : pickTaskRequest.getPickTasks()) {
            String key = pickTask.getVehicleId() + "_" + pickTask.getPickStand();
            if (vehicleStandMap.containsKey(key)) {
                continue;
            }
            vehicleStandMap.put(key, pickTask);
        }
        int successCount = 0;
        int failCount = 0;
        int exceptionCount = 0;
        conveyTaskService.cancelPickTasks(vehicleStandMap, successCount, failCount, exceptionCount);
        return BaseWmsApiResponse.success("取消拣选任务成功" + successCount + "条，失败" + failCount + "条，异常" + exceptionCount + "条。");
    }

    /**
     * 获取当前站台任务---实现
     *
     * @param wmsRequest 请求信息
     * @return 获取结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WmsApiResponse<TaskConfirmVo> getCurrentTask(BaseWmsRequest wmsRequest) {
        if (wmsRequest == null || StringUtils.isEmpty(wmsRequest.getStandId())) {
            // 缺少站台号
            return WmsApiResponse.error("请求缺少信息，请输入站台号。", null);
        }
        // 查询当前站台的拣选任务
        List<TAppPickTask> pickTasks = appPickTaskService.list(new LambdaQueryWrapper<TAppPickTask>()
                .eq(TAppPickTask::getPickStand, wmsRequest.getStandId())
                .eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode()));
        if (pickTasks == null || pickTasks.isEmpty()) {
            // 当前站台没有任务
            return WmsApiResponse.error("当前站台没有任务。", null);
        }
        TAppPickTask thisStandPickTask = pickTasks.getFirst();
        // 查找这个载具对应的库存信息：数量>0
        List<TAppStock> thisVehicleStocks = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                .eq(TAppStock::getVehicleId, thisStandPickTask.getVehicleId())
                .gt(TAppStock::getRealNum, 0));
        if (thisVehicleStocks == null || thisVehicleStocks.isEmpty()) {
            return WmsApiResponse.instanceOf(WmsApiResponseCodeEnums.WARNING.getCode(), "当前箱子已经是空箱，请直接放行。", null);
        }
        // 判断是否有任务需求
        TaskConfirmVo confirmVo = conveyTaskService.getCurrentStandTask(thisStandPickTask);
        if (confirmVo != null) {
            return WmsApiResponse.success("请根据界面提示拣选。", confirmVo);
        }
        return WmsApiResponse.instanceOf(WmsApiResponseCodeEnums.WARNING.getCode(), "当前箱子没有拣选需求，请直接放行。", null);
    }

    /**
     * 确认当前站台任务---实现
     *
     * @param confirmTaskRequest 请求信息
     * @return 确认结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse confirmCurrentTask(ConfirmTaskRequest confirmTaskRequest) {
        if (confirmTaskRequest == null || StringUtils.isEmpty(confirmTaskRequest.getStandId())) {
            return BaseWmsApiResponse.error("请求缺少信息，请输入站台号。");
        }
        // 查询当前站台上的已到达的拣选任务
        List<TAppPickTask> pickTaskList = appPickTaskService.list(new LambdaQueryWrapper<TAppPickTask>()
                .eq(TAppPickTask::getPickStand, confirmTaskRequest.getStandId())
                .eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode()));
        if (pickTaskList == null || pickTaskList.isEmpty()) {
            return BaseWmsApiResponse.error("当前站台没有箱子到达, 请检查。");
        }
        if (pickTaskList.size() > 1) {
            return BaseWmsApiResponse.error("当前站台有多个箱子到达，请检查。");
        }
        // 当前站台到达的拣选任务
        TAppPickTask thisPickTask = pickTaskList.getFirst();
        if (confirmTaskRequest.getTaskConfirm() != null && StringUtils.isNotEmpty(confirmTaskRequest.getTaskConfirm().getTaskId())) {
            // 更新工作信息
            String updateTaskResult = updateTaskInfo(confirmTaskRequest);
            if (StringUtils.isNotEmpty(updateTaskResult)) {
                return BaseWmsApiResponse.error("更新任务信息失败：" + updateTaskResult + "，请重试。");
            }
        }
        // 更新库存信息
        stockDataService.updateStockInfo(confirmTaskRequest.getStockConfirm(), confirmTaskRequest.getStandId(), confirmTaskRequest.getUserName(), "出库拣选", null);
        // 查询库存获得当前载具中存储的库存列表
        LambdaQueryWrapper<TAppStock> stockQueryWrapper = new LambdaQueryWrapper<TAppStock>()
                .eq(TAppStock::getVehicleId, thisPickTask.getVehicleId())
                .gt(TAppStock::getRealNum, 0);
        List<TAppStock> stockList = appStockService.list(stockQueryWrapper);
        // 界面直接点击确认/放行
        if (!stockList.isEmpty()) {
            // 判断还有没有当前站台的其他拣选任务
            TaskConfirmVo taskConfirmVo = conveyTaskService.getCurrentStandTask(thisPickTask);
            if (taskConfirmVo != null) {
                return BaseWmsApiResponse.warn("当前载具还有其他拣选任务，请根据界面信息进行拣配。");
            }
            WorkConfirmVo resultVo = conveyTaskService.getCurrentStandWork(thisPickTask);
            if (resultVo != null) {
                return BaseWmsApiResponse.warn("当前载具还有工作，请切换到拣配界面进行拣配。");
            }
            // 判断当前载具是否还有盘点任务
            List<String> goodsIds = stockList.stream().map(TAppStock::getGoodsId).distinct().toList();
            List<TAppInventory> inventoryTasks = appInventoryService.list(new LambdaQueryWrapper<TAppInventory>()
                    .eq(TAppInventory::getVehicleId, thisPickTask.getVehicleId())
                    .in(TAppInventory::getGoodsId, goodsIds));
            if (inventoryTasks != null && !inventoryTasks.isEmpty()) {
                return BaseWmsApiResponse.warn("当前载具还有盘点任务，请切换到盘点界面进行拣配。");
            }
        } else {
            // 取消后续拣选任务
            conveyTaskService.cancelOtherStandPickTasks(thisPickTask.getVehicleId(), thisPickTask.getPickStand());
        }
        // 放行
        if (conveyTaskService.releaseStandVehicle(thisPickTask)) {
            return BaseWmsApiResponse.success("确认成功。");
        } else {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return BaseWmsApiResponse.error("释放箱子失败。");
        }
    }

    /**
     * 请求盘点---实现
     * @param inventoryRequest 盘点请求
     * @return 请求结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse requestInventory(InventoryRequest inventoryRequest) {
        if (inventoryRequest == null) {
            return BaseWmsApiResponse.error("请求为NULL。");
        }
        if (StringUtils.isEmpty(inventoryRequest.getStandId())) {
            return BaseWmsApiResponse.error("请求缺少信息，请输入站台号。");
        }
        if (!appStandService.exists(new LambdaQueryWrapper<TAppStand>().eq(TAppStand::getStandId, inventoryRequest.getStandId())
                .eq(TAppStand::getStandType, 1))) {
            return BaseWmsApiResponse.error("非拣选站台不允许盘点。");
        }
        if (StringUtils.isEmpty(inventoryRequest.getGoodsId())) {
            return BaseWmsApiResponse.error("请求缺少信息，请输入料号。");
        }
        // 判断这个料有没有还没盘点完的任务
        List<TAppInventory> inventoryList = appInventoryService.list(new LambdaQueryWrapper<TAppInventory>()
                .eq(TAppInventory::getGoodsId, inventoryRequest.getGoodsId())
                .eq(StringUtils.isNotEmpty(inventoryRequest.getVehicleId()), TAppInventory::getVehicleId, inventoryRequest.getVehicleId()));
        if (inventoryList != null && !inventoryList.isEmpty()) {
            String errMsg = StringUtils.isNotEmpty(inventoryRequest.getVehicleId()) ? "载具：" + inventoryRequest.getVehicleId() : "";
            return BaseWmsApiResponse.error(errMsg + "料号：" + inventoryRequest.getGoodsId() + "还有盘点任务未完成。");
        }
        // 查询库存，创建盘点任务
        List<TAppStock> stockList = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                .eq(TAppStock::getGoodsId, inventoryRequest.getGoodsId())
                .eq(StringUtils.isNotEmpty(inventoryRequest.getVehicleId()), TAppStock::getVehicleId, inventoryRequest.getVehicleId()));
        if (stockList == null || stockList.isEmpty()) {
            return BaseWmsApiResponse.error("物料" + inventoryRequest.getGoodsId() + "没有库存。");
        }
        // 根据载具号map一下
        Map<String, TAppInventory> inventoryByVehicleMap = new HashMap<>();
        // 盘点单号
        String orderId = UUIDUtils.getNewUUID();
        for (TAppStock stock : stockList) {
            if (!inventoryByVehicleMap.containsKey(stock.getVehicleId())) {
                // 添加盘点任务
                TAppInventory inventoryTask = new TAppInventory(
                        UUIDUtils.getNewUUID(),
                        inventoryRequest.getGoodsId(),
                        stock.getVehicleId(),
                        null,
                        null,
                        inventoryRequest.getStandId(),
                        inventoryRequest.getUserName(),
                        WmsInvTypeEnums.INV_TYPE_1.getCode(),
                        WmsInvStatusEnums.INIT.getCode(),
                        WmsInvResultEnums.NONE.getCode(),
                        LocalDateTime.now(),
                        null,
                        orderId
                );
                inventoryByVehicleMap.put(stock.getVehicleId(), inventoryTask);
            }
        }
        if (!inventoryByVehicleMap.isEmpty()) {
            appInventoryService.saveBatch(inventoryByVehicleMap.values());
        }
        // 保存盘点任务
        return BaseWmsApiResponse.success("创建盘点任务成功。");
    }

    /**
     * 查询盘点确认信息
     * @param inventoryConfirmRequest 请求
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<InventoryConfirmVo> getInventoryConfirm(InventoryConfirmRequest inventoryConfirmRequest) {
        // 判断请求是否参数完备
        if (inventoryConfirmRequest == null) {
            return WmsApiResponse.error("请求参数为空。", null);
        }
        if (StringUtils.isEmpty(inventoryConfirmRequest.getStandId())) {
            return WmsApiResponse.error("请求参数缺少站台号。", null);
        }
        // 查询当前站台的拣选任务
        List<TAppPickTask> pickTaskList = appPickTaskService.list(new LambdaQueryWrapper<TAppPickTask>()
                .eq(TAppPickTask::getPickStand, inventoryConfirmRequest.getStandId())
                .eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode()));
        if (pickTaskList == null || pickTaskList.isEmpty()) {
            return WmsApiResponse.error("当前站台没有箱子到达, 请检查。", null);
        }
        if (pickTaskList.size() > 1) {
            return WmsApiResponse.error("当前站台有多个箱子到达，请检查。", null);
        }
        // 获取当前拣选任务
        TAppPickTask thisPickTask = pickTaskList.getFirst();
        InventoryConfirmVo inventoryConfirmVo = conveyTaskService.getInventoryConfirm(thisPickTask.getVehicleId());
        if (inventoryConfirmVo != null) {
            // 返回结果
            return WmsApiResponse.success("查询盘点确认信息成功。", inventoryConfirmVo);
        }
        return WmsApiResponse.instanceOf(WmsApiResponseCodeEnums.WARNING.getCode(),"当前箱子没有要盘点的任务，请放行。", null);
    }

    /**
     * 确认盘点信息
     * @param inventoryConfirmRequest 确认请求
     * @return 处理结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse confirmInventory(InventoryConfirmRequest inventoryConfirmRequest) {
        if (inventoryConfirmRequest == null) {
            return BaseWmsApiResponse.error("请求信息为空。");
        }
        if (StringUtils.isEmpty(inventoryConfirmRequest.getStandId())) {
            return BaseWmsApiResponse.error("请求信息缺少站台号。");
        }
        // 查询当前站台上的已到达的拣选任务
        List<TAppPickTask> pickTaskList = appPickTaskService.list(new LambdaQueryWrapper<TAppPickTask>()
                .eq(TAppPickTask::getPickStand, inventoryConfirmRequest.getStandId())
                .eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode()));
        if (pickTaskList == null || pickTaskList.isEmpty()) {
            return BaseWmsApiResponse.error("当前站台没有箱子到达, 请检查。");
        }
        if (pickTaskList.size() > 1) {
            return BaseWmsApiResponse.error("当前站台有多个箱子到达，请检查。");
        }
        // 当前站台到达的拣选任务
        TAppPickTask thisPickTask = pickTaskList.getFirst();
        if (StringUtils.isNotEmpty(inventoryConfirmRequest.getInventoryId())) {
            TAppInventory targetInventory = appInventoryService.getById(inventoryConfirmRequest.getInventoryId());
            if (targetInventory != null) {
                if (!Objects.equals(targetInventory.getVehicleId(), thisPickTask.getVehicleId())) {
                    // 盘点的载具号与当前站台到达的拣选任务载具号不一致，请检查。
                    return BaseWmsApiResponse.error("盘点的载具号与当前站台到达的载具号不一致，请检查。");
                }
                if (inventoryConfirmRequest.getConfirmNum() == null || inventoryConfirmRequest.getConfirmNum() < 0) {
                    return BaseWmsApiResponse.error("请求信息中的盘点确认数量不正确。");
                }
                // 添加盘点记录
                TAppInventoryRecord inventoryRecord = new TAppInventoryRecord();
                inventoryRecord.setInventoryId(inventoryConfirmRequest.getInventoryId());
                inventoryRecord.setGoodsId(targetInventory.getGoodsId());
                inventoryRecord.setVehicleId(targetInventory.getVehicleId());
                // 查询这个载具-料号对应的库存数量
                List<TAppStock> thisVehicleAndGoodsStock = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                        .eq(TAppStock::getVehicleId, targetInventory.getVehicleId())
                        .eq(TAppStock::getGoodsId, targetInventory.getGoodsId()));
                int stockNum = 0;
                if (thisVehicleAndGoodsStock != null && !thisVehicleAndGoodsStock.isEmpty()) {
                    // 获取realNum总和
                    stockNum = thisVehicleAndGoodsStock.stream().mapToInt(TAppStock::getRealNum).sum();
                }
                inventoryRecord.setStockNum(stockNum);
                inventoryRecord.setConfirmNum(inventoryConfirmRequest.getConfirmNum());
                inventoryRecord.setInvStand(inventoryConfirmRequest.getStandId());
                inventoryRecord.setInvUser(inventoryConfirmRequest.getUserName());
                inventoryRecord.setInvType(WmsInvTypeEnums.INV_TYPE_1.getCode());
                inventoryRecord.setInvStatus(WmsInvStatusEnums.CONFIRMED.getCode());
                if (stockNum < inventoryConfirmRequest.getConfirmNum()) {
                    // 盘盈
                    inventoryRecord.setInvResult(WmsInvResultEnums.PLUS.getCode());
                } else if (stockNum == inventoryConfirmRequest.getConfirmNum()) {
                    // 正常
                    inventoryRecord.setInvResult(WmsInvResultEnums.EQUAL.getCode());
                } else {
                    // 盘亏
                    inventoryRecord.setInvResult(WmsInvResultEnums.MINUS.getCode());
                }
                inventoryRecord.setInvCreateTime(targetInventory.getInvCreateTime());
                inventoryRecord.setInvConfirmTime(LocalDateTime.now());
                inventoryRecord.setInvOrderId(targetInventory.getInventoryId());
                appInventoryRecordService.save(inventoryRecord);
                // 移除任务表
                appInventoryService.removeById(inventoryConfirmRequest.getInventoryId());
                // 根据盘点确认信息更新库存
                StockConfirmEntity stockConfirm = new StockConfirmEntity();
                stockConfirm.setVehicleId(targetInventory.getVehicleId());
                stockConfirm.setGoodsId(targetInventory.getGoodsId());
                stockConfirm.setRealRemainQty(inventoryConfirmRequest.getConfirmNum());
                // 更新库存信息
                stockDataService.updateStockInfo(stockConfirm, inventoryConfirmRequest.getStandId(), inventoryConfirmRequest.getUserName(), "盘点确认", targetInventory.getInventoryId());
            } else {
                return BaseWmsApiResponse.error("请求的盘点任务号未查到对应的盘点任务。");
            }
        }
        // 查询库存获得当前载具中存储的库存列表
        LambdaQueryWrapper<TAppStock> stockQueryWrapper = new LambdaQueryWrapper<TAppStock>()
                .eq(TAppStock::getVehicleId, thisPickTask.getVehicleId());
        List<TAppStock> stockList = appStockService.list(stockQueryWrapper);
        // 界面直接点击确认/放行
        if (!stockList.isEmpty()) {
            // 判断是否还有其他盘点任务
            List<TAppInventory> otherInventoryList = appInventoryService.list(new LambdaQueryWrapper<TAppInventory>()
                    .eq(TAppInventory::getVehicleId, thisPickTask.getVehicleId())
                    .ne(TAppInventory::getInventoryId, inventoryConfirmRequest.getInventoryId()));
            if (otherInventoryList != null && !otherInventoryList.isEmpty()) {
                return BaseWmsApiResponse.error("当前载具还有其他的盘点任务，请继续盘点。");
            }
            // 判断还有没有当前站台的其他拣选任务
            TaskConfirmVo taskConfirmVo = conveyTaskService.getCurrentStandTask(thisPickTask);
            if (taskConfirmVo != null) {
                return BaseWmsApiResponse.warn("当前载具还有紧急出库任务，请切换到出库界面信息进行拣配。");
            }
            WorkConfirmVo resultVo = conveyTaskService.getCurrentStandWork(thisPickTask);
            if (resultVo != null) {
                return BaseWmsApiResponse.warn("当前载具还有工作，请切换到拣配界面进行拣配。");
            }
        } else {
            // 取消后续拣选任务
            conveyTaskService.cancelOtherStandPickTasks(thisPickTask.getVehicleId(), thisPickTask.getPickStand());
        }
        // 放行
        if (conveyTaskService.releaseStandVehicle(thisPickTask)) {
            return BaseWmsApiResponse.success("确认成功。");
        } else {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return BaseWmsApiResponse.error("释放箱子失败。");
        }
    }

    /**
     * 更新出库单信息
     * @param confirmTaskRequest 确认信息
     */
    private String updateTaskInfo(ConfirmTaskRequest confirmTaskRequest) {
        if (confirmTaskRequest == null) {
            return "请求参数为空";
        }
        TaskConfirmEntity taskConfirm = confirmTaskRequest.getTaskConfirm();
        if (taskConfirm == null || StringUtils.isEmpty(taskConfirm.getTaskId())) {
            return "请求参数不全";
        }
        // 查询对应的任务
        TAppOuts outs = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
                .eq(TAppOuts::getTaskId, taskConfirm.getTaskId()));
        if (outs == null || taskConfirm.getRealPickQty() == null) {
            return "未查到对应的任务或者实际拣选数量未填写";
        }
        outs.setPickNum(outs.getPickNum() + taskConfirm.getRealPickQty());
        outs.setUserName(confirmTaskRequest.getUserName());
        if (outs.getPickNum() >= outs.getNeedNum()) {
            // 生成记录
            TAppOutsRecord record = new TAppOutsRecord(
                    outs.getTaskId(),
                    outs.getGoodsId(),
                    outs.getVehicleId(),
                    outs.getNeedNum(),
                    outs.getDistributeNum(),
                    outs.getPickNum(),
                    outs.getOutType(),
                    outs.getDestination(),
                    outs.getUserName(),
                    outs.getReason(),
                    outs.getRequestTime()
            );
            // 删除出库单
            appOutsService.removeById(outs.getTaskId());
            // 添加记录
            appOutsRecordService.save(record);
        } else {
            // 更新出库单
            appOutsService.updateById(outs);
        }
        // 清除拣选计划
        LambdaQueryWrapper<TAppPickPlan> pickPlanQueryWrapper = new LambdaQueryWrapper<TAppPickPlan>()
                .eq(TAppPickPlan::getWorkIndex, confirmTaskRequest.getTaskConfirm().getTaskId());
        if (confirmTaskRequest.getStockConfirm() != null && StringUtils.isNotEmpty(confirmTaskRequest.getStockConfirm().getVehicleId())) {
            // 箱号
            pickPlanQueryWrapper.eq(TAppPickPlan::getVehicleId, confirmTaskRequest.getStockConfirm().getVehicleId());
        }
        appPickPlanService.remove(pickPlanQueryWrapper);
        return "";
    }
}
