package easydo.technology.service.impl;

import easydo.technology.components.JdbcClient;
import easydo.technology.enums.MESEnum;
import easydo.technology.exception.BizException;
import easydo.technology.model.*;
import easydo.technology.model.vo.DispatchVO;
import easydo.technology.model.vo.ProductOrderDispatchVO;
import easydo.technology.service.FlowNoService;
import easydo.technology.service.MaterialRequisitionService;
import easydo.technology.service.ProductOrderDispatchService;
import easydo.technology.system.model.SysUser;
import easydo.technology.utils.SecurityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 派工单服务实现类
 * 
 * ============================================
 * getPage() 接口表关联关系图
 * ============================================
 * 
 * 主表：product_order_dispatch（派工单）
 * │
 * ├─→ product_order（工单）
 * │   关联：dispatch.order_id = order.id
 * │
 * ├─→ process_stage（工序）
 * │   关联：dispatch.stage_id = stage.id
 * │
 * ├─→ product_order_bom（工单BOM）
 * │   关联：dispatch.order_id = order_bom.order_id 
 * │          AND dispatch.bom_id = order_bom.bom_id
 * │   │
 * │   └─→ product_bom（产品BOM）
 * │       关联：order_bom.bom_id = product_bom.id
 * │
 * ├─→ dispatch_user_item（派工人员）
 * │   关联：dispatch.id = user_item.dispatch_id
 * │   │
 * │   └─→ sys_user（用户）
 * │       关联：user_item.user_id = user.id
 * │
 * └─→ material_requisition（领料单）
 *     关联：dispatch.order_id = requisition.order_id
 *            AND dispatch.bom_id = requisition.bom_id
 * 
 * ============================================
 * 查询优化说明
 * ============================================
 * 
 * 当前实现：单表查询 + 应用层拼接
 * - 优点：逻辑清晰，易于维护
 * - 缺点：查询次数多（N+1问题）
 * 
 * 查询次数统计（假设返回10条记录）：
 * - 主查询：1次
 * - 工单/工序/BOM：各10次
 * - 派工人员：10次
 * - 用户信息：30次（假设每个派工3人）
 * - 领料单：5次（去重优化后）
 * - 总计：约86次数据库查询
 * 
 * 优化方向：
 * 1. 主查询改用连表SQL（减少到1次）
 * 2. 子查询改用批量IN查询（3-4次）
 * 3. 总查询次数可降至4-5次
 * 
 * ============================================
 */
@Service
public class ProductOrderDispatchServiceImpl implements ProductOrderDispatchService {

    @Resource
    private JdbcClient jdbcClient;
    @Resource
    private DataSource dataSource;
    @Resource
    private FlowNoService flowNoService;
    @Resource
    private MaterialRequisitionService materialRequisitionService;

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    @SuppressWarnings("unchecked")
    public Map<String, Object> getPage(Map<String, Object> map) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            // 查询派工记录分页数据
            Map<String, Object> result = jdbcClient.getJdbcPage(map, ProductOrderDispatch.class, connection);
            List<ProductOrderDispatch> list = (List<ProductOrderDispatch>) result.get("records");
            
            if (list == null || list.isEmpty()) {
                return result;
            }

            // 转换为 VO 对象
            List<ProductOrderDispatchVO> voList = new ArrayList<>();
            for (ProductOrderDispatch model : list) {
                ProductOrderDispatchVO vo = new ProductOrderDispatchVO();
                
                // 复制主要字段
                vo.setId(model.getId());
                vo.setCode(model.getCode());
                vo.setName(model.getName());
                vo.setOrderId(model.getOrderId());
                vo.setBomId(model.getBomId());
                vo.setStageId(model.getStageId());
                vo.setRouteId(model.getRouteId());
                vo.setOrderNum(model.getOrderNum());
                vo.setProcessNum(model.getProcessNum());
                vo.setProcessTimeHour(model.getProcessTimeHour());
                vo.setReadyTimeHour(model.getReadyTimeHour());
                vo.setMoveNum(model.getMoveNum());
                vo.setMoveTimeHour(model.getMoveTimeHour());
                vo.setStatus(model.getStatus());
                vo.setIsReport(model.getIsReport());
                vo.setIsReview(model.getIsReview());
                vo.setIsRound(model.getIsRound());
                vo.setIsInspection(model.getIsInspection());
                vo.setBeginDate(model.getBeginDate());
                vo.setEndDate(model.getEndDate());
                vo.setCreateTime(model.getCreateTime());
                vo.setTenantId(model.getTenantId());
                
                // 查询并设置工单信息（返回整表对象）
                if (model.getOrderId() != null) {
                    ProductOrder orderParam = new ProductOrder();
                    orderParam.setId(model.getOrderId());
                    ProductOrder order = jdbcClient.getJdbcModelById(orderParam, connection);
                    if (order != null) {
                        vo.setProductOrder(order);
                    }
                }
                
                // 查询并设置工序信息（返回整表对象）
                if (model.getStageId() != null) {
                    ProcessStage stageParam = new ProcessStage();
                    stageParam.setId(model.getStageId());
                    ProcessStage stage = jdbcClient.getJdbcModelById(stageParam, connection);
                    if (stage != null) {
                        vo.setStage(stage);
                    }
                }
                
                // 查询并设置 BOM 信息
                if (model.getBomId() != null) {
                    // 注意：派工表中的 bomId 对应 product_order_bom.bom_id（产品BOM主键），不是 product_order_bom.id
                    ProductOrderBom bomQueryParam = new ProductOrderBom();
                    bomQueryParam.setOrderId(model.getOrderId());
                    bomQueryParam.setBomId(model.getBomId());
                    List<ProductOrderBom> bomList = jdbcClient.getJdbcList(bomQueryParam, connection);

                    if (bomList != null && !bomList.isEmpty()) {
                        ProductOrderBom bom = bomList.get(0);

                        vo.setProductOrderBom(bom);

                        // 查询产品 BOM 信息（返回整表对象）
                        if (bom.getBomId() != null) {
                            ProductBom productBomParam = new ProductBom();
                            productBomParam.setId(bom.getBomId());
                            ProductBom productBom = jdbcClient.getJdbcModelById(productBomParam, connection);
                            if (productBom != null) {
                                vo.setProductBom(productBom);
                            }
                        }
                    }
                }
                
                // 查询并设置派工人员列表
                DispatchUserItem userItemParam = new DispatchUserItem();
                userItemParam.setDispatchId(model.getId());
                List<DispatchUserItem> userItems = jdbcClient.getJdbcList(userItemParam, connection);
                if (userItems != null && !userItems.isEmpty()) {
                    List<ProductOrderDispatchVO.SimpleDispatchUserItem> simpleUserItems = new ArrayList<>();
                    for (DispatchUserItem item : userItems) {
                        ProductOrderDispatchVO.SimpleDispatchUserItem simpleItem = new ProductOrderDispatchVO.SimpleDispatchUserItem();
                        simpleItem.setId(item.getId());
                        simpleItem.setUserId(item.getUserId());
                        simpleItem.setStatus(item.getStatus());
                        simpleItem.setIsReport(item.getIsReport());
                        simpleItem.setIsReview(item.getIsReview());
                        
                        // 查询用户信息
                        if (item.getUserId() != null) {
                            SysUser userParam = new SysUser();
                            userParam.setId(item.getUserId());
                            SysUser user = jdbcClient.getJdbcModelById(userParam, connection);
                            if (user != null) {
                                ProductOrderDispatchVO.SimpleUser simpleUser = new ProductOrderDispatchVO.SimpleUser();
                                simpleUser.setId(user.getId());
                                simpleUser.setUsername(user.getUsername());
                                simpleUser.setNickName(user.getNickName());
                                simpleItem.setUser(simpleUser);
                            }
                        }
                        
                        simpleUserItems.add(simpleItem);
                    }
                    vo.setUserItems(simpleUserItems);
                }
                
                voList.add(vo);
            }
            
            // 批量查询所有派工单的领料单状态并设置领料状态
            if (!voList.isEmpty()) {
                calculateRequisitionStatus(voList, connection);
            }
            
            // 替换 records
            result.put("records", voList);
            return result;
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @Override
    public String dispatch(DispatchVO vo) throws Exception {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BizException("用户未登录");
        }

        Connection connection = dataSource.getConnection();
        connection.setAutoCommit(false);
        try {
            // 1. 校验工单是否存在
            ProductOrder orderParam = new ProductOrder();
            orderParam.setId(vo.getOrderId());
            ProductOrder order = jdbcClient.getJdbcModelById(orderParam, connection);
            if (order == null) {
                throw new BizException("工单不存在");
            }

            // 2. 获取租户ID
            String tenantId = order.getTenantId();

            // 3. 按明细处理：新增 / 修改 / 删除
            if (vo.getItems() != null && !vo.getItems().isEmpty()) {
                for (DispatchVO.DispatchItem item : vo.getItems()) {
                    boolean hasId = item.getId() != null && !item.getId().trim().isEmpty();
                    boolean deleteOnly = hasId
                            && (item.getBomId() == null || item.getBomId().trim().isEmpty())
                            && (item.getStageId() == null || item.getStageId().trim().isEmpty())
                            && (item.getUserIds() == null || item.getUserIds().isEmpty())
                            && item.getOrderNum() == null
                            && item.getProcessNum() == null
                            && item.getProcessTimeHour() == null
                            && item.getReadyTimeHour() == null
                            && item.getMoveNum() == null
                            && item.getMoveTimeHour() == null
                            && (item.getBeginDate() == null || item.getBeginDate().trim().isEmpty())
                            && (item.getEndDate() == null || item.getEndDate().trim().isEmpty());

                    // 删除：仅传派工id
                    if (deleteOnly) {
                        ProductOrderDispatch deleteParam = new ProductOrderDispatch();
                        deleteParam.setId(item.getId());
                        ProductOrderDispatch existDispatch = jdbcClient.getJdbcModelById(deleteParam, connection);
                        if (existDispatch == null) {
                            throw new BizException("派工记录不存在: " + item.getId());
                        }
                        if (!vo.getOrderId().equals(existDispatch.getOrderId())) {
                            throw new BizException("派工记录与工单不匹配: " + item.getId());
                        }

                        // 先删派工人员子表
                        DispatchUserItem removeUserItemParam = new DispatchUserItem();
                        removeUserItemParam.setDispatchId(item.getId());
                        jdbcClient.jdbcRemove(removeUserItemParam, connection);

                        // 删除关联领料单明细与主单（按 dispatch_id 关联）
                        MaterialRequisition requisitionQuery = new MaterialRequisition();
                        requisitionQuery.setDispatchId(item.getId());
                        List<MaterialRequisition> requisitionList = jdbcClient.getJdbcList(requisitionQuery, connection);
                        if (requisitionList != null && !requisitionList.isEmpty()) {
                            for (MaterialRequisition requisition : requisitionList) {
                                if (requisition.getId() == null || requisition.getId().trim().isEmpty()) {
                                    continue;
                                }

                                MaterialRequisitionItem requisitionItemParam = new MaterialRequisitionItem();
                                requisitionItemParam.setRequisitionId(requisition.getId());
                                jdbcClient.jdbcRemove(requisitionItemParam, connection);

                                MaterialRequisition removeRequisitionParam = new MaterialRequisition();
                                removeRequisitionParam.setId(requisition.getId());
                                jdbcClient.jdbcRemoveById(removeRequisitionParam, connection);
                            }
                        }

                        // 再删派工主表
                        ProductOrderDispatch removeDispatchParam = new ProductOrderDispatch();
                        removeDispatchParam.setId(item.getId());
                        jdbcClient.jdbcRemoveById(removeDispatchParam, connection);
                        continue;
                    }

                    // 新增/修改都需要完整基础字段
                    if (item.getBomId() == null || item.getBomId().trim().isEmpty()) {
                        throw new BizException("bomId 不能为空");
                    }
                    if (item.getStageId() == null || item.getStageId().trim().isEmpty()) {
                        throw new BizException("工序不能为空");
                    }
                    if (item.getUserIds() == null || item.getUserIds().isEmpty()) {
                        throw new BizException("派工人员不能为空");
                    }

                    // 校验 BOM 是否存在于工单中，并获取 routeId
                    ProductOrderBom bomQueryParam = new ProductOrderBom();
                    bomQueryParam.setOrderId(vo.getOrderId());
                    bomQueryParam.setBomId(item.getBomId());
                    List<ProductOrderBom> bomList = jdbcClient.getJdbcList(bomQueryParam, connection);
                    
                    if (bomList == null || bomList.isEmpty()) {
                        throw new BizException("工单中不存在该BOM: " + item.getBomId());
                    }
                    
                    ProductOrderBom bom = bomList.get(0);
                    String routeId = bom.getRouteId();
                    if (routeId == null || routeId.isEmpty()) {
                        throw new BizException("BOM 未关联工艺路线: " + item.getBomId());
                    }

                    // 校验工序是否存在
                    ProcessStage stageParam = new ProcessStage();
                    stageParam.setId(item.getStageId());
                    ProcessStage stage = jdbcClient.getJdbcModelById(stageParam, connection);
                    if (stage == null) {
                        throw new BizException("工序不存在: " + item.getStageId());
                    }

                    if (hasId) {
                        // 修改：传派工id + 修改字段
                        ProductOrderDispatch updateParam = new ProductOrderDispatch();
                        updateParam.setId(item.getId());
                        ProductOrderDispatch existDispatch = jdbcClient.getJdbcModelById(updateParam, connection);
                        if (existDispatch == null) {
                            throw new BizException("派工记录不存在: " + item.getId());
                        }
                        if (!vo.getOrderId().equals(existDispatch.getOrderId())) {
                            throw new BizException("派工记录与工单不匹配: " + item.getId());
                        }

                        existDispatch.setCode(item.getCode());
                        existDispatch.setName(item.getName());
                        existDispatch.setRouteId(routeId);
                        existDispatch.setBomId(item.getBomId());
                        existDispatch.setStageId(item.getStageId());
                        existDispatch.setOrderNum(item.getOrderNum());
                        existDispatch.setProcessNum(item.getProcessNum());
                        existDispatch.setProcessTimeHour(item.getProcessTimeHour());
                        existDispatch.setReadyTimeHour(item.getReadyTimeHour());
                        existDispatch.setMoveNum(item.getMoveNum());
                        existDispatch.setMoveTimeHour(item.getMoveTimeHour());
                        existDispatch.setIsInspection(item.getIsInspection() != null ? item.getIsInspection() : false);
                        existDispatch.setBeginDate(item.getBeginDate());
                        existDispatch.setEndDate(item.getEndDate());
                        jdbcClient.jdbcUpdateById(existDispatch, connection);

                        // 子表先删后插，确保人员同步
                        DispatchUserItem removeUserItemParam = new DispatchUserItem();
                        removeUserItemParam.setDispatchId(item.getId());
                        jdbcClient.jdbcRemove(removeUserItemParam, connection);

                        for (Long userIdItem : item.getUserIds()) {
                            DispatchUserItem userItem = new DispatchUserItem();
                            userItem.setDispatchId(existDispatch.getId());
                            userItem.setOrderId(vo.getOrderId());
                            userItem.setUserId(userIdItem);
                            userItem.setRouteId(routeId);
                            userItem.setBomId(item.getBomId());
                            userItem.setStageId(item.getStageId());
                            userItem.setOrderNum(item.getOrderNum());
                            userItem.setProcessNum(item.getProcessNum());
                            userItem.setProcessTimeHour(item.getProcessTimeHour());
                            userItem.setReadyTimeHour(item.getReadyTimeHour());
                            userItem.setMoveNum(item.getMoveNum());
                            userItem.setMoveTimeHour(item.getMoveTimeHour());
                            userItem.setBeginDate(item.getBeginDate());
                            userItem.setEndDate(item.getEndDate());
                            userItem.setStatus(existDispatch.getStatus());
                            userItem.setIsReport(false);
                            userItem.setIsReview(false);
                            userItem.setIsRound(false);
                            userItem.setTenantId(tenantId);
                            userItem.setCreateId(userId);
                            userItem.setCreateTime(LocalDateTime.now().format(FORMATTER));
                            jdbcClient.jdbcInsert(userItem, connection);
                        }
                    } else {
                        // 新增：不传派工id
                        ProductOrderDispatch dispatch = new ProductOrderDispatch();
                        dispatch.setOrderId(vo.getOrderId());
                        dispatch.setTenantId(tenantId);
                        String dispatchCode = flowNoService.generateProductOrderDispatchCode(dispatch, connection);
                        dispatch.setCode((item.getCode() != null && !item.getCode().trim().isEmpty()) ? item.getCode() : dispatchCode);
                        dispatch.setName(item.getName());
                        dispatch.setRouteId(routeId);
                        dispatch.setBomId(item.getBomId());
                        dispatch.setStageId(item.getStageId());
                        dispatch.setOrderNum(item.getOrderNum());
                        dispatch.setProcessNum(item.getProcessNum());
                        dispatch.setProcessTimeHour(item.getProcessTimeHour());
                        dispatch.setReadyTimeHour(item.getReadyTimeHour());
                        dispatch.setMoveNum(item.getMoveNum());
                        dispatch.setMoveTimeHour(item.getMoveTimeHour());
                        dispatch.setIsInspection(item.getIsInspection() != null ? item.getIsInspection() : false);
                        dispatch.setBeginDate(item.getBeginDate());
                        dispatch.setEndDate(item.getEndDate());
                        dispatch.setStatus(MESEnum.PRODUCT_ORDER_DISPATCH_OF_STATUS_PENDING.getValue());
                        dispatch.setIsReport(false);
                        dispatch.setIsReview(false);
                        dispatch.setIsRound(false);
                        dispatch.setTenantId(tenantId);
                        dispatch.setCreateId(userId);
                        dispatch.setCreateTime(LocalDateTime.now().format(FORMATTER));

                        jdbcClient.jdbcInsert(dispatch, connection);

                        // 生成领料单（如果是首道工序）
                        materialRequisitionService.generateRequisition(dispatch, connection);

                        for (Long userIdItem : item.getUserIds()) {
                            DispatchUserItem userItem = new DispatchUserItem();
                            userItem.setDispatchId(dispatch.getId());
                            userItem.setOrderId(vo.getOrderId());
                            userItem.setUserId(userIdItem);
                            userItem.setRouteId(routeId);
                            userItem.setBomId(item.getBomId());
                            userItem.setStageId(item.getStageId());
                            userItem.setOrderNum(item.getOrderNum());
                            userItem.setProcessNum(item.getProcessNum());
                            userItem.setProcessTimeHour(item.getProcessTimeHour());
                            userItem.setReadyTimeHour(item.getReadyTimeHour());
                            userItem.setMoveNum(item.getMoveNum());
                            userItem.setMoveTimeHour(item.getMoveTimeHour());
                            userItem.setBeginDate(item.getBeginDate());
                            userItem.setEndDate(item.getEndDate());
                            userItem.setStatus(MESEnum.PRODUCT_ORDER_DISPATCH_OF_STATUS_PENDING.getValue());
                            userItem.setIsReport(false);
                            userItem.setIsReview(false);
                            userItem.setIsRound(false);
                            userItem.setTenantId(tenantId);
                            userItem.setCreateId(userId);
                            userItem.setCreateTime(LocalDateTime.now().format(FORMATTER));
                            jdbcClient.jdbcInsert(userItem, connection);
                        }
                    }
                }
            }

            // 4. 更新工单状态为进行中（如果当前是待进行状态）
            if (MESEnum.PRODUCT_ORDER_OF_STATUS_PENDING.getValue().equals(order.getStatus())) {
                order.setStatus(MESEnum.PRODUCT_ORDER_OF_STATUS_PROCESSING.getValue());
                jdbcClient.jdbcUpdateById(order, connection);
            }

            connection.commit();
            return "派工处理成功";
        } catch (Exception e) {
            connection.rollback();
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @Override
    public List<Map<String, Object>> getDispatchSummary(String orderId) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            // 1. 查询该工单的所有派工记录（从主表 product_order_dispatch）
            ProductOrderDispatch dispatchParam = new ProductOrderDispatch();
            dispatchParam.setOrderId(orderId);
            List<ProductOrderDispatch> dispatchList = jdbcClient.getJdbcList(dispatchParam, connection);
            
            // 2. 组装派工记录列表
            List<Map<String, Object>> dispatches = new ArrayList<>();
            
            if (dispatchList != null) {
                for (ProductOrderDispatch dispatch : dispatchList) {
                    Map<String, Object> dispatchInfo = new HashMap<>();
                    
                    // 基本字段
                    dispatchInfo.put("id", dispatch.getId());
                    dispatchInfo.put("code", dispatch.getCode());
                    dispatchInfo.put("orderId", dispatch.getOrderId());
                    dispatchInfo.put("bomId", dispatch.getBomId());
                    dispatchInfo.put("stageId", dispatch.getStageId());
                    dispatchInfo.put("routeId", dispatch.getRouteId());
                    dispatchInfo.put("orderNum", dispatch.getOrderNum());
                    dispatchInfo.put("processNum", dispatch.getProcessNum());
                    dispatchInfo.put("processTimeHour", dispatch.getProcessTimeHour());
                    dispatchInfo.put("readyTimeHour", dispatch.getReadyTimeHour());
                    dispatchInfo.put("moveNum", dispatch.getMoveNum());
                    dispatchInfo.put("moveTimeHour", dispatch.getMoveTimeHour());
                    dispatchInfo.put("status", dispatch.getStatus());
                    dispatchInfo.put("isReport", dispatch.getIsReport());
                    dispatchInfo.put("isReview", dispatch.getIsReview());
                    dispatchInfo.put("isRound", dispatch.getIsRound());
                    dispatchInfo.put("isInspection", dispatch.getIsInspection());
                    dispatchInfo.put("beginDate", dispatch.getBeginDate());
                    dispatchInfo.put("endDate", dispatch.getEndDate());
                    dispatchInfo.put("createTime", dispatch.getCreateTime());
                    
                    // 3. 查询关联的用户信息（从子表 dispatch_user_item）
                    DispatchUserItem userItemParam = new DispatchUserItem();
                    userItemParam.setDispatchId(dispatch.getId());
                    List<DispatchUserItem> userItems = jdbcClient.getJdbcList(userItemParam, connection);
                    
                    List<Map<String, Object>> users = new ArrayList<>();
                    if (userItems != null) {
                        for (DispatchUserItem userItem : userItems) {
                            SysUser userParam = new SysUser();
                            userParam.setId(userItem.getUserId());
                            SysUser user = jdbcClient.getJdbcModelById(userParam, connection);
                            
                            Map<String, Object> userInfo = new HashMap<>();
                            userInfo.put("userId", userItem.getUserId());
                            userInfo.put("userName", user != null ? user.getUsername() : "");
                            users.add(userInfo);
                        }
                    }
                    
                    dispatchInfo.put("users", users);
                    dispatches.add(dispatchInfo);
                }
            }
            
            return dispatches;
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }
    
    /**
     * 批量计算派工单的领料状态（基于领料单出库状态）
     * 
     * 业务逻辑说明：
     * 1. 只有首道工序需要关心领料状态（原材料是否领取）
     * 2. 非首道工序的"料"来自上一道工序的产出，不需要关心原材料领料
     * 3. 非首道工序应该关心上一道工序的报工状态（另外的字段）
     * 
     * @param voList 派工单VO列表
     * @param connection 数据库连接
     */
    private void calculateRequisitionStatus(List<ProductOrderDispatchVO> voList, Connection connection) throws Exception {
        // 缓存：工单ID+BOM ID → 领料单列表
        Map<String, List<MaterialRequisition>> orderBomRequisitionMap = new HashMap<>();
        
        // 收集所有首道工序的查询条件
        for (ProductOrderDispatchVO vo : voList) {
            if (vo.getId() == null) {
                continue;
            }
            
            // 判断是否为首道工序
            boolean isFirstStage = isFirstStage(vo, connection);
            
            if (isFirstStage) {
                // 只有首道工序才查询领料单
                if (vo.getOrderId() != null && vo.getBomId() != null) {
                    String key = vo.getOrderId() + "_" + vo.getBomId();
                    if (!orderBomRequisitionMap.containsKey(key)) {
                        MaterialRequisition requisitionQuery = new MaterialRequisition();
                        requisitionQuery.setOrderId(vo.getOrderId());
                        requisitionQuery.setBomId(vo.getBomId());
                        List<MaterialRequisition> requisitions = jdbcClient.getJdbcList(requisitionQuery, connection);
                        orderBomRequisitionMap.put(key, requisitions != null ? requisitions : new ArrayList<>());
                    }
                }
            }
        }
        
        // 为每个派工单计算领料状态
        for (ProductOrderDispatchVO vo : voList) {
            if (vo.getId() == null) {
                vo.setRequisitionStatus(null);  // 无效派工单，不显示状态
                continue;
            }
            
            // 判断是否为首道工序
            boolean isFirstStage = isFirstStage(vo, connection);
            
            if (isFirstStage) {
                // 首道工序：显示领料状态
                String key = vo.getOrderId() + "_" + vo.getBomId();
                List<MaterialRequisition> requisitions = orderBomRequisitionMap.get(key);
                
                // 计算领料状态
                String requisitionStatus = calculateRequisitionStatusByRequisitions(requisitions);
                vo.setRequisitionStatus(requisitionStatus);
                
                // 设置领料单信息
                if (requisitions != null && !requisitions.isEmpty()) {
                    List<ProductOrderDispatchVO.SimpleMaterialRequisition> simpleRequisitions = new ArrayList<>();
                    for (MaterialRequisition req : requisitions) {
                        ProductOrderDispatchVO.SimpleMaterialRequisition simpleReq = 
                            new ProductOrderDispatchVO.SimpleMaterialRequisition();
                        simpleReq.setId(req.getId());
                        simpleReq.setCode(req.getCode());
                        simpleReq.setName(req.getName());
                        simpleReq.setDispatchId(req.getDispatchId());
                        simpleReq.setOrderId(req.getOrderId());
                        simpleReq.setBomId(req.getBomId());
                        simpleReq.setRequisitionType(req.getRequisitionType());
                        simpleReq.setOutboundStatus(req.getOutboundStatus());
                        simpleReq.setStatus(req.getStatus());
                        simpleReq.setRequisitionDate(req.getRequisitionDate());
                        simpleReq.setReceiverId(req.getReceiverId());
                        simpleReq.setRemark(req.getRemark());
                        simpleReq.setTenantId(req.getTenantId());
                        simpleReq.setCreateId(req.getCreateId());
                        simpleReq.setCreateTime(req.getCreateTime());
                        simpleReq.setUpdateId(req.getUpdateId());
                        simpleReq.setUpdateTime(req.getUpdateTime());
                        simpleRequisitions.add(simpleReq);
                    }
                    vo.setMaterialRequisitions(simpleRequisitions);
                }
            } else {
                // 非首道工序：不显示领料状态（前端可以判断 null 不显示该字段）
                vo.setRequisitionStatus(null);
                vo.setMaterialRequisitions(null);
            }
        }
    }
    
    /**
     * 判断派工单是否为首道工序
     * 
     * @param vo 派工单VO
     * @param connection 数据库连接
     * @return true-首道工序，false-非首道工序
     */
    private boolean isFirstStage(ProductOrderDispatchVO vo, Connection connection) throws Exception {
        if (vo.getRouteId() == null || vo.getStageId() == null) {
            return false;
        }
        
        // 查询该工艺路线的所有工序
        ProcessRouteDetail allRouteQuery = new ProcessRouteDetail();
        allRouteQuery.setRouteId(vo.getRouteId());
        List<ProcessRouteDetail> allRouteDetails = jdbcClient.getJdbcList(allRouteQuery, connection);
        
        if (allRouteDetails == null || allRouteDetails.isEmpty()) {
            return false;
        }
        
        // 找出最小的 order_num
        Integer minOrderNum = allRouteDetails.stream()
            .map(ProcessRouteDetail::getOrderNum)
            .filter(num -> num != null)
            .min(Integer::compareTo)
            .orElse(null);
        
        if (minOrderNum == null) {
            return false;
        }
        
        // 查询当前派工的工序信息
        ProcessRouteDetail currentRouteQuery = new ProcessRouteDetail();
        currentRouteQuery.setRouteId(vo.getRouteId());
        currentRouteQuery.setStageId(vo.getStageId());
        List<ProcessRouteDetail> currentRouteDetails = jdbcClient.getJdbcList(currentRouteQuery, connection);
        
        if (currentRouteDetails == null || currentRouteDetails.isEmpty()) {
            return false;
        }
        
        ProcessRouteDetail currentRouteDetail = currentRouteDetails.get(0);
        return currentRouteDetail.getOrderNum() != null 
            && currentRouteDetail.getOrderNum().equals(minOrderNum);
    }
    
    /**
     * 根据领料单列表计算领料状态
     * 规则：
     * - applied/pending → 未领料
     * - partial → 部分领料
     * - completed → 已领料
     * - 混合状态 → 部分领料
     * 
     * @param requisitions 领料单列表
     * @return 领料状态
     */
    private String calculateRequisitionStatusByRequisitions(List<MaterialRequisition> requisitions) {
        // 没有领料单，返回"未领料"
        if (requisitions == null || requisitions.isEmpty()) {
            return MESEnum.DISPATCH_REQUISITION_STATUS_PENDING.getValue();
        }
        
        // 统计出库状态
        boolean hasCompleted = false;  // 出库完毕
        boolean hasPartial = false;    // 部分出库
        boolean hasAppliedOrPending = false;  // 申请完毕或未出库
        
        for (MaterialRequisition req : requisitions) {
            String status = req.getOutboundStatus();
            if (MESEnum.MATERIAL_REQUISITION_OUTBOUND_STATUS_COMPLETED.getValue().equals(status)) {
                hasCompleted = true;
            } else if (MESEnum.MATERIAL_REQUISITION_OUTBOUND_STATUS_PARTIAL.getValue().equals(status)) {
                hasPartial = true;
            } else if (MESEnum.MATERIAL_REQUISITION_OUTBOUND_STATUS_APPLIED.getValue().equals(status) 
                    || MESEnum.MATERIAL_REQUISITION_OUTBOUND_STATUS_PENDING.getValue().equals(status)) {
                hasAppliedOrPending = true;
            }
        }
        
        // 判断领料状态
        if (hasCompleted && !hasPartial && !hasAppliedOrPending) {
            // 全部出库完毕 → 已领料
            return MESEnum.DISPATCH_REQUISITION_STATUS_COMPLETE.getValue();
        } else if (hasAppliedOrPending && !hasPartial && !hasCompleted) {
            // 全部是申请完毕/未出库 → 未领料
            return MESEnum.DISPATCH_REQUISITION_STATUS_PENDING.getValue();
        } else {
            // 其他情况（有部分出库，或混合状态）→ 部分领料
            return MESEnum.DISPATCH_REQUISITION_STATUS_PARTIALLY.getValue();
        }
    }
}
