using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OrpaonVision.Core.Common;
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());
}
}
///
/// 触发产品进入事件。
///
public Result TriggerProductEntered()
{
return TriggerTransition(StateTrigger.ProductEntered, "产品进入检测区域");
}
///
/// 触发开始层识别事件。
///
public Result TriggerStartLayerIdentification()
{
return TriggerTransition(StateTrigger.StartLayerIdentification, "开始层识别");
}
///
/// 触发层识别完成事件。
///
public Result TriggerLayerIdentificationCompleted()
{
return TriggerTransition(StateTrigger.LayerIdentificationCompleted, "层识别完成");
}
///
/// 触发NG检测事件。
///
public Result TriggerNgDetected(string reason)
{
return TriggerTransition(StateTrigger.NgDetected, reason ?? "检测到NG");
}
///
/// 触发人工干预事件。
///
public Result TriggerManualIntervention(string reason)
{
return TriggerTransition(StateTrigger.ManualIntervention, reason ?? "需要人工干预");
}
///
/// 触发故障事件。
///
public Result TriggerFault(string reason)
{
return TriggerTransition(StateTrigger.Fault, reason ?? "系统故障");
}
///
/// 触发故障恢复事件。
///
public Result TriggerFaultRecovered(string reason)
{
return TriggerTransition(StateTrigger.FaultRecovered, reason ?? "故障已恢复");
}
///
/// 触发初始化事件。
///
public Result TriggerInitialize()
{
return TriggerTransition(StateTrigger.Initialize, "系统初始化");
}
///
/// 触发初始化完成事件。
///
public Result TriggerInitialized()
{
return TriggerTransition(StateTrigger.Initialized, "系统初始化完成");
}
///
/// 触发启动事件。
///
public Result TriggerStart()
{
return TriggerTransition(StateTrigger.Start, "系统启动");
}
///
/// 触发完成事件。
///
public Result TriggerComplete()
{
return TriggerTransition(StateTrigger.Complete, "处理完成");
}
///
/// 获取当前状态。
///
public RuntimeState GetCurrentState()
{
lock (_stateLock)
{
return _currentState;
}
}
///
/// 获取当前层级。
///
public int GetCurrentLayer()
{
lock (_stateLock)
{
return _currentLayer;
}
}
///
/// 检查是否可以执行特定操作。
///
public bool CanExecuteOperation(StateTrigger trigger)
{
lock (_stateLock)
{
var guardResult = EvaluateTransitionGuard(trigger, _currentState, null);
return guardResult.IsAllowed;
}
}
///
/// 完成处理流程。
///
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.ForcePass,
TargetStatus = SessionStatus.Completed,
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.ResetAndRelease,
TargetStatus = SessionStatus.Active,
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.SkipInspection,
TargetStatus = SessionStatus.Active,
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. 执行状态迁移(直接设置目标层)
StateTransitionEvent transitionEvent;
lock (_stateLock)
{
if (targetLayer < 1 || targetLayer > _options.TotalLayers)
{
return Result.Fail("INVALID_TARGET_LAYER", $"目标层 {targetLayer} 无效");
}
var previousLayer = _currentLayer;
_currentLayer = targetLayer;
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
}
#if false
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());
}
}
///
/// 触发产品进入事件。
///
public Result TriggerProductEntered()
{
return TriggerTransition(StateTrigger.ProductEntered, "产品进入检测区域");
}
///
/// 触发开始层识别事件。
///
public Result TriggerStartLayerIdentification()
{
return TriggerTransition(StateTrigger.StartLayerIdentification, "开始层识别");
}
///
/// 触发层识别完成事件。
///
public Result TriggerLayerIdentificationCompleted()
{
return TriggerTransition(StateTrigger.LayerIdentificationCompleted, "层识别完成");
}
///
/// 触发NG检测事件。
///
public Result TriggerNgDetected(string reason)
{
return TriggerTransition(StateTrigger.NgDetected, reason ?? "检测到NG");
}
///
/// 触发人工干预事件。
///
public Result TriggerManualIntervention(string reason)
{
return TriggerTransition(StateTrigger.ManualIntervention, reason ?? "需要人工干预");
}
///
/// 触发故障事件。
///
public Result TriggerFault(string reason)
{
return TriggerTransition(StateTrigger.Fault, reason ?? "系统故障");
}
///
/// 触发故障恢复事件。
///
public Result TriggerFaultRecovered(string reason)
{
return TriggerTransition(StateTrigger.FaultRecovered, reason ?? "故障已恢复");
}
///
/// 触发初始化事件。
///
public Result TriggerInitialize()
{
return TriggerTransition(StateTrigger.Initialize, "系统初始化");
}
///
/// 触发初始化完成事件。
///
public Result TriggerInitialized()
{
return TriggerTransition(StateTrigger.Initialized, "系统初始化完成");
}
///
/// 触发启动事件。
///
public Result TriggerStart()
{
return TriggerTransition(StateTrigger.Start, "系统启动");
}
///
/// 触发完成事件。
///
public Result TriggerComplete()
{
return TriggerTransition(StateTrigger.Complete, "处理完成");
}
///
/// 获取当前状态。
///
public RuntimeState GetCurrentState()
{
lock (_stateLock)
{
return _currentState;
}
}
///
/// 获取当前层级。
///
public int GetCurrentLayer()
{
lock (_stateLock)
{
return _currentLayer;
}
}
///
/// 检查是否可以执行特定操作。
///
public bool CanExecuteOperation(StateTrigger trigger)
{
lock (_stateLock)
{
var guardResult = EvaluateTransitionGuard(trigger, _currentState, null);
return guardResult.IsAllowed;
}
}
///
/// 完成处理流程。
///
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
}
#endif