mes-processes/mes-plcSend/src/main/java/com/mes/interaction/vehicle/handler/LoadVehicleLogicHandler.java
@@ -15,9 +15,8 @@
import com.mes.interaction.vehicle.model.VehicleState;
import com.mes.interaction.vehicle.model.VehicleStatus;
import com.mes.interaction.vehicle.model.VehicleTask;
import com.mes.s7.enhanced.EnhancedS7Serializer;
import com.mes.s7.provider.S7SerializerProvider;
import com.mes.service.PlcDynamicDataService;
import com.mes.plc.client.PlcClient;
import com.mes.plc.factory.PlcClientFactory;
import com.mes.task.model.TaskExecutionContext;
import com.mes.interaction.workstation.scanner.handler.HorizontalScannerLogicHandler;
import lombok.extern.slf4j.Slf4j;
@@ -28,6 +27,7 @@
import javax.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
 * 大车设备逻辑处理器
@@ -56,10 +56,7 @@
    private DeviceStatusService deviceStatusService;
    
    @Autowired(required = false)
    private PlcDynamicDataService plcDynamicDataService;
    @Autowired(required = false)
    private S7SerializerProvider s7SerializerProvider;
    private PlcClientFactory plcClientFactory;
    // MES字段列表(进片和出片共用同一套协议)
    // 根据协议,使用带数字后缀的字段名(1-6对应6个玻璃位置)
@@ -120,9 +117,13 @@
    @Autowired
    public LoadVehicleLogicHandler(
            DevicePlcOperationService devicePlcOperationService,
            @Qualifier("deviceGlassInfoService") GlassInfoService glassInfoService) {
            @Qualifier("deviceGlassInfoService") GlassInfoService glassInfoService,
            PlcClientFactory plcClientFactory) {
        super(devicePlcOperationService);
        this.glassInfoService = glassInfoService;
        this.plcClientFactory = plcClientFactory;
        // 设置 PlcClientFactory 到基类
        this.setPlcClientFactory(plcClientFactory);
    }
    @Override
@@ -137,7 +138,7 @@
            Map<String, Object> params,
            Map<String, Object> logicParams) {
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        log.info("执行大车设备操作: deviceId={}, deviceName={}, operation={}", 
            deviceId, deviceConfig.getDeviceName(), operation);
@@ -288,7 +289,7 @@
            Map<String, Object> logicParams) {
        
        VehicleTask task = new VehicleTask();
        task.setTaskId(generateTaskId(deviceConfig.getDeviceId()));
        task.setTaskId(generateTaskId(String.valueOf(deviceConfig.getId())));
        task.setTaskName("大车设备-" + operation);
        task.setOperation(operation);
        
@@ -364,7 +365,7 @@
        Boolean triggerRequest = (Boolean) params.getOrDefault("triggerRequest", autoFeed);
        List<GlassInfo> plannedGlasses = planGlassLoading(glassInfos, vehicleCapacity, glassGap,
                deviceConfig.getDeviceId());
                String.valueOf(deviceConfig.getId()));
        if (plannedGlasses == null) {
            // 玻璃没有长度时返回null表示错误
            return DevicePlcVO.OperationResult.builder()
@@ -436,7 +437,7 @@
        // 如果执行成功,更新位置信息到状态
        if (Boolean.TRUE.equals(result.getSuccess())) {
            VehicleStatus status = statusManager.getOrCreateVehicleStatus(
                deviceConfig.getDeviceId(), deviceConfig.getDeviceName());
                String.valueOf(deviceConfig.getId()), deviceConfig.getDeviceName());
            if (positionCode != null || positionValue != null) {
                VehiclePosition position = new VehiclePosition(positionCode, positionValue);
                status.setCurrentPosition(position);
@@ -521,15 +522,15 @@
        
        // 重置时,清除任务并恢复为空闲状态,停止监控
        if (Boolean.TRUE.equals(result.getSuccess())) {
            statusManager.clearVehicleTask(deviceConfig.getDeviceId());
            statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.IDLE);
            stopStateMonitoring(deviceConfig.getDeviceId());
            statusManager.clearVehicleTask(String.valueOf(deviceConfig.getId()));
            statusManager.updateVehicleStatus(String.valueOf(deviceConfig.getId()), VehicleState.IDLE);
            stopStateMonitoring(String.valueOf(deviceConfig.getId()));
            handleStopTaskMonitor(deviceConfig);
            handleStopIdleMonitor(deviceConfig);
            updateDeviceOnlineStatus(deviceConfig, true);
        } else {
            // 即便重置失败,也尝试停止内部监控,避免任务取消后仍然反复写PLC
            stopStateMonitoring(deviceConfig.getDeviceId());
            stopStateMonitoring(String.valueOf(deviceConfig.getId()));
            handleStopTaskMonitor(deviceConfig);
            handleStopIdleMonitor(deviceConfig);
        }
@@ -636,15 +637,15 @@
        
        // 清空后,恢复为空闲状态,停止监控
        if (Boolean.TRUE.equals(result.getSuccess())) {
            statusManager.clearVehicleTask(deviceConfig.getDeviceId());
            statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.IDLE);
            stopStateMonitoring(deviceConfig.getDeviceId());
            statusManager.clearVehicleTask(String.valueOf(deviceConfig.getId()));
            statusManager.updateVehicleStatus(String.valueOf(deviceConfig.getId()), VehicleState.IDLE);
            stopStateMonitoring(String.valueOf(deviceConfig.getId()));
            handleStopTaskMonitor(deviceConfig);
            handleStopIdleMonitor(deviceConfig);
            updateDeviceOnlineStatus(deviceConfig, true);
        } else {
            // 写入失败也尝试停止监控,避免任务取消后仍旧运行
            stopStateMonitoring(deviceConfig.getDeviceId());
            stopStateMonitoring(String.valueOf(deviceConfig.getId()));
            handleStopTaskMonitor(deviceConfig);
            handleStopIdleMonitor(deviceConfig);
        }
@@ -661,7 +662,7 @@
            deviceStatusService.updateDeviceOnlineStatus(deviceConfig.getId(), status);
        } catch (Exception e) {
            log.warn("同步设备在线状态到数据库失败: deviceId={}, online={}, error={}",
                    deviceConfig.getDeviceId(), online, e.getMessage());
                    String.valueOf(deviceConfig.getId()), online, e.getMessage());
        }
    }
@@ -869,7 +870,7 @@
     * 定期检查大车的 state1~6,当检测到 state=1 时自动协调卧转立设备
     */
    private void startStateMonitoring(DeviceConfig deviceConfig, Map<String, Object> logicParams) {
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        
        // 如果已经在监控,先停止旧的监控任务
        stopStateMonitoring(deviceId);
@@ -940,7 +941,7 @@
     * 检查大车状态并协调卧转立设备(内部方法,由监控线程调用)
     */
    private void checkAndCoordinateState(DeviceConfig deviceConfig) {
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        List<String> alreadyCoordinated = coordinatedStates.get(deviceId);
        if (alreadyCoordinated == null) {
            alreadyCoordinated = new CopyOnWriteArrayList<>();
@@ -1228,7 +1229,7 @@
            Map<String, Object> params,
            Map<String, Object> logicParams) {
        
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        
        // 停止旧的监控任务
        handleStopIdleMonitor(deviceConfig);
@@ -1247,20 +1248,17 @@
                }
                
                // 检查是否有待处理的进片或出片任务
                if (plcDynamicDataService != null && s7SerializerProvider != null) {
                    EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
                    if (serializer != null) {
                        // 检查进片任务
                        Map<String, Object> mesData = plcDynamicDataService.readPlcData(
                                deviceConfig, MES_FIELDS, serializer);
                        Integer mesSend = parseInteger(mesData != null ? mesData.get("mesSend") : null);
                        // 进片和出片共用mesSend字段,只需检查一次
                        // 如果有待处理的任务,不设置plcRequest(等待任务处理)
                        if (mesSend != null && mesSend == 1) {
                            log.debug("大车空闲监控: deviceId={}, 检测到待处理任务(mesSend=1),不设置plcRequest", deviceId);
                            return;
                        }
                PlcClient plcClient = getPlcClient(deviceConfig);
                if (plcClient != null) {
                    // 检查进片任务
                    Map<String, Object> mesData = plcClient.readData(MES_FIELDS.toArray(new String[0]));
                    Integer mesSend = parseInteger(mesData != null ? mesData.get("mesSend") : null);
                    // 进片和出片共用mesSend字段,只需检查一次
                    // 如果有待处理的任务,不设置plcRequest(等待任务处理)
                    if (mesSend != null && mesSend == 1) {
                        log.debug("大车空闲监控: deviceId={}, 检测到待处理任务(mesSend=1),不设置plcRequest", deviceId);
                        return;
                    }
                }
                
@@ -1289,7 +1287,7 @@
     * 停止空闲监控
     */
    private DevicePlcVO.OperationResult handleStopIdleMonitor(DeviceConfig deviceConfig) {
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        ScheduledFuture<?> future = idleMonitoringTasks.remove(deviceId);
        if (future != null && !future.isCancelled()) {
            future.cancel(false);
@@ -1310,19 +1308,12 @@
            Map<String, Object> params,
            Map<String, Object> logicParams) {
        
        if (plcDynamicDataService == null || s7SerializerProvider == null) {
        String deviceId = String.valueOf(deviceConfig.getId());
        PlcClient plcClient = getPlcClient(deviceConfig);
        if (plcClient == null) {
            return DevicePlcVO.OperationResult.builder()
                    .success(false)
                    .message("PlcDynamicDataService或S7SerializerProvider未注入")
                    .build();
        }
        String deviceId = deviceConfig.getDeviceId();
        EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
        if (serializer == null) {
            return DevicePlcVO.OperationResult.builder()
                    .success(false)
                    .message("获取PLC序列化器失败")
                    .message("获取PLC客户端失败")
                    .build();
        }
        
@@ -1351,8 +1342,7 @@
            }
            
            // 读取MES字段(进片和出片共用)
            Map<String, Object> mesData = plcDynamicDataService.readPlcData(
                    deviceConfig, MES_FIELDS, serializer);
            Map<String, Object> mesData = plcClient.readData(MES_FIELDS.toArray(new String[0]));
            if (mesData == null || mesData.isEmpty()) {
                log.warn("读取MES字段失败: deviceId={}, mesData为空或null", deviceId);
                return DevicePlcVO.OperationResult.builder()
@@ -1517,8 +1507,8 @@
            // 如果有多设备任务上下文,则记录本次MES下发的玻璃ID列表到上下文,供分批校验使用
            if (params != null) {
                Object ctxObj = params.get("_taskContext");
                if (ctxObj instanceof com.mes.task.model.TaskExecutionContext) {
                    com.mes.task.model.TaskExecutionContext ctx = (com.mes.task.model.TaskExecutionContext) ctxObj;
                if (ctxObj instanceof TaskExecutionContext) {
                    TaskExecutionContext ctx = (TaskExecutionContext) ctxObj;
                    List<String> batchIds = new ArrayList<>();
                    for (GlassTaskInfo g : glasses) {
                        if (g != null && g.glassId != null && !g.glassId.isEmpty()) {
@@ -1550,7 +1540,7 @@
            // 清空plcRequest(表示已接收任务)
            Map<String, Object> payload = new HashMap<>();
            payload.put("plcRequest", 0);
            plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
            plcClient.writeData(payload);
            log.info("已清空plcRequest=0: deviceId={}", deviceId);
            
            // 更新车辆状态为执行中
@@ -1563,7 +1553,7 @@
            String taskType = isOutbound ? "出片" : "进片";
            String glassIds = glasses.stream()
                    .map(g -> g.glassId)
                    .collect(java.util.stream.Collectors.joining(","));
                    .collect(Collectors.joining(","));
            log.info("MES{}任务已创建: deviceId={}, glassCount={}, glassIds=[{}], 起始位置={}格, 目标位置={}格, 距离{}格->{}格, gotime={}ms({}秒), cartime={}ms({}秒)", 
                    taskType, deviceId, glasses.size(), glassIds,
                    firstGlass.startPosition, firstGlass.targetPosition,
@@ -1711,7 +1701,7 @@
     */
    private Integer getCurrentPosition(DeviceConfig deviceConfig, Map<String, Object> logicParams) {
        // 从状态管理器获取
        VehicleStatus status = statusManager.getVehicleStatus(deviceConfig.getDeviceId());
        VehicleStatus status = statusManager.getVehicleStatus(String.valueOf(deviceConfig.getId()));
        if (status != null && status.getCurrentPosition() != null) {
            return status.getCurrentPosition().getPositionValue();
        }
@@ -1802,7 +1792,7 @@
            Map<String, Object> params,
            Map<String, Object> logicParams) {
        
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        
        // 停止旧的监控任务
        handleStopTaskMonitor(deviceConfig);
@@ -1843,13 +1833,9 @@
                                      MesTaskInfo taskInfo,
                                      Map<String, Object> logicParams) {
        
        if (plcDynamicDataService == null || s7SerializerProvider == null) {
            return;
        }
        String deviceId = deviceConfig.getDeviceId();
        EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
        if (serializer == null) {
        String deviceId = String.valueOf(deviceConfig.getId());
        PlcClient plcClient = getPlcClient(deviceConfig);
        if (plcClient == null) {
            return;
        }
        
@@ -1899,24 +1885,24 @@
                // 优先检查是否标记为破损(state=8)
                // 检查任务信息中是否标记了该玻璃为破损
                if (taskInfo.brokenGlassIndices != null && taskInfo.brokenGlassIndices.contains(i)) {
                    updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 8, taskInfo);
                    updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 8, taskInfo);
                    log.info("玻璃标记为破损: deviceId={}, stateField={}, glassIndex={}", 
                            deviceConfig.getDeviceId(), stateField, i);
                            String.valueOf(deviceConfig.getId()), stateField, i);
                    continue;
                }
                
                // 检查超时未完成(state=3)
                if (elapsed >= state3TimeoutTime && (currentState == null || currentState < 2)) {
                    updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 3, taskInfo);
                    updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 3, taskInfo);
                    log.warn("任务超时未完成: deviceId={}, stateField={}, elapsed={}ms, expectedTime={}ms", 
                            deviceConfig.getDeviceId(), stateField, elapsed, state2Time);
                            String.valueOf(deviceConfig.getId()), stateField, elapsed, state2Time);
                    continue;
                }
                
                // 正常状态更新
                if (elapsed >= state1Time && elapsed < state2Time) {
                    // state应该为1(上车完成)
                    boolean stateChanged = updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 1, taskInfo);
                    boolean stateChanged = updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 1, taskInfo);
                    if (stateChanged) {
                        hasStateOne = true;
                        currentStepDesc = "玻璃已上车(state=1),正在运输到目标位置";
@@ -1925,7 +1911,7 @@
                    }
                } else if (elapsed >= state2Time) {
                    // state应该为2(运输完成)
                    boolean stateChanged = updateStateIfNeeded(deviceConfig, serializer, stateValues, stateField, 2, taskInfo);
                    boolean stateChanged = updateStateIfNeeded(deviceConfig, plcClient, stateValues, stateField, 2, taskInfo);
                    if (stateChanged) {
                        hasStateTwo = true;
                        currentStepDesc = "玻璃已到达目标位置(state=2),等待MES确认";
@@ -1949,7 +1935,7 @@
            
            // 检查是否所有state都>=2,如果是则给MES汇报
            if (elapsed >= state2Time && allStatesCompleted(stateValues, glassCount)) {
                reportToMes(deviceConfig, serializer, taskInfo, logicParams);
                reportToMes(deviceConfig, plcClient, taskInfo, logicParams);
                // 记录MES确认开始等待的时间(只记录一次)
                if (taskInfo.mesConfirmStartTime == null) {
                    taskInfo.mesConfirmStartTime = System.currentTimeMillis();
@@ -1972,7 +1958,7 @@
     * @return 是否发生了状态变化(从非目标状态变为目标状态)
     */
    private boolean updateStateIfNeeded(DeviceConfig deviceConfig,
                                     EnhancedS7Serializer serializer,
                                     PlcClient plcClient,
                                     Map<String, Object> currentStates,
                                     String stateField,
                                     int targetState,
@@ -1986,7 +1972,7 @@
        // 注意:如果当前state已经是3(未完成)或8(破损),不再更新
        if (currentState != null && (currentState == 3 || currentState == 8)) {
            log.debug("任务状态已为异常状态,不再更新: deviceId={}, stateField={}, currentState={}, targetState={}", 
                    deviceConfig.getDeviceId(), stateField, currentState, targetState);
                    String.valueOf(deviceConfig.getId()), stateField, currentState, targetState);
            return false;
        }
        
@@ -1995,15 +1981,15 @@
            try {
                Map<String, Object> payload = new HashMap<>();
                payload.put(stateField, targetState);
                plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
                plcClient.writeData(payload);
                
                log.info("任务状态已更新到PLC: deviceId={}, stateField={}, currentState={}, targetState={}", 
                        deviceConfig.getDeviceId(), stateField, currentState, targetState);
                        String.valueOf(deviceConfig.getId()), stateField, currentState, targetState);
                // 返回true表示状态发生了变化
                return true;
            } catch (Exception e) {
                log.error("写入PLC state字段失败: deviceId={}, stateField={}, targetState={}, error={}", 
                        deviceConfig.getDeviceId(), stateField, targetState, e.getMessage());
                        String.valueOf(deviceConfig.getId()), stateField, targetState, e.getMessage());
                return false;
            }
        }
@@ -2066,7 +2052,7 @@
     * 给MES汇报
     */
    private void reportToMes(DeviceConfig deviceConfig,
                             EnhancedS7Serializer serializer,
                             PlcClient plcClient,
                             MesTaskInfo taskInfo,
                             Map<String, Object> logicParams) {
        
@@ -2074,18 +2060,18 @@
            // 设置汇报字
            Map<String, Object> payload = new HashMap<>();
            payload.put("plcReport", 1);
            plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
            plcClient.writeData(payload);
            
            String taskType = taskInfo.isOutbound ? "出片" : "进片";
            String glassIds = taskInfo.glasses.stream()
                    .map(g -> g.glassId)
                    .collect(java.util.stream.Collectors.joining(","));
            log.info("已给MES汇报({}任务): deviceId={}, glassCount={}, glassIds=[{}]", 
                    taskType, deviceConfig.getDeviceId(), taskInfo.glasses.size(), glassIds);
                    taskType, String.valueOf(deviceConfig.getId()), taskInfo.glasses.size(), glassIds);
            
            // 多设备任务场景下,不在这里阻塞等待MES确认,由任务引擎定时调用checkMesConfirm
        } catch (Exception e) {
            log.error("给MES汇报异常: deviceId={}", deviceConfig.getDeviceId(), e);
            log.error("给MES汇报异常: deviceId={}", String.valueOf(deviceConfig.getId()), e);
        }
    }
@@ -2096,21 +2082,14 @@
    public DevicePlcVO.OperationResult checkMesConfirm(DeviceConfig deviceConfig,
                                                       Map<String, Object> params,
                                                       Map<String, Object> logicParams) {
        if (plcDynamicDataService == null || s7SerializerProvider == null) {
        String deviceId = String.valueOf(deviceConfig.getId());
        PlcClient plcClient = getPlcClient(deviceConfig);
        if (plcClient == null) {
            return DevicePlcVO.OperationResult.builder()
                    .success(false)
                    .message("PlcDynamicDataService或S7SerializerProvider未注入")
                    .message("获取PLC客户端失败")
                    .build();
        }
        EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
        if (serializer == null) {
            return DevicePlcVO.OperationResult.builder()
                    .success(false)
                    .message("获取PLC序列化器失败")
                    .build();
        }
        String deviceId = deviceConfig.getDeviceId();
        MesTaskInfo taskInfo = currentTasks.get(deviceId);
        
        // 如果没有任务记录,优先尝试补偿性地检查一次MES任务(避免因时序问题一直noTask)
@@ -2184,13 +2163,13 @@
                // 超时视为任务失败:清理任务状态并停止监控,避免继续累加等待时间
                try {
                    clearTaskStates(deviceConfig, serializer);
                    clearTaskStates(deviceConfig, plcClient);
                } catch (Exception e) {
                    log.warn("MES确认超时时清空任务状态失败: deviceId={}, error={}", deviceId, e.getMessage());
                }
                statusManager.updateVehicleStatus(deviceConfig.getDeviceId(), VehicleState.ERROR);
                statusManager.clearVehicleTask(deviceConfig.getDeviceId());
                currentTasks.remove(deviceConfig.getDeviceId());
                statusManager.updateVehicleStatus(String.valueOf(deviceConfig.getId()), VehicleState.ERROR);
                statusManager.clearVehicleTask(String.valueOf(deviceConfig.getId()));
                currentTasks.remove(String.valueOf(deviceConfig.getId()));
                handleStopTaskMonitor(deviceConfig);
                return DevicePlcVO.OperationResult.builder()
@@ -2200,15 +2179,14 @@
                        .build();
            }
            
            Object confirmValue = plcDynamicDataService.readPlcField(
                    deviceConfig, "mesConfirm", serializer);
            Integer confirm = parseInteger(confirmValue);
            Map<String, Object> confirmData = plcClient.readData("mesConfirm");
            Integer confirm = parseInteger(confirmData != null ? confirmData.get("mesConfirm") : null);
            boolean completed = confirm != null && confirm == 1;
            data.put("completed", completed);
            if (completed) {
                // MES已确认:本次交互完成(不在设备侧判断“是否还有更多玻璃”,由任务引擎统一编排)
                clearTaskStates(deviceConfig, serializer);
                // MES已确认:本次交互完成(不在设备侧判断"是否还有更多玻璃",由任务引擎统一编排)
                clearTaskStates(deviceConfig, plcClient);
                // 记录已完成的任务签名,避免MES未复位时被重复拉起
                if (taskInfo != null && taskInfo.mesSignature != null) {
@@ -2218,11 +2196,11 @@
                // 任务完成,恢复为空闲状态
                statusManager.updateVehicleStatus(
                        deviceConfig.getDeviceId(), VehicleState.IDLE);
                statusManager.clearVehicleTask(deviceConfig.getDeviceId());
                        String.valueOf(deviceConfig.getId()), VehicleState.IDLE);
                statusManager.clearVehicleTask(String.valueOf(deviceConfig.getId()));
                // 移除任务记录(如果有)
                currentTasks.remove(deviceConfig.getDeviceId());
                currentTasks.remove(String.valueOf(deviceConfig.getId()));
                // 停止任务监控
                handleStopTaskMonitor(deviceConfig);
@@ -2230,9 +2208,9 @@
                // 恢复plcRequest=1(可以接收新任务)
                Map<String, Object> payload = new HashMap<>();
                payload.put("plcRequest", 1);
                plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
                plcClient.writeData(payload);
                log.info("MES任务已确认完成: deviceId={}", deviceConfig.getDeviceId());
                log.info("MES任务已确认完成: deviceId={}", String.valueOf(deviceConfig.getId()));
                String taskType = (taskInfo != null && taskInfo.isOutbound) ? "出片" : "进片";
                return DevicePlcVO.OperationResult.builder()
                        .success(true)
@@ -2256,7 +2234,7 @@
                    .data(data)
                    .build();
        } catch (Exception e) {
            log.error("检查MES确认状态异常: deviceId={}", deviceConfig.getDeviceId(), e);
            log.error("检查MES确认状态异常: deviceId={}", String.valueOf(deviceConfig.getId()), e);
            return DevicePlcVO.OperationResult.builder()
                    .success(false)
                    .message("检查MES确认状态异常: " + e.getMessage())
@@ -2272,7 +2250,7 @@
    private DevicePlcVO.OperationResult handleMarkBroken(DeviceConfig deviceConfig,
                                                         Map<String, Object> params,
                                                         Map<String, Object> logicParams) {
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        MesTaskInfo taskInfo = currentTasks.get(deviceId);
        if (taskInfo == null) {
            return DevicePlcVO.OperationResult.builder()
@@ -2321,20 +2299,27 @@
        }
        
        // 立即写入PLC的state字段
        EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
        if (serializer != null) {
        PlcClient plcClient = getPlcClient(deviceConfig);
        if (plcClient != null) {
            try {
                Map<String, Object> payload = new HashMap<>();
                for (Integer index : brokenIndices) {
                    String stateField = "state" + (index + 1);
                    payload.put(stateField, 8);
                }
                plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
                log.info("已标记玻璃为破损并写入PLC: deviceId={}, brokenIndices={}",
                        deviceId, brokenIndices);
                boolean success = plcClient.writeData(payload);
                if (success) {
                    log.info("已标记玻璃为破损并写入PLC: deviceId={}, brokenIndices={}",
                            deviceId, brokenIndices);
                } else {
                    log.error("写入破损状态到PLC失败: deviceId={}, brokenIndices={}",
                            deviceId, brokenIndices);
                }
            } catch (Exception e) {
                log.error("写入破损状态到PLC失败: deviceId={}, error={}", deviceId, e.getMessage());
            }
        } else {
            log.error("获取PLC客户端失败,无法写入破损状态: deviceId={}", deviceId);
        }
        
        return DevicePlcVO.OperationResult.builder()
@@ -2346,7 +2331,7 @@
    /**
     * 清空任务状态
     */
    private void clearTaskStates(DeviceConfig deviceConfig, EnhancedS7Serializer serializer) {
    private void clearTaskStates(DeviceConfig deviceConfig, PlcClient plcClient) {
        try {
            Map<String, Object> payload = new HashMap<>();
            // 清空state1~6
@@ -2355,9 +2340,9 @@
            }
            // 清空汇报字
            payload.put("plcReport", 0);
            plcDynamicDataService.writePlcData(deviceConfig, payload, serializer);
            plcClient.writeData(payload);
        } catch (Exception e) {
            log.error("清空任务状态异常: deviceId={}", deviceConfig.getDeviceId(), e);
            log.error("清空任务状态异常: deviceId={}", String.valueOf(deviceConfig.getId()), e);
        }
    }
@@ -2365,7 +2350,7 @@
     * 停止任务监控
     */
    private DevicePlcVO.OperationResult handleStopTaskMonitor(DeviceConfig deviceConfig) {
        String deviceId = deviceConfig.getDeviceId();
        String deviceId = String.valueOf(deviceConfig.getId());
        ScheduledFuture<?> future = taskMonitoringTasks.remove(deviceId);
        if (future != null && !future.isCancelled()) {
            future.cancel(false);
@@ -2498,13 +2483,10 @@
    }
    private void clearDynamicTaskStates(DeviceConfig deviceConfig) {
        if (plcDynamicDataService == null || s7SerializerProvider == null) {
            return;
        }
        try {
            EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
            if (serializer != null) {
                clearTaskStates(deviceConfig, serializer);
            PlcClient plcClient = getPlcClient(deviceConfig);
            if (plcClient != null) {
                clearTaskStates(deviceConfig, plcClient);
            }
        } catch (Exception e) {
            log.warn("清空大车state字段失败: deviceId={}, error={}", deviceConfig != null ? deviceConfig.getId() : "null", e.getMessage());