using MainShell.Common;
using MainShell.EventArgsFolder;
using MainShell.Process;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MW.WorkFlow;
namespace MainShell.ProcessResult
{
public class ProcessResultManager
{
private readonly MachineState _machineState;
private readonly IEventAggregator _eventAggregator;
///
/// 流程运行状态记录(仅在自动模式下持久化)
///
public ProcessFlowState FlowState { get; } = new ProcessFlowState();
///
/// 基板定位的业务结果数据(始终持久化)
///
public SubstratePositionProcessResult SubstratePositionResult { get; } = new SubstratePositionProcessResult();
///
/// 芯片定位的业务结果数据(始终持久化)
///
public DiePositionProcessResult DiePositionResult { get; } = new DiePositionProcessResult();
///
/// 基板测高的业务结果数据(始终持久化)
///
public SubstrateHeightMeasureProcessResult SubstrateHeightMeasureResult { get; } = new SubstrateHeightMeasureProcessResult();
///
/// 精度复检的业务结果数据(始终持久化)
///
public DieRecheckProcessResult DieRecheckResult { get; } = new DieRecheckProcessResult();
///
/// 首页统计与条码展示状态(始终持久化)
///
public ProductionDashboardState DashboardState { get; } = new ProductionDashboardState();
///
/// 准备区状态(用于恢复前一致性校验)
///
public PreparationAreaProcessState PreparationAreaState { get; } = new PreparationAreaProcessState();
private readonly AutoProductionResumeValidator _resumeValidator = new AutoProductionResumeValidator();
///
/// 当前芯片使用位状态
///
public CurrentChipProcessState CurrentChipState { get; } = new CurrentChipProcessState();
///
/// 自动流程运行态
///
public AutoProductionRuntimeState AutoProductionRuntimeState { get; } = new AutoProductionRuntimeState();
public ProcessResultManager(MachineState machineState, IEventAggregator eventAggregator)
{
_machineState = machineState ?? throw new ArgumentNullException(nameof(machineState));
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
// 构造时读取一次
ReloadAll();
}
public void UpdateFlowState(string workflowName, string parentActivityName, string activityName, ProcessExecutionStatus status, string errorMessage = null)
{
FlowState.WorkflowName = workflowName;
FlowState.ParentActivityName = parentActivityName;
FlowState.CurrentActivityName = activityName;
FlowState.Status = status.ToString();
FlowState.ErrorMessage = errorMessage;
FlowState.LastUpdateTime = DateTime.Now;
if (ShouldPersistFlowState(workflowName))
{
FlowState.Write();
}
_eventAggregator.Publish(new ProcessFlowStateChangedEventArgs
{
WorkflowName = workflowName,
ParentActivityName = parentActivityName,
CurrentActivityName = activityName,
Status = status,
ErrorMessage = errorMessage
});
}
public void UpdateFlowState(string workflowName, string parentActivityName, string activityName, string status, string errorMessage = null)
{
ProcessExecutionStatus parsed;
if (!Enum.TryParse(status, true, out parsed))
{
parsed = ProcessExecutionStatus.Unknown;
}
UpdateFlowState(workflowName, parentActivityName, activityName, parsed, errorMessage);
}
public void UpdateExecutionPointer(WorkflowExecutionPointer executionPointer)
{
if (executionPointer == null)
{
return;
}
FlowState.WorkflowName = executionPointer.WorkflowName;
FlowState.ParentActivityName = executionPointer.FlowName;
FlowState.CurrentActivityName = executionPointer.ActivityName;
FlowState.CurrentStepId = executionPointer.CurrentStepId;
FlowState.NextStepId = executionPointer.NextStepId;
FlowState.LastUpdateTime = executionPointer.UpdatedAt == default(DateTime) ? DateTime.Now : executionPointer.UpdatedAt;
if (ShouldPersistFlowState(executionPointer.WorkflowName))
{
FlowState.Write();
}
}
public void ReportWorkflowFault(WorkflowFaultInfo faultInfo)
{
if (faultInfo == null)
{
return;
}
FlowState.WorkflowName = faultInfo.WorkflowName;
FlowState.ParentActivityName = faultInfo.FlowName;
FlowState.CurrentActivityName = faultInfo.ActivityName;
FlowState.CurrentStepId = faultInfo.CurrentStepId;
FlowState.NextStepId = faultInfo.CurrentStepId;
FlowState.Status = ProcessExecutionStatus.Faulted.ToString();
FlowState.ErrorMessage = faultInfo.ErrorMessage;
FlowState.LastUpdateTime = faultInfo.OccurredAt == default(DateTime) ? DateTime.Now : faultInfo.OccurredAt;
if (ShouldPersistFlowState(faultInfo.WorkflowName))
{
FlowState.Write();
}
_eventAggregator.Publish(new ProcessFlowStateChangedEventArgs
{
WorkflowName = faultInfo.WorkflowName,
ParentActivityName = faultInfo.FlowName,
CurrentActivityName = faultInfo.ActivityName,
Status = ProcessExecutionStatus.Faulted,
ErrorMessage = faultInfo.ErrorMessage
});
}
public bool TryGetResumeStepId(string workflowName, out string resumeStepId)
{
resumeStepId = null;
if (string.IsNullOrWhiteSpace(workflowName) ||
!string.Equals(FlowState.WorkflowName, workflowName, StringComparison.OrdinalIgnoreCase) ||
string.IsNullOrWhiteSpace(FlowState.NextStepId))
{
return false;
}
if (string.Equals(FlowState.Status, ProcessExecutionStatus.Completed.ToString(), StringComparison.OrdinalIgnoreCase) ||
string.Equals(FlowState.Status, ProcessExecutionStatus.Canceled.ToString(), StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (!_resumeValidator.IsStateConsistentForResume(FlowState.NextStepId, PreparationAreaState, CurrentChipState))
{
FlowState.ErrorMessage = _resumeValidator.BuildResumeValidationError(FlowState.NextStepId, PreparationAreaState, CurrentChipState);
FlowState.LastUpdateTime = DateTime.Now;
if (ShouldPersistFlowState(workflowName))
{
FlowState.Write();
}
return false;
}
resumeStepId = FlowState.NextStepId;
return true;
}
public void SaveSubstratePositionResult()
{
SubstratePositionResult.Write();
}
public void SaveDiePositionResult()
{
DiePositionResult.Write();
}
public void SaveSubstrateHeightMeasureResult()
{
SubstrateHeightMeasureResult.Write();
}
public void SaveDieRecheckResult()
{
DieRecheckResult.Write();
}
public void SaveDashboardState()
{
DashboardState.Write();
}
public void SavePreparationAreaState(ChipPreparationStateSnapshot snapshot)
{
if (snapshot == null)
{
return;
}
PreparationAreaState.Status = snapshot.Status;
PreparationAreaState.ActiveRequestId = snapshot.ActiveRequestId;
PreparationAreaState.RecipeName = snapshot.RecipeName;
PreparationAreaState.SourceStepId = snapshot.SourceStepId;
PreparationAreaState.CurrentStage = snapshot.CurrentStage;
PreparationAreaState.ErrorMessage = snapshot.ErrorMessage;
PreparationAreaState.LastUpdatedTime = snapshot.LastUpdatedTime;
PreparationAreaState.CurrentAction = snapshot.CurrentAction;
PreparationAreaState.HasPreparedChip = snapshot.IsChipLoaded;
PreparationAreaState.Write();
}
public void SaveCurrentChipState(CurrentChipLifecycleState chipState)
{
CurrentChipState.State = chipState;
CurrentChipState.LastUpdatedTime = DateTime.Now;
CurrentChipState.Write();
}
public void SaveAutoProductionRuntimeState(AutoProductionRuntimeState runtimeState)
{
if (runtimeState == null)
{
return;
}
AutoProductionRuntimeState.CurrentSubstratePendingCount = runtimeState.CurrentSubstratePendingCount;
AutoProductionRuntimeState.CurrentSubstrateProcessedCount = runtimeState.CurrentSubstrateProcessedCount;
AutoProductionRuntimeState.CurrentChipRemainingCount = runtimeState.CurrentChipRemainingCount;
AutoProductionRuntimeState.TransferNeedsRecheck = runtimeState.TransferNeedsRecheck;
AutoProductionRuntimeState.TransferChipExhausted = runtimeState.TransferChipExhausted;
AutoProductionRuntimeState.LastUpdatedTime = runtimeState.LastUpdatedTime;
AutoProductionRuntimeState.Write();
}
///
/// 强制从磁盘重新加载所有状态和结果数据
/// 在启动或恢复自动流程前调用,确保获取到最新的(可能是手动操作产生的)结果数据
///
public void ReloadAll()
{
// 1. 读取断点状态(决定从哪一步开始)
FlowState.Read();
// 2. 读取业务结果(决定流程所需的数据上下文)
// 无论之前是手动还是自动写入的,这里统一读取最新值
SubstratePositionResult.Read();
DiePositionResult.Read();
SubstrateHeightMeasureResult.Read();
DieRecheckResult.Read();
// 3. 首页运行数据
DashboardState.Read();
// 4. 准备区状态
PreparationAreaState.Read();
// 5. 当前芯片使用位状态
CurrentChipState.Read();
// 6. 自动流程运行态
AutoProductionRuntimeState.Read();
// 后续如果有其他结果类(如 WaferMapResult),也在这里读取
// WaferMapResult.Read();
}
private bool ShouldPersistFlowState(string workflowName)
{
return _machineState.CurrentMode == MachineMode.Auto ||
string.Equals(workflowName, ProcessFlowName.AutoProduction, StringComparison.OrdinalIgnoreCase);
}
}
}