Files
Shi.Ji e31d3560bb 添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
2026-05-18 11:43:09 +08:00

320 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using MainShell.Common;
using MainShell.Filewritable;
using MainShell.Models;
using MainShell.Recipe.Models;
using MainShell.Recipe.Services;
using MaxwellFramework.Core.Common.Command;
using Newtonsoft.Json.Linq;
using Stylet;
using StyletIoC;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
namespace MainShell.Recipe.ViewModel
{
public class SubstrateRecipeViewModel : RecipeViewModelBase<SubstrateRecipe>, IHandle<WaferNameChangedEventArgs>
{
private readonly RecipeWrapManager _wrapManager;
private readonly IEventAggregator _eventAggregator;
private SubstrateRecipe _substrateRecipe;
public SubstrateRecipe SubstrateRecipe
{
get { return _substrateRecipe; }
set
{
if (SetAndNotify(ref _substrateRecipe, value))
{
if (SubstrateTeachViewModel != null)
{
SubstrateTeachViewModel.SubstrateRecipe = value;
}
if (SubstrateHeightMeasureViewModel != null)
{
SubstrateHeightMeasureViewModel.SubstrateRecipe = value;
}
}
}
}
protected override SubstrateRecipe CurrentRecipe
{
get => SubstrateRecipe;
set => SubstrateRecipe = value;
}
protected override string RecipeFolderPath => Paths.SubstrateRecipe;
protected override string EmptyRecipeDisplayName => "当前基板配方";
protected override string GetActiveRecipeName()
{
return RecipeManager.CurrentSubstrateRecipe?.RecipeName;
}
protected override void SwitchActiveRecipe(string recipeName)
{
RecipeManager.SwitchSubstrateRecipe(recipeName);
}
protected override void ClearActiveRecipe()
{
RecipeManager.ClearSubstrateRecipe();
}
private int _selectedTabIndex;
/// <summary>
/// 当前选中的 Tab 索引0=基础设置显示配方列表1=参数示教(隐藏配方列表)
/// </summary>
public int SelectedTabIndex
{
get => _selectedTabIndex;
set
{
if (SetAndNotify(ref _selectedTabIndex, value))
HideRecipePanel = value != 0;
}
}
private SubstrateTeachViewModel _substrateTeachViewModel;
[Inject]
public SubstrateTeachViewModel SubstrateTeachViewModel
{
get { return _substrateTeachViewModel; }
set
{
if (SetAndNotify(ref _substrateTeachViewModel, value) && value != null)
{
value.SubstrateRecipe = SubstrateRecipe;
}
}
}
private SubstrateHeightMeasureViewModel _substrateHeightMeasureViewModel;
[Inject]
public SubstrateHeightMeasureViewModel SubstrateHeightMeasureViewModel
{
get { return _substrateHeightMeasureViewModel; }
set
{
if (SetAndNotify(ref _substrateHeightMeasureViewModel, value) && value != null)
{
value.SubstrateRecipe = SubstrateRecipe;
}
}
}
public ObservableCollection<RecipeWrap> WaferRecipes => _wrapManager.WaferRecipeWraps;
public SubstrateRecipeViewModel(RecipeWrapManager wrapManager, IEventAggregator eventAggregator, RecipeManager recipeManager)
: base(recipeManager)
{
_wrapManager = wrapManager;
RecipeWraps = wrapManager.SubstrateRecipeWraps;
RegisterButtonGroupEvents();
_eventAggregator = eventAggregator;
_eventAggregator.Unsubscribe(this);
_eventAggregator.Subscribe(this);
DeleteSelectWaferInfoCmd = new DelegateCommand(DeleteSelectWaferInfo);
}
#region//Commands
public ICommand DeleteSelectWaferInfoCmd { get; private set; }
#endregion
protected override string GetUnsavedChangesMessage()
{
var differenceSummary = GetRecipeDifferenceSummary();
return string.IsNullOrWhiteSpace(differenceSummary)
? $"配方“{CurrentRecipeDisplayName}”有未保存修改,是否先保存?"
: $"配方“{CurrentRecipeDisplayName}”有未保存修改:\r\n{differenceSummary}\r\n是否先保存";
}
protected override void OnViewLoaded()
{
base.OnViewLoaded();
InitializeSelection(RecipeManager.CurrentSubstrateRecipe?.RecipeName);
}
protected override void OnRecipeLoaded(SubstrateRecipe recipe, RecipeWrap recipeWrap)
{
}
protected override void AfterDeleteCurrentRecipe(string deletedRecipeName)
{
RecipeManager.DeleteSubstrateRecipe(deletedRecipeName);
_eventAggregator.Publish(new SubstrateDeletedEventArgs
{
DeletedName = deletedRecipeName,
});
}
public override void OnCopyRecipe(object sender, EventArgs eventArgs)
{
base.OnCopyRecipe(sender, eventArgs);
}
public override void OnImportRecipe(object sender, EventArgs eventArgs)
{
if (eventArgs is RecipeEventArgs args)
{
}
}
public override void OnExportRecipe(object sender, EventArgs eventArgs)
{
if (eventArgs is RecipeEventArgs args)
{
}
}
public override void OnReNameRecipe(object sender, EventArgs eventArgs)
{
if (eventArgs is RecipeRenameEventArgs args)
{
if (TryRenameRecipe(args))
{
_eventAggregator.Publish(new SubstrateNameChangedEventArgs
{
OldName = args.OldRecipeName,
NewName = args.NewRecipeName,
});
}
}
}
public void Handle(WaferNameChangedEventArgs message)
{
}
private string GetRecipeDifferenceSummary()
{
if (SubstrateRecipe == null)
return string.Empty;
var path = System.IO.Path.Combine(SubstrateRecipe.Dir ?? string.Empty, SubstrateRecipe.FileName ?? string.Empty);
if (!System.IO.File.Exists(path))
return "1. 当前配方文件尚未保存到磁盘";
var currentSnapshot = SubstrateRecipe.CreateSnapshot();
if (string.Equals(LastSavedSnapshot ?? string.Empty, currentSnapshot, StringComparison.Ordinal))
return string.Empty;
try
{
var originalToken = JToken.Parse(LastSavedSnapshot ?? string.Empty);
var currentToken = JToken.Parse(currentSnapshot);
var differences = new List<string>();
CollectDifferences(originalToken, currentToken, string.Empty, differences, 6);
if (differences.Count == 0)
return "1. 当前配方内容与上次保存快照不一致";
return string.Join("\r\n", differences);
}
catch
{
return "1. 当前配方内容与上次保存快照不一致";
}
}
private void CollectDifferences(JToken originalToken, JToken currentToken, string path, IList<string> differences, int maxCount)
{
if (differences.Count >= maxCount)
return;
if (JToken.DeepEquals(originalToken, currentToken))
return;
if (originalToken == null || currentToken == null)
{
differences.Add($"{differences.Count + 1}. {FormatDifference(path, originalToken, currentToken)}");
return;
}
if (originalToken.Type == JTokenType.Object && currentToken.Type == JTokenType.Object)
{
var originalObject = (JObject)originalToken;
var currentObject = (JObject)currentToken;
var propertyNames = originalObject.Properties().Select(p => p.Name)
.Union(currentObject.Properties().Select(p => p.Name))
.Distinct()
.ToList();
foreach (var propertyName in propertyNames)
{
var nextPath = string.IsNullOrWhiteSpace(path) ? propertyName : $"{path}.{propertyName}";
CollectDifferences(originalObject[propertyName], currentObject[propertyName], nextPath, differences, maxCount);
if (differences.Count >= maxCount)
return;
}
return;
}
if (originalToken.Type == JTokenType.Array && currentToken.Type == JTokenType.Array)
{
var originalArray = (JArray)originalToken;
var currentArray = (JArray)currentToken;
var maxLength = Math.Max(originalArray.Count, currentArray.Count);
for (var i = 0; i < maxLength; i++)
{
var nextPath = $"{path}[{i}]";
var originalItem = i < originalArray.Count ? originalArray[i] : null;
var currentItem = i < currentArray.Count ? currentArray[i] : null;
CollectDifferences(originalItem, currentItem, nextPath, differences, maxCount);
if (differences.Count >= maxCount)
return;
}
return;
}
differences.Add($"{differences.Count + 1}. {FormatDifference(path, originalToken, currentToken)}");
}
private string FormatDifference(string path, JToken originalToken, JToken currentToken)
{
var displayPath = string.IsNullOrWhiteSpace(path) ? "配方根节点" : path;
return $"{displayPath}{FormatTokenValue(originalToken)} -> {FormatTokenValue(currentToken)}";
}
private string FormatTokenValue(JToken token)
{
if (token == null || token.Type == JTokenType.Null || token.Type == JTokenType.Undefined)
return "空";
var value = token.ToString(Newtonsoft.Json.Formatting.None);
if (value.Length > 80)
return value.Substring(0, 80) + "...";
return value;
}
#region//Methods
public void AddWaferSelectInfo()
{
if (SubstrateRecipe == null)
{
MwMessageBox.Show("请先选择或创建基板配方");
return;
}
SubstrateRecipe.WaferSelectInfos.Add(new Models.SubstrateParameter.WaferSelectInfo());
}
private void DeleteSelectWaferInfo(object obj)
{
if (obj is Models.SubstrateParameter.WaferSelectInfo info)
{
SubstrateRecipe.WaferSelectInfos.Remove(info);
}
}
#endregion
}
}