ProcessDetailV2ViewModel.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. using Aitex.Core.UI.Control;
  2. using Aitex.Core.Util;
  3. using Caliburn.Micro.Core;
  4. using DocumentFormat.OpenXml.Drawing;
  5. using DocumentFormat.OpenXml.Drawing.Diagrams;
  6. using MECF.Framework.Common.DataCenter;
  7. using MECF.Framework.Common.Equipment;
  8. using MECF.Framework.Common.Jobs;
  9. using MECF.Framework.Common.Utilities;
  10. using MECF.Framework.UI.Client.CenterViews.Editors.Recipe;
  11. using MECF.Framework.UI.Client.ClientBase;
  12. using OpenSEMI.ClientBase.Command;
  13. using SciChart.Core.Extensions;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.ComponentModel;
  17. using System.Data;
  18. using System.Diagnostics.Eventing.Reader;
  19. using System.Linq;
  20. using System.Text;
  21. using System.Threading.Tasks;
  22. using System.Windows.Input;
  23. namespace MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory
  24. {
  25. public class ProcessDetailV2ViewModel : ModuleUiViewModelBase
  26. {
  27. #region
  28. [Subscription("Rt.Status")]
  29. public string RtStatus { get; set; }
  30. [Subscription("PM1.Status")]
  31. public string PM1Status { get; set; }
  32. private int _upperSDNum = 0;
  33. public int UpperSDNum
  34. {
  35. get => _upperSDNum;
  36. set
  37. {
  38. _upperSDNum = value;
  39. NotifyOfPropertyChange(nameof(UpperSDNum));
  40. }
  41. }
  42. private int _productNum = 0;
  43. public int ProductNum
  44. {
  45. get => _productNum;
  46. set
  47. {
  48. _productNum = value;
  49. NotifyOfPropertyChange(nameof(ProductNum));
  50. }
  51. }
  52. private int _monitorNum1 = 0;
  53. public int MonitorNum1
  54. {
  55. get => _monitorNum1;
  56. set
  57. {
  58. _monitorNum1 = value;
  59. NotifyOfPropertyChange(nameof(MonitorNum1));
  60. }
  61. }
  62. private int _monitorNum2 = 0;
  63. public int MonitorNum2
  64. {
  65. get => _monitorNum2;
  66. set
  67. {
  68. _monitorNum2 = value;
  69. NotifyOfPropertyChange(nameof(MonitorNum2));
  70. }
  71. }
  72. private int _lowerSDNum = 0;
  73. public int LowerSDNum
  74. {
  75. get => _lowerSDNum;
  76. set
  77. {
  78. _lowerSDNum = value;
  79. NotifyOfPropertyChange(nameof(LowerSDNum));
  80. }
  81. }
  82. private int _selectItemIndex = 0;
  83. public int SelectItemIndex
  84. {
  85. get => _selectItemIndex;
  86. set
  87. {
  88. _selectItemIndex = value;
  89. NotifyOfPropertyChange(nameof(SelectItemIndex));
  90. }
  91. }
  92. private int _tableCount = 0;
  93. public int TableCount
  94. {
  95. get => _tableCount;
  96. set
  97. {
  98. _tableCount = value;
  99. NotifyOfPropertyChange(nameof(TableCount));
  100. }
  101. }
  102. private List<string> _boatMapWafers = new List<string>();
  103. public List<string> BoatMapWafers
  104. {
  105. get => _boatMapWafers;
  106. set
  107. {
  108. _boatMapWafers = value;
  109. NotifyOfPropertyChange(nameof(BoatMapWafers));
  110. }
  111. }
  112. private ProcessDetailV2ViewData _viewData;
  113. public ProcessDetailV2ViewData ViewData
  114. {
  115. get => _viewData;
  116. set
  117. {
  118. _viewData = value;
  119. NotifyOfPropertyChange(nameof(ViewData));
  120. }
  121. }
  122. private RecipeDataBase _layoutRecipe = new RecipeDataBase();
  123. public RecipeDataBase LayoutRecipe
  124. {
  125. get { return _layoutRecipe; }
  126. set { _layoutRecipe = value; this.NotifyOfPropertyChange(nameof(LayoutRecipe)); }
  127. }
  128. private RecipeDataBase _processRecipe = new RecipeDataBase();
  129. public RecipeDataBase ProcessRecipe
  130. {
  131. get { return _processRecipe; }
  132. set { _processRecipe = value; this.NotifyOfPropertyChange(nameof(ProcessRecipe)); }
  133. }
  134. private ProcessHistoryLot _pJInfo = new ProcessHistoryLot();
  135. public ProcessHistoryLot PJInfo
  136. {
  137. get { return _pJInfo; }
  138. set { _pJInfo = value; this.NotifyOfPropertyChange(nameof(PJInfo)); }
  139. }
  140. private readonly RecipeProvider _recipeProvider = new RecipeProvider();
  141. private RecipeFormatBuilder _columnBuilder = new RecipeFormatBuilder();
  142. private string _processPrefix = "Furnace\\Process";
  143. private string _layoutPrefix = "Furnace\\Layout";
  144. public ICommand AlarmInformationCommand { get; set; }
  145. public ICommand EventLoggingCommand { get; set; }
  146. public ICommand PMCTraceLoggingCommand { get; set; }
  147. public ICommand VPCommand { get; set; }
  148. #endregion
  149. public ProcessDetailV2ViewModel()
  150. {
  151. AlarmInformationCommand = new BaseCommand<object>(AlarmInformationMethod);
  152. EventLoggingCommand = new BaseCommand<object>(EventLoggingMethod);
  153. PMCTraceLoggingCommand = new BaseCommand<object>(PMCTraceLoggingMethod);
  154. VPCommand = new BaseCommand<object>(VPMethod);
  155. }
  156. private void AlarmInformationMethod(object e) {
  157. //
  158. }
  159. private void EventLoggingMethod(object e) { }
  160. private void PMCTraceLoggingMethod(object e) { }
  161. private void VPMethod(object e) { }
  162. protected override void OnViewLoaded(object _view)
  163. {
  164. base.OnViewLoaded(_view);
  165. ViewData = new ProcessDetailV2ViewData();
  166. LoadLayoutInfo(PJInfo.LayoutName);
  167. LoadProcessData();
  168. if (string.IsNullOrEmpty(PJInfo.LayoutName))
  169. {
  170. ViewData.ProcessStartTime = ViewData.PJobStartTime;
  171. ViewData.ProcessEndTime = ViewData.PJobEndTime;
  172. }
  173. }
  174. private void LoadProcessData()
  175. {
  176. var pjStartNoEnd = PJInfo.StartTime != DateTime.MinValue && PJInfo.EndTime == DateTime.MinValue;
  177. var pjStartAndEnd = PJInfo.StartTime != DateTime.MinValue && PJInfo.EndTime != DateTime.MinValue;
  178. var hasLayoutRecipe = !string.IsNullOrEmpty(PJInfo.LayoutName);
  179. string sql = $"SELECT * FROM process_data where (pj_id ='{PJInfo.PjId}')";
  180. if (string.IsNullOrEmpty(PJInfo.PjId))
  181. {
  182. sql = $"SELECT * FROM process_data where (recipe_name ='{PJInfo.RecipeName}' and process_begin_time >= '{PJInfo.StartTime:yyyy/MM/dd HH:mm:ss.fff}' and process_end_time <= '{PJInfo.EndTime:yyyy/MM/dd HH:mm:ss.fff}') order by process_begin_time DESC;";
  183. }
  184. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  185. string processDataStatus = "";
  186. if (dbData != null && dbData.Rows.Count > 0)
  187. {
  188. ViewData.ProcessStartTime = dbData.Rows[0]["process_begin_time"].ToString();
  189. ViewData.ProcessEndTime = dbData.Rows[0]["process_end_time"].ToString();
  190. processDataStatus = dbData.Rows[0]["process_status"].ToString();
  191. }
  192. if (pjStartNoEnd)
  193. {
  194. ViewData.IsSettingUp = true;
  195. ViewData.IsProcessComplete = false;
  196. ViewData.IsProcessing = false;
  197. }
  198. if (!string.IsNullOrEmpty(ViewData.ProcessStartTime) && string.IsNullOrEmpty(ViewData.ProcessEndTime))
  199. {
  200. ViewData.IsSettingUp = false;
  201. ViewData.IsProcessComplete = false;
  202. ViewData.IsProcessing = true;
  203. }
  204. if (pjStartAndEnd)
  205. {
  206. ViewData.IsSettingUp = false;
  207. ViewData.IsProcessComplete = true;
  208. ViewData.IsProcessing = false;
  209. }
  210. if (PJInfo.Form == ProcessEndResultEnum.Abort.ToDescription())
  211. {
  212. ViewData.ProcessEndResult = ProcessEndResultEnum.Abort.ToDescription();
  213. return;
  214. }
  215. if (PJInfo.Form == ProcessEndResultEnum.Normal.ToDescription() && !string.IsNullOrEmpty(processDataStatus) && processDataStatus == ProcessEndResultEnum.Succeed.ToDescription())
  216. {
  217. ViewData.ProcessEndResult = ProcessEndResultEnum.NORMALEND.ToDescription();
  218. return;
  219. }
  220. if (pjStartNoEnd || (PJInfo.Form == ProcessEndResultEnum.Normal.ToDescription() && string.IsNullOrEmpty(processDataStatus)))
  221. {
  222. ViewData.ProcessEndResult = ProcessEndResultEnum.NONE.ToDescription();
  223. return;
  224. }
  225. }
  226. protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  227. {
  228. // RefreshCassetteDataTask();
  229. }
  230. private void RefreshCassetteDataTask()
  231. {
  232. var wafers = ModuleManager.ModuleInfos[ModuleName.PM1.ToString()].WaferManager.Wafers;
  233. }
  234. private void LoadLayoutInfo(string layoutName)
  235. {
  236. ViewData.PJobStartTime = PJInfo.StartTime.ToString("yyyy/MM/dd HH:mm:ss.fff");
  237. ViewData.PJobEndTime = PJInfo.EndTime.ToString("yyyy/MM/dd HH:mm:ss.fff");
  238. if (string.IsNullOrEmpty(layoutName))
  239. {
  240. return;
  241. }
  242. _columnBuilder.Build("Layout");
  243. LayoutRecipe.PrefixPath = _layoutPrefix;
  244. var recipeContent = _recipeProvider.LoadRecipe(LayoutRecipe.PrefixPath, layoutName);
  245. //if (string.IsNullOrEmpty(recipeContent))
  246. //{
  247. // System.Windows.MessageBox.Show($"{layoutName} is empty, please confirm the file is valid.");
  248. // return;
  249. //}
  250. // LayoutRecipe.InitData(LayoutRecipe.PrefixPath, layoutName, recipeContent, _columnBuilder.Configs, "PM1");
  251. var waferNumberAll = (int)QueryDataClient.Instance.Service.GetConfig("Boat.SlotCount");
  252. var cassetteSlotCount = (int)QueryDataClient.Instance.Service.GetConfig("System.CassetteSlotCount");
  253. List<string> listWafers = QueryDataClient.Instance.Service.GetLayoutRecipeContent(recipeContent, waferNumberAll.ToString(), cassetteSlotCount.ToString());
  254. BoatMapWafers = listWafers;
  255. if (null != BoatMapWafers && BoatMapWafers.Count > 0)
  256. {
  257. var data = ComputSD(BoatMapWafers);
  258. ComputWafer(listWafers);
  259. }
  260. }
  261. private void ComputWafer(List<string> listWafers)
  262. {
  263. UpperSDNum = listWafers.Where(x => x == "SD").Count();
  264. LowerSDNum = listWafers.Where(x => x == "FD").Count();
  265. ProductNum = listWafers.Where(x => x.StartsWith("P")).Count();
  266. MonitorNum1 = listWafers.Where(x => x == "M1").Count();
  267. MonitorNum2 = listWafers.Where(x => x == "M2").Count();
  268. }
  269. private Tuple<int, int> ComputSD(List<string> dataSource)
  270. {
  271. List<string> otherSlot = dataSource.Where(a => a != "SD" && !string.IsNullOrEmpty(a)).ToList().Distinct().ToList();
  272. if (dataSource == null || dataSource.Count == 0)
  273. {
  274. return new Tuple<int, int>(0, 0);
  275. }
  276. List<int> minList = new List<int>();
  277. for (int i = 0; i < dataSource.Count; i++)
  278. {
  279. var item = dataSource[i];
  280. if (otherSlot.Contains(item) && !string.IsNullOrEmpty(item))
  281. {
  282. break;
  283. }
  284. if (string.IsNullOrEmpty(item))
  285. {
  286. continue;
  287. }
  288. minList.Add(i);
  289. }
  290. dataSource.Reverse();
  291. List<int> maxList = new List<int>();
  292. for (int i = 0; i < dataSource.Count; i++)
  293. {
  294. var item = dataSource[i];
  295. if (otherSlot.Contains(item) && !string.IsNullOrEmpty(item))
  296. {
  297. break;
  298. }
  299. if (string.IsNullOrEmpty(item))
  300. {
  301. continue;
  302. }
  303. maxList.Add(i);
  304. }
  305. return new Tuple<int, int>(minList.Count(), maxList.Count());
  306. }
  307. public enum ProcessEndResultEnum
  308. {
  309. [Description("NORMAL END")]
  310. NORMALEND,
  311. [Description("ABNORMAL END")]
  312. ABNORMALEND,
  313. [Description("NONE")]
  314. NONE,
  315. [Description("Recipe Abort")]
  316. Abort,
  317. [Description("Normal")]
  318. Normal, [Description("Succeed")]
  319. Succeed,
  320. }
  321. public class ProcessDetailV2ViewData : PropertyChangedBase
  322. {
  323. private string _processEndResult;
  324. public string ProcessEndResult
  325. {
  326. get => _processEndResult;
  327. set
  328. {
  329. _processEndResult = value;
  330. NotifyOfPropertyChange(nameof(ProcessEndResult));
  331. }
  332. }
  333. private string _pJobStartTime = "";
  334. public string PJobStartTime
  335. {
  336. get => _pJobStartTime;
  337. set
  338. {
  339. _pJobStartTime = value;
  340. NotifyOfPropertyChange(nameof(PJobStartTime));
  341. }
  342. }
  343. public string PJobEndTime
  344. {
  345. get => _pJobEndTime;
  346. set
  347. {
  348. _pJobEndTime = value;
  349. NotifyOfPropertyChange(nameof(PJobEndTime));
  350. }
  351. }
  352. private string _pJobEndTime = "";
  353. public string ExecREcipeThinckess
  354. {
  355. get => _execREcipeThinckess;
  356. set
  357. {
  358. _execREcipeThinckess = value;
  359. NotifyOfPropertyChange(nameof(ExecREcipeThinckess));
  360. }
  361. }
  362. private string _execREcipeThinckess = "";
  363. public string ProcessStartTime
  364. {
  365. get => _processStartTime;
  366. set
  367. {
  368. _processStartTime = value;
  369. NotifyOfPropertyChange(nameof(ProcessStartTime));
  370. }
  371. }
  372. private string _processStartTime = "";
  373. public string ProcessEndTime
  374. {
  375. get => _processEndTime;
  376. set
  377. {
  378. _processEndTime = value;
  379. NotifyOfPropertyChange(nameof(ProcessEndTime));
  380. }
  381. }
  382. private string _processEndTime = "";
  383. public string CJobId
  384. {
  385. get => _cJobId;
  386. set
  387. {
  388. _cJobId = value;
  389. NotifyOfPropertyChange(nameof(CJobId));
  390. }
  391. }
  392. private string _cJobId = "";
  393. private List<string> _pCarrierIdList = new List<string>();
  394. public List<string> PCarrierIdList
  395. {
  396. get => _pCarrierIdList;
  397. set
  398. {
  399. _pCarrierIdList = value;
  400. NotifyOfPropertyChange(nameof(PCarrierIdList));
  401. }
  402. }
  403. private bool _isSettingUp = false;
  404. public bool IsSettingUp
  405. {
  406. get => _isSettingUp;
  407. set
  408. {
  409. _isSettingUp = value;
  410. NotifyOfPropertyChange(nameof(IsSettingUp));
  411. }
  412. }
  413. private bool _isProcessing = false;
  414. public bool IsProcessing
  415. {
  416. get => _isProcessing;
  417. set
  418. {
  419. _isProcessing = value;
  420. NotifyOfPropertyChange(nameof(IsProcessing));
  421. }
  422. }
  423. private bool _isProcessComplete = false;
  424. public bool IsProcessComplete
  425. {
  426. get => _isProcessComplete;
  427. set
  428. {
  429. _isProcessComplete = value;
  430. NotifyOfPropertyChange(nameof(IsProcessComplete));
  431. }
  432. }
  433. }
  434. }
  435. }