ProcessHistoryViewModel.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. using MECF.Framework.Common.DataCenter;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Windows.Media;
  6. using System.Linq;
  7. using Prism.Commands;
  8. using Prism.Mvvm;
  9. using Venus_MainPages.Unity;
  10. using Venus_MainPages.Views;
  11. using System.Collections.ObjectModel;
  12. using System.Windows.Threading;
  13. using System.Windows;
  14. using Aitex.Core.RT.Log;
  15. using Aitex.Core.UI.ControlDataContext;
  16. using WPF.Themes.UserControls;
  17. using System.IO;
  18. using Newtonsoft.Json;
  19. using System.Runtime.Serialization;
  20. using Microsoft.VisualBasic.Logging;
  21. using ExcelLibrary.BinaryFileFormat;
  22. using ExcelLibrary.SpreadSheet;
  23. using Venus_Themes.UserControls;
  24. namespace Venus_MainPages.ViewModels
  25. {
  26. public class ProcessHistoryViewModel : BindableBase
  27. {
  28. #region 私有字段
  29. private ProcessHistoryView view;
  30. List<string> keys = new List<string>();
  31. RealtimeProvider _provider = new RealtimeProvider();
  32. private ObservableCollection<ParameterNode> _ParameterNodes;
  33. DispatcherTimer timer = new DispatcherTimer();
  34. ObservableCollection<PdKeyData> _PdKeyDataObservation = new ObservableCollection<PdKeyData>();
  35. public List<string> RecipesAdd = new List<string>();
  36. public List<SolidColorBrush> solidColorBrushes = new List<SolidColorBrush>();
  37. //DateTime currentTime;
  38. private RecipeItem selectedRecipeItem;
  39. private bool m_IsShowStep;
  40. private int m_PageCount;
  41. private int m_onePageCounts = 7;
  42. private int m_Total;
  43. private bool m_FirstLoadFlag = true;
  44. #endregion
  45. #region 属性
  46. public List<HistoryDataItem> ProcessData { get; set; }
  47. public List<Recipeslist> CheboxRecipes { get; set; }
  48. public ProcessDataChartDataItem ProcessChartData { get; set; }
  49. public DateTime StartDateTime { get; set; }
  50. public DateTime EndDateTime { get; set; }
  51. public string SelectedValuePM { get; set; }
  52. public string RecipeName { get; set; }
  53. public ObservableCollection<PdKeyData> OldPdKeyDataCollection { get; set; }
  54. public ObservableCollection<RecipeItem> Recipes { get; set; }
  55. public class Recipeslist
  56. {
  57. public string BoxName { get; set; }
  58. }
  59. public class RecipeAdd
  60. {
  61. public string Recipesname { get; set; }
  62. }
  63. public ObservableCollection<ParameterNode> ParameterNodes
  64. {
  65. get { return _ParameterNodes; }
  66. set { SetProperty(ref _ParameterNodes, value); }
  67. }
  68. public ObservableCollection<PdKeyData> PdKeyDataCollection
  69. {
  70. get { return _PdKeyDataObservation; }
  71. set { SetProperty(ref _PdKeyDataObservation, value); }
  72. }
  73. public bool IsShowStep
  74. {
  75. get { return m_IsShowStep; }
  76. set { SetProperty(ref m_IsShowStep, value); }
  77. }
  78. public int PageCount
  79. {
  80. get { return m_PageCount; }
  81. set
  82. {
  83. SetProperty(ref m_PageCount, value);
  84. }
  85. }
  86. public int Total
  87. {
  88. get { return m_Total; }
  89. set
  90. {
  91. SetProperty(ref m_Total, value);
  92. }
  93. }
  94. #endregion
  95. #region 命令
  96. private DelegateCommand<object> _LoadCommandPD;
  97. public DelegateCommand<object> LoadCommandPD =>
  98. _LoadCommandPD ?? (_LoadCommandPD = new DelegateCommand<object>(OnLoadPd));
  99. private DelegateCommand _SearchRecipeCommand;
  100. public DelegateCommand SearchRecipeCommand =>
  101. _SearchRecipeCommand ?? (_SearchRecipeCommand = new DelegateCommand(SearchRecipes));
  102. private DelegateCommand<object> _PdParameterCheckCommand;
  103. public DelegateCommand<object> PdParameterCheckCommand =>
  104. _PdParameterCheckCommand ?? (_PdParameterCheckCommand = new DelegateCommand<object>(OnParameterCheck));
  105. private DelegateCommand<object> _DataGridSelectionChangedCommand;
  106. public DelegateCommand<object> DataGridSelectionChangedCommand =>
  107. _DataGridSelectionChangedCommand ?? (_DataGridSelectionChangedCommand = new DelegateCommand<object>(OnDataGridSelectionChanged));
  108. private DelegateCommand _SearchDataCommand;
  109. public DelegateCommand SearchDataCommand =>
  110. _SearchDataCommand ?? (_SearchDataCommand = new DelegateCommand(OnSearchData));
  111. private DelegateCommand _ClearDataCommand;
  112. public DelegateCommand ClearDataCommand =>
  113. _ClearDataCommand ?? (_ClearDataCommand = new DelegateCommand(OnClearData));
  114. //private DelegateCommand _ExportRecipesCommand;
  115. //public DelegateCommand ExportRecipesCommand =>
  116. //_ExportRecipesCommand ?? (_ExportRecipesCommand = new DelegateCommand(OnExportRecipes));
  117. private DelegateCommand _RecipeDataExportCommand;
  118. public DelegateCommand RecipeDataExportCommand =>
  119. _RecipeDataExportCommand ?? (_RecipeDataExportCommand = new DelegateCommand(OnExportRecipeData));
  120. #endregion
  121. #region 构造函数
  122. public ProcessHistoryViewModel()
  123. {
  124. ProcessData = new List<HistoryDataItem>() { };
  125. ProcessChartData = new ProcessDataChartDataItem(60000);
  126. Recipes = new ObservableCollection<RecipeItem>();
  127. timer.Interval = TimeSpan.FromSeconds(0.5);
  128. OldPdKeyDataCollection = new ObservableCollection<PdKeyData>();
  129. CheboxRecipes = new List<Recipeslist>();
  130. solidColorBrushes.Add(new SolidColorBrush(Colors.Green));
  131. solidColorBrushes.Add(new SolidColorBrush(Colors.Red));
  132. solidColorBrushes.Add(new SolidColorBrush(Colors.Blue));
  133. solidColorBrushes.Add(new SolidColorBrush(Colors.Orange));
  134. solidColorBrushes.Add(new SolidColorBrush(Colors.Yellow));
  135. solidColorBrushes.Add(new SolidColorBrush(Colors.YellowGreen));
  136. solidColorBrushes.Add(new SolidColorBrush(Colors.AliceBlue));
  137. solidColorBrushes.Add(new SolidColorBrush(Colors.Chocolate));
  138. solidColorBrushes.Add(new SolidColorBrush(Colors.Cyan));
  139. solidColorBrushes.Add(new SolidColorBrush(Colors.DarkGreen));
  140. }
  141. #endregion
  142. #region 命令方法
  143. private void OnLoadPd(Object eventView)
  144. {
  145. if (m_FirstLoadFlag)
  146. {
  147. m_FirstLoadFlag = false;
  148. this.view = (ProcessHistoryView)eventView;
  149. this.view.wfTimeFrom.Value = DateTime.Today;
  150. this.view.wfTimeTo.Value = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 23, 59, 59, 999);
  151. this.LoadRecipeCheckBox();
  152. this.view.pageControl.CurrentPageChanged += PageControl_CurrentPageChanged;
  153. }
  154. }
  155. private void PageControl_CurrentPageChanged(int currentPage)
  156. {
  157. PageChanged(currentPage);
  158. }
  159. public void PageChanged(int CurrentPage)
  160. {
  161. Recipes.Clear();
  162. string sql = $"SELECT * FROM \"process_data\" where \"process_begin_time\" >='{StartDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff")}' and \"process_begin_time\" <='{EndDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff")}' ";
  163. if (!string.IsNullOrEmpty(SelectedValuePM))
  164. {
  165. string[] pms = SelectedValuePM.Split(',');
  166. if (pms.Length > 0)
  167. {
  168. sql += " and (FALSE ";
  169. foreach (var pm in pms)
  170. {
  171. sql += $" OR \"process_in\"='{pm}' ";
  172. }
  173. sql += " ) ";
  174. }
  175. }
  176. if (!string.IsNullOrEmpty(RecipeName))
  177. {
  178. sql += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());
  179. }
  180. sql += $" order by \"process_begin_time\" ASC limit {m_onePageCounts} offset {(CurrentPage - 1) * m_onePageCounts};";
  181. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  182. if (dbData == null || dbData.Rows.Count == 0) return;
  183. for (int i = 0; i < dbData.Rows.Count; i++)
  184. {
  185. RecipeItem item = new RecipeItem();
  186. item.Selected = false;
  187. item.Recipe = dbData.Rows[i]["recipe_name"].ToString();
  188. item.Guid = dbData.Rows[i]["guid"].ToString();
  189. item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();
  190. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  191. item.Status = dbData.Rows[i]["process_status"].ToString();
  192. item.SlotID = dbData.Rows[i]["slot_id"].ToString();
  193. item.RecipeType = dbData.Rows[i]["recipe_type"].ToString();
  194. item.LotID = dbData.Rows[i]["lot_id"].ToString();
  195. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  196. item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  197. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  198. item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  199. Recipes.Add(item);
  200. }
  201. }
  202. private void LoadRecipeCheckBox()
  203. {
  204. List<string> chamber = new List<string>() { "PMA", "PMB", "PMC", "PMD" };
  205. CheboxRecipes.Clear();
  206. foreach (string item in chamber)
  207. {
  208. string path = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", item);
  209. if (Directory.Exists(path))
  210. {
  211. string[] dir = Directory.GetFiles(path);
  212. for (int i = 0; i < dir.Length; i++)
  213. {
  214. CheboxRecipes.Add(new Recipeslist { BoxName = Path.GetFileName(dir[i]) });
  215. }
  216. }
  217. }
  218. }
  219. public void SearchRecipes()
  220. {
  221. SearchRecipe(this.view.wfTimeFrom.Value, this.view.wfTimeTo.Value);
  222. }
  223. public void searchlot(string id)
  224. {
  225. Recipes.Clear();
  226. try
  227. {
  228. string sql1 = string.Format($"SELECT * FROM \"lot_wafer_data\" where guid ='{id}'; ");
  229. DataTable dbData1 = QueryDataClient.Instance.Service.QueryData(sql1);
  230. string lot_data_guid = dbData1.Rows[0]["wafer_data_guid"].ToString();
  231. string sql = string.Format($"SELECT * FROM \"process_data\" where wafer_data_guid ='{lot_data_guid}'");
  232. if (!string.IsNullOrEmpty(SelectedValuePM))
  233. {
  234. string[] pms = SelectedValuePM.Split(',');
  235. if (pms.Length > 0)
  236. {
  237. sql += " and (FALSE ";
  238. foreach (var pm in pms)
  239. {
  240. sql += $" OR \"process_in\"='{pm}' ";
  241. }
  242. sql += " ) ";
  243. }
  244. }
  245. if (!string.IsNullOrEmpty(RecipeName))
  246. {
  247. sql += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());
  248. }
  249. sql += " order by \"process_begin_time\" ASC;";
  250. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  251. System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  252. {
  253. if (dbData == null || dbData.Rows.Count == 0) return;
  254. for (int i = 0; i < dbData.Rows.Count; i++)
  255. {
  256. RecipeItem item = new RecipeItem();
  257. item.Selected = false;
  258. item.Recipe = dbData.Rows[i]["recipe_name"].ToString();
  259. item.Guid = dbData.Rows[i]["guid"].ToString();
  260. item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();
  261. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  262. item.Status = dbData.Rows[i]["process_status"].ToString();
  263. item.SlotID = dbData.Rows[i]["slot_id"].ToString();
  264. item.LotID = dbData.Rows[i]["lot_id"].ToString();
  265. item.RecipeType = dbData.Rows[i]["recipe_type"].ToString();
  266. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  267. item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  268. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  269. item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  270. Recipes.Add(item);
  271. }
  272. }));
  273. }
  274. catch (Exception e)
  275. {
  276. LOG.WriteExeption(e);
  277. }
  278. }
  279. public void SearchRecipe(DateTime start, DateTime end)
  280. {
  281. this.StartDateTime = start;
  282. this.EndDateTime = end;
  283. Recipes.Clear();
  284. try
  285. {
  286. string sqlGetCount = $"SELECT COUNT(*) FROM \"process_data\" where \"process_begin_time\" >='{StartDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff")}' and \"process_begin_time\" <='{EndDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff")}' ";
  287. if (!string.IsNullOrEmpty(SelectedValuePM))
  288. {
  289. string[] pms = SelectedValuePM.Split(',');
  290. if (pms.Length > 0)
  291. {
  292. sqlGetCount += " and (FALSE ";
  293. foreach (var pm in pms)
  294. {
  295. sqlGetCount += $" OR \"process_in\"='{pm}' ";
  296. }
  297. sqlGetCount += " ) ";
  298. }
  299. }
  300. if (!string.IsNullOrEmpty(RecipeName))
  301. {
  302. sqlGetCount += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());
  303. }
  304. sqlGetCount += " ;";
  305. Total = QueryDataClient.Instance.Service.GetDBEventAllCount(sqlGetCount);
  306. PageCount = (Total / m_onePageCounts) + 1;
  307. string sql = $"SELECT * FROM \"process_data\" where \"process_begin_time\" >='{StartDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff")}' and \"process_begin_time\" <='{EndDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff")}' ";
  308. if (!string.IsNullOrEmpty(SelectedValuePM))
  309. {
  310. string[] pms = SelectedValuePM.Split(',');
  311. if (pms.Length > 0)
  312. {
  313. sql += " and (FALSE ";
  314. foreach (var pm in pms)
  315. {
  316. sql += $" OR \"process_in\"='{pm}' ";
  317. }
  318. sql += " ) ";
  319. }
  320. }
  321. if (!string.IsNullOrEmpty(RecipeName))
  322. {
  323. sql += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());
  324. }
  325. sql += $" order by \"process_begin_time\" ASC ";
  326. if (PageCount > 5)
  327. {
  328. sql += $" limit {m_onePageCounts} offset {(1 - 1) * m_onePageCounts};";
  329. }
  330. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  331. if (dbData == null || dbData.Rows.Count == 0) return;
  332. for (int i = 0; i < dbData.Rows.Count; i++)
  333. {
  334. RecipeItem item = new RecipeItem();
  335. item.Selected = false;
  336. item.Recipe = dbData.Rows[i]["recipe_name"].ToString();
  337. item.Guid = dbData.Rows[i]["guid"].ToString();
  338. item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();
  339. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  340. item.Status = dbData.Rows[i]["process_status"].ToString();
  341. item.SlotID = dbData.Rows[i]["slot_id"].ToString();
  342. item.RecipeType = dbData.Rows[i]["recipe_type"].ToString();
  343. item.LotID = dbData.Rows[i]["lot_id"].ToString();
  344. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  345. item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  346. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  347. item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  348. Recipes.Add(item);
  349. }
  350. }
  351. catch (Exception e)
  352. {
  353. LOG.WriteExeption(e);
  354. }
  355. }
  356. private void CalKeys(ParameterNode parameterNode)
  357. {
  358. if (parameterNode.ChildNodes.Count > 0)
  359. {
  360. foreach (var item in parameterNode.ChildNodes)
  361. {
  362. CalKeys(item);
  363. }
  364. }
  365. else
  366. {
  367. if (parameterNode.Selected == true)
  368. {
  369. keys.Add(parameterNode.Name);
  370. }
  371. }
  372. }
  373. private Dictionary<string, List<HistoryDataItem>> GetData(List<string> keys, DateTime from, DateTime to)
  374. {
  375. string sql = "select time AS InternalTimeStamp";
  376. foreach (var dataId in keys)
  377. {
  378. sql += "," + string.Format("\"{0}\"", dataId);
  379. }
  380. sql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
  381. from.ToString("yyyyMMdd") + "." + "Data", from.Ticks, to.Ticks);
  382. DataTable dataTable = QueryDataClient.Instance.Service.QueryData(sql);
  383. Dictionary<string, List<HistoryDataItem>> historyData = new Dictionary<string, List<HistoryDataItem>>();
  384. if (dataTable == null || dataTable.Rows.Count == 0)
  385. return null;
  386. DateTime dt = new DateTime();
  387. Dictionary<int, string> colName = new Dictionary<int, string>();
  388. for (int colNo = 0; colNo < dataTable.Columns.Count; colNo++)
  389. {
  390. colName.Add(colNo, dataTable.Columns[colNo].ColumnName);
  391. historyData[dataTable.Columns[colNo].ColumnName] = new List<HistoryDataItem>();
  392. }
  393. for (int rowNo = 0; rowNo < dataTable.Rows.Count; rowNo++)
  394. {
  395. PointCollection points = new PointCollection();
  396. var row = dataTable.Rows[rowNo];
  397. for (int i = 0; i < dataTable.Columns.Count; i++)
  398. {
  399. HistoryDataItem data = new HistoryDataItem();
  400. if (i == 0)
  401. {
  402. long ticks = (long)row[i];
  403. dt = new DateTime(ticks);
  404. continue;
  405. }
  406. else
  407. {
  408. string dataId = colName[i];
  409. if (row[i] is DBNull || row[i] == null)
  410. {
  411. data.dateTime = dt;
  412. data.dbName = colName[i];
  413. data.value = 0;
  414. }
  415. else if (row[i] is bool)
  416. {
  417. data.dateTime = dt;
  418. data.dbName = colName[i];
  419. data.value = (bool)row[i] ? 1 : 0;
  420. }
  421. else
  422. {
  423. data.dateTime = dt;
  424. data.dbName = colName[i];
  425. data.value = float.Parse(row[i].ToString());
  426. }
  427. }
  428. historyData[data.dbName].Add(data);
  429. }
  430. }
  431. foreach (var item in historyData)
  432. {
  433. item.Value.Sort((x, y) => DateTime.Compare(x.dateTime, y.dateTime));
  434. }
  435. return historyData;
  436. }
  437. private bool RefreshTreeStatusToChild(ParameterNode node)
  438. {
  439. if (node.ChildNodes.Count > 0)
  440. {
  441. for (int i = 0; i < node.ChildNodes.Count; i++)
  442. {
  443. ParameterNode n = node.ChildNodes[i];
  444. n.Selected = node.Selected;
  445. if (!RefreshTreeStatusToChild(n))
  446. {
  447. //uncheck left node
  448. for (int j = i; j < node.ChildNodes.Count; j++)
  449. {
  450. node.ChildNodes[j].Selected = !node.Selected;
  451. }
  452. //node.Selected = !node.Selected;
  453. return false;
  454. }
  455. }
  456. }
  457. //else
  458. //{
  459. // if (node.Selected == true)
  460. // {
  461. // keys.Add(node.Name);
  462. // }
  463. // else
  464. // {
  465. // keys.Remove(node.Name);
  466. // }
  467. //}
  468. return true;
  469. }
  470. private void RefreshTreeStatusToParent(ParameterNode node)
  471. {
  472. if (node.ParentNode != null)
  473. {
  474. if (node.Selected)
  475. {
  476. bool flag = true;
  477. for (int i = 0; i < node.ParentNode.ChildNodes.Count; i++)
  478. {
  479. if (!node.ParentNode.ChildNodes[i].Selected)
  480. {
  481. flag = false; //as least one child is unselected
  482. break;
  483. }
  484. }
  485. if (flag)
  486. node.ParentNode.Selected = true;
  487. }
  488. else
  489. {
  490. node.ParentNode.Selected = false;
  491. }
  492. RefreshTreeStatusToParent(node.ParentNode);
  493. }
  494. }
  495. public static T DeepCopyJson<T>(T obj)
  496. {
  497. // 序列化
  498. string json = JsonConvert.SerializeObject(obj);
  499. // 反序列化
  500. return JsonConvert.DeserializeObject<T>(json);
  501. }
  502. private void OnParameterCheck(object obj)
  503. {
  504. ParameterNode node = obj as ParameterNode;
  505. if (!RefreshTreeStatusToChild(node))
  506. {
  507. node.Selected = !node.Selected;
  508. }
  509. else
  510. {
  511. RefreshTreeStatusToParent(node);
  512. }
  513. keys.Clear();
  514. for (int i = 0; i < ParameterNodes.Count; i++)
  515. {
  516. CalKeys(ParameterNodes[i]);
  517. }
  518. if (keys.Count > 10)
  519. {
  520. WPFMessageBox.ShowWarning("最多显示10个数据");
  521. return;
  522. }
  523. OldPdKeyDataCollection.Clear();
  524. OldPdKeyDataCollection = DeepCopyJson(PdKeyDataCollection);
  525. PdKeyDataCollection.Clear();
  526. for (int i = 0; i < keys.Count; i++)
  527. {
  528. if (i == 10)
  529. {
  530. break;
  531. }
  532. PdKeyDataCollection.Add(new PdKeyData() { Key = keys[i], Color = solidColorBrushes[i], UniqueId = i });
  533. }
  534. Compare(OldPdKeyDataCollection, PdKeyDataCollection);
  535. PdKeyDataCollection = DeepCopyJson(OldPdKeyDataCollection);
  536. }
  537. public void Compare(ObservableCollection<PdKeyData> olddata, ObservableCollection<PdKeyData> newdata)
  538. {
  539. if (newdata != null)
  540. {
  541. for (int i = 0; i < newdata.Count; i++)
  542. {
  543. var lists = olddata.ToList().Find(t => t.Key == newdata[i].Key);
  544. if (lists == null)
  545. {
  546. olddata.Add(new PdKeyData() { Key = newdata[i].Key, Color = solidColorBrushes[i], UniqueId = olddata.Count + 1 });
  547. }
  548. }
  549. for (int i = 0; i < olddata.Count; i++)
  550. {
  551. var lists = newdata.ToList().Find(t => t.Key == olddata[i].Key);
  552. if (lists == null)
  553. {
  554. olddata.Remove(olddata[i]);
  555. }
  556. }
  557. }
  558. }
  559. public void UpdateData(RecipeItem dataLog)
  560. {
  561. OnClearData();
  562. //CheckRecipe(dataLog.Guid);
  563. }
  564. public void CheckRecipe(string RecipeGuid)
  565. {
  566. string sql = $"SELECT * FROM \"recipe_step_data\" where \"process_data_guid\" = '{RecipeGuid}' order by step_number ASC;";
  567. var dbData = QueryDataClient.Instance.Service.QueryData(sql);
  568. List<StepData> steps = new List<StepData>();
  569. if (dbData != null && dbData.Rows.Count > 0)
  570. {
  571. for (int i = 0; i < dbData.Rows.Count; i++)
  572. {
  573. StepData item = new StepData();
  574. item.No = int.Parse(dbData.Rows[i]["step_number"].ToString());
  575. item.Name = dbData.Rows[i]["step_name"].ToString();
  576. if (!dbData.Rows[i]["step_begin_time"].Equals(DBNull.Value))
  577. item.StartTime = (DateTime)dbData.Rows[i]["step_begin_time"];
  578. if (!dbData.Rows[i]["step_end_time"].Equals(DBNull.Value))
  579. item.EndTime = (DateTime)dbData.Rows[i]["step_end_time"];
  580. item.ActualTime = item.EndTime.CompareTo(item.StartTime) <= 0 ? "" : item.EndTime.Subtract(item.StartTime).TotalSeconds.ToString();
  581. item.SettingTime = dbData.Rows[i]["step_time"].ToString();
  582. //annotation.Add(VerLine(Brushes.Blue, item.StartTime, Brushes.Blue, $"{item.No}:{item.Name}"));
  583. }
  584. }
  585. }
  586. public void OnDataGridSelectionChanged(object obj)
  587. {
  588. selectedRecipeItem = obj as RecipeItem;
  589. ParameterNodes = new ObservableCollection<ParameterNode>(_provider.GetParameters().Where(x => x.Name == selectedRecipeItem?.Chamber));
  590. }
  591. public void OnSearchData()
  592. {
  593. ProcessData.Clear();
  594. this.view.MyDrawGraphicsControl.ClearPlotPoints();
  595. var Keys = new List<string>();
  596. PdKeyDataCollection.ToList().ForEach(key =>
  597. {
  598. Keys.Add(key.Key);
  599. });
  600. if (keys.Count == 0)
  601. {
  602. return;
  603. }
  604. var result = GetData(Keys.Distinct().ToList(), Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));
  605. if (result == null)
  606. {
  607. return;
  608. }
  609. List<PointCollection> cls = new List<PointCollection>();
  610. for (int i = 0; i < Keys.Count; i++)
  611. {
  612. PointCollection points = new PointCollection();
  613. int k = 1;
  614. result[Keys[i]].ForEach(point =>
  615. {
  616. ProcessData.Add(new HistoryDataItem() { dateTime = point.dateTime, dbName = Keys[i], value = point.value });
  617. points.Add(new Point() { X = point.dateTime.ToOADate(), Y = point.value });
  618. k += 1;
  619. });
  620. cls.Add(points);
  621. }
  622. for (int i = 0; i < PdKeyDataCollection.Count(); i++)
  623. {
  624. var _color = PdKeyDataCollection[i].Color.Color;
  625. view.MyDrawGraphicsControl.m_PenCollencteions[i] = new System.Drawing.Pen(System.Drawing.Color.FromArgb(_color.A, _color.R, _color.G, _color.B), 2);
  626. }
  627. this.view.MyDrawGraphicsControl.PointCollections = cls;
  628. this.view.MyDrawGraphicsControl.FitControl();
  629. this.view.MyDrawGraphicsControl.YPoints.Clear();
  630. //var item = QueryDataClient.Instance.Service.GetHistorySteps(Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));
  631. //if (item!=null)
  632. //{
  633. // item.ForEach(x =>
  634. // {
  635. // this.view.MyDrawGraphicsControl.YPoints.Add(new Venus_Core.StepItem() { StartValue = x.StartTime.ToOADate(), Information = $"{x.RecipeId}:{x.StepNo}" });
  636. // });
  637. //}
  638. if (IsShowStep)
  639. {
  640. var item2 = QueryDataClient.Instance.Service.GetHistorySteps(Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));
  641. item2?.ForEach(x =>
  642. {
  643. if (x.RecipeId == selectedRecipeItem.Chamber)
  644. {
  645. this.view.MyDrawGraphicsControl.YPoints.Add(new Venus_Core.StepItem() { StartValue = x.StartTime.ToOADate(), Information = $"{x.RecipeId}\n{x.StepNo}\n{x.StartTime.ToString("HH:mm:ss:fff")}" });
  646. }
  647. });
  648. }
  649. }
  650. private void CloseAll(ObservableCollection<ParameterNode> parameterNodes)
  651. {
  652. if (parameterNodes != null)
  653. {
  654. foreach (var item in parameterNodes)
  655. {
  656. item.Selected = false;
  657. if (item.ChildNodes.Count > 0)
  658. {
  659. CloseAll(item.ChildNodes);
  660. }
  661. }
  662. }
  663. }
  664. private void OnClearData()
  665. {
  666. this.view.MyDrawGraphicsControl.YPoints.Clear();
  667. PdKeyDataCollection.Clear();
  668. this.view.MyDrawGraphicsControl.ClearPlotPoints();
  669. CloseAll(ParameterNodes);
  670. }
  671. public void ColorChanged()
  672. {
  673. for (int i = 0; i < PdKeyDataCollection.Count(); i++)
  674. {
  675. var _color = PdKeyDataCollection[i].Color.Color;
  676. this.view.MyDrawGraphicsControl.m_PenCollencteions[i] = new System.Drawing.Pen(System.Drawing.Color.FromArgb(_color.A, _color.R, _color.G, _color.B), 2);
  677. }
  678. }
  679. //private void OnExportRecipes()
  680. //{
  681. // try
  682. // {
  683. // Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  684. // dlg.DefaultExt = ".xls"; // Default file extension
  685. // dlg.Filter = "Excel数据表格文件(*.xls)|*.xls"; // Filter files by extension
  686. // Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  687. // if (result == true) // Process open file dialog box results
  688. // {
  689. // System.Data.DataSet ds = new System.Data.DataSet();
  690. // ds.Tables.Add(new System.Data.DataTable("Recipes"));
  691. // ds.Tables[0].Columns.Add("Start");
  692. // ds.Tables[0].Columns.Add("End");
  693. // ds.Tables[0].Columns.Add("Chamber");
  694. // ds.Tables[0].Columns.Add("Guid");
  695. // ds.Tables[0].Columns.Add("WaferID");
  696. // ds.Tables[0].Columns.Add("Recipe");
  697. // ds.Tables[0].Columns.Add("Status");
  698. // foreach (var item in Recipes)
  699. // {
  700. // var row = ds.Tables[0].NewRow();
  701. // row[0] = item.StartTime;
  702. // row[1] = item.EndTime;
  703. // row[2] = item.Chamber;
  704. // row[3] = item.Guid;
  705. // row[4] = item.LotID;
  706. // row[5] = item.Recipe;
  707. // row[6] = item.Status;
  708. // ds.Tables[0].Rows.Add(row);
  709. // }
  710. // ds.WriteXml(dlg.FileName);
  711. // }
  712. // }
  713. // catch
  714. // {
  715. // MessageBox.Show("导出系统日志发生错误", "导出失败", MessageBoxButton.OK, MessageBoxImage.Warning);
  716. // }
  717. //}
  718. private void OnExportRecipeData()
  719. {
  720. try
  721. {
  722. RecipeItem log = (this.view.dataGrid_RecipeList.SelectedItem) as RecipeItem;
  723. if (log == null)
  724. {
  725. WPFMessageBox.ShowError("没有数据,先从列表中选择一个批次");
  726. return;
  727. }
  728. Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  729. dlg.DefaultExt = ".xls"; // Default file extension
  730. dlg.Filter = "数据表格文件|*.xls"; // Filter files by extension
  731. dlg.FileName = string.Format("{0}-{1}", StartDateTime.ToString("yyyyMMdd"), log.Recipe.Replace(" ", "").Replace("/", ""));
  732. Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  733. if (result != true) // Process open file dialog box results
  734. return;
  735. System.Data.DataSet ds = new System.Data.DataSet();
  736. ds.Tables.Add(new System.Data.DataTable("RecipeData"));
  737. //var item = ProcessData;
  738. ds.Tables[0].Columns.Add("Name");
  739. ds.Tables[0].Columns.Add("Time");
  740. ds.Tables[0].Columns.Add("Value");
  741. foreach (var item in ProcessData)
  742. {
  743. var row = ds.Tables[0].NewRow();
  744. row[0] = item.dbName;
  745. row[1] = item.dateTime;
  746. row[2] = item.value;
  747. ds.Tables[0].Rows.Add(row);
  748. }
  749. ds.WriteXml(dlg.FileName);
  750. }
  751. catch (Exception ex)
  752. {
  753. WPFMessageBox.ShowError($"导出系统日志发生错误{ex.Message}");
  754. }
  755. }
  756. }
  757. #endregion
  758. #region 数据类
  759. public class RecipeItem : BindableBase
  760. {
  761. public bool Selected { get; set; }
  762. public string Recipe { get; set; }
  763. public string Guid { get; set; }
  764. public string RecipeRunGuid { get; set; }
  765. public string Chamber { get; set; }
  766. public string Status { get; set; }
  767. public string StartTime { get; set; }
  768. public string EndTime { get; set; }
  769. public string LotID { get; set; }
  770. public string SlotID { get; set; }
  771. public string RecipeType { get; set; }
  772. }
  773. public class StepData
  774. {
  775. [DataMember]
  776. public int No { get; set; }
  777. [DataMember]
  778. public string Name { get; set; }
  779. [DataMember]
  780. public DateTime StartTime { get; set; }
  781. [DataMember]
  782. public DateTime EndTime { get; set; }
  783. [DataMember]
  784. public string ActualTime { get; set; }
  785. [DataMember]
  786. public string SettingTime { get; set; }
  787. }
  788. public class PdKeyData : BindableBase, ICloneable
  789. {
  790. public string Key { get; set; }
  791. public SolidColorBrush _Color;
  792. public SolidColorBrush Color
  793. {
  794. get { return _Color; }
  795. set { SetProperty(ref _Color, value); }
  796. }
  797. public int UniqueId { get; set; }
  798. public object Clone()
  799. {
  800. return MemberwiseClone();
  801. }
  802. }
  803. #endregion
  804. }