using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OrpaonVision.Core.Results; using OrpaonVision.Core.ManualOverride; using OrpaonVision.SiteApp.Runtime.Contracts; using OrpaonVision.SiteApp.Runtime.Options; using System.Collections.Concurrent; namespace OrpaonVision.SiteApp.Runtime.Services; /// /// 高级运行时状态机服务。 /// public sealed class AdvancedRuntimeStateMachineService : IRuntimeStateMachineService, IDisposable { private readonly ILogger _logger; private readonly RuntimeOptions _options; private readonly IManualOverrideService _manualOverrideService; private readonly ConcurrentQueue _eventHistory; private readonly object _stateLock = new(); private RuntimeState _currentState; private int _currentLayer; private DateTime _lastTransitionTime; private bool _isPaused; private bool _isStopped; public AdvancedRuntimeStateMachineService( ILogger logger, IOptions options, IManualOverrideService manualOverrideService) { _logger = logger; _options = options.Value; _manualOverrideService = manualOverrideService; _eventHistory = new ConcurrentQueue(); Reset(); } /// public RuntimeStateSnapshotDto GetSnapshot() { lock (_stateLock) { return new RuntimeStateSnapshotDto { CurrentLayer = _currentLayer, TotalLayers = _options.TotalLayers, StateText = GetStateDescription(_currentState) }; } } /// public Result MoveToNextLayer() { lock (_stateLock) { try { _logger.LogDebug("尝试移动到下一层:当前层={CurrentLayer},总层数={TotalLayers}", _currentLayer, _options.TotalLayers); // 检查是否可以移动 if (!CanMoveToNextLayer()) { var reason = GetCannotMoveForwardReason(); _logger.LogWarning("无法移动到下一层:{Reason}", reason); return Result.Fail("CANNOT_MOVE_FORWARD", reason); } // 记录状态转换事件 var previousState = _currentState; var previousLayer = _currentLayer; // 执行状态转换 _currentLayer++; _currentState = RuntimeState.Running; _lastTransitionTime = DateTime.UtcNow; // 记录事件 var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.LayerForward, PreviousState = previousState, NewState = _currentState, PreviousLayer = previousLayer, NewLayer = _currentLayer, Timestamp = _lastTransitionTime, Reason = "用户请求移动到下一层" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("已移动到第 {CurrentLayer} 层,状态:{State}", _currentLayer, _currentState); // 检查是否完成所有层 if (_currentLayer >= _options.TotalLayers) { return CompleteProcess(); } return Result.Success("LAYER_MOVED_FORWARD", $"已移动到第 {_currentLayer} 层"); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "移动到下一层失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "MOVE_TO_NEXT_LAYER_FAILED", "移动到下一层失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } } /// public Result MoveToPreviousLayer() { lock (_stateLock) { try { _logger.LogDebug("尝试移动到上一层:当前层={CurrentLayer}", _currentLayer); // 检查是否可以移动 if (!CanMoveToPreviousLayer()) { var reason = GetCannotMoveBackwardReason(); _logger.LogWarning("无法移动到上一层:{Reason}", reason); return Result.Fail("CANNOT_MOVE_BACKWARD", reason); } // 记录状态转换事件 var previousState = _currentState; var previousLayer = _currentLayer; // 执行状态转换 _currentLayer--; _currentState = RuntimeState.Running; _lastTransitionTime = DateTime.UtcNow; // 记录事件 var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.LayerBackward, PreviousState = previousState, NewState = _currentState, PreviousLayer = previousLayer, NewLayer = _currentLayer, Timestamp = _lastTransitionTime, Reason = "用户请求移动到上一层" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("已移动到第 {CurrentLayer} 层,状态:{State}", _currentLayer, _currentState); return Result.Success("LAYER_MOVED_BACKWARD", $"已移动到第 {_currentLayer} 层"); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "移动到上一层失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "MOVE_TO_PREVIOUS_LAYER_FAILED", "移动到上一层失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } } /// public Result Pause() { lock (_stateLock) { try { _logger.LogDebug("尝试暂停状态机"); // 检查是否可以暂停 if (!CanPause()) { var reason = GetCannotPauseReason(); _logger.LogWarning("无法暂停:{Reason}", reason); return Result.Fail("CANNOT_PAUSE", reason); } // 记录状态转换事件 var previousState = _currentState; // 执行状态转换 _currentState = RuntimeState.Paused; _isPaused = true; _lastTransitionTime = DateTime.UtcNow; // 记录事件 var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.Pause, PreviousState = previousState, NewState = _currentState, PreviousLayer = _currentLayer, NewLayer = _currentLayer, Timestamp = _lastTransitionTime, Reason = "用户请求暂停" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("状态机已暂停,当前层:{CurrentLayer}", _currentLayer); return Result.Success("STATE_MACHINE_PAUSED", "状态机已暂停"); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "暂停状态机失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "PAUSE_STATE_MACHINE_FAILED", "暂停状态机失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } } /// public Result Resume() { lock (_stateLock) { try { _logger.LogDebug("尝试恢复状态机"); // 检查是否可以恢复 if (!CanResume()) { var reason = GetCannotResumeReason(); _logger.LogWarning("无法恢复:{Reason}", reason); return Result.Fail("CANNOT_RESUME", reason); } // 记录状态转换事件 var previousState = _currentState; // 执行状态转换 _currentState = RuntimeState.Running; _isPaused = false; _lastTransitionTime = DateTime.UtcNow; // 记录事件 var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.Resume, PreviousState = previousState, NewState = _currentState, PreviousLayer = _currentLayer, NewLayer = _currentLayer, Timestamp = _lastTransitionTime, Reason = "用户请求恢复" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("状态机已恢复,当前层:{CurrentLayer}", _currentLayer); return Result.Success("STATE_MACHINE_RESUMED", "状态机已恢复"); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "恢复状态机失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "RESUME_STATE_MACHINE_FAILED", "恢复状态机失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } } /// public Result Stop() { lock (_stateLock) { try { _logger.LogDebug("尝试停止状态机"); // 检查是否可以停止 if (!CanStop()) { var reason = GetCannotStopReason(); _logger.LogWarning("无法停止:{Reason}", reason); return Result.Fail("CANNOT_STOP", reason); } // 记录状态转换事件 var previousState = _currentState; // 执行状态转换 _currentState = RuntimeState.Stopped; _isStopped = true; _isPaused = false; _lastTransitionTime = DateTime.UtcNow; // 记录事件 var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.Stop, PreviousState = previousState, NewState = _currentState, PreviousLayer = _currentLayer, NewLayer = _currentLayer, Timestamp = _lastTransitionTime, Reason = "用户请求停止" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("状态机已停止,当前层:{CurrentLayer}", _currentLayer); return Result.Success("STATE_MACHINE_STOPPED", "状态机已停止"); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "停止状态机失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "STOP_STATE_MACHINE_FAILED", "停止状态机失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } } /// public void Reset() { lock (_stateLock) { try { _logger.LogInformation("重置状态机"); // 记录重置事件 var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.Reset, PreviousState = _currentState, NewState = RuntimeState.Idle, PreviousLayer = _currentLayer, NewLayer = 1, Timestamp = DateTime.UtcNow, Reason = "用户请求重置" }; _eventHistory.Enqueue(transitionEvent); // 重置状态 _currentState = RuntimeState.Idle; _currentLayer = 1; _lastTransitionTime = DateTime.UtcNow; _isPaused = false; _isStopped = false; _logger.LogInformation("状态机已重置"); } catch (Exception ex) { _logger.LogError(ex, "重置状态机失败"); } } } /// public Result> GetEventHistory(int maxCount = 100) { try { var events = _eventHistory.ToArray(); var recentEvents = events.Length > maxCount ? events[^maxCount..] : events; return Result>.Success(recentEvents.ToList(), message: $"获取到 {recentEvents.Length} 个历史事件"); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取事件历史失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_EVENT_HISTORY_FAILED", "获取事件历史失败", traceId); return Result>.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// /// 完成处理流程。 /// private Result CompleteProcess() { _currentState = RuntimeState.Completed; _lastTransitionTime = DateTime.UtcNow; // 记录完成事件 var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.Complete, PreviousState = RuntimeState.Running, NewState = _currentState, PreviousLayer = _currentLayer - 1, NewLayer = _currentLayer, Timestamp = _lastTransitionTime, Reason = "所有层处理完成" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("处理流程已完成,共处理 {TotalLayers} 层", _options.TotalLayers); return Result.Success("PROCESS_COMPLETED", $"所有 {_options.TotalLayers} 层处理完成"); } #region 新增守卫条件方法 private GuardResult CanInitialize() { return _currentState == RuntimeState.Uninitialized ? new GuardResult { IsAllowed = true, Reason = "可以从未初始化状态开始初始化" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许初始化" }; } private GuardResult CanStart() { return _currentState == RuntimeState.Idle ? new GuardResult { IsAllowed = true, Reason = "可以从空闲状态开始运行" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许开始运行" }; } private GuardResult CanAcceptProduct() { return _currentState == RuntimeState.Ready ? new GuardResult { IsAllowed = true, Reason = "就绪状态可以接受产品" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许接受产品" }; } private GuardResult CanStartLayerIdentification() { return _currentState == RuntimeState.WaitingProduct || _currentState == RuntimeState.Ready ? new GuardResult { IsAllowed = true, Reason = "可以开始层识别" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许开始层识别" }; } private GuardResult CanCompleteLayerIdentification() { return _currentState == RuntimeState.LayerIdentifying ? new GuardResult { IsAllowed = true, Reason = "可以完成层识别" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许完成层识别" }; } private GuardResult CanMoveToNextLayerGuard() { if (_currentState != RuntimeState.Running) return new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许移动到下一层" }; if (_currentLayer >= _options.TotalLayers) return new GuardResult { IsAllowed = false, Reason = "已到达最后一层" }; return new GuardResult { IsAllowed = true, Reason = "可以移动到下一层" }; } private GuardResult CanMoveToPreviousLayerGuard() { if (_currentState != RuntimeState.Running) return new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许移动到上一层" }; if (_currentLayer <= 1) return new GuardResult { IsAllowed = false, Reason = "已在第一层" }; return new GuardResult { IsAllowed = true, Reason = "可以移动到上一层" }; } private GuardResult CanPauseGuard() { return _currentState == RuntimeState.Running && !_isPaused && !_isStopped ? new GuardResult { IsAllowed = true, Reason = "运行状态可以暂停" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许暂停" }; } private GuardResult CanResumeGuard() { return _currentState == RuntimeState.Paused && _isPaused && !_isStopped ? new GuardResult { IsAllowed = true, Reason = "暂停状态可以恢复" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许恢复" }; } private GuardResult CanStopGuard() { return _currentState != RuntimeState.Stopped && _currentState != RuntimeState.Completed && _currentState != RuntimeState.ShuttingDown ? new GuardResult { IsAllowed = true, Reason = "可以停止" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许停止" }; } private GuardResult CanHandleNg() { return (_currentState == RuntimeState.Running || _currentState == RuntimeState.LayerIdentifying) && !_isStopped ? new GuardResult { IsAllowed = true, Reason = "可以处理NG检测" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许处理NG" }; } private GuardResult CanAcceptManualIntervention() { return (_currentState == RuntimeState.NgLocked || _currentState == RuntimeState.Faulted || _currentState == RuntimeState.Error) && !_isStopped ? new GuardResult { IsAllowed = true, Reason = "可以接受人工干预" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许人工干预" }; } private GuardResult CanCompleteManualIntervention() { return _currentState == RuntimeState.ManualIntervening ? new GuardResult { IsAllowed = true, Reason = "可以完成人工干预" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许完成人工干预" }; } private GuardResult CanHandleFault() { return _currentState != RuntimeState.ShuttingDown && _currentState != RuntimeState.Uninitialized ? new GuardResult { IsAllowed = true, Reason = "可以处理故障" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许处理故障" }; } private GuardResult CanRecoverFromFault() { return _currentState == RuntimeState.Faulted ? new GuardResult { IsAllowed = true, Reason = "可以从故障状态恢复" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许从故障恢复" }; } private GuardResult CanResetGuard() { return _currentState != RuntimeState.ShuttingDown && _currentState != RuntimeState.Uninitialized ? new GuardResult { IsAllowed = true, Reason = "可以重置" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许重置" }; } private GuardResult CanShutdown() { return _currentState != RuntimeState.ShuttingDown && _currentState != RuntimeState.Uninitialized ? new GuardResult { IsAllowed = true, Reason = "可以关闭" } : new GuardResult { IsAllowed = false, Reason = $"当前状态 {_currentState} 不允许关闭" }; } #endregion #region 人工干预闭环方法 /// /// 执行人工放行操作。 /// public async Task> ExecuteManualReleaseAsync(Guid sessionId, string operatorId, string? reason = null, CancellationToken cancellationToken = default) { try { _logger.LogInformation("开始执行人工放行操作:会话ID={SessionId},操作员={OperatorId}", sessionId, operatorId); // 1. 权限校验 var permissionResult = await _manualOverrideService.GetOverridePermissionAsync(sessionId, operatorId, cancellationToken); if (!permissionResult.IsSuccess || !permissionResult.Data?.HasPermission == true) { return Result.Fail("PERMISSION_DENIED", "人工放行权限校验失败"); } // 2. 构建人工干预请求 var overrideRequest = new ManualOverrideRequest { RequestId = Guid.NewGuid(), SessionId = sessionId, OperatorId = operatorId, OperatorName = operatorId, OverrideType = OverrideType.Release, TargetStatus = SessionStatus.Running, RequestTimeUtc = DateTime.UtcNow }; // 3. 条件验证 var validationResult = await _manualOverrideService.ValidateOverrideConditionsAsync(sessionId, overrideRequest, cancellationToken); if (!validationResult.IsSuccess || !validationResult.Data?.IsValid == true) { return Result.Fail("VALIDATION_FAILED", "人工放行条件验证失败"); } // 4. 执行状态迁移 var transitionResult = TriggerTransition(StateTrigger.ManualInterventionCompleted, reason ?? "人工放行", new { OperatorId = operatorId }); if (!transitionResult.IsSuccess) { return transitionResult; } // 5. 执行人工干预 var overrideResult = await _manualOverrideService.ExecuteManualOverrideAsync(overrideRequest, cancellationToken); if (!overrideResult.IsSuccess) { return Result.Fail("OVERRIDE_FAILED", "人工放行执行失败"); } // 6. 记录审计日志 await LogManualOverrideAuditAsync(sessionId, overrideRequest, overrideResult.Data, reason, cancellationToken); _logger.LogInformation("人工放行操作成功完成:会话ID={SessionId},操作员={OperatorId}", sessionId, operatorId); return transitionResult; } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "执行人工放行操作失败。TraceId: {TraceId}", traceId); return Result.FailWithTrace("MANUAL_RELEASE_FAILED", "执行人工放行操作失败", traceId); } } /// /// 执行人工复位操作。 /// public async Task> ExecuteManualResetAsync(Guid sessionId, string operatorId, string? reason = null, CancellationToken cancellationToken = default) { try { _logger.LogInformation("开始执行人工复位操作:会话ID={SessionId},操作员={OperatorId}", sessionId, operatorId); // 1. 权限校验 var permissionResult = await _manualOverrideService.GetOverridePermissionAsync(sessionId, operatorId, cancellationToken); if (!permissionResult.IsSuccess || !permissionResult.Data?.HasPermission == true) { return Result.Fail("PERMISSION_DENIED", "人工复位权限校验失败"); } // 2. 构建人工干预请求 var overrideRequest = new ManualOverrideRequest { RequestId = Guid.NewGuid(), SessionId = sessionId, OperatorId = operatorId, OperatorName = operatorId, OverrideType = OverrideType.Reset, TargetStatus = SessionStatus.Ready, RequestTimeUtc = DateTime.UtcNow }; // 3. 条件验证 var validationResult = await _manualOverrideService.ValidateOverrideConditionsAsync(sessionId, overrideRequest, cancellationToken); if (!validationResult.IsSuccess || !validationResult.Data?.IsValid == true) { return Result.Fail("VALIDATION_FAILED", "人工复位条件验证失败"); } // 4. 执行状态迁移 var transitionResult = TriggerTransition(StateTrigger.Reset, reason ?? "人工复位", new { OperatorId = operatorId }); if (!transitionResult.IsSuccess) { return transitionResult; } // 5. 执行人工干预 var overrideResult = await _manualOverrideService.ExecuteManualOverrideAsync(overrideRequest, cancellationToken); if (!overrideResult.IsSuccess) { return Result.Fail("OVERRIDE_FAILED", "人工复位执行失败"); } // 6. 记录审计日志 await LogManualOverrideAuditAsync(sessionId, overrideRequest, overrideResult.Data, reason, cancellationToken); _logger.LogInformation("人工复位操作成功完成:会话ID={SessionId},操作员={OperatorId}", sessionId, operatorId); return transitionResult; } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "执行人工复位操作失败。TraceId: {TraceId}", traceId); return Result.FailWithTrace("MANUAL_RESET_FAILED", "执行人工复位操作失败", traceId); } } /// /// 执行人工跳层操作。 /// public async Task> ExecuteManualSkipLayerAsync(Guid sessionId, string operatorId, int targetLayer, string? reason = null, CancellationToken cancellationToken = default) { try { _logger.LogInformation("开始执行人工跳层操作:会话ID={SessionId},操作员={OperatorId},目标层={TargetLayer}", sessionId, operatorId, targetLayer); // 1. 权限校验 var permissionResult = await _manualOverrideService.GetOverridePermissionAsync(sessionId, operatorId, cancellationToken); if (!permissionResult.IsSuccess || !permissionResult.Data?.HasPermission == true) { return Result.Fail("PERMISSION_DENIED", "人工跳层权限校验失败"); } // 2. 构建人工干预请求 var overrideRequest = new ManualOverrideRequest { RequestId = Guid.NewGuid(), SessionId = sessionId, OperatorId = operatorId, OperatorName = operatorId, OverrideType = OverrideType.SkipLayer, TargetStatus = SessionStatus.Running, RequestTimeUtc = DateTime.UtcNow }; // 3. 条件验证 var validationResult = await _manualOverrideService.ValidateOverrideConditionsAsync(sessionId, overrideRequest, cancellationToken); if (!validationResult.IsSuccess || !validationResult.Data?.IsValid == true) { return Result.Fail("VALIDATION_FAILED", "人工跳层条件验证失败"); } // 4. 执行状态迁移(直接设置目标层) lock (_stateLock) { if (targetLayer < 1 || targetLayer > _options.TotalLayers) { return Result.Fail("INVALID_TARGET_LAYER", $"目标层 {targetLayer} 无效"); } var previousLayer = _currentLayer; _currentLayer = targetLayer; var transitionEvent = new StateTransitionEvent { EventType = StateTransitionEventType.LayerForward, PreviousState = _currentState, NewState = _currentState, PreviousLayer = previousLayer, NewLayer = _currentLayer, Timestamp = DateTime.UtcNow, Reason = reason ?? $"人工跳层到第{targetLayer}层", Trigger = StateTrigger.ManualIntervention, GuardResult = "人工干预跳层" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("人工跳层成功:{PreviousLayer} -> {NewLayer}", previousLayer, _currentLayer); // 5. 执行人工干预 var overrideResult = await _manualOverrideService.ExecuteManualOverrideAsync(overrideRequest, cancellationToken); // 6. 记录审计日志 await LogManualOverrideAuditAsync(sessionId, overrideRequest, overrideResult.Data, reason, cancellationToken); return Result.Success(transitionEvent, "人工跳层成功"); } } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "执行人工跳层操作失败。TraceId: {TraceId}", traceId); return Result.FailWithTrace("MANUAL_SKIP_LAYER_FAILED", "执行人工跳层操作失败", traceId); } } /// /// 记录人工干预审计日志。 /// private async Task LogManualOverrideAuditAsync(Guid sessionId, ManualOverrideRequest request, ManualOverrideResult? result, string? reason, CancellationToken cancellationToken) { try { // 这里可以通过审计服务记录日志 // 目前使用日志记录 _logger.LogInformation( "人工干预审计记录:会话ID={SessionId},请求ID={RequestId},操作员={OperatorId},类型={OverrideType},原因={Reason},结果={OverrideResult}", sessionId, request.RequestId, request.OperatorId, request.OverrideType, reason, result?.OverrideResult); } catch (Exception ex) { _logger.LogError(ex, "记录人工干预审计日志失败"); } } #endregion #region 状态检查方法 private bool CanMoveToNextLayer() { return !_isStopped && !_isPaused && _currentLayer < _options.TotalLayers; } private bool CanMoveToPreviousLayer() { return !_isStopped && !_isPaused && _currentLayer > 1; } private bool CanPause() { return _currentState == RuntimeState.Running && !_isPaused && !_isStopped; } private bool CanResume() { return _currentState == RuntimeState.Paused && _isPaused && !_isStopped; } private bool CanReset() { return true; // 总是可以重置 } private bool CanStop() { return _currentState != RuntimeState.Stopped && _currentState != RuntimeState.Completed; } #endregion #region 错误原因获取方法 private string GetCannotMoveForwardReason() { if (_isStopped) return "状态机已停止"; if (_isPaused) return "状态机已暂停"; if (_currentLayer >= _options.TotalLayers) return "已到达最后一层"; return "未知原因"; } private string GetCannotMoveBackwardReason() { if (_isStopped) return "状态机已停止"; if (_isPaused) return "状态机已暂停"; if (_currentLayer <= 1) return "已在第一层"; return "未知原因"; } private string GetCannotPauseReason() { if (_isPaused) return "状态机已暂停"; if (_isStopped) return "状态机已停止"; if (_currentState == RuntimeState.Completed) return "处理已完成"; if (_currentState != RuntimeState.Running) return "状态机不在运行状态"; return "未知原因"; } private string GetCannotResumeReason() { if (!_isPaused) return "状态机未暂停"; if (_isStopped) return "状态机已停止"; return "未知原因"; } private string GetCannotStopReason() { if (_isStopped) return "状态机已停止"; if (_currentState == RuntimeState.Completed) return "处理已完成"; return "未知原因"; } #endregion #region 状态描述方法 private string GetStateDescription(RuntimeState state) { return state switch { RuntimeState.Uninitialized => "未初始化", RuntimeState.Initializing => "初始化中", RuntimeState.Idle => "空闲", RuntimeState.Ready => "就绪", RuntimeState.WaitingProduct => "等待产品", RuntimeState.LayerIdentifying => "层识别中", RuntimeState.Running => "运行中", RuntimeState.Paused => "已暂停", RuntimeState.Stopped => "已停止", RuntimeState.Completed => "已完成", RuntimeState.NgLocked => "NG锁定", RuntimeState.ManualIntervening => "人工干预", RuntimeState.Faulted => "故障", RuntimeState.Error => "错误", RuntimeState.ShuttingDown => "关闭中", _ => "未知状态" }; } private string GetDetailedStateDescription(RuntimeState state) { return state switch { RuntimeState.Uninitialized => "状态机未初始化,需要执行初始化流程", RuntimeState.Initializing => "状态机正在初始化,加载配置和资源", RuntimeState.Idle => "状态机处于空闲状态,等待开始处理", RuntimeState.Ready => "状态机已就绪,等待产品进入工位", RuntimeState.WaitingProduct => "状态机正在等待产品进入检测区域", RuntimeState.LayerIdentifying => $"状态机正在识别第 {_currentLayer} 层的部件", RuntimeState.Running => $"状态机正在运行,当前处理第 {_currentLayer} 层", RuntimeState.Paused => $"状态机已暂停,当前在第 {_currentLayer} 层", RuntimeState.Stopped => "状态机已停止,需要重置才能重新开始", RuntimeState.Completed => $"所有 {_options.TotalLayers} 层处理已完成", RuntimeState.NgLocked => "检测到NG,状态机已锁定,需要人工干预", RuntimeState.ManualIntervening => "人工正在进行干预操作", RuntimeState.Faulted => "设备发生故障,需要检查并修复", RuntimeState.Error => "状态机发生错误,需要检查并重置", RuntimeState.ShuttingDown => "状态机正在关闭,清理资源中", _ => "状态机处于未知状态" }; } #endregion /// /// 基于触发器执行状态转换。 /// public Result TriggerTransition(StateTrigger trigger, string? reason = null, object? parameters = null) { lock (_stateLock) { try { _logger.LogDebug("尝试触发状态转换:触发器={Trigger},当前状态={CurrentState}", trigger, _currentState); // 检查转换是否被允许 var guardResult = EvaluateTransitionGuard(trigger, _currentState, parameters); if (!guardResult.IsAllowed) { _logger.LogWarning("状态转换被守卫条件拒绝:触发器={Trigger},原因={Reason}", trigger, guardResult.Reason); return Result.Fail("TRANSITION_GUARD_REJECTED", guardResult.Reason); } // 获取目标状态 var targetState = GetTargetState(trigger, _currentState); if (targetState == _currentState) { _logger.LogWarning("状态转换无效果:触发器={Trigger},当前状态={CurrentState}", trigger, _currentState); return Result.Fail("TRANSITION_NO_EFFECT", "状态转换无效果"); } // 执行状态转换 return ExecuteStateTransition(trigger, targetState, reason ?? $"触发器 {trigger} 执行"); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "触发状态转换失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "TRIGGER_TRANSITION_FAILED", "触发状态转换失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } } /// /// 评估状态转换守卫条件。 /// private GuardResult EvaluateTransitionGuard(StateTrigger trigger, RuntimeState currentState, object? parameters) { return trigger switch { StateTrigger.Initialize => CanInitialize(), StateTrigger.Start => CanStart(), StateTrigger.ProductEntered => CanAcceptProduct(), StateTrigger.StartLayerIdentification => CanStartLayerIdentification(), StateTrigger.LayerIdentificationCompleted => CanCompleteLayerIdentification(), StateTrigger.MoveToNextLayer => CanMoveToNextLayerGuard(), StateTrigger.MoveToPreviousLayer => CanMoveToPreviousLayerGuard(), StateTrigger.Pause => CanPauseGuard(), StateTrigger.Resume => CanResumeGuard(), StateTrigger.Stop => CanStopGuard(), StateTrigger.NgDetected => CanHandleNg(), StateTrigger.ManualIntervention => CanAcceptManualIntervention(), StateTrigger.ManualInterventionCompleted => CanCompleteManualIntervention(), StateTrigger.Fault => CanHandleFault(), StateTrigger.FaultRecovered => CanRecoverFromFault(), StateTrigger.Reset => CanResetGuard(), StateTrigger.Shutdown => CanShutdown(), _ => new GuardResult { IsAllowed = false, Reason = $"未知的触发器: {trigger}" } }; } /// /// 获取触发器的目标状态。 /// private RuntimeState GetTargetState(StateTrigger trigger, RuntimeState currentState) { return trigger switch { StateTrigger.Initialize => RuntimeState.Initializing, StateTrigger.Initialized => RuntimeState.Idle, StateTrigger.Start => RuntimeState.Ready, StateTrigger.ProductEntered => RuntimeState.LayerIdentifying, StateTrigger.StartLayerIdentification => RuntimeState.LayerIdentifying, StateTrigger.LayerIdentificationCompleted => RuntimeState.Running, StateTrigger.MoveToNextLayer => RuntimeState.Running, StateTrigger.MoveToPreviousLayer => RuntimeState.Running, StateTrigger.Pause => RuntimeState.Paused, StateTrigger.Resume => RuntimeState.Running, StateTrigger.Stop => RuntimeState.Stopped, StateTrigger.Complete => RuntimeState.Completed, StateTrigger.NgDetected => RuntimeState.NgLocked, StateTrigger.ManualIntervention => RuntimeState.ManualIntervening, StateTrigger.ManualInterventionCompleted => RuntimeState.Running, StateTrigger.Fault => RuntimeState.Faulted, StateTrigger.FaultRecovered => RuntimeState.Running, StateTrigger.Error => RuntimeState.Error, StateTrigger.Reset => RuntimeState.Idle, StateTrigger.Shutdown => RuntimeState.ShuttingDown, _ => currentState }; } /// /// 执行状态转换。 /// private Result ExecuteStateTransition(StateTrigger trigger, RuntimeState targetState, string reason) { var previousState = _currentState; var previousLayer = _currentLayer; // 更新状态 _currentState = targetState; _lastTransitionTime = DateTime.UtcNow; // 特殊处理某些转换 if (trigger == StateTrigger.MoveToNextLayer) { _currentLayer++; } else if (trigger == StateTrigger.MoveToPreviousLayer) { _currentLayer--; } else if (trigger == StateTrigger.Reset) { _currentLayer = 1; _isPaused = false; _isStopped = false; } // 创建转换事件 var transitionEvent = new StateTransitionEvent { EventType = GetEventTypeFromTrigger(trigger), PreviousState = previousState, NewState = targetState, PreviousLayer = previousLayer, NewLayer = _currentLayer, Timestamp = _lastTransitionTime, Reason = reason, Trigger = trigger, GuardResult = "守卫条件通过" }; _eventHistory.Enqueue(transitionEvent); _logger.LogInformation("状态转换成功:{PreviousState} -> {NewState},触发器={Trigger},原因={Reason}", previousState, targetState, trigger, reason); return Result.Success(transitionEvent, "状态转换成功"); } /// /// 从触发器获取事件类型。 /// private StateTransitionEventType GetEventTypeFromTrigger(StateTrigger trigger) { return trigger switch { StateTrigger.MoveToNextLayer => StateTransitionEventType.LayerForward, StateTrigger.MoveToPreviousLayer => StateTransitionEventType.LayerBackward, StateTrigger.Pause => StateTransitionEventType.Pause, StateTrigger.Resume => StateTransitionEventType.Resume, StateTrigger.Stop => StateTransitionEventType.Stop, StateTrigger.Reset => StateTransitionEventType.Reset, StateTrigger.Complete => StateTransitionEventType.Complete, StateTrigger.NgDetected => StateTransitionEventType.NgLocked, StateTrigger.ManualIntervention => StateTransitionEventType.ManualIntervention, StateTrigger.Fault => StateTransitionEventType.Fault, StateTrigger.Shutdown => StateTransitionEventType.Shutdown, _ => StateTransitionEventType.Error }; } /// /// 释放资源。 /// public void Dispose() { try { _eventHistory.Clear(); _logger.LogInformation("运行状态机服务已释放"); } catch (Exception ex) { _logger.LogError(ex, "释放运行状态机服务资源时发生错误"); } } } #region 状态机内部类型 /// /// 守卫条件结果。 /// internal sealed class GuardResult { public bool IsAllowed { get; init; } public string Reason { get; init; } = string.Empty; } /// /// 状态转换触发器。 /// public enum StateTrigger { /// /// 初始化触发器。 /// Initialize, /// /// 初始化完成触发器。 /// Initialized, /// /// 启动触发器。 /// Start, /// /// 产品进入触发器。 /// ProductEntered, /// /// 开始层识别触发器。 /// StartLayerIdentification, /// /// 层识别完成触发器。 /// LayerIdentificationCompleted, /// /// 移动到下一层触发器。 /// MoveToNextLayer, /// /// 移动到上一层触发器。 /// MoveToPreviousLayer, /// /// 暂停触发器。 /// Pause, /// /// 恢复触发器。 /// Resume, /// /// 停止触发器。 /// Stop, /// /// 完成触发器。 /// Complete, /// /// NG检测触发器。 /// NgDetected, /// /// 人工干预触发器。 /// ManualIntervention, /// /// 人工干预完成触发器。 /// ManualInterventionCompleted, /// /// 故障触发器。 /// Fault, /// /// 故障恢复触发器。 /// FaultRecovered, /// /// 错误触发器。 /// Error, /// /// 重置触发器。 /// Reset, /// /// 关闭触发器。 /// Shutdown } /// /// 状态转换事件。 /// public sealed class StateTransitionEvent { public StateTransitionEventType EventType { get; init; } public RuntimeState PreviousState { get; init; } public RuntimeState NewState { get; init; } public int PreviousLayer { get; init; } public int NewLayer { get; init; } public DateTime Timestamp { get; init; } public string Reason { get; init; } = string.Empty; public StateTrigger Trigger { get; init; } public string? GuardResult { get; init; } } /// /// 状态转换事件类型。 /// public enum StateTransitionEventType { LayerForward, LayerBackward, Pause, Resume, Stop, Reset, Complete, Error, NgLocked, ManualIntervention, Fault, Shutdown } #endregion /// /// 运行状态枚举。 /// public enum RuntimeState { /// /// 未初始化状态。 /// Uninitialized, /// /// 初始化中状态。 /// Initializing, /// /// 空闲状态。 /// Idle, /// /// 就绪状态,等待产品。 /// Ready, /// /// 等待产品状态。 /// WaitingProduct, /// /// 层识别中状态。 /// LayerIdentifying, /// /// 运行中状态。 /// Running, /// /// 已暂停状态。 /// Paused, /// /// 已停止状态。 /// Stopped, /// /// 已完成状态。 /// Completed, /// /// NG锁定状态。 /// NgLocked, /// /// 人工干预状态。 /// ManualIntervening, /// /// 故障状态。 /// Faulted, /// /// 错误状态。 /// Error, /// /// 关闭中状态。 /// ShuttingDown }