终端一体化运控平台
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

302 行
15 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using BPA.Helper;
  7. using System.Collections.Concurrent;
  8. using System.Collections.ObjectModel;
  9. using System.Windows;
  10. using System.Threading;
  11. using BPASmartClient.CustomResource.Pages.Model;
  12. using BPASmartClient.CustomResource.UserControls.MessageShow;
  13. using BPASmartClient.CustomResource.UserControls;
  14. using BPASmartClient.Model.柔性味魔方;
  15. using BPASmartClient.Model;
  16. using System.Diagnostics;
  17. using Microsoft.EntityFrameworkCore.Metadata.Internal;
  18. using System.Data.SqlClient;
  19. namespace BPASmartClient.DosingSystemSingle.ViewModel
  20. {
  21. public class RecipeControlViewModel : NotifyBase
  22. {
  23. static ConcurrentQueue<string> RecipeNames = new ConcurrentQueue<string>();
  24. static ObservableCollection<StockStatusModel> StockStatus = new ObservableCollection<StockStatusModel>();
  25. static ObservableCollection<string> RawMaterialReset = new ObservableCollection<string>();
  26. public RecipeControlViewModel()
  27. {
  28. StartCommand = new BPARelayCommand<object>(RecipeIssued);
  29. ChangeRecipeStateCommand = new BPARelayCommand<object>(ChangeRecipeState);
  30. CancelRecipeCommand = new BPARelayCommand<object>(CancelRecipe);
  31. RecipeRun();
  32. RecipeStatusInquire();
  33. }
  34. private async void CancelRecipe(object o)
  35. {
  36. if (o != null && o is RecipeModel recipe)
  37. {
  38. var res = MessageNotify.GetInstance.ShowDialog($"是否取消配方 【{recipe.RecipeName}】制作", DialogType.Warning);
  39. if (res)
  40. {
  41. int index = Recipes.ToList().FindIndex(p => p.RecipeName == recipe.RecipeName);
  42. if (index >= 0 && index < Recipes.Count)
  43. {
  44. await Task.Factory.StartNew(new Action(() =>
  45. {
  46. Recipes.ElementAt(index).IsEnable = true;
  47. Json<LocaPar>.Data.Recipes.ElementAt(index).IsEnable = true;
  48. Recipes.ElementAt(index).Are.Set();
  49. App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); }));
  50. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方 [{recipe.RecipeName}] 取消成功");
  51. }));
  52. }
  53. }
  54. }
  55. }
  56. /// <summary>
  57. /// 配方下发
  58. /// </summary>
  59. private void RecipeIssued(object o)
  60. {
  61. if (o != null && o is string deviceName)
  62. {
  63. int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == deviceName);
  64. if (index >= 0 && index < Recipes.Count)
  65. {
  66. for (int i = 0; i < Recipes.ElementAt(index).RawMaterials.Count; i++)
  67. {
  68. if (Recipes.ElementAt(index).RawMaterials.ElementAt(i).RawMaterialSource == 1)
  69. {
  70. string ip = Recipes.ElementAt(index).RawMaterials.ElementAt(i).DeviceIp;
  71. var device = DeviceInquire.GetInstance.GetDevice(ip);
  72. if (!device.IsConnected)
  73. {
  74. MessageNotify.GetInstance.ShowDialog($"设备 【{device.DeviceName}】 未连接,不允许下发此配方", DialogType.Error);
  75. return;
  76. }
  77. }
  78. }
  79. Recipes.ElementAt(index).IsEnable = false;
  80. Json<LocaPar>.Data.Recipes.ElementAt(index).IsEnable = false;
  81. }
  82. MessageNotify.GetInstance.ShowUserLog($"下发工单 {Recipes.ElementAt(index).RecipeName}");
  83. RecipeNames.Enqueue(deviceName);
  84. var t = RecipeNames.GetHashCode();
  85. var res = Recipes.FirstOrDefault(p => p.RecipeName == deviceName);
  86. UserTreeWait.Add(new RecipeModel { RecipStatus = "等待制作", SerialNum = UserTreeWait.Count + 1, RecipeName = deviceName, RawMaterials = res.RawMaterials });
  87. }
  88. NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方下发成功!");
  89. MessageNotify.GetInstance.ShowUserLog($"下发工单 {Guid.NewGuid().ToString()}");
  90. }
  91. /// <summary>
  92. /// 配方业务执行
  93. /// </summary>
  94. private void RecipeRun()
  95. {
  96. ThreadManage.GetInstance().StartLong(new Action(() =>
  97. {
  98. if (RecipeNames.Count > 0)
  99. {
  100. int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == RecipeNames.ElementAt(0));
  101. if (index >= 0 && index < Recipes.Count)
  102. {
  103. Recipes.ElementAt(index).Are.Reset();
  104. Recipes.ElementAt(index).IsEnable = false;
  105. StockStatus.Clear();
  106. App.Current.Dispatcher.Invoke(new Action(() =>
  107. {
  108. recipeProcesses.Clear();
  109. if (UserTreeWait.Count > 0) UserTreeWait.RemoveAt(0);
  110. }));
  111. CurrentRecipeName = Recipes.ElementAt(index).RecipeName;
  112. var recipe = Recipes.ElementAt(index);
  113. ObservableCollection<RawMaterialModel> RawMater = new ObservableCollection<RawMaterialModel>();
  114. foreach (var item in recipe.RawMaterials)
  115. {
  116. DeviceInquire.GetInstance.GetDevice(item.DeviceIp)?.Start(item.RawMaterialWeight);//启动并写入每个原料重量
  117. RawMater.Add(new RawMaterialModel()
  118. {
  119. RawMaterialName = item.RawMaterialName,
  120. DeviceIp = item.DeviceIp,
  121. DownLimtFeedback = item.DownLimtFeedback,
  122. Loc = item.Loc,
  123. RawMaterialId = item.RawMaterialId,
  124. RawMaterialSource = item.RawMaterialSource,
  125. RawMaterialType = item.RawMaterialType,
  126. RawMaterialWeight = item.RawMaterialWeight,
  127. RecipeStatus = item.RecipeStatus,
  128. SelectIndex = item.SelectIndex,
  129. Status = item.Status,
  130. UpLimtFeedback = item.UpLimtFeedback,
  131. UpLimtWeightFeedback = item.UpLimtWeightFeedback,
  132. WeightFeedback = item.WeightFeedback,
  133. });
  134. }
  135. App.Current.Dispatcher.Invoke(() =>
  136. {
  137. recipeProcesses.Add(new RecipeModel()
  138. {
  139. RawMaterials = RawMater,
  140. IsEnable = recipe.IsEnable,
  141. RecipeName = recipe.RecipeName,
  142. SerialNum = recipe.SerialNum,
  143. RecipCode = recipe.RecipCode,
  144. });
  145. });
  146. Recipes.ElementAt(index).Are.WaitOne();//阻塞,直到当前配方完成
  147. RecipeNames.TryDequeue(out string deviceName);
  148. var recipeComple = Recipes.ElementAt(index);
  149. ObservableCollection<RawMaterialModel> RawMaterComple = new ObservableCollection<RawMaterialModel>();
  150. foreach (var item in recipeComple.RawMaterials)
  151. {
  152. RawMaterComple.Add(new RawMaterialModel()
  153. {
  154. RawMaterialName = item.RawMaterialName,
  155. DeviceIp = item.DeviceIp,
  156. DownLimtFeedback = item.DownLimtFeedback,
  157. Loc = item.Loc,
  158. RawMaterialId = item.RawMaterialId,
  159. RawMaterialSource = item.RawMaterialSource,
  160. RawMaterialType = item.RawMaterialType,
  161. RawMaterialWeight = item.RawMaterialWeight,
  162. RecipeStatus = item.RecipeStatus,
  163. SelectIndex = item.SelectIndex,
  164. Status = item.Status,
  165. UpLimtFeedback = item.UpLimtFeedback,
  166. UpLimtWeightFeedback = item.UpLimtWeightFeedback,
  167. WeightFeedback = item.WeightFeedback,
  168. });
  169. }
  170. App.Current.Dispatcher.Invoke(() =>
  171. {
  172. UserTreeCompelete.Add(new RecipeModel()
  173. {
  174. RawMaterials = RawMaterComple,
  175. IsEnable = recipeComple.IsEnable,
  176. RecipeName = recipeComple.RecipeName,
  177. SerialNum = UserTreeCompelete.Count + 1,
  178. RecipCode = recipeComple.RecipCode,
  179. RecipStatus = "制作完成"
  180. });
  181. });
  182. App.Current.Dispatcher.Invoke(new Action(() =>
  183. {
  184. recipeProcesses.Clear();
  185. CurrentRecipeName = string.Empty;
  186. }));//完成后清空当前配方
  187. }
  188. }
  189. Thread.Sleep(1000);
  190. }), "启动配方下发");
  191. }
  192. /// <summary>
  193. /// 配方执行状态监听
  194. /// </summary>
  195. private void RecipeStatusInquire()
  196. {
  197. ThreadManage.GetInstance().StartLong(new Action(() =>
  198. {
  199. for (int i = 0; i < Recipes.Count; i++)
  200. {
  201. for (int m = 0; m < Recipes.ElementAt(i).RawMaterials.Count; m++)
  202. {
  203. var RunStatus = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp).deviceStatus.RunStatus;
  204. //设备状态显示
  205. if (Recipes.ElementAt(i).RecipeName == CurrentRecipeName)
  206. {
  207. string tempRawMaterialName = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp).DeviceName;
  208. int recIndex = recipeProcesses.ToList().FindIndex(p => p.RecipeName == CurrentRecipeName);
  209. if (recIndex >= 0 && recIndex < recipeProcesses.Count)
  210. {
  211. int index = recipeProcesses.ElementAt(recIndex).RawMaterials.ToList().FindIndex(p => p.RawMaterialName == tempRawMaterialName);
  212. if (index >= 0 && index < recipeProcesses.ElementAt(recIndex).RawMaterials.Count)
  213. {
  214. //测试使用
  215. recipeProcesses.ElementAt(recIndex).RawMaterials.ElementAt(index).RecipeStatus = RunStatus;
  216. if (recipeProcesses.ElementAt(recIndex).RawMaterials.ElementAt(index).RecipeStatus == 3)
  217. {
  218. DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(index).DeviceIp).StatusReset();
  219. if (!RawMaterialReset.Contains(Recipes.ElementAt(i).RawMaterials.ElementAt(index).RawMaterialName))
  220. {
  221. RawMaterialReset.Add(Recipes.ElementAt(i).RawMaterials.ElementAt(index).RawMaterialName);
  222. }
  223. }
  224. if (RawMaterialReset.Count >= recipeProcesses.ElementAt(recIndex).RawMaterials.Count)
  225. {
  226. RawMaterialReset.Clear();
  227. int recipIndex = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == CurrentRecipeName);
  228. App.Current.Dispatcher.Invoke(new Action(() => { recipeProcesses.Clear(); }));
  229. Recipes.ElementAt(recipIndex).IsEnable = true;
  230. Json<LocaPar>.Data.Recipes.ElementAt(recipIndex).IsEnable = true;
  231. Recipes.ElementAt(recipIndex).Are.Set();
  232. Thread.Sleep(100);
  233. }
  234. }
  235. }
  236. }
  237. }
  238. }
  239. Thread.Sleep(100);
  240. }), "RecipeControlViewModelStatusInquire");
  241. }
  242. public BPARelayCommand<object> StartCommand { get; set; }
  243. public BPARelayCommand<object> ChangeRecipeStateCommand { get; set; }
  244. public BPARelayCommand<object> CancelRecipeCommand { get; set; }
  245. public static ObservableCollection<RecipeModel> Recipes { get; set; } = Json<LocaPar>.Data.Recipes;
  246. public static string CurrentRecipeName { get { return _RecipeName; } set { _RecipeName = value; OnStaticPropertyChanged(); } }
  247. private static string _RecipeName;
  248. /// <summary>
  249. /// 当前正在制作的配方
  250. /// </summary>
  251. public static ObservableCollection<RecipeModel> recipeProcesses { get; set; } = new ObservableCollection<RecipeModel>();
  252. /// <summary>
  253. /// 等待制作的配方
  254. /// </summary>
  255. public static ObservableCollection<RecipeModel> UserTreeWait { get; set; } = new ObservableCollection<RecipeModel>();
  256. /// <summary>
  257. /// 已完成的配方
  258. /// </summary>
  259. public static ObservableCollection<RecipeModel> UserTreeCompelete { get; set; } = new ObservableCollection<RecipeModel>();
  260. private void ChangeRecipeState(object o)
  261. {
  262. if (o == null) return;
  263. if (o is string id)
  264. {
  265. var Recipe = recipeProcesses.FirstOrDefault(p => p.RecipeName == CurrentRecipeName);
  266. if (Recipe != null)
  267. {
  268. var res = Recipe.RawMaterials.FirstOrDefault(p => p.RawMaterialId == id);
  269. if (res != null)
  270. {
  271. if (res.RecipeStatus == 3)
  272. {
  273. res.RecipeStatus = 1;
  274. }
  275. else
  276. {
  277. res.RecipeStatus = 3;
  278. }
  279. }
  280. }
  281. }
  282. }
  283. }
  284. }