ProcessHistoryViewModel.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  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 limit {m_onePageCounts} offset {(1 - 1) * m_onePageCounts};";
  326. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  327. if (dbData == null || dbData.Rows.Count == 0) return;
  328. for (int i = 0; i < dbData.Rows.Count; i++)
  329. {
  330. RecipeItem item = new RecipeItem();
  331. item.Selected = false;
  332. item.Recipe = dbData.Rows[i]["recipe_name"].ToString();
  333. item.Guid = dbData.Rows[i]["guid"].ToString();
  334. item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();
  335. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  336. item.Status = dbData.Rows[i]["process_status"].ToString();
  337. item.SlotID = dbData.Rows[i]["slot_id"].ToString();
  338. item.RecipeType = dbData.Rows[i]["recipe_type"].ToString();
  339. item.LotID = dbData.Rows[i]["lot_id"].ToString();
  340. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  341. item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  342. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  343. item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss");
  344. Recipes.Add(item);
  345. }
  346. }
  347. catch (Exception e)
  348. {
  349. LOG.WriteExeption(e);
  350. }
  351. }
  352. private void CalKeys(ParameterNode parameterNode)
  353. {
  354. if (parameterNode.ChildNodes.Count > 0)
  355. {
  356. foreach (var item in parameterNode.ChildNodes)
  357. {
  358. CalKeys(item);
  359. }
  360. }
  361. else
  362. {
  363. if (parameterNode.Selected == true)
  364. {
  365. keys.Add(parameterNode.Name);
  366. }
  367. }
  368. }
  369. private Dictionary<string, List<HistoryDataItem>> GetData(List<string> keys, DateTime from, DateTime to)
  370. {
  371. string sql = "select time AS InternalTimeStamp";
  372. foreach (var dataId in keys)
  373. {
  374. sql += "," + string.Format("\"{0}\"", dataId);
  375. }
  376. sql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
  377. from.ToString("yyyyMMdd") + "." + "Data", from.Ticks, to.Ticks);
  378. DataTable dataTable = QueryDataClient.Instance.Service.QueryData(sql);
  379. Dictionary<string, List<HistoryDataItem>> historyData = new Dictionary<string, List<HistoryDataItem>>();
  380. if (dataTable == null || dataTable.Rows.Count == 0)
  381. return null;
  382. DateTime dt = new DateTime();
  383. Dictionary<int, string> colName = new Dictionary<int, string>();
  384. for (int colNo = 0; colNo < dataTable.Columns.Count; colNo++)
  385. {
  386. colName.Add(colNo, dataTable.Columns[colNo].ColumnName);
  387. historyData[dataTable.Columns[colNo].ColumnName] = new List<HistoryDataItem>();
  388. }
  389. for (int rowNo = 0; rowNo < dataTable.Rows.Count; rowNo++)
  390. {
  391. PointCollection points = new PointCollection();
  392. var row = dataTable.Rows[rowNo];
  393. for (int i = 0; i < dataTable.Columns.Count; i++)
  394. {
  395. HistoryDataItem data = new HistoryDataItem();
  396. if (i == 0)
  397. {
  398. long ticks = (long)row[i];
  399. dt = new DateTime(ticks);
  400. continue;
  401. }
  402. else
  403. {
  404. string dataId = colName[i];
  405. if (row[i] is DBNull || row[i] == null)
  406. {
  407. data.dateTime = dt;
  408. data.dbName = colName[i];
  409. data.value = 0;
  410. }
  411. else if (row[i] is bool)
  412. {
  413. data.dateTime = dt;
  414. data.dbName = colName[i];
  415. data.value = (bool)row[i] ? 1 : 0;
  416. }
  417. else
  418. {
  419. data.dateTime = dt;
  420. data.dbName = colName[i];
  421. data.value = float.Parse(row[i].ToString());
  422. }
  423. }
  424. historyData[data.dbName].Add(data);
  425. }
  426. }
  427. foreach (var item in historyData)
  428. {
  429. item.Value.Sort((x, y) => DateTime.Compare(x.dateTime, y.dateTime));
  430. }
  431. return historyData;
  432. }
  433. private bool RefreshTreeStatusToChild(ParameterNode node)
  434. {
  435. if (node.ChildNodes.Count > 0)
  436. {
  437. for (int i = 0; i < node.ChildNodes.Count; i++)
  438. {
  439. ParameterNode n = node.ChildNodes[i];
  440. n.Selected = node.Selected;
  441. if (!RefreshTreeStatusToChild(n))
  442. {
  443. //uncheck left node
  444. for (int j = i; j < node.ChildNodes.Count; j++)
  445. {
  446. node.ChildNodes[j].Selected = !node.Selected;
  447. }
  448. //node.Selected = !node.Selected;
  449. return false;
  450. }
  451. }
  452. }
  453. //else
  454. //{
  455. // if (node.Selected == true)
  456. // {
  457. // keys.Add(node.Name);
  458. // }
  459. // else
  460. // {
  461. // keys.Remove(node.Name);
  462. // }
  463. //}
  464. return true;
  465. }
  466. private void RefreshTreeStatusToParent(ParameterNode node)
  467. {
  468. if (node.ParentNode != null)
  469. {
  470. if (node.Selected)
  471. {
  472. bool flag = true;
  473. for (int i = 0; i < node.ParentNode.ChildNodes.Count; i++)
  474. {
  475. if (!node.ParentNode.ChildNodes[i].Selected)
  476. {
  477. flag = false; //as least one child is unselected
  478. break;
  479. }
  480. }
  481. if (flag)
  482. node.ParentNode.Selected = true;
  483. }
  484. else
  485. {
  486. node.ParentNode.Selected = false;
  487. }
  488. RefreshTreeStatusToParent(node.ParentNode);
  489. }
  490. }
  491. public static T DeepCopyJson<T>(T obj)
  492. {
  493. // 序列化
  494. string json = JsonConvert.SerializeObject(obj);
  495. // 反序列化
  496. return JsonConvert.DeserializeObject<T>(json);
  497. }
  498. private void OnParameterCheck(object obj)
  499. {
  500. ParameterNode node = obj as ParameterNode;
  501. if (!RefreshTreeStatusToChild(node))
  502. {
  503. node.Selected = !node.Selected;
  504. }
  505. else
  506. {
  507. RefreshTreeStatusToParent(node);
  508. }
  509. keys.Clear();
  510. for (int i = 0; i < ParameterNodes.Count; i++)
  511. {
  512. CalKeys(ParameterNodes[i]);
  513. }
  514. if (keys.Count > 10)
  515. {
  516. WPFMessageBox.ShowWarning("最多显示10个数据");
  517. return;
  518. }
  519. OldPdKeyDataCollection.Clear();
  520. OldPdKeyDataCollection = DeepCopyJson(PdKeyDataCollection);
  521. PdKeyDataCollection.Clear();
  522. for (int i = 0; i < keys.Count; i++)
  523. {
  524. if (i == 10)
  525. {
  526. break;
  527. }
  528. PdKeyDataCollection.Add(new PdKeyData() { Key = keys[i], Color = solidColorBrushes[i], UniqueId = i });
  529. }
  530. Compare(OldPdKeyDataCollection, PdKeyDataCollection);
  531. PdKeyDataCollection = DeepCopyJson(OldPdKeyDataCollection);
  532. }
  533. public void Compare(ObservableCollection<PdKeyData> olddata, ObservableCollection<PdKeyData> newdata)
  534. {
  535. if (newdata != null)
  536. {
  537. for (int i = 0; i < newdata.Count; i++)
  538. {
  539. var lists = olddata.ToList().Find(t => t.Key == newdata[i].Key);
  540. if (lists == null)
  541. {
  542. olddata.Add(new PdKeyData() { Key = newdata[i].Key, Color = solidColorBrushes[i], UniqueId = olddata.Count + 1 });
  543. }
  544. }
  545. for (int i = 0; i < olddata.Count; i++)
  546. {
  547. var lists = newdata.ToList().Find(t => t.Key == olddata[i].Key);
  548. if (lists == null)
  549. {
  550. olddata.Remove(olddata[i]);
  551. }
  552. }
  553. }
  554. }
  555. public void UpdateData(RecipeItem dataLog)
  556. {
  557. OnClearData();
  558. //CheckRecipe(dataLog.Guid);
  559. }
  560. public void CheckRecipe(string RecipeGuid)
  561. {
  562. string sql = $"SELECT * FROM \"recipe_step_data\" where \"process_data_guid\" = '{RecipeGuid}' order by step_number ASC;";
  563. var dbData = QueryDataClient.Instance.Service.QueryData(sql);
  564. List<StepData> steps = new List<StepData>();
  565. if (dbData != null && dbData.Rows.Count > 0)
  566. {
  567. for (int i = 0; i < dbData.Rows.Count; i++)
  568. {
  569. StepData item = new StepData();
  570. item.No = int.Parse(dbData.Rows[i]["step_number"].ToString());
  571. item.Name = dbData.Rows[i]["step_name"].ToString();
  572. if (!dbData.Rows[i]["step_begin_time"].Equals(DBNull.Value))
  573. item.StartTime = (DateTime)dbData.Rows[i]["step_begin_time"];
  574. if (!dbData.Rows[i]["step_end_time"].Equals(DBNull.Value))
  575. item.EndTime = (DateTime)dbData.Rows[i]["step_end_time"];
  576. item.ActualTime = item.EndTime.CompareTo(item.StartTime) <= 0 ? "" : item.EndTime.Subtract(item.StartTime).TotalSeconds.ToString();
  577. item.SettingTime = dbData.Rows[i]["step_time"].ToString();
  578. //annotation.Add(VerLine(Brushes.Blue, item.StartTime, Brushes.Blue, $"{item.No}:{item.Name}"));
  579. }
  580. }
  581. }
  582. public void OnDataGridSelectionChanged(object obj)
  583. {
  584. selectedRecipeItem = obj as RecipeItem;
  585. ParameterNodes = new ObservableCollection<ParameterNode>(_provider.GetParameters().Where(x => x.Name == selectedRecipeItem?.Chamber));
  586. }
  587. public void OnSearchData()
  588. {
  589. ProcessData.Clear();
  590. this.view.MyDrawGraphicsControl.ClearPlotPoints();
  591. var Keys = new List<string>();
  592. PdKeyDataCollection.ToList().ForEach(key =>
  593. {
  594. Keys.Add(key.Key);
  595. });
  596. if (keys.Count == 0)
  597. {
  598. return;
  599. }
  600. var result = GetData(Keys.Distinct().ToList(), Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));
  601. if (result == null)
  602. {
  603. return;
  604. }
  605. List<PointCollection> cls = new List<PointCollection>();
  606. for (int i = 0; i < Keys.Count; i++)
  607. {
  608. PointCollection points = new PointCollection();
  609. int k = 1;
  610. result[Keys[i]].ForEach(point =>
  611. {
  612. ProcessData.Add(new HistoryDataItem() { dateTime = point.dateTime, dbName = Keys[i], value = point.value });
  613. points.Add(new Point() { X = point.dateTime.ToOADate(), Y = point.value });
  614. k += 1;
  615. });
  616. cls.Add(points);
  617. }
  618. for (int i = 0; i < PdKeyDataCollection.Count(); i++)
  619. {
  620. var _color = PdKeyDataCollection[i].Color.Color;
  621. view.MyDrawGraphicsControl.m_PenCollencteions[i] = new System.Drawing.Pen(System.Drawing.Color.FromArgb(_color.A, _color.R, _color.G, _color.B), 2);
  622. }
  623. this.view.MyDrawGraphicsControl.PointCollections = cls;
  624. this.view.MyDrawGraphicsControl.FitControl();
  625. this.view.MyDrawGraphicsControl.YPoints.Clear();
  626. //var item = QueryDataClient.Instance.Service.GetHistorySteps(Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));
  627. //if (item!=null)
  628. //{
  629. // item.ForEach(x =>
  630. // {
  631. // this.view.MyDrawGraphicsControl.YPoints.Add(new Venus_Core.StepItem() { StartValue = x.StartTime.ToOADate(), Information = $"{x.RecipeId}:{x.StepNo}" });
  632. // });
  633. //}
  634. if (IsShowStep)
  635. {
  636. var item2 = QueryDataClient.Instance.Service.GetHistorySteps(Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));
  637. item2?.ForEach(x =>
  638. {
  639. if (x.RecipeId == selectedRecipeItem.Chamber)
  640. {
  641. 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")}" });
  642. }
  643. });
  644. }
  645. }
  646. private void CloseAll(ObservableCollection<ParameterNode> parameterNodes)
  647. {
  648. if (parameterNodes != null)
  649. {
  650. foreach (var item in parameterNodes)
  651. {
  652. item.Selected = false;
  653. if (item.ChildNodes.Count > 0)
  654. {
  655. CloseAll(item.ChildNodes);
  656. }
  657. }
  658. }
  659. }
  660. private void OnClearData()
  661. {
  662. this.view.MyDrawGraphicsControl.YPoints.Clear();
  663. PdKeyDataCollection.Clear();
  664. this.view.MyDrawGraphicsControl.ClearPlotPoints();
  665. CloseAll(ParameterNodes);
  666. }
  667. public void ColorChanged()
  668. {
  669. for (int i = 0; i < PdKeyDataCollection.Count(); i++)
  670. {
  671. var _color = PdKeyDataCollection[i].Color.Color;
  672. this.view.MyDrawGraphicsControl.m_PenCollencteions[i] = new System.Drawing.Pen(System.Drawing.Color.FromArgb(_color.A, _color.R, _color.G, _color.B), 2);
  673. }
  674. }
  675. //private void OnExportRecipes()
  676. //{
  677. // try
  678. // {
  679. // Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  680. // dlg.DefaultExt = ".xls"; // Default file extension
  681. // dlg.Filter = "Excel数据表格文件(*.xls)|*.xls"; // Filter files by extension
  682. // Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  683. // if (result == true) // Process open file dialog box results
  684. // {
  685. // System.Data.DataSet ds = new System.Data.DataSet();
  686. // ds.Tables.Add(new System.Data.DataTable("Recipes"));
  687. // ds.Tables[0].Columns.Add("Start");
  688. // ds.Tables[0].Columns.Add("End");
  689. // ds.Tables[0].Columns.Add("Chamber");
  690. // ds.Tables[0].Columns.Add("Guid");
  691. // ds.Tables[0].Columns.Add("WaferID");
  692. // ds.Tables[0].Columns.Add("Recipe");
  693. // ds.Tables[0].Columns.Add("Status");
  694. // foreach (var item in Recipes)
  695. // {
  696. // var row = ds.Tables[0].NewRow();
  697. // row[0] = item.StartTime;
  698. // row[1] = item.EndTime;
  699. // row[2] = item.Chamber;
  700. // row[3] = item.Guid;
  701. // row[4] = item.LotID;
  702. // row[5] = item.Recipe;
  703. // row[6] = item.Status;
  704. // ds.Tables[0].Rows.Add(row);
  705. // }
  706. // ds.WriteXml(dlg.FileName);
  707. // }
  708. // }
  709. // catch
  710. // {
  711. // MessageBox.Show("导出系统日志发生错误", "导出失败", MessageBoxButton.OK, MessageBoxImage.Warning);
  712. // }
  713. //}
  714. private void OnExportRecipeData()
  715. {
  716. try
  717. {
  718. RecipeItem log = (this.view.dataGrid_RecipeList.SelectedItem) as RecipeItem;
  719. if (log == null)
  720. {
  721. WPFMessageBox.ShowError("没有数据,先从列表中选择一个批次");
  722. return;
  723. }
  724. Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  725. dlg.DefaultExt = ".xls"; // Default file extension
  726. dlg.Filter = "数据表格文件|*.xls"; // Filter files by extension
  727. dlg.FileName = string.Format("{0}-{1}", StartDateTime.ToString("yyyyMMdd"), log.Recipe.Replace(" ", "").Replace("/", ""));
  728. Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  729. if (result != true) // Process open file dialog box results
  730. return;
  731. System.Data.DataSet ds = new System.Data.DataSet();
  732. ds.Tables.Add(new System.Data.DataTable("RecipeData"));
  733. //var item = ProcessData;
  734. ds.Tables[0].Columns.Add("Name");
  735. ds.Tables[0].Columns.Add("Time");
  736. ds.Tables[0].Columns.Add("Value");
  737. foreach (var item in ProcessData)
  738. {
  739. var row = ds.Tables[0].NewRow();
  740. row[0] = item.dbName;
  741. row[1] = item.dateTime;
  742. row[2] = item.value;
  743. ds.Tables[0].Rows.Add(row);
  744. }
  745. ds.WriteXml(dlg.FileName);
  746. }
  747. catch (Exception ex)
  748. {
  749. WPFMessageBox.ShowError($"导出系统日志发生错误{ex.Message}");
  750. }
  751. }
  752. }
  753. #endregion
  754. #region 数据类
  755. public class RecipeItem : BindableBase
  756. {
  757. public bool Selected { get; set; }
  758. public string Recipe { get; set; }
  759. public string Guid { get; set; }
  760. public string RecipeRunGuid { get; set; }
  761. public string Chamber { get; set; }
  762. public string Status { get; set; }
  763. public string StartTime { get; set; }
  764. public string EndTime { get; set; }
  765. public string LotID { get; set; }
  766. public string SlotID { get; set; }
  767. public string RecipeType { get; set; }
  768. }
  769. public class StepData
  770. {
  771. [DataMember]
  772. public int No { get; set; }
  773. [DataMember]
  774. public string Name { get; set; }
  775. [DataMember]
  776. public DateTime StartTime { get; set; }
  777. [DataMember]
  778. public DateTime EndTime { get; set; }
  779. [DataMember]
  780. public string ActualTime { get; set; }
  781. [DataMember]
  782. public string SettingTime { get; set; }
  783. }
  784. public class PdKeyData : BindableBase, ICloneable
  785. {
  786. public string Key { get; set; }
  787. public SolidColorBrush _Color;
  788. public SolidColorBrush Color
  789. {
  790. get { return _Color; }
  791. set { SetProperty(ref _Color, value); }
  792. }
  793. public int UniqueId { get; set; }
  794. public object Clone()
  795. {
  796. return MemberwiseClone();
  797. }
  798. }
  799. #endregion
  800. }