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.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wms_main.app.AppCommon;
import com.wms_main.constant.enums.others.DbsStatusEnums;
import com.wms_main.constant.enums.wms.*;
import com.wms_main.dao.*;
import com.wms_main.model.bo.wms.BoxSummary;
import com.wms_main.model.bo.wms.GoodsLackSummary;
import com.wms_main.model.bo.wms.OrderConfirmEntity;
import com.wms_main.model.bo.wms.StockConfirmEntity;
import com.wms_main.model.dto.query.*;
import com.wms_main.model.dto.request.wms.*;
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.*;
import com.wms_main.repository.utils.FileUtils;
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.IStockDataService;
import com.wms_main.service.controller.IKateWorkControllerService;
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.*;
import java.util.stream.Collectors;

/**
 * 卡特工作控制类服务接口实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class KateWorkControllerServiceImpl implements IKateWorkControllerService {
    private final ITAppDbsService appDbsService;// dbs服务
    private final ITAppProductService appProductService;// 成品配料单服务
    private final ITAppProductExtendService appProductExtendService;// 成品-单片对应服务
    private final ITAppSingleProductService appSingleProductService;// 单片配料单服务
    private final ITAppWorkService appWorkService;// 工作服务
    private final ITAppPickTaskService appPickTaskService;// 拣选任务服务
    private final ITAppStockService appStockService;// 库存服务
    private final IConveyTaskService conveyTaskService;// 输送线任务服务
    private final ITAppGoodsService appGoodsService;// 物料服务
    private final ITAppStandWorkService appStandWorkService;// 站台工作服务
    private final ITAppImageService appImageService;// 图纸服务
    private final IStockDataService stockDataService;// 库存数据服务
    private final ITAppStandService appStandService;// 站台服务
    private final ITAppKanbanService appKanbanService;// 看板服务
    private final ITAppWorkRecordService appWorkRecordService;// 工作记录服务
    private final ITAppPickPlanService appPickPlanService;// 拣选计划服务
    private final ITAppInventoryService appInventoryService;// 盘点任务服务
    private final AppCommon appCommon;

    /**
     * 查询卡特工作
     *
     * @param kateWorksQuery 卡特工作查询参数
     * @return 卡特工作列表
     */
    @Override
    public WmsApiResponse<KateWorkOptionsVo> queryKateWorks(KateWorksQuery kateWorksQuery) {
        if (kateWorksQuery == null) {
            // 空请求，直接返回空。
            return WmsApiResponse.success(new KateWorkOptionsVo());
        }
        // 结果集
        KateWorkOptionsVo result = new KateWorkOptionsVo();
        // 分为两种情况
        if (StringUtils.isEmpty(kateWorksQuery.getWorkOrder())) {
            // 1. 工单号未填的情况下，返回所有的工单
            List<TAppDbs> dbsList = appDbsService.list(new LambdaQueryWrapper<TAppDbs>()
                    .eq(kateWorksQuery.getPlanStartDate() != null, TAppDbs::getTestPlanStartDate, kateWorksQuery.getPlanStartDate()));
            if (dbsList != null && !dbsList.isEmpty()) {
                // 获取工单列表
                result.setWorkOrder(dbsList.stream().map(TAppDbs::getWorkOrder).distinct().toList());
            }
        } else {
            // 2. 工单号已填写的情况下，查询到对应的DBS信息
            List<TAppDbs> dbsList = appDbsService.list(new LambdaQueryWrapper<TAppDbs>()
                    .like(TAppDbs::getWorkOrder, kateWorksQuery.getWorkOrder())
                    .ne(TAppDbs::getDbsStatus, DbsStatusEnums.FINISH.getValue()));
            if (dbsList == null || dbsList.isEmpty()) {
                // 返回空列表
                return WmsApiResponse.success(new KateWorkOptionsVo());
            }
            if (dbsList.size() > 1) {
                // 备选工单超过1条，直接返回
                result.setWorkOrder(dbsList.stream().map(TAppDbs::getWorkOrder).distinct().toList());
                return WmsApiResponse.success(result);
            }
            TAppDbs dbs = dbsList.getFirst();
            // 设置工单号列表
            result.setWorkOrder(List.of(dbs.getWorkOrder()));
            // 设置原始成品号
            result.setProductIdOrigin(dbs.getProductIdOrigin());
            // 设置过滤成品号
            result.setProductId(dbs.getProductId());
            if (!getWorkOptionsOfServicePieces(kateWorksQuery, dbs.getProductIdOrigin(), result)) {
                if (getWorkOptionsOfNonServicePieces(kateWorksQuery, dbs.getProductId(), result)) {
                    result.setProductType(1);// 普通成品
                }
            } else {
                result.setProductType(2);// 服务件成品
            }
        }
        return WmsApiResponse.success(result);
    }

    /**
     * 初始化任务
     *
     * @param initKateWorkRequest 请求信息
     * @return 初始化任务响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse initWorks(InitKateWorkRequest initKateWorkRequest) {
        if (initKateWorkRequest == null) {
            return BaseWmsApiResponse.error("请求信息为空，无法创建工作。");
        }
        if (StringUtils.isEmpty(initKateWorkRequest.getStandId())) {
            return BaseWmsApiResponse.error("缺少站台号，无法创建工作。");
        }
        if (!appStandService.exists(new LambdaQueryWrapper<TAppStand>().eq(TAppStand::getStandId, initKateWorkRequest.getStandId())
                .eq(TAppStand::getStandType, 1))) {
            return BaseWmsApiResponse.error("当前站台非拣选站台，不允许创建工作。");
        }
        // 判断请求是否完整
        if (StringUtils.isEmpty(initKateWorkRequest.getWorkOrder())) {
            return BaseWmsApiResponse.error("请求信息不完整，缺少工单号。");
        }
        // 先判断当前站台是否有其他需要做的工作
        List<TAppWork> currentStandWorkList = appWorkService.list(new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkStand, initKateWorkRequest.getStandId())
                .ne(TAppWork::getWorkOrder, initKateWorkRequest.getWorkOrder())
                .notIn(TAppWork::getWorkStatus, -1, 2));
        if (currentStandWorkList != null && !currentStandWorkList.isEmpty()) {
            return BaseWmsApiResponse.error("当前站台还有其他工单未完成，无法创建新的工单。");
        }
        // 判断当前工单的工作是否已经存在，如果选择了单片，则只下发单片。
        List<TAppWork> allcurrentWorkOrderWorkList = appWorkService.list(new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkOrder, initKateWorkRequest.getWorkOrder()));
        if (allcurrentWorkOrderWorkList != null && !allcurrentWorkOrderWorkList.isEmpty()) {
            // 筛选是不是单片
            List<TAppWork> currentWorkOrderWorkList = allcurrentWorkOrderWorkList.stream().filter(work -> {
                if (StringUtils.isNotEmpty(initKateWorkRequest.getSingleProductId())) {
                    return Objects.equals(work.getSingleProductId(), initKateWorkRequest.getSingleProductId());
                } else {
                    return StringUtils.isEmpty(work.getSingleProductId());
                }
            }).toList();
            if (!currentWorkOrderWorkList.isEmpty()) {
                // 根据查询条件筛选出对应的暂存数据
                List<TAppWork> filterWorks = currentWorkOrderWorkList.stream()
                        .filter(work -> {
                            boolean result = work.getWorkStatus() == -1;
                            // 料盒号
                            if (StringUtils.isNotEmpty(initKateWorkRequest.getBoxNo())) {
                                result = result && Objects.equals(work.getBoxNo(), initKateWorkRequest.getBoxNo());
                            }
                            // 物料号
                            if (StringUtils.isNotEmpty(initKateWorkRequest.getGoodsId())) {
                                result = result && Objects.equals(work.getGoodsId(), initKateWorkRequest.getGoodsId());
                            }
                            return result;
                        }).toList();
                if (filterWorks.isEmpty()) {
                    return BaseWmsApiResponse.error("当前工单已生成工作，请勿重复下发。");
                }
                try {
                    // 将这些工作的状态设置为待执行
                    appWorkService.update(
                            new LambdaUpdateWrapper<TAppWork>()
                                    .set(TAppWork::getWorkStatus, 0)
                                    .set(TAppWork::getWorkStand, initKateWorkRequest.getStandId())
                                    .in(TAppWork::getWorkIndex, filterWorks.stream().map(TAppWork::getWorkIndex).toList())
                    );
                    return BaseWmsApiResponse.success("创建工作成功。");
                } catch (Exception e) {
                    // 回滚事务
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return BaseWmsApiResponse.error("创建工作失败。");
                }
            }
        }
        // 生成新的工作详情
        // ->
        // 查询dbs信息
        List<TAppDbs> dbsList = appDbsService.list(new LambdaQueryWrapper<TAppDbs>()
                .eq(TAppDbs::getWorkOrder, initKateWorkRequest.getWorkOrder())
                .ne(TAppDbs::getDbsStatus, 2));
        if (dbsList == null || dbsList.isEmpty()) {
            return BaseWmsApiResponse.error("工单未查询到DBS信息，请检查。");
        }
        if (dbsList.size() > 1) {
            return BaseWmsApiResponse.error("工单存在多个DBS信息，请检查。");
        }
        // 添加work表
        List<TAppWork> workList = new ArrayList<>();
        // 查询配料相关表
        TAppDbs dbs = dbsList.getFirst();
        // 查询所有的库外物料信息
        List<TAppGoods> outGoodsList = appGoodsService.list(new LambdaQueryWrapper<TAppGoods>()
                .notLike(TAppGoods::getPutArea, "ASRS"));
        List<String> outGoodsIds = outGoodsList.stream().map(TAppGoods::getGoodsId).distinct().toList();
        // 创建服务件工作
        createServicePiecesWork(outGoodsIds, dbs, workList);
        if (workList.isEmpty()) {
            // 创建非服务件工作
            createNonServicePiecesWork(outGoodsIds, dbs, workList);
        }
        // 设置暂存及站台等信息
        for (TAppWork work : workList) {
            if (StringUtils.isNotEmpty(initKateWorkRequest.getSingleProductId())) {
                if (!Objects.equals(work.getSingleProductId(), initKateWorkRequest.getSingleProductId())) {
                    // 单片号不对应
                    work.setWorkStatus(-1);
                } else if (StringUtils.isNotEmpty(initKateWorkRequest.getBoxNo()) && !Objects.equals(work.getBoxNo(), initKateWorkRequest.getBoxNo())) {
                    // 料盒号不对应
                    work.setWorkStatus(-1);
                } else if (StringUtils.isNotEmpty(initKateWorkRequest.getGoodsId()) && !Objects.equals(work.getGoodsId(), initKateWorkRequest.getGoodsId())) {
                    // 料号不对应
                    work.setWorkStatus(-1);
                } else {
                    work.setWorkStatus(0);
                }
            } else {
                if (StringUtils.isNotEmpty(work.getSingleProductId())) {
                    // 单片不下发
                    work.setWorkStatus(-1);
                } else if (StringUtils.isNotEmpty(initKateWorkRequest.getBoxNo()) && !Objects.equals(work.getBoxNo(), initKateWorkRequest.getBoxNo())) {
                    // 料盒号不对应
                    work.setWorkStatus(-1);
                } else if (StringUtils.isNotEmpty(initKateWorkRequest.getGoodsId()) && !Objects.equals(work.getGoodsId(), initKateWorkRequest.getGoodsId())) {
                    // 料号不对应
                    work.setWorkStatus(-1);
                } else {
                    work.setWorkStatus(0);
                }
            }
            work.setWorkStand(initKateWorkRequest.getStandId());
            work.setWorkUser(initKateWorkRequest.getUserName());
        }
        try {
            if (workList.isEmpty()) {
                return BaseWmsApiResponse.error("没有工作可以创建，请检查。");
            }
            // 保存工作
            appWorkService.saveBatch(workList);
            // 更新原始dbs状态
            appDbsService.update(new LambdaUpdateWrapper<TAppDbs>()
                    .set(TAppDbs::getWorkStand, initKateWorkRequest.getStandId())
                    .set(TAppDbs::getDbsStatus, 1).eq(TAppDbs::getDbsId, dbs.getDbsId()));
            return BaseWmsApiResponse.success("创建工作成功。");
        } catch (Exception e) {
            // 回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return BaseWmsApiResponse.error("发生异常，请重试。");
        }
    }

    /**
     * 查询当前需要配料的工作---实现
     *
     * @param kateWorksQuery 查询参数
     * @return 查询结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WmsApiResponse<WorkConfirmVo> getCurrentWorks(KateWorksQuery kateWorksQuery) {
        if (kateWorksQuery == null || StringUtils.isEmpty(kateWorksQuery.getStandId())) {
            return WmsApiResponse.error("请求缺少信息，请输入站台号。", null);
        }
        // 查询是否已经有正在拣选的
        List<TAppStandWork> standWorkList = appStandWorkService.list(new LambdaQueryWrapper<TAppStandWork>()
                .eq(TAppStandWork::getStandId, kateWorksQuery.getStandId()));
        if (standWorkList == null || standWorkList.isEmpty()) {
            return WmsApiResponse.error("当前站台工作已全部完成。", null);
        }
        TAppStandWork thisStandWork = standWorkList.getFirst();
        // 查询库存预警数量
        if (StringUtils.isNotEmpty(thisStandWork.getGoodsId())) {
            // 返回第一条
            return WmsApiResponse.success("请根据界面信息进行拣配。", new WorkConfirmVo(
                    new OrderConfirmEntity(
                            thisStandWork.getWorkIndex(),
                            thisStandWork.getWorkOrder(),
                            thisStandWork.getProductId(),
                            thisStandWork.getSingleProductId(),
                            thisStandWork.getGoodsId(),
                            thisStandWork.getBoxNo(),
                            thisStandWork.getPlanPickQty(),
                            thisStandWork.getRealPickQty()),
                    new StockConfirmEntity(
                            thisStandWork.getStockId(),
                            thisStandWork.getVehicleId(),
                            thisStandWork.getGoodsId(),
                            thisStandWork.getPlanRemainQty(),
                            thisStandWork.getRealRemainQty(),
                            thisStandWork.getIsOut(),
                            thisStandWork.getPutArea(),
                            stockDataService.getWarningQty())
            ));
        }
        // 查询当前站台上的已到达的拣选任务
        List<TAppPickTask> pickTaskList = appPickTaskService.list(new LambdaQueryWrapper<TAppPickTask>()
                .eq(TAppPickTask::getPickStand, kateWorksQuery.getStandId())
                .eq(TAppPickTask::getPickStatus, WmsPickTaskStatusEnum.ARRIVE.getCode()));
        if (pickTaskList == null || pickTaskList.isEmpty()) {
            // 这里需要增加库外料拣配工作的生成。
            WorkConfirmVo resultVo = getOutGoodsStandWork(kateWorksQuery.getStandId(), thisStandWork);
            if (resultVo != null) {
                setStandWork(resultVo, thisStandWork);
                // 保存pickWork
                try {
                    appStandWorkService.updateById(thisStandWork);
                    return WmsApiResponse.success("请根据界面信息进行拣配。", resultVo);
                } catch (Exception e) {
                    // 回滚事务
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return WmsApiResponse.error("更新站台拣配信息异常，请检查原因。", null);
                }
            }
            OrderConfirmEntity boxRelatedVo = new OrderConfirmEntity();
            boxRelatedVo.setWorkOrder(thisStandWork.getWorkOrder());
            boxRelatedVo.setBoxNo(thisStandWork.getBoxNo());
            boxRelatedVo.setProductId(thisStandWork.getProductId());
            boxRelatedVo.setSingleProductId(thisStandWork.getSingleProductId());
            resultVo = new WorkConfirmVo(boxRelatedVo, null);
            return WmsApiResponse.error("当前站台没有箱子到达, 请检查。", resultVo);
        }
        if (pickTaskList.size() > 1) {
            return WmsApiResponse.error("当前站台有多个箱子到达，请检查。", null);
        }
        // 当前站台到达的拣选任务
        TAppPickTask thisPickTask = pickTaskList.getFirst();
        WorkConfirmVo resultVo = conveyTaskService.getCurrentStandWork(thisPickTask);
        if (resultVo != null) {
            setStandWork(resultVo, thisStandWork);
            // 保存pickWork
            try {
                appStandWorkService.updateById(thisStandWork);
                return WmsApiResponse.success("请根据界面信息进行拣配。", resultVo);
            } catch (Exception e) {
                // 回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return WmsApiResponse.error("更新站台拣配信息异常，请检查原因。", null);
            }
        }
        return WmsApiResponse.instanceOf(WmsApiResponseCodeEnums.WARNING.getCode(), "该载具没有拣选工作，请直接确认放行。", null);
    }

    /**
     * 实现
     *
     * @param confirmWorkRequest 确认请求
     * @return 确认结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse confirmCurrentWork(ConfirmWorkRequest confirmWorkRequest) {
        if (confirmWorkRequest == null || StringUtils.isEmpty(confirmWorkRequest.getStandId())) {
            return BaseWmsApiResponse.error("请求缺少信息，请输入站台号。");
        }
        // 查询这个站台的拣选工作
        List<TAppStandWork> standWorkList = appStandWorkService.list(new LambdaQueryWrapper<TAppStandWork>()
                .eq(TAppStandWork::getStandId, confirmWorkRequest.getStandId()));
        if (standWorkList != null && !standWorkList.isEmpty()) {
            TAppStandWork thisStandWork = standWorkList.getFirst();
            if (StringUtils.isNotEmpty(thisStandWork.getGoodsId()) && thisStandWork.getIsOut() == 1) {
                if (confirmWorkRequest.getOrderConfirm() != null && Objects.equals(confirmWorkRequest.getOrderConfirm().getGoodsId(), thisStandWork.getGoodsId())) {
                    // 更新工作信息
                    updateWorkInfo(confirmWorkRequest);
                    return BaseWmsApiResponse.success("确认库外料拣配成功。");
                }
            }
        }
        // 查询当前站台上的已到达的拣选任务
        List<TAppPickTask> pickTaskList = appPickTaskService.list(new LambdaQueryWrapper<TAppPickTask>()
                .eq(TAppPickTask::getPickStand, confirmWorkRequest.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 (confirmWorkRequest.getOrderConfirm() != null && StringUtils.isNotEmpty(confirmWorkRequest.getOrderConfirm().getWorkIndex())) {
            // 更新工作信息
            String updateWorkResult = updateWorkInfo(confirmWorkRequest);
            if (StringUtils.isNotEmpty(updateWorkResult)) {
                return BaseWmsApiResponse.error("更新工作信息失败：" + updateWorkResult + "，请重试。");
            }
        }
        // 更新库存信息
        stockDataService.updateStockInfo(confirmWorkRequest.getStockConfirm(), confirmWorkRequest.getStandId(), confirmWorkRequest.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()) {
            WorkConfirmVo resultVo = conveyTaskService.getCurrentStandWork(thisPickTask);
            if (resultVo != null) {
                return BaseWmsApiResponse.warn("当前载具还有工作，请根据界面信息进行拣配。");
            }
            // 判断还有没有当前站台的其他拣选任务
            TaskConfirmVo taskConfirmVo = conveyTaskService.getCurrentStandTask(thisPickTask);
            if (taskConfirmVo != 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 request 请求参数
     * @return 图纸
     */
    @Override
    public WmsApiResponse<ImageVo> getImageOfWork(BaseWmsRequest request) {
        if (request == null || StringUtils.isEmpty(request.getStandId())) {
            return WmsApiResponse.error("请求缺少信息，请输入站台号。", null);
        }
        // 查询是否已经有正在拣选的
        List<TAppStandWork> standWorkList = appStandWorkService.list(new LambdaQueryWrapper<TAppStandWork>()
                .eq(TAppStandWork::getStandId, request.getStandId()));
        if (standWorkList == null || standWorkList.isEmpty()) {
            return WmsApiResponse.error("当前站台没有正在拣选的工作。", null);
        }
        TAppStandWork nowWork = standWorkList.getFirst();
        String productId = nowWork.getProductId();// 总成
        if (StringUtils.isNotEmpty(nowWork.getSingleProductId())) {
            productId = nowWork.getSingleProductId();// 单片
        }
        // 查询对应的图纸
        List<TAppImage> imageList = appImageService.list(new LambdaQueryWrapper<TAppImage>()
                .eq(TAppImage::getProductId, productId)
                .eq(TAppImage::getBoxNo, nowWork.getBoxNo()));
        if (imageList == null || imageList.isEmpty()) {
            return WmsApiResponse.error("成品号：" + productId + "，料盒号：" + nowWork.getBoxNo() + "，没有图纸。", null);
        }
        // 查询到存放图片的ip
        String imageIp = getImageIp();
        ImageVo imageVo = new ImageVo(
                imageList.getFirst().getImageId(),
                imageList.getFirst().getProductId(),
                imageList.getFirst().getBoxNo(),
                imageIp,
                imageList.getFirst().getImagePath(),
                imageList.getFirst().getImageName(),
                FileUtils.getImageDetail(imageList.getFirst().getImagePath(), imageList.getFirst().getImageName()),
                imageList.getFirst().getImageType()
        );
        return WmsApiResponse.success("获取图纸成功。", imageVo);
    }

    /**
     * 配料界面获取料盒信息
     *
     * @param request 请求
     * @return 显示信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WmsApiResponse<BoxDetailVo> getBoxesAndLacks(BaseWmsRequest request) {
        if (StringUtils.isEmpty(request.getStandId())) {
            // 站台号不能为空
            return WmsApiResponse.error("请求缺少信息，请输入站台号。", null);
        }
        // 查询当前站台的拣货工作
        List<TAppStandWork> standWorkList = appStandWorkService.list(new LambdaQueryWrapper<TAppStandWork>()
                .eq(TAppStandWork::getStandId, request.getStandId()));
        if (standWorkList == null || standWorkList.isEmpty()) {
            return WmsApiResponse.error("当前站台工作已全部完成。", null);
        }
        TAppStandWork thisStandWork = standWorkList.getFirst();
        // 查询对应的dbs
        List<TAppDbs> dbsList = appDbsService.list(new LambdaQueryWrapper<TAppDbs>()
                .eq(TAppDbs::getWorkOrder, thisStandWork.getWorkOrder()));
        if (dbsList == null || dbsList.isEmpty()) {
            return WmsApiResponse.error("DBS数据异常：不存在工单" + thisStandWork.getWorkOrder() + "。", null);
        }
        TAppDbs thisDbs = dbsList.getFirst();
        // 计划产量
        int planProduction = thisDbs.getPlanProduction();
        // 结果集
        BoxSummary boxSummary = new BoxSummary();
        boxSummary.setWorkOrder(thisStandWork.getWorkOrder());
        boxSummary.setTaoQty(planProduction);
        boxSummary.setProductId(thisStandWork.getProductId());
        boxSummary.setSingleProductId(StringUtils.isEmpty(thisStandWork.getSingleProductId()) ? thisStandWork.getProductId() : thisStandWork.getSingleProductId());
        boxSummary.setBoxNo(thisStandWork.getBoxNo());
        // 设置打印标签相关的信息
        boxSummary.setProductIdOrigin(thisDbs.getProductIdOrigin());
        boxSummary.setKittingDate(thisDbs.getTestPlanStartDate());
        boxSummary.setProduceDate(thisDbs.getPntPlanStartDate());
        boxSummary.setTestNo(thisDbs.getTestNo());
        boxSummary.setProductionQty(planProduction);
        List<GoodsLackSummary> goodsLackSummary = new ArrayList<>();
        // 查询所有库存
        List<TAppStock> stockList = appStockService.list(new LambdaQueryWrapper<TAppStock>().gt(TAppStock::getRemainNum, 0));
        // 生成物料数量map
        Map<String, Integer> goodsMap = new HashMap<>();
        for (TAppStock stock : stockList) {
            if (goodsMap.containsKey(stock.getGoodsId())) {
                goodsMap.replace(stock.getGoodsId(), goodsMap.get(stock.getGoodsId()) + stock.getRemainNum());
            } else {
                goodsMap.put(stock.getGoodsId(), stock.getRemainNum());
            }
        }
        // 查询所有的库外物料信息
        List<TAppGoods> outGoodsList = appGoodsService.list(new LambdaQueryWrapper<TAppGoods>()
                .notLike(TAppGoods::getPutArea, "ASRS"));
        List<String> outGoodsIds = outGoodsList.stream().map(TAppGoods::getGoodsId).distinct().toList();
        // 找到站台工作下对应的工作详情
        List<TAppWork> workList = appWorkService.list(new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkOrder, thisStandWork.getWorkOrder())
                .eq(TAppWork::getProductId, thisStandWork.getProductId())
                .eq(StringUtils.isNotEmpty(thisStandWork.getSingleProductId()), TAppWork::getSingleProductId, thisStandWork.getSingleProductId())
                .eq(TAppWork::getBoxNo, thisStandWork.getBoxNo()));
        if (workList.isEmpty()) {
            return WmsApiResponse.error("未查询到相关工作信息，请转至站台工作界面、工作详情界面检查。", null);
        }
        // 添加缺料信息
        for (TAppWork work : workList) {
            GoodsLackSummary tempGoodsLack = new GoodsLackSummary();
            tempGoodsLack.setGoodsId(work.getGoodsId());
            tempGoodsLack.setFinishNum(work.getFinishNum());
            int remainNeedNum = work.getNeedNum() - work.getDistributeNum();
            tempGoodsLack.setNeedNum(work.getNeedNum());
            if (outGoodsIds.contains(work.getGoodsId())) {
                tempGoodsLack.setLackNum(0);
                tempGoodsLack.setStockNum(0);
                tempGoodsLack.setRemark("库外料");
            } else {
                if (!goodsMap.containsKey(work.getGoodsId())) {
                    tempGoodsLack.setLackNum(remainNeedNum);
                    tempGoodsLack.setStockNum(0);
                    tempGoodsLack.setRemark("缺料");
                } else if (goodsMap.get(work.getGoodsId()) >= remainNeedNum) {
                    tempGoodsLack.setLackNum(0);
                    tempGoodsLack.setStockNum(goodsMap.get(work.getGoodsId()));
                    tempGoodsLack.setRemark("不缺料");
                    // 更新剩余数量
                    goodsMap.replace(work.getGoodsId(), goodsMap.get(work.getGoodsId()) - remainNeedNum);
                } else {
                    tempGoodsLack.setLackNum(remainNeedNum - goodsMap.get(work.getGoodsId()));
                    tempGoodsLack.setStockNum(goodsMap.get(work.getGoodsId()));
                    tempGoodsLack.setRemark("缺料");
                    // 分配完缺料，删除该物料
                    goodsMap.remove(work.getGoodsId());
                }
            }
            // 添加物料信息
            goodsLackSummary.add(tempGoodsLack);
        }
        // 成品类型
        int productType = workList.getFirst().getProductType();
        // 查询配料单的成品号
        String queryProductId = thisStandWork.getProductId();
        if (StringUtils.isNotEmpty(thisStandWork.getSingleProductId())) {
            queryProductId = thisStandWork.getSingleProductId();
        }
        // 查询到对应的图纸信息
        List<TAppImage> imageList = appImageService.list(new LambdaQueryWrapper<TAppImage>()
                .eq(TAppImage::getProductId, queryProductId)
                .eq(TAppImage::getBoxNo, thisStandWork.getBoxNo()));
        if (imageList != null && !imageList.isEmpty()) {
            boxSummary.setImageId(imageList.getFirst().getImageId());
        }
        if (productType == 1) {
            // 非服务件---查询非服务件清单
            List<TAppProduct> productList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                    .eq(TAppProduct::getProductId, queryProductId)
                    .eq(TAppProduct::getBoxNo, thisStandWork.getBoxNo()));
            if (productList == null || productList.isEmpty()) {
                return WmsApiResponse.error("数据异常：不存在成品号" + queryProductId + "，料盒号：" + thisStandWork.getBoxNo() + "。", null);
            }
            // 最大料盒数量
            int maxBoxQty = 0;
            for (TAppProduct product : productList) {
                // 设置料盒数量
                int tempBoxQty = Math.ceilDiv(planProduction, product.getQuantityOfPair());
                if (tempBoxQty > maxBoxQty) {
                    maxBoxQty = tempBoxQty;
                }
            }
            // 设置料盒数量
            boxSummary.setBoxQty(maxBoxQty);
        } else {
            // 配料的是服务件
            List<TAppSingleProduct> singleProductList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                    .eq(TAppSingleProduct::getProductId, queryProductId)
                    .eq(TAppSingleProduct::getBoxNo, thisStandWork.getBoxNo()));
            if (singleProductList == null || singleProductList.isEmpty()) {
                return WmsApiResponse.error("服务件数据异常：不存在服务件成品号" + queryProductId + "，料盒号：" + thisStandWork.getBoxNo() + "。", null);
            }
            // 最大料盒数量
            int maxBoxQty = 0;
            for (TAppSingleProduct singleProduct : singleProductList) {
                // 设置料盒数量
                int tempBoxQty = Math.ceilDiv(planProduction, singleProduct.getQuantityOfPair());
                if (tempBoxQty > maxBoxQty) {
                    maxBoxQty = tempBoxQty;
                }
            }
            // 设置料盒数量
            boxSummary.setBoxQty(maxBoxQty);
        }
        return WmsApiResponse.success("获取料盒信息成功。", new BoxDetailVo(boxSummary, goodsLackSummary));
    }

    /**
     * 查询看板（分页）实现
     *
     * @param kanbanQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<PageVo<KanbanVo>> queryKanbanByPage(KanbanQuery kanbanQuery) {
        Page<TAppKanban> page = kanbanQuery.toMpPage();
        LambdaQueryWrapper<TAppKanban> lambdaQueryWrapper = new LambdaQueryWrapper<TAppKanban>()
                .like(StringUtils.isNotEmpty(kanbanQuery.getGoodsId()), TAppKanban::getGoodsId, kanbanQuery.getGoodsId())
                .like(StringUtils.isNotEmpty(kanbanQuery.getKanbanId()), TAppKanban::getKanbanId, kanbanQuery.getKanbanId())
                .eq(kanbanQuery.getKanbanStatus() != null, TAppKanban::getKanbanStatus, kanbanQuery.getKanbanStatus());
        Page<TAppKanban> kanbanPage = appKanbanService.page(page, lambdaQueryWrapper);

        PageVo<KanbanVo> pageVo = PageVo.of(kanbanPage, KanbanVo::ofPo);
        return WmsApiResponse.success("查询看板数据成功", pageVo);
    }

    /**
     * 生成需求看板
     * @param genRequest 请求参数
     * @return 生成结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse genClcKanbanRequirement(GenKanbanRequirementRequest genRequest) {
        if (genRequest.getPlanStartDateFrom() == null || genRequest.getPlanStartDateTo() == null) {
            return BaseWmsApiResponse.error("请选择开始时间和结束时间。");
        }
        if (genRequest.getPlanStartDateFrom().isAfter(genRequest.getPlanStartDateTo())) {
            return BaseWmsApiResponse.error("开始时间不能大于结束时间。");
        }
        // 查找这个时间段内的所有dbs计划---未开始的
        List<TAppDbs> dbsList = appDbsService.list(new LambdaQueryWrapper<TAppDbs>()
                .between(TAppDbs::getTestPlanStartDate, genRequest.getPlanStartDateFrom(), genRequest.getPlanStartDateTo())
                .lt(TAppDbs::getDbsStatus, 2));
        // 总的物料需求
        Map<String, Integer> totalGoodsRequireMap = new HashMap<>();
        // 物料数量需求---根据总成号区分
        Map<String, Map<String, Integer>> goodsRequireByProductMap = new HashMap<>();
        // 迭代计划表，获取
        for (TAppDbs dbs : dbsList) {
            Map<String, Integer> goodsRequireOfDbsMap = new HashMap<>();// 当前dbs的物料需求
            Map<String, Integer> goodsRequireOfProductMap;// 当前成品的物料需求
            // 获得物料需求
            if (dbs.getDbsStatus() == 0) {
                if (goodsRequireByProductMap.containsKey(dbs.getProductIdOrigin())) {
                    // 包含原始成品号
                    goodsRequireOfProductMap = goodsRequireByProductMap.get(dbs.getProductIdOrigin());
                } else {
                    goodsRequireOfProductMap = getGoodsRequireMapOfServiceProduct(dbs.getProductIdOrigin());
                    if (!goodsRequireOfProductMap.isEmpty()) {
                        // 存在服务件配料单，添加这个总成的Map
                        goodsRequireByProductMap.put(dbs.getProductIdOrigin(), goodsRequireOfProductMap);
                    } else {
                        if (goodsRequireByProductMap.containsKey(dbs.getProductId())) {
                            // 直接获得当前总成的物料需求
                            goodsRequireOfProductMap = goodsRequireByProductMap.get(dbs.getProductId());
                        } else {
                            // 去查询非服务件配料单
                            goodsRequireOfProductMap = getGoodsRequireMapOfNonServiceProduct(dbs.getProductId());
                            if (goodsRequireOfProductMap.isEmpty()) {
                                return BaseWmsApiResponse.error("工单" + dbs.getWorkOrder() + "的物料需求为空，请检查数据。");
                            }
                            // 添加这个非服务件配件清单的map
                            goodsRequireByProductMap.put(dbs.getProductId(), goodsRequireOfProductMap);
                        }
                    }
                }
                // 需求*产量
                for (String goodsId : goodsRequireOfProductMap.keySet()) {
                    goodsRequireOfDbsMap.put(goodsId, goodsRequireOfProductMap.get(goodsId) * dbs.getPlanProduction());
                }
            } else {
                // 查询已经生成的工作清单里面的物料需求
                goodsRequireOfDbsMap = getRemainRequireMapOfOrder(dbs.getWorkOrder());
            }
            // 合并需求
            mergeRequire(totalGoodsRequireMap, goodsRequireOfDbsMap);
        }
        // 获取需要的物料的基本信息
        List<String> goodsIds = new ArrayList<>(totalGoodsRequireMap.keySet());
        if (goodsIds.isEmpty()) {
            // 没有需求，将所有的看板需求置满
            appKanbanService.update(new LambdaUpdateWrapper<TAppKanban>()
                    .set(TAppKanban::getKanbanStatus, 1)
                    .set(TAppKanban::getLastUpdateTime, LocalDateTime.now())
                    .set(TAppKanban::getLastUpdateUser, genRequest.getUserName()));
            return BaseWmsApiResponse.error("所选时间段内没有工作需求。");
        }
        // 所有的非库外料且看板维护的料
        List<TAppGoods> goodsList = appGoodsService.list(new LambdaQueryWrapper<TAppGoods>()
                .in(TAppGoods::getGoodsId, goodsIds)
                .like(TAppGoods::getPutArea, "ASRS")
                .like(TAppGoods::getFeedingType, "Kanban"));
        // 整合物料信息为map
        Map<String, TAppGoods> filterGoodsMap = goodsList.stream().collect(Collectors.toMap(TAppGoods::getGoodsId, goods -> goods));
        // 获取筛选过的需要的物料的库存信息
        List<TAppStock> stockList = appStockService.list(new LambdaQueryWrapper<TAppStock>()
                .in(TAppStock::getGoodsId, filterGoodsMap.keySet())
                .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());
            }
        }
        // 生成看板需求
        List<TAppKanban> kanbanList = appKanbanService.list(new LambdaQueryWrapper<TAppKanban>()
                .in(TAppKanban::getGoodsId, filterGoodsMap.keySet()));
        // 更新后的看板需求
        List<TAppKanban> updateKanbanList = new ArrayList<>();
        for (String goodsId : filterGoodsMap.keySet()) {
            TAppGoods thisGoods = filterGoodsMap.get(goodsId);
            // 需求数量
            int needNum = totalGoodsRequireMap.get(goodsId);
            // 库存数量
            int stockNum = stockByGoodsMap.getOrDefault(goodsId, 0);
            if (needNum > 0 && needNum > stockNum) {
                // 剩余可补物料数量
                int remainKanbanGoodsNum = needNum - stockNum;
                // 剩余可补看板个数
                int remainKanbanQty = Math.ceilDiv(remainKanbanGoodsNum, thisGoods.getBoxQty());
                // 可以补看板
                List<TAppKanban> thisGoodsKanbanList = kanbanList.stream()
                        .filter(kanban -> kanban.getGoodsId().equals(goodsId)).toList();
                for (TAppKanban kanban : thisGoodsKanbanList) {
                    if (remainKanbanQty == 0) {
                        break;
                    }
                    kanban.setKanbanStatus(0);
                    kanban.setLastUpdateTime(LocalDateTime.now());
                    kanban.setLastUpdateUser(genRequest.getUserName());
                    updateKanbanList.add(kanban);
                    // 可用看板个数-1
                    remainKanbanQty--;
                }
            }
        }
        // 先置满所有看板需求
        appKanbanService.update(new LambdaUpdateWrapper<TAppKanban>()
                .set(TAppKanban::getKanbanStatus, 1)
                .set(TAppKanban::getLastUpdateTime, LocalDateTime.now())
                .set(TAppKanban::getLastUpdateUser, genRequest.getUserName()));
        // 更新看板需求
        appKanbanService.updateBatchById(updateKanbanList);
        return BaseWmsApiResponse.success("生成看板需求成功。");
    }

    /**
     * 查询图纸---实现
     *
     * @param imageQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<List<ImageVo>> requestImageDetail(ImageQuery imageQuery) {
        if (imageQuery == null) {
            return WmsApiResponse.error("查询参数为空。", null);
        }
        // 查询图纸
        List<TAppImage> imageList = appImageService.list(new LambdaQueryWrapper<TAppImage>()
                .eq(StringUtils.isNotEmpty(imageQuery.getImageId()), TAppImage::getImageId, imageQuery.getImageId())
                .eq(StringUtils.isNotEmpty(imageQuery.getProductId()), TAppImage::getProductId, imageQuery.getProductId())
                .eq(StringUtils.isNotEmpty(imageQuery.getBoxNo()), TAppImage::getBoxNo, imageQuery.getBoxNo())
                .eq(imageQuery.getImageType() != null, TAppImage::getImageType, imageQuery.getImageType()));
        List<ImageVo> imageVoList = new ArrayList<>();
        // 查询到存放图片的ip
        String imageIp = getImageIp();
        for (TAppImage image : imageList) {
            ImageVo imageVo = new ImageVo(
                    image.getImageId(),
                    image.getProductId(),
                    image.getBoxNo(),
                    imageIp,
                    image.getImagePath(),
                    image.getImageName(),
                    FileUtils.getImageDetail(image.getImagePath(), image.getImageName()),
                    image.getImageType());
            imageVoList.add(imageVo);
        }

        return WmsApiResponse.success("查询图纸成功。", imageVoList);
    }

    /**
     * 查询DBS（分页）---实现
     *
     * @param dbsQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<PageVo<DbsVo>> queryDbsByPage(DbsQuery dbsQuery) {
        Page<TAppDbs> page = dbsQuery.toMpPage();
        LambdaQueryWrapper<TAppDbs> lambdaQueryWrapper = new LambdaQueryWrapper<TAppDbs>()
                .like(StringUtils.isNotEmpty(dbsQuery.getWorkOrder()), TAppDbs::getWorkOrder, dbsQuery.getWorkOrder())
                .like(StringUtils.isNotEmpty(dbsQuery.getProductId()), TAppDbs::getProductId, dbsQuery.getProductId())
                .eq(dbsQuery.getDbsStatus() != null, TAppDbs::getDbsStatus, dbsQuery.getDbsStatus())
                .eq(dbsQuery.getPlanStartDate() != null, TAppDbs::getTestPlanStartDate, dbsQuery.getPlanStartDate());
        Page<TAppDbs> pagePo = appDbsService.page(page, lambdaQueryWrapper);

        PageVo<DbsVo> pageVo = PageVo.of(pagePo, DbsVo::ofPo);
        return WmsApiResponse.success("查询DBS数据成功", pageVo);
    }

    /**
     * 查询配料单列表（分页）---实现
     *
     * @param kittingBomQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<PageVo<KittingBomVo>> queryKittingBomByPage(KittingBomQuery kittingBomQuery) {
        if (kittingBomQuery == null || kittingBomQuery.getBomType() == null) {
            return WmsApiResponse.error("查询参数为空，配料单类型必须。", null);
        }
        if (kittingBomQuery.getBomType() == 1) {
            // 非服务件配料单
            Page<TAppProduct> page = kittingBomQuery.toMpPage();
            LambdaQueryWrapper<TAppProduct> lambdaQueryWrapper = new LambdaQueryWrapper<TAppProduct>()
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getModel()), TAppProduct::getModel, kittingBomQuery.getModel())
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getProductId()), TAppProduct::getProductId, kittingBomQuery.getProductId())
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getGoodsId()), TAppProduct::getGoodsId, kittingBomQuery.getGoodsId())
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getBoxNo()), TAppProduct::getBoxNo, kittingBomQuery.getBoxNo());
            Page<TAppProduct> pagePo = appProductService.page(page, lambdaQueryWrapper);

            PageVo<KittingBomVo> pageVo = PageVo.of(pagePo, KittingBomVo::ofProduct);
            return WmsApiResponse.success("查询非服务件配料单成功。", pageVo);
        } else {
            // 服务件配料单
            Page<TAppSingleProduct> page = kittingBomQuery.toMpPage();
            LambdaQueryWrapper<TAppSingleProduct> lambdaQueryWrapper = new LambdaQueryWrapper<TAppSingleProduct>()
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getModel()), TAppSingleProduct::getModel, kittingBomQuery.getModel())
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getProductId()), TAppSingleProduct::getProductId, kittingBomQuery.getProductId())
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getGoodsId()), TAppSingleProduct::getGoodsId, kittingBomQuery.getGoodsId())
                    .like(StringUtils.isNotEmpty(kittingBomQuery.getBoxNo()), TAppSingleProduct::getBoxNo, kittingBomQuery.getBoxNo());
            Page<TAppSingleProduct> pagePo = appSingleProductService.page(page, lambdaQueryWrapper);

            PageVo<KittingBomVo> pageVo = PageVo.of(pagePo, KittingBomVo::ofSingleProduct);
            return WmsApiResponse.success("查询服务件配料单成功。", pageVo);
        }
    }

    /**
     * 查询图纸列表（分页）---实现
     * @param imageQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<PageVo<ImageVo>> queryImagesByPage(ImageQuery imageQuery) {
        Page<TAppImage> page = imageQuery.toMpPage();
        LambdaQueryWrapper<TAppImage> lambdaQueryWrapper = new LambdaQueryWrapper<TAppImage>()
                .like(StringUtils.isNotEmpty(imageQuery.getImageId()), TAppImage::getImageId, imageQuery.getImageId())
                .like(StringUtils.isNotEmpty(imageQuery.getProductId()), TAppImage::getProductId, imageQuery.getProductId())
                .like(StringUtils.isNotEmpty(imageQuery.getBoxNo()), TAppImage::getBoxNo, imageQuery.getBoxNo())
                .eq(imageQuery.getImageType() != null, TAppImage::getImageType, imageQuery.getImageType());
        Page<TAppImage> pagePo = appImageService.page(page, lambdaQueryWrapper);

        PageVo<ImageVo> pageVo = PageVo.of(pagePo, ImageVo::ofPo);
        return WmsApiResponse.success("查询图纸数据成功", pageVo);
    }

    /**
     * 配料单对应关系实现---分页
     *
     * @param kittingBomRelationQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<PageVo<KittingBomRelationVo>> queryKittingRelationByPage(KittingBomRelationQuery kittingBomRelationQuery) {
        Page<TAppProductExtend> page = kittingBomRelationQuery.toMpPage();
        LambdaQueryWrapper<TAppProductExtend> lambdaQueryWrapper = new LambdaQueryWrapper<TAppProductExtend>()
                .like(StringUtils.isNotEmpty(kittingBomRelationQuery.getModel()), TAppProductExtend::getModel, kittingBomRelationQuery.getModel())
                .like(StringUtils.isNotEmpty(kittingBomRelationQuery.getProductId()), TAppProductExtend::getProductId, kittingBomRelationQuery.getProductId())
                .like(StringUtils.isNotEmpty(kittingBomRelationQuery.getSingleProductId()), TAppProductExtend::getSingleProductId, kittingBomRelationQuery.getSingleProductId());
        Page<TAppProductExtend> pagePo = appProductExtendService.page(page, lambdaQueryWrapper);

        PageVo<KittingBomRelationVo> pageVo = PageVo.of(pagePo, KittingBomRelationVo::ofPo);
        return WmsApiResponse.success("查询配对关系成功", pageVo);
    }

    /**
     * 查询工单汇总（分页）---实现
     *
     * @param workSummaryQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<PageVo<KateWorkVo>> queryWorkSummaryByPage(WorkSummaryQuery workSummaryQuery) {
        if (workSummaryQuery == null || workSummaryQuery.getSummaryType() == null) {
            return WmsApiResponse.error("查询参数为空，数据类型必须。", null);
        }
        if (workSummaryQuery.getSummaryType() == 1) {
            // 未关闭订单
            Page<TAppWork> page = workSummaryQuery.toMpPage();
            LambdaQueryWrapper<TAppWork> lambdaQueryWrapper = new LambdaQueryWrapper<TAppWork>()
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getWorkOrder()), TAppWork::getWorkOrder, workSummaryQuery.getWorkOrder())
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getProductId()), TAppWork::getProductId, workSummaryQuery.getProductId())
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getSingleProductId()), TAppWork::getSingleProductId, workSummaryQuery.getSingleProductId())
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getBoxNo()), TAppWork::getBoxNo, workSummaryQuery.getBoxNo())
                    .eq(workSummaryQuery.getWorkStatus() != null, TAppWork::getWorkStatus, workSummaryQuery.getWorkStatus())
                    .eq(workSummaryQuery.getLackStatus() != null, TAppWork::getLackStatus, workSummaryQuery.getLackStatus());
            Page<TAppWork> pagePo = appWorkService.page(page, lambdaQueryWrapper);

            PageVo<KateWorkVo> pageVo = PageVo.of(pagePo, KateWorkVo::ofWork);
            return WmsApiResponse.success("查询工作数据成功。", pageVo);
        } else {
            // 已关闭订单
            Page<TAppWorkRecord> page = workSummaryQuery.toMpPage();
            LambdaQueryWrapper<TAppWorkRecord> lambdaQueryWrapper = new LambdaQueryWrapper<TAppWorkRecord>()
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getWorkOrder()), TAppWorkRecord::getWorkOrder, workSummaryQuery.getWorkOrder())
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getProductId()), TAppWorkRecord::getProductId, workSummaryQuery.getProductId())
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getSingleProductId()), TAppWorkRecord::getSingleProductId, workSummaryQuery.getSingleProductId())
                    .like(StringUtils.isNotEmpty(workSummaryQuery.getBoxNo()), TAppWorkRecord::getBoxNo, workSummaryQuery.getBoxNo())
                    .eq(workSummaryQuery.getWorkStatus() != null, TAppWorkRecord::getWorkStatus, workSummaryQuery.getWorkStatus())
                    .eq(workSummaryQuery.getLackStatus() != null, TAppWorkRecord::getLackStatus, workSummaryQuery.getLackStatus());
            Page<TAppWorkRecord> pagePo = appWorkRecordService.page(page, lambdaQueryWrapper);

            PageVo<KateWorkVo> pageVo = PageVo.of(pagePo, KateWorkVo::ofWorkRecord);
            return WmsApiResponse.success("查询工作数据成功。", pageVo);
        }
    }

    /**
     * 查询当前站台待工作的物料列表 实现
     *
     * @param workSummaryQuery 查询参数
     * @return 查询结果---分页
     */
    @Override
    public WmsApiResponse<PageVo<KateWorkVo>> queryWorkingGoodsByPage(WorkSummaryQuery workSummaryQuery) {
        if (workSummaryQuery == null || workSummaryQuery.getStandId() == null) {
            return WmsApiResponse.error("请求缺少站台号。", null);
        }
        // 查询这个站台的当前工作信息
        List<TAppStandWork> currentStandWorks = appStandWorkService.list(new LambdaQueryWrapper<TAppStandWork>()
                .eq(TAppStandWork::getStandId, workSummaryQuery.getStandId()));
        if (currentStandWorks == null || currentStandWorks.isEmpty()) {
            return WmsApiResponse.error("当前站台没有配料工作。", null);
        }
        TAppStandWork currentStandWork = currentStandWorks.getFirst();
        // 未关闭订单
        Page<TAppWork> page = workSummaryQuery.toMpPage();
        LambdaQueryWrapper<TAppWork> lambdaQueryWrapper = new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkOrder, currentStandWork.getWorkOrder())
                .eq(TAppWork::getProductId, currentStandWork.getProductId())
                .eq(StringUtils.isNotEmpty(currentStandWork.getSingleProductId()), TAppWork::getSingleProductId, currentStandWork.getSingleProductId())
                .eq(TAppWork::getBoxNo, currentStandWork.getBoxNo())
                .notIn(TAppWork::getWorkStatus, -1, 2);
        Page<TAppWork> pagePo = appWorkService.page(page, lambdaQueryWrapper);

        PageVo<KateWorkVo> pageVo = PageVo.of(pagePo, KateWorkVo::ofWork);
        return WmsApiResponse.success("查询当前站台待配物料列表成功。", pageVo);
    }

    /**
     * 查询缺料列表
     *
     * @param kateWorksQuery 查询参数
     * @return 查询结果
     */
    @Override
    public WmsApiResponse<List<KateWorkVo>> getLackGoods(KateWorksQuery kateWorksQuery) {
        if (kateWorksQuery == null) {
            return WmsApiResponse.error("查询参数为空。", null);
        }
        LambdaQueryWrapper<TAppWork> lambdaQueryWrapper = new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkOrder, kateWorksQuery.getWorkOrder())
                .eq(StringUtils.isNotEmpty(kateWorksQuery.getProductId()), TAppWork::getProductId, kateWorksQuery.getProductId())
                .eq(StringUtils.isNotEmpty(kateWorksQuery.getSingleProductId()), TAppWork::getSingleProductId, kateWorksQuery.getSingleProductId())
                .eq(TAppWork::getBoxNo, kateWorksQuery.getBoxNo())
                .eq(TAppWork::getLackStatus, 1);
        List<TAppWork> poList = appWorkService.list(lambdaQueryWrapper);
        if (poList == null || poList.isEmpty()) {
            return WmsApiResponse.error("没有找到缺料信息。", null);
        }
        List<KateWorkVo> resultList = poList.stream().map(KateWorkVo::ofWork).toList();
        return WmsApiResponse.success("查询缺料信息成功。", resultList);
    }

    /**
     * 更新工作信息---实现
     *
     * @param updateWorkRequest 更新请求
     * @return 处理结果
     */
    @Override
    public BaseWmsApiResponse updateKateWorks(UpdateWorkRequest updateWorkRequest) {
        if (updateWorkRequest == null || StringUtils.isEmpty(updateWorkRequest.getWorkIndex())) {
            return BaseWmsApiResponse.error("请求参数不完整，缺少主键。");
        }
        // 查询当前这一条的工作详情
        TAppWork thisWork = appWorkService.getOne(new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkIndex, updateWorkRequest.getWorkIndex()));
        if (thisWork == null) {
            return BaseWmsApiResponse.error("请求的工作不存在。");
        }
        // 更新数据
        if (updateWorkRequest.getDistributeNum() != null && updateWorkRequest.getDistributeNum() >= 0 && updateWorkRequest.getDistributeNum() <= thisWork.getNeedNum()) {
            // 已分配数量必须介于0和需求数量之间
            thisWork.setDistributeNum(updateWorkRequest.getDistributeNum());
        }
        if (updateWorkRequest.getFinishNum() != null && updateWorkRequest.getFinishNum() >= 0 && updateWorkRequest.getFinishNum() <= thisWork.getNeedNum()) {
            // 已完成数量必须介于0和需求数量之间
            thisWork.setFinishNum(updateWorkRequest.getFinishNum());
        }
        if (updateWorkRequest.getWorkStatus() != null) {
            if (!updateWorkRequest.getWorkStatus().equals(thisWork.getWorkStatus()) && updateWorkRequest.getWorkStatus() == 2) {
                // 更新成完成状态需要同步更新完成时间与完成用户。
                thisWork.setWorkUser(updateWorkRequest.getUserName());
                thisWork.setFinishTime(LocalDateTime.now());
            }
            thisWork.setWorkStatus(updateWorkRequest.getWorkStatus());
        }
        if (updateWorkRequest.getLackStatus() != null && thisWork.getFinishNum() >= thisWork.getNeedNum()) {
            // 只有已完成数量满足了需求数量时，才能更新缺料状态
            thisWork.setLackStatus(updateWorkRequest.getLackStatus());
        }
        // 更新数据
        appWorkService.updateById(thisWork);
        return BaseWmsApiResponse.success("更新工作信息成功。");
    }

    /**
     * 关闭当前工作
     *
     * @param closeWorkRequest 关闭请求
     * @return 处理结果
     */
    @Override
    public BaseWmsApiResponse closeCurrentWorks(UpdateWorkRequest closeWorkRequest) {
        if (closeWorkRequest == null || StringUtils.isEmpty(closeWorkRequest.getWorkIndex())) {
            return BaseWmsApiResponse.error("请求参数不完整，缺少主键。");
        }
        // 查询当前这一条的工作详情
        TAppWork thisWork = appWorkService.getOne(new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkIndex, closeWorkRequest.getWorkIndex()));
        if (thisWork == null) {
            return BaseWmsApiResponse.error("请求的工作不存在。");
        }
        // 如果不需要更新，返回不需要再次更新
        if (thisWork.getFinishNum() >= thisWork.getNeedNum() && thisWork.getLackStatus() == 0 && thisWork.getWorkStatus() == 2) {
            return BaseWmsApiResponse.error("所选工作已关闭，不需要重复操作。");
        }
        // 更新数据
        thisWork.setDistributeNum(thisWork.getFinishNum());
        thisWork.setFinishNum(thisWork.getNeedNum());
        thisWork.setLackStatus(0);
        thisWork.setWorkStatus(DbsStatusEnums.FINISH.getValue());
        thisWork.setFinishTime(LocalDateTime.now());
        thisWork.setWorkUser(closeWorkRequest.getUserName());
        appWorkService.updateById(thisWork);
        return BaseWmsApiResponse.success("关闭缺料工作成功。");
    }

    /**
     * 获取料盒打印标签数量
     * @param kateWorksQuery 查询参数
     * @return 标签信息
     */
    @Override
    public WmsApiResponse<BoxSummary> requestPrintBoxTags(KateWorksQuery kateWorksQuery) {
        if (kateWorksQuery == null) {
            // 站台号不能为空
            return WmsApiResponse.error("请求为空。", null);
        }
        if (StringUtils.isEmpty(kateWorksQuery.getWorkOrder())) {
            return WmsApiResponse.error("请求缺少工单号。", null);
        }
        if (StringUtils.isEmpty(kateWorksQuery.getBoxNo())) {
            return WmsApiResponse.error("请求缺少料盒号。", null);
        }
        // 查询对应的dbs
        List<TAppDbs> dbsList = appDbsService.list(new LambdaQueryWrapper<TAppDbs>()
                .eq(TAppDbs::getWorkOrder, kateWorksQuery.getWorkOrder()));
        if (dbsList == null || dbsList.isEmpty()) {
            return WmsApiResponse.error("DBS数据异常：不存在工单" + kateWorksQuery.getWorkOrder() + "。", null);
        }
        TAppDbs thisDbs = dbsList.getFirst();
        // 计划产量
        int planProduction = thisDbs.getPlanProduction();
        // 结果集
        BoxSummary boxSummary = new BoxSummary();
        boxSummary.setWorkOrder(thisDbs.getWorkOrder());
        boxSummary.setTaoQty(planProduction);
        boxSummary.setSingleProductId(kateWorksQuery.getSingleProductId());
        boxSummary.setBoxNo(kateWorksQuery.getBoxNo());
        // 设置打印标签相关的信息
        boxSummary.setProductIdOrigin(thisDbs.getProductIdOrigin());
        boxSummary.setKittingDate(thisDbs.getTestPlanStartDate());
        boxSummary.setProduceDate(thisDbs.getPntPlanStartDate());
        boxSummary.setTestNo(thisDbs.getTestNo());
        boxSummary.setProductionQty(planProduction);
        // 服务件
        List<TAppSingleProduct> singleProductList;
        // 非服务件
        List<TAppProduct> productList = new ArrayList<>();
        // 查询对应料盒信息
        String queryProductId = thisDbs.getProductIdOrigin();
        if (StringUtils.isNotEmpty(kateWorksQuery.getSingleProductId())) {
            // 输入单片号
            queryProductId = kateWorksQuery.getSingleProductId();
            // 查询服务件
            singleProductList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                    .eq(TAppSingleProduct::getProductId, queryProductId)
                    .eq(TAppSingleProduct::getBoxNo, kateWorksQuery.getBoxNo()));
            if (singleProductList.isEmpty()) {
                // 查询非服务件
                productList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                        .eq(TAppProduct::getProductId, queryProductId)
                        .eq(TAppProduct::getBoxNo, kateWorksQuery.getBoxNo()));
            }
        } else {
            // 查询服务件
            singleProductList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                    .eq(TAppSingleProduct::getProductId, queryProductId)
                    .eq(TAppSingleProduct::getBoxNo, kateWorksQuery.getBoxNo()));
            if (singleProductList.isEmpty()) {
                queryProductId = thisDbs.getProductId();
                // 查询非服务件
                productList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                        .eq(TAppProduct::getProductId, queryProductId)
                        .eq(TAppProduct::getBoxNo, kateWorksQuery.getBoxNo()));
            }
        }
        if (singleProductList.isEmpty() && productList.isEmpty()) {
            return WmsApiResponse.error("数据异常：配料单信息缺失。", null);
        }
        // 查询到对应的图纸信息
        List<TAppImage> imageList = appImageService.list(new LambdaQueryWrapper<TAppImage>()
                .eq(TAppImage::getProductId, queryProductId)
                .eq(TAppImage::getBoxNo, kateWorksQuery.getBoxNo()));
        if (imageList != null && !imageList.isEmpty()) {
            boxSummary.setImageId(imageList.getFirst().getImageId());
        }
        // 最大料盒数量
        int maxBoxQty = 0;
        if (!singleProductList.isEmpty()) {
            boxSummary.setProductId(thisDbs.getProductIdOrigin());
            // 处理服务件
            for (TAppSingleProduct singleProduct : singleProductList) {
                // 设置料盒数量
                int tempBoxQty = Math.ceilDiv(planProduction, singleProduct.getQuantityOfPair());
                if (tempBoxQty > maxBoxQty) {
                    maxBoxQty = tempBoxQty;
                }
            }
        } else {
            if (!productList.isEmpty()) {
                // 处理非服务件
                boxSummary.setProductId(thisDbs.getProductId());
                for (TAppProduct product : productList) {
                    // 设置料盒数量
                    int tempBoxQty = Math.ceilDiv(planProduction, product.getQuantityOfPair());
                    if (tempBoxQty > maxBoxQty) {
                        maxBoxQty = tempBoxQty;
                    }
                }
            }
        }
        // 设置料盒数量
        boxSummary.setBoxQty(maxBoxQty);
        return WmsApiResponse.success("获取料盒标签数据成功。", boxSummary);
    }

    /**
     * 删除dbs计划---实现
     * @param dbsRequest 删除请求
     * @return 删除结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseWmsApiResponse deleteDbsPlan(DbsRequest dbsRequest) {
        if (dbsRequest == null) {
            // 请求为空
            return BaseWmsApiResponse.error("请求为空。");
        }
        if (StringUtils.isEmpty(dbsRequest.getDbsId()) && StringUtils.isEmpty(dbsRequest.getWorkOrder())) {
            return BaseWmsApiResponse.error("dbsId、工单号必须输入一个。");
        }
        // 查询对应的dbs信息
        List<TAppDbs> targetDbsList = appDbsService.list(new LambdaQueryWrapper<TAppDbs>()
                .eq(StringUtils.isNotEmpty(dbsRequest.getDbsId()), TAppDbs::getDbsId, dbsRequest.getDbsId())
                .eq(StringUtils.isNotEmpty(dbsRequest.getWorkOrder()), TAppDbs::getWorkOrder, dbsRequest.getWorkOrder()));
        if (targetDbsList == null || targetDbsList.isEmpty()) {
            // 未查询到对应的dbs信息
            return BaseWmsApiResponse.error("未查询到对应的dbs信息。");
        }
        TAppDbs targetDbs = targetDbsList.getFirst();
        if (!Objects.equals(targetDbs.getDbsStatus(), DbsStatusEnums.NEW.getValue())) {
            // 当前dbs状态为关闭
            return BaseWmsApiResponse.error("当前DBS已经在做，无法删除。");
        }
        // 删除dbs
        return appDbsService.removeById(targetDbs.getDbsId()) ? BaseWmsApiResponse.success("删除DBS成功。") : BaseWmsApiResponse.error("删除DBS失败。");
    }

    /**
     * 获取服务件成品号的物料需求
     *
     * @param productIdOrigin 服务件成品号
     * @return 物料需求Map
     */
    private Map<String, Integer> getGoodsRequireMapOfServiceProduct(String productIdOrigin) {
        Map<String, Integer> goodsRequireMap = new HashMap<>();
        // 查询到所有的总成配料单信息
        List<TAppSingleProduct> productList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                .eq(TAppSingleProduct::getProductId, productIdOrigin));
        for (TAppSingleProduct product : productList) {
            if (goodsRequireMap.containsKey(product.getGoodsId())) {
                goodsRequireMap.replace(product.getGoodsId(), goodsRequireMap.get(product.getGoodsId()) + product.getQuantity1Pair());
            } else {
                goodsRequireMap.put(product.getGoodsId(), product.getQuantity1Pair());
            }
        }
        // 判断是否包含单片
        List<TAppProductExtend> productExtendList = appProductExtendService.list(new LambdaQueryWrapper<TAppProductExtend>()
                .eq(TAppProductExtend::getProductId, productIdOrigin));
        if (productExtendList == null || productExtendList.isEmpty()) {
            return goodsRequireMap;
        }
        // 查询对应的单片信息清单
        List<String> singleProductIds = productExtendList.stream().map(TAppProductExtend::getSingleProductId).distinct().toList();
        List<TAppSingleProduct> singleProductList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                .in(TAppSingleProduct::getProductId, singleProductIds));
        for (TAppSingleProduct singleProduct : singleProductList) {
            if (goodsRequireMap.containsKey(singleProduct.getGoodsId())) {
                goodsRequireMap.replace(singleProduct.getGoodsId(), goodsRequireMap.get(singleProduct.getGoodsId()) + singleProduct.getQuantity1Pair());
            } else {
                goodsRequireMap.put(singleProduct.getGoodsId(), singleProduct.getQuantity1Pair());
            }
        }
        return goodsRequireMap;
    }

    /**
     * 获取非服务件成品号的物料需求
     *
     * @param productId 非服务件成品号
     * @return 物料需求Map
     */
    private Map<String, Integer> getGoodsRequireMapOfNonServiceProduct(String productId) {
        Map<String, Integer> goodsRequireMap = new HashMap<>();
        // 查询到所有的总成配料单信息
        List<TAppProduct> productList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                .eq(TAppProduct::getProductId, productId));
        for (TAppProduct product : productList) {
            if (goodsRequireMap.containsKey(product.getGoodsId())) {
                goodsRequireMap.replace(product.getGoodsId(), goodsRequireMap.get(product.getGoodsId()) + product.getQuantity1Pair());
            } else {
                goodsRequireMap.put(product.getGoodsId(), product.getQuantity1Pair());
            }
        }
        // 判断是否包含单片
        List<TAppProductExtend> productExtendList = appProductExtendService.list(new LambdaQueryWrapper<TAppProductExtend>()
                .eq(TAppProductExtend::getProductId, productId));
        if (productExtendList == null || productExtendList.isEmpty()) {
            return goodsRequireMap;
        }
        // 查询对应的单片信息清单
        List<String> singleProductIds = productExtendList.stream().map(TAppProductExtend::getSingleProductId).distinct().toList();
        List<TAppProduct> singleProductList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                .in(TAppProduct::getProductId, singleProductIds));
        for (TAppProduct singleProduct : singleProductList) {
            if (goodsRequireMap.containsKey(singleProduct.getGoodsId())) {
                goodsRequireMap.replace(singleProduct.getGoodsId(), goodsRequireMap.get(singleProduct.getGoodsId()) + singleProduct.getQuantity1Pair());
            } else {
                goodsRequireMap.put(singleProduct.getGoodsId(), singleProduct.getQuantity1Pair());
            }
        }
        return goodsRequireMap;
    }

    /**
     * 获得当前工单的剩余物料需求
     *
     * @param workOrder 工单号
     * @return 物料需求Map
     */
    private Map<String, Integer> getRemainRequireMapOfOrder(String workOrder) {
        Map<String, Integer> goodsRequireMap = new HashMap<>();
        // 查找到这个工单下未完成的工作
        List<TAppWork> workList = appWorkService.list(new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getWorkOrder, workOrder)
                .ne(TAppWork::getWorkStatus, 2));
        if (workList == null || workList.isEmpty()) {
            return goodsRequireMap;
        }
        for (TAppWork work : workList) {
            if (goodsRequireMap.containsKey(work.getGoodsId())) {
                goodsRequireMap.replace(work.getGoodsId(), goodsRequireMap.get(work.getGoodsId()) + work.getNeedNum() - work.getFinishNum());
            } else {
                goodsRequireMap.put(work.getGoodsId(), work.getNeedNum() - work.getFinishNum());
            }
        }
        return goodsRequireMap;
    }

    /**
     * 合并需求
     *
     * @param originRequireMap     原需求Map
     * @param additionalRequireMap 额外需求Map
     */
    private void mergeRequire(Map<String, Integer> originRequireMap, Map<String, Integer> additionalRequireMap) {
        if (additionalRequireMap.isEmpty()) {
            return;
        }
        // 迭代处理需求
        for (String key : additionalRequireMap.keySet()) {
            if (originRequireMap.containsKey(key)) {
                // 叠加替换
                originRequireMap.replace(key, originRequireMap.get(key) + additionalRequireMap.get(key));
            } else {
                // 新增
                originRequireMap.put(key, additionalRequireMap.get(key));
            }
        }
    }

    /**
     * 获得一条库外料工作
     *
     * @param standId       站台号
     * @param thisStandWork 站台工作
     * @return 结果
     */
    private WorkConfirmVo getOutGoodsStandWork(String standId, TAppStandWork thisStandWork) {
        // 查找对应的库内料工作---一次性只能拣配一种料，一个料盒（因为要覆盖到一张图纸）
        List<TAppWork> works = appWorkService.list(new LambdaQueryWrapper<TAppWork>()
                .eq(TAppWork::getIsOut, 1)
                .eq(TAppWork::getWorkOrder, thisStandWork.getWorkOrder())
                .eq(TAppWork::getBoxNo, thisStandWork.getBoxNo())
                .eq(TAppWork::getWorkStand, standId)
                .notIn(TAppWork::getWorkStatus, -1, 2));
        for (TAppWork work : works) {
            if (work.getNeedNum() > work.getFinishNum()) {
                // 当前工作剩余需求数量
                int thisNeedNum = work.getNeedNum() - work.getFinishNum();
                // 命中，开始设置返回数据
                OrderConfirmEntity orderConfirmVo = new OrderConfirmEntity(
                        work.getWorkIndex(),
                        work.getWorkOrder(),
                        work.getProductId(),
                        work.getSingleProductId(),
                        work.getGoodsId(),
                        work.getBoxNo(),
                        thisNeedNum,
                        thisNeedNum
                );
                // 查找到这个库外料
                TAppGoods outGoods = new TAppGoods();
                try {
                    outGoods = appGoodsService.getOne(new LambdaQueryWrapper<TAppGoods>()
                            .eq(TAppGoods::getGoodsId, work.getGoodsId()));
                } catch (Exception e) {
                    log.error("物料{}存在多个选项。", work.getGoodsId());
                }
                StockConfirmEntity stockConfirmVo = new StockConfirmEntity(
                        "",
                        "库外料",
                        outGoods.getGoodsId(),
                        0,
                        0,
                        1,
                        outGoods.getPutArea(),
                        0
                );
                return new WorkConfirmVo(orderConfirmVo, stockConfirmVo);
            }
        }
        return null;
    }

    /**
     * 更新工作信息
     *
     * @param confirmWorkRequest 工作确认信息
     */
    private String updateWorkInfo(ConfirmWorkRequest confirmWorkRequest) {
        // 判断请求是否为空
        if (confirmWorkRequest == null) {
            return "确认请求为空";
        }
        OrderConfirmEntity orderConfirm = confirmWorkRequest.getOrderConfirm();
        if (orderConfirm == null || StringUtils.isEmpty(orderConfirm.getWorkIndex())
                || orderConfirm.getRealPickQty() == null) {
            return "工作确认请求信息不全";
        }
        // 查询对应的工作信息
        List<TAppWork> targetWorks = appWorkService.list(new LambdaQueryWrapper<TAppWork>()
                .eq(StringUtils.isNotEmpty(orderConfirm.getWorkIndex()), TAppWork::getWorkIndex, orderConfirm.getWorkIndex())
        );
        if (targetWorks == null || targetWorks.isEmpty()) {
            return "未查到对应工作信息";
        }
        TAppWork work = targetWorks.getFirst();
        if (orderConfirm.getRealPickQty() < 0) {
            return "实际拣选数量不能为负整数";
        }
        work.setFinishNum(work.getFinishNum() + orderConfirm.getRealPickQty());
        if (work.getFinishNum() >= work.getNeedNum()) {
            work.setWorkStatus(2);
            work.setLackStatus(0);
            work.setFinishTime(LocalDateTime.now());
        }
        work.setWorkUser(confirmWorkRequest.getUserName());
        // 更新
        appWorkService.updateById(work);
        // 清除当前站台的正在工作信息
        appStandWorkService.update(new LambdaUpdateWrapper<TAppStandWork>()
                .set(TAppStandWork::getWorkIndex, "")
                .set(TAppStandWork::getGoodsId, "")
                .set(TAppStandWork::getPlanPickQty, 0)
                .set(TAppStandWork::getRealPickQty, 0)
                .set(TAppStandWork::getStockId, "")
                .set(TAppStandWork::getVehicleId, "")
                .set(TAppStandWork::getPlanRemainQty, 0)
                .set(TAppStandWork::getRealRemainQty, 0)
                .set(TAppStandWork::getIsOut, 0)
                .set(TAppStandWork::getPutArea, "")
                .eq(TAppStandWork::getStandId, confirmWorkRequest.getStandId()));
        // 清除拣选计划
        // 清除拣选计划
        LambdaQueryWrapper<TAppPickPlan> pickPlanQueryWrapper = new LambdaQueryWrapper<TAppPickPlan>()
                .eq(TAppPickPlan::getWorkIndex, confirmWorkRequest.getOrderConfirm().getWorkIndex());
        if (confirmWorkRequest.getStockConfirm() != null && StringUtils.isNotEmpty(confirmWorkRequest.getStockConfirm().getVehicleId())) {
            // 箱号
            pickPlanQueryWrapper.eq(TAppPickPlan::getVehicleId, confirmWorkRequest.getStockConfirm().getVehicleId());
        }
        appPickPlanService.remove(pickPlanQueryWrapper);
        return "";
    }

    /**
     * 设置站台信息
     *
     * @param resultVo      结果视图
     * @param thisStandWork 当前站台工作信息
     */
    private void setStandWork(WorkConfirmVo resultVo, TAppStandWork thisStandWork) {
        thisStandWork.setWorkIndex(resultVo.getOrderConfirmVo().getWorkIndex());
        thisStandWork.setGoodsId(resultVo.getOrderConfirmVo().getGoodsId());
        thisStandWork.setPlanPickQty(resultVo.getOrderConfirmVo().getPlanPickQty());
        thisStandWork.setRealPickQty(resultVo.getOrderConfirmVo().getRealPickQty());
        thisStandWork.setStockId(resultVo.getStockConfirmVo().getStockId());
        thisStandWork.setVehicleId(resultVo.getStockConfirmVo().getVehicleId());
        thisStandWork.setPlanRemainQty(resultVo.getStockConfirmVo().getPlanRemainQty());
        thisStandWork.setRealRemainQty(resultVo.getStockConfirmVo().getRealRemainQty());
        thisStandWork.setIsOut(resultVo.getStockConfirmVo().getIsOut());
        thisStandWork.setPutArea(resultVo.getStockConfirmVo().getPutArea());
    }

    /**
     * 获取imageIp
     *
     * @return 获取图纸ip
     */
    private String getImageIp() {
        String imageIp = "";
        try {
            imageIp = appCommon.getConfigByKey(AppConfigKeyEnums.IMAGE_IP.getKey());
        } catch (Exception e) {
            log.error("图纸存放ip不正确。");
        }
        return imageIp;
    }

    /**
     * 获取服务件配料单的options
     *
     * @param kateWorksQuery  查询条件
     * @param productIdOrigin 原始成品号
     * @param result          结果集
     * @return true：有服务件配料，false：无服务件配料
     */
    private boolean getWorkOptionsOfServicePieces(KateWorksQuery kateWorksQuery, String productIdOrigin, KateWorkOptionsVo result) {
        if (StringUtils.isEmpty(productIdOrigin)) {
            return false;
        }
        // 查找服务件配料单
        List<TAppSingleProduct> serviceProductList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                .eq(TAppSingleProduct::getProductId, productIdOrigin));
        // 查询成品-单片以获取单片Options
        List<TAppProductExtend> singleProductExtendListAll = appProductExtendService.list(new LambdaQueryWrapper<TAppProductExtend>()
                .eq(TAppProductExtend::getProductId, productIdOrigin));
        if ((serviceProductList == null || serviceProductList.isEmpty())
                && (singleProductExtendListAll == null || singleProductExtendListAll.isEmpty())) {
            // 没有任何的配料单
            return false;
        }
        // 设置单片配料单选项
        if (singleProductExtendListAll != null && !singleProductExtendListAll.isEmpty()) {
            result.setSingleProductId(singleProductExtendListAll.stream().map(TAppProductExtend::getSingleProductId).distinct().toList());
        }
        // 判断是否选择了单片号
        if (StringUtils.isNotEmpty(kateWorksQuery.getSingleProductId())) {
            // 查询单片配料单，这里直接从成品配料单中查找
            List<TAppSingleProduct> singleServiceProducts = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                    .eq(TAppSingleProduct::getProductId, kateWorksQuery.getSingleProductId()));
            if (singleServiceProducts == null || singleServiceProducts.isEmpty()) {
                return true;
            }
            // 设置料盒号以及料号
            result.setBoxNo(singleServiceProducts.stream().map(TAppSingleProduct::getBoxNo).distinct().toList());
            // 设置料号
            result.setGoodsId(singleServiceProducts.stream()
                    .filter(singleServiceProduct -> StringUtils.isEmpty(kateWorksQuery.getBoxNo()) || (StringUtils.isNotEmpty(kateWorksQuery.getBoxNo()) && Objects.equals(singleServiceProduct.getBoxNo(), kateWorksQuery.getBoxNo())))
                    .map(TAppSingleProduct::getGoodsId).distinct().toList());
        } else {
            if (serviceProductList == null || serviceProductList.isEmpty()) {
                return true;
            }
            // 设置料盒号以及料号
            result.setBoxNo(serviceProductList.stream().map(TAppSingleProduct::getBoxNo).distinct().toList());
            // 设置料号
            result.setGoodsId(serviceProductList.stream()
                    .filter(serviceProduct -> StringUtils.isEmpty(kateWorksQuery.getBoxNo()) || (StringUtils.isNotEmpty(kateWorksQuery.getBoxNo()) && Objects.equals(serviceProduct.getBoxNo(), kateWorksQuery.getBoxNo())))
                    .map(TAppSingleProduct::getGoodsId).distinct().toList());
        }

        return true;
    }

    /**
     * 获取非服务件配料单的options
     *
     * @param kateWorksQuery 查询条件
     * @param productId      过滤成品号
     * @param result         结果集
     * @return true：有非服务件配料，false：无非服务件配料
     */
    private boolean getWorkOptionsOfNonServicePieces(KateWorksQuery kateWorksQuery, String productId, KateWorkOptionsVo result) {
        if (StringUtils.isEmpty(productId)) {
            return false;
        }
        // 查找成品配料单
        List<TAppProduct> productList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                .eq(TAppProduct::getProductId, productId));
        // 查询成品-单片以获取单片Options
        List<TAppProductExtend> singleProductExtendListAll = appProductExtendService.list(new LambdaQueryWrapper<TAppProductExtend>()
                .eq(TAppProductExtend::getProductId, productId));
        if ((productList == null || productList.isEmpty())
                && (singleProductExtendListAll == null || singleProductExtendListAll.isEmpty())) {
            // 没有任何的配料单
            return false;
        }
        // 设置单片配料单选项
        if (singleProductExtendListAll != null && !singleProductExtendListAll.isEmpty()) {
            result.setSingleProductId(singleProductExtendListAll.stream().map(TAppProductExtend::getSingleProductId).distinct().toList());
        }
        // 判断是否选择了单片号
        if (StringUtils.isNotEmpty(kateWorksQuery.getSingleProductId())) {
            // 查询单片配料单，这里直接从成品配料单中查找
            List<TAppProduct> singleProducts = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                    .eq(TAppProduct::getProductId, kateWorksQuery.getSingleProductId()));
            if (singleProducts == null || singleProducts.isEmpty()) {
                return true;
            }
            // 设置料盒号以及料号
            result.setBoxNo(singleProducts.stream().map(TAppProduct::getBoxNo).distinct().toList());
            // 设置料号
            result.setGoodsId(singleProducts.stream()
                    .filter(singleProduct -> StringUtils.isEmpty(kateWorksQuery.getBoxNo()) || (StringUtils.isNotEmpty(kateWorksQuery.getBoxNo()) && Objects.equals(singleProduct.getBoxNo(), kateWorksQuery.getBoxNo())))
                    .map(TAppProduct::getGoodsId).distinct().toList());
        } else {
            if (productList == null || productList.isEmpty()) {
                return true;
            }
            // 设置料盒号以及料号
            result.setBoxNo(productList.stream().map(TAppProduct::getBoxNo).distinct().toList());
            // 设置料号
            result.setGoodsId(productList.stream()
                    .filter(product -> StringUtils.isEmpty(kateWorksQuery.getBoxNo()) || (StringUtils.isNotEmpty(kateWorksQuery.getBoxNo()) && Objects.equals(product.getBoxNo(), kateWorksQuery.getBoxNo())))
                    .map(TAppProduct::getGoodsId).distinct().toList());
        }

        return true;
    }

    /**
     * 创建服务件工作
     *
     * @param outGoodsIds 库外料
     * @param dbs         dbs计划
     * @param workList    工作列表
     */
    private void createServicePiecesWork(List<String> outGoodsIds, TAppDbs dbs, List<TAppWork> workList) {
        int productionNum = dbs.getPlanProduction();// 计划产量
        // 查询服务件配料单
        List<TAppSingleProduct> serviceProductList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                .eq(TAppSingleProduct::getProductId, dbs.getProductIdOrigin()));
        // 创建服务件工作
        for (TAppSingleProduct serviceProduct : serviceProductList) {
            TAppWork tempServiceProductWork = new TAppWork();
            tempServiceProductWork.setWorkIndex(UUIDUtils.getNewUUID());
            tempServiceProductWork.setWorkOrder(dbs.getWorkOrder());
            tempServiceProductWork.setPlanStartDate(dbs.getTestPlanStartDate());
            tempServiceProductWork.setProductId(dbs.getProductIdOrigin());
            tempServiceProductWork.setGoodsId(serviceProduct.getGoodsId());
            tempServiceProductWork.setBoxNo(serviceProduct.getBoxNo());
            tempServiceProductWork.setNeedNum(productionNum * serviceProduct.getQuantity1Pair());
            tempServiceProductWork.setDistributeNum(0);
            tempServiceProductWork.setFinishNum(0);
            tempServiceProductWork.setProductType(2);
            tempServiceProductWork.setCreateTime(LocalDateTime.now());
            if (outGoodsIds.contains(serviceProduct.getGoodsId())) {
                tempServiceProductWork.setIsOut(1);
            } else {
                tempServiceProductWork.setIsOut(0);
            }
            tempServiceProductWork.setLackStatus(0);
            workList.add(tempServiceProductWork);
        }
        // 查询服务件是否包含单片
        List<TAppProductExtend> singleProductExtendList = appProductExtendService.list(new LambdaQueryWrapper<TAppProductExtend>()
                .eq(TAppProductExtend::getProductId, dbs.getProductIdOrigin()));
        if (singleProductExtendList == null || singleProductExtendList.isEmpty()) {
            return;
        }
        // 获取所有的服务件单片号
        List<String> singleServiceProductIds = singleProductExtendList.stream().map(TAppProductExtend::getSingleProductId).distinct().toList();
        // 查询所有的服务件单片配料单
        List<TAppSingleProduct> singleServiceProductList = appSingleProductService.list(new LambdaQueryWrapper<TAppSingleProduct>()
                .in(TAppSingleProduct::getProductId, singleServiceProductIds));
        // 创建服务件单片工作
        for (TAppSingleProduct singleServiceProduct : singleServiceProductList) {
            TAppWork tempSingleServiceProductWork = new TAppWork();
            tempSingleServiceProductWork.setWorkIndex(UUIDUtils.getNewUUID());
            tempSingleServiceProductWork.setWorkOrder(dbs.getWorkOrder());
            tempSingleServiceProductWork.setPlanStartDate(dbs.getTestPlanStartDate());
            tempSingleServiceProductWork.setProductId(dbs.getProductIdOrigin());
            tempSingleServiceProductWork.setSingleProductId(singleServiceProduct.getProductId());
            tempSingleServiceProductWork.setGoodsId(singleServiceProduct.getGoodsId());
            tempSingleServiceProductWork.setBoxNo(singleServiceProduct.getBoxNo());
            tempSingleServiceProductWork.setNeedNum(productionNum * singleServiceProduct.getQuantity1Pair());
            tempSingleServiceProductWork.setDistributeNum(0);
            tempSingleServiceProductWork.setFinishNum(0);
            tempSingleServiceProductWork.setProductType(2);
            tempSingleServiceProductWork.setCreateTime(LocalDateTime.now());
            if (outGoodsIds.contains(singleServiceProduct.getGoodsId())) {
                tempSingleServiceProductWork.setIsOut(1);
            } else {
                tempSingleServiceProductWork.setIsOut(0);
            }
            tempSingleServiceProductWork.setLackStatus(0);
            workList.add(tempSingleServiceProductWork);
        }
    }

    /**
     * 创建非服务件工作
     *
     * @param outGoodsIds 库外料
     * @param dbs         dbs计划
     * @param workList    工作列表
     */
    private void createNonServicePiecesWork(List<String> outGoodsIds, TAppDbs dbs, List<TAppWork> workList) {
        int productionNum = dbs.getPlanProduction();// 计划产量
        // 查询服务件配料单
        List<TAppProduct> nonServiceProductList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                .eq(TAppProduct::getProductId, dbs.getProductId()));
        // 创建服务件工作
        for (TAppProduct nonServiceProduct : nonServiceProductList) {
            TAppWork tempNonServiceProductWork = new TAppWork();
            tempNonServiceProductWork.setWorkIndex(UUIDUtils.getNewUUID());
            tempNonServiceProductWork.setWorkOrder(dbs.getWorkOrder());
            tempNonServiceProductWork.setPlanStartDate(dbs.getTestPlanStartDate());
            tempNonServiceProductWork.setProductId(nonServiceProduct.getProductId());
            tempNonServiceProductWork.setGoodsId(nonServiceProduct.getGoodsId());
            tempNonServiceProductWork.setBoxNo(nonServiceProduct.getBoxNo());
            tempNonServiceProductWork.setNeedNum(productionNum * nonServiceProduct.getQuantity1Pair());
            tempNonServiceProductWork.setDistributeNum(0);
            tempNonServiceProductWork.setFinishNum(0);
            tempNonServiceProductWork.setProductType(1);
            tempNonServiceProductWork.setCreateTime(LocalDateTime.now());
            if (outGoodsIds.contains(nonServiceProduct.getGoodsId())) {
                tempNonServiceProductWork.setIsOut(1);
            } else {
                tempNonServiceProductWork.setIsOut(0);
            }
            tempNonServiceProductWork.setLackStatus(0);
            workList.add(tempNonServiceProductWork);
        }
        // 查询服务件是否包含单片
        List<TAppProductExtend> singleProductExtendList = appProductExtendService.list(new LambdaQueryWrapper<TAppProductExtend>()
                .eq(TAppProductExtend::getProductId, dbs.getProductId()));
        if (singleProductExtendList == null || singleProductExtendList.isEmpty()) {
            return;
        }
        // 获取所有的服务件单片号
        List<String> singleNonServiceProductIds = singleProductExtendList.stream().map(TAppProductExtend::getSingleProductId).distinct().toList();
        // 查询所有的服务件单片配料单
        List<TAppProduct> singleNonServiceProductList = appProductService.list(new LambdaQueryWrapper<TAppProduct>()
                .in(TAppProduct::getProductId, singleNonServiceProductIds));
        // 创建服务件单片工作
        for (TAppProduct singleNonServiceProduct : singleNonServiceProductList) {
            TAppWork tempSingleNonServiceProductWork = new TAppWork();
            tempSingleNonServiceProductWork.setWorkIndex(UUIDUtils.getNewUUID());
            tempSingleNonServiceProductWork.setWorkOrder(dbs.getWorkOrder());
            tempSingleNonServiceProductWork.setPlanStartDate(dbs.getTestPlanStartDate());
            tempSingleNonServiceProductWork.setProductId(dbs.getProductId());
            tempSingleNonServiceProductWork.setSingleProductId(singleNonServiceProduct.getProductId());
            tempSingleNonServiceProductWork.setGoodsId(singleNonServiceProduct.getGoodsId());
            tempSingleNonServiceProductWork.setBoxNo(singleNonServiceProduct.getBoxNo());
            tempSingleNonServiceProductWork.setNeedNum(productionNum * singleNonServiceProduct.getQuantity1Pair());
            tempSingleNonServiceProductWork.setDistributeNum(0);
            tempSingleNonServiceProductWork.setFinishNum(0);
            tempSingleNonServiceProductWork.setProductType(1);
            tempSingleNonServiceProductWork.setCreateTime(LocalDateTime.now());
            if (outGoodsIds.contains(singleNonServiceProduct.getGoodsId())) {
                tempSingleNonServiceProductWork.setIsOut(1);
            } else {
                tempSingleNonServiceProductWork.setIsOut(0);
            }
            tempSingleNonServiceProductWork.setLackStatus(0);
            workList.add(tempSingleNonServiceProductWork);
        }
    }
}
