using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using BPA.Helper; using System.Collections.Concurrent; using System.Collections.ObjectModel; using System.Windows; using System.Threading; using BPASmartClient.CustomResource.Pages.Model; using BPASmartClient.CustomResource.UserControls.MessageShow; using BPASmartClient.CustomResource.UserControls; using BPASmartClient.Model.柔性味魔方; using BPASmartClient.Model; using System.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Internal; using System.Data.SqlClient; namespace BPASmartClient.DosingSystemSingle.ViewModel { public class RecipeControlViewModel : NotifyBase { static ConcurrentQueue RecipeNames = new ConcurrentQueue(); static ObservableCollection StockStatus = new ObservableCollection(); static ObservableCollection RawMaterialReset = new ObservableCollection(); public RecipeControlViewModel() { StartCommand = new BPARelayCommand(RecipeIssued); ChangeRecipeStateCommand = new BPARelayCommand(ChangeRecipeState); CancelRecipeCommand = new BPARelayCommand(CancelRecipe); RecipeRun(); RecipeStatusInquire(); } private async void CancelRecipe(object o) { if (o != null && o is RecipeModel recipe) { var res = MessageNotify.GetInstance.ShowDialog($"是否取消配方 【{recipe.RecipeName}】制作", DialogType.Warning); if (res) { int index = Recipes.ToList().FindIndex(p => p.RecipeName == recipe.RecipeName); if (index >= 0 && index < Recipes.Count) { await Task.Factory.StartNew(new Action(() => { Recipes.ElementAt(index).IsEnable = true; Json.Data.Recipes.ElementAt(index).IsEnable = true; Recipes.ElementAt(index).Are.Set(); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); })); NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方 [{recipe.RecipeName}] 取消成功"); })); } } } } /// /// 配方下发 /// private void RecipeIssued(object o) { if (o != null && o is string deviceName) { int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == deviceName); if (index >= 0 && index < Recipes.Count) { for (int i = 0; i < Recipes.ElementAt(index).RawMaterials.Count; i++) { if (Recipes.ElementAt(index).RawMaterials.ElementAt(i).RawMaterialSource == 1) { string ip = Recipes.ElementAt(index).RawMaterials.ElementAt(i).DeviceIp; var device = DeviceInquire.GetInstance.GetDevice(ip); if (!device.IsConnected) { MessageNotify.GetInstance.ShowDialog($"设备 【{device.DeviceName}】 未连接,不允许下发此配方", DialogType.Error); return; } } } Recipes.ElementAt(index).IsEnable = false; Json.Data.Recipes.ElementAt(index).IsEnable = false; } MessageNotify.GetInstance.ShowUserLog($"下发工单 {Recipes.ElementAt(index).RecipeName}"); RecipeNames.Enqueue(deviceName); var t = RecipeNames.GetHashCode(); var res = Recipes.FirstOrDefault(p => p.RecipeName == deviceName); UserTreeWait.Add(new RecipeModel { RecipStatus = "等待制作", SerialNum = UserTreeWait.Count + 1, RecipeName = deviceName, RawMaterials = res.RawMaterials }); } NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方下发成功!"); MessageNotify.GetInstance.ShowUserLog($"下发工单 {Guid.NewGuid().ToString()}"); } /// /// 配方业务执行 /// private void RecipeRun() { ThreadManage.GetInstance().StartLong(new Action(() => { if (RecipeNames.Count > 0) { int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(0)); if (index >= 0 && index < Recipes.Count) { Recipes.ElementAt(index).Are.Reset(); Recipes.ElementAt(index).IsEnable = false; StockStatus.Clear(); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); if (UserTreeWait.Count > 0) UserTreeWait.RemoveAt(0); })); CurrentRecipeName = Recipes.ElementAt(index).RecipeName; var recipe = Recipes.ElementAt(index); ObservableCollection RawMater = new ObservableCollection(); foreach (var item in recipe.RawMaterials) { DeviceInquire.GetInstance.GetDevice(item.DeviceIp)?.Start(item.RawMaterialWeight);//启动并写入每个原料重量 RawMater.Add(new RawMaterialModel() { RawMaterialName = item.RawMaterialName, DeviceIp = item.DeviceIp, DownLimtFeedback = item.DownLimtFeedback, Loc = item.Loc, RawMaterialId = item.RawMaterialId, RawMaterialSource = item.RawMaterialSource, RawMaterialType = item.RawMaterialType, RawMaterialWeight = item.RawMaterialWeight, RecipeStatus = item.RecipeStatus, SelectIndex = item.SelectIndex, Status = item.Status, UpLimtFeedback = item.UpLimtFeedback, UpLimtWeightFeedback = item.UpLimtWeightFeedback, WeightFeedback = item.WeightFeedback, }); } App.Current.Dispatcher.Invoke(() => { recipeProcesses.Add(new RecipeModel() { RawMaterials = RawMater, IsEnable = recipe.IsEnable, RecipeName = recipe.RecipeName, SerialNum = recipe.SerialNum, RecipCode = recipe.RecipCode, }); }); Recipes.ElementAt(index).Are.WaitOne();//阻塞,直到当前配方完成 RecipeNames.TryDequeue(out string deviceName); var recipeComple = Recipes.ElementAt(index); ObservableCollection RawMaterComple = new ObservableCollection(); foreach (var item in recipeComple.RawMaterials) { RawMaterComple.Add(new RawMaterialModel() { RawMaterialName = item.RawMaterialName, DeviceIp = item.DeviceIp, DownLimtFeedback = item.DownLimtFeedback, Loc = item.Loc, RawMaterialId = item.RawMaterialId, RawMaterialSource = item.RawMaterialSource, RawMaterialType = item.RawMaterialType, RawMaterialWeight = item.RawMaterialWeight, RecipeStatus = item.RecipeStatus, SelectIndex = item.SelectIndex, Status = item.Status, UpLimtFeedback = item.UpLimtFeedback, UpLimtWeightFeedback = item.UpLimtWeightFeedback, WeightFeedback = item.WeightFeedback, }); } App.Current.Dispatcher.Invoke(() => { UserTreeCompelete.Add(new RecipeModel() { RawMaterials = RawMaterComple, IsEnable = recipeComple.IsEnable, RecipeName = recipeComple.RecipeName, SerialNum = UserTreeCompelete.Count + 1, RecipCode = recipeComple.RecipCode, RecipStatus = "制作完成" }); }); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); CurrentRecipeName = string.Empty; }));//完成后清空当前配方 } } Thread.Sleep(1000); }), "启动配方下发"); } /// /// 配方执行状态监听 /// private void RecipeStatusInquire() { ThreadManage.GetInstance().StartLong(new Action(() => { for (int i = 0; i < Recipes.Count; i++) { for (int m = 0; m < Recipes.ElementAt(i).RawMaterials.Count; m++) { var RunStatus = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp).deviceStatus.RunStatus; //设备状态显示 if (Recipes.ElementAt(i).RecipeName == CurrentRecipeName) { string tempRawMaterialName = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp).DeviceName; int recIndex = recipeProcesses.ToList().FindIndex(p => p.RecipeName == CurrentRecipeName); if (recIndex >= 0 && recIndex < recipeProcesses.Count) { int index = recipeProcesses.ElementAt(recIndex).RawMaterials.ToList().FindIndex(p => p.RawMaterialName == tempRawMaterialName); if (index >= 0 && index < recipeProcesses.ElementAt(recIndex).RawMaterials.Count) { //测试使用 recipeProcesses.ElementAt(recIndex).RawMaterials.ElementAt(index).RecipeStatus = RunStatus; if (recipeProcesses.ElementAt(recIndex).RawMaterials.ElementAt(index).RecipeStatus == 3) { DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(index).DeviceIp).StatusReset(); if (!RawMaterialReset.Contains(Recipes.ElementAt(i).RawMaterials.ElementAt(index).RawMaterialName)) { RawMaterialReset.Add(Recipes.ElementAt(i).RawMaterials.ElementAt(index).RawMaterialName); } } if (RawMaterialReset.Count >= recipeProcesses.ElementAt(recIndex).RawMaterials.Count) { RawMaterialReset.Clear(); int recipIndex = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == CurrentRecipeName); App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); })); Recipes.ElementAt(recipIndex).IsEnable = true; Json.Data.Recipes.ElementAt(recipIndex).IsEnable = true; Recipes.ElementAt(recipIndex).Are.Set(); Thread.Sleep(100); } } } } } } Thread.Sleep(100); }), "RecipeControlViewModelStatusInquire"); } public BPARelayCommand StartCommand { get; set; } public BPARelayCommand ChangeRecipeStateCommand { get; set; } public BPARelayCommand CancelRecipeCommand { get; set; } public static ObservableCollection Recipes { get; set; } = Json.Data.Recipes; public static string CurrentRecipeName { get { return _RecipeName; } set { _RecipeName = value; OnStaticPropertyChanged(); } } private static string _RecipeName; /// /// 当前正在制作的配方 /// public static ObservableCollection recipeProcesses { get; set; } = new ObservableCollection(); /// /// 等待制作的配方 /// public static ObservableCollection UserTreeWait { get; set; } = new ObservableCollection(); /// /// 已完成的配方 /// public static ObservableCollection UserTreeCompelete { get; set; } = new ObservableCollection(); private void ChangeRecipeState(object o) { if (o == null) return; if (o is string id) { var Recipe = recipeProcesses.FirstOrDefault(p => p.RecipeName == CurrentRecipeName); if (Recipe != null) { var res = Recipe.RawMaterials.FirstOrDefault(p => p.RawMaterialId == id); if (res != null) { if (res.RecipeStatus == 3) { res.RecipeStatus = 1; } else { res.RecipeStatus = 3; } } } } } } }