ProcessHistoryViewModel.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Data;
  5. using System.Linq;
  6. using System.Windows;
  7. using System.Windows.Media;
  8. using Aitex.Core.RT.Log;
  9. using Aitex.Core.UI.ControlDataContext;
  10. using Aitex.Core.UI.MVVM;
  11. using MECF.Framework.Common.CommonData;
  12. using MECF.Framework.Common.ControlDataContext;
  13. using MECF.Framework.Common.DataCenter;
  14. using MECF.Framework.Common.Utilities;
  15. using SciChart.Charting.Visuals.Annotations;
  16. using SciChart.Charting.Visuals.Axes;
  17. using SciChart.Charting.Visuals.RenderableSeries;
  18. using SciChart.Data.Model;
  19. using VirgoUI.Client.Models.Sys;
  20. using Cali = Caliburn.Micro;
  21. namespace VirgoUI.Client.Models.History.ProcessHistory
  22. {
  23. public class ProcessHistoryViewModel : UiViewModelBase
  24. {
  25. private int MenuPermission;
  26. public ObservableCollection<RecipeItem> Recipes { get; set; }
  27. public List<HistoryDataItem> ProcessData { get; set; }
  28. public ObservableCollection<IRenderableSeries> SelectedData { get; set; }
  29. public ObservableCollection<RecipeItem> SelectedRecipes { get; set; }
  30. public DateTime StartDateTime { get; set; }
  31. public DateTime EndDateTime { get; set; }
  32. public string SelectedValuePM { get; set; }
  33. public string RecipeName { get; set; }
  34. public ProcessDataChartDataItem ProcessChartData
  35. {
  36. get;
  37. set;
  38. }
  39. public AutoRange ChartAutoRange
  40. {
  41. get { return EnableAutoZoom ? AutoRange.Always : AutoRange.Never; }
  42. }
  43. public AutoRange AutoRangeX
  44. {
  45. get => _autoRangeX;
  46. set
  47. {
  48. _autoRangeX = value;
  49. NotifyOfPropertyChange(nameof(AutoRangeX));
  50. }
  51. }
  52. public AutoRange AutoRangeY
  53. {
  54. get => _autoRangeY;
  55. set
  56. {
  57. _autoRangeY = value;
  58. NotifyOfPropertyChange(nameof(AutoRangeY));
  59. }
  60. }
  61. private bool _enableAutoZoom = true;
  62. public bool EnableAutoZoom
  63. {
  64. get { return _enableAutoZoom; }
  65. set
  66. {
  67. _enableAutoZoom = value;
  68. NotifyOfPropertyChange(nameof(EnableAutoZoom));
  69. NotifyOfPropertyChange(nameof(ChartAutoRange));
  70. }
  71. }
  72. private IRange _TimeRange;
  73. public IRange TimeRange
  74. {
  75. get { return _TimeRange; }
  76. set
  77. {
  78. _TimeRange = value;
  79. NotifyOfPropertyChange("TimeRange");
  80. }
  81. }
  82. private IRange _ValueRange;
  83. public IRange ValueRange
  84. {
  85. get { return _ValueRange; }
  86. set { _ValueRange = value; }
  87. }
  88. Cali.WindowManager wm = new Cali.WindowManager();
  89. SelectDataViewModel selectDataDlg = new SelectDataViewModel();
  90. private AutoRange _autoRangeX;
  91. private AutoRange _autoRangeY;
  92. private ProcessHistoryView view;
  93. public ProcessHistoryViewModel()
  94. {
  95. MenuPermission = ClientApp.Instance.GetPermission("ProcessHistory");
  96. var now = DateTime.Now;
  97. StartDateTime = now.AddHours(-2);
  98. EndDateTime = now;
  99. DisplayName = "Process History";
  100. ProcessChartData = new ProcessDataChartDataItem(60000);
  101. SelectedData = new ObservableCollection<IRenderableSeries>();
  102. SelectedRecipes = new ObservableCollection<RecipeItem>();
  103. Recipes = new ObservableCollection<RecipeItem>();
  104. TimeRange = new DateRange(DateTime.Now.AddMinutes(-1), DateTime.Now.AddMinutes(59));
  105. AutoRangeX = AutoRange.Once;
  106. AutoRangeY = AutoRange.Once;
  107. }
  108. public void SelectData()
  109. {
  110. selectDataDlg.SelectedRecipes.Clear();
  111. selectDataDlg.SelectedParameters.Clear();
  112. var settings = new Dictionary<string, object> { { "Title", "Select Recipe Data" } };
  113. bool? ret = wm.ShowDialog(selectDataDlg, null, settings);
  114. if (ret == null || !ret.Value) return;
  115. SelectedData.Clear();
  116. double valueMin = double.MaxValue;
  117. double valueMax = double.MinValue;
  118. DateTime dtMin = DateTime.MaxValue;
  119. DateTime dtMax = DateTime.MinValue;
  120. foreach (var recipe in selectDataDlg.SelectedRecipes)
  121. {
  122. if (Convert.ToDateTime(recipe.StartTime) < dtMin)
  123. dtMin = Convert.ToDateTime(recipe.StartTime);
  124. if (!string.IsNullOrEmpty(recipe.EndTime))
  125. {
  126. if (Convert.ToDateTime(recipe.EndTime) > dtMax)
  127. dtMax = Convert.ToDateTime(recipe.EndTime);
  128. }
  129. QueryData(recipe, selectDataDlg.SelectedParameters, ref valueMin, ref valueMax);
  130. }
  131. TimeRange = new DateRange(dtMin.AddMinutes(-1), dtMax.AddMinutes(5));
  132. ValueRange = new DoubleRange(valueMin - 5, valueMax + 5);
  133. }
  134. public void QueryData(RecipeItem recipe, ObservableCollection<string> keys, ref double min, ref double max)
  135. {
  136. if (string.IsNullOrEmpty(recipe.StartTime))
  137. {
  138. MessageBox.Show($"can not query recipe data, did not record {recipe.Recipe} start time");
  139. return;
  140. }
  141. DateTime dtFrom = Convert.ToDateTime(recipe.StartTime);
  142. DateTime dtTo = dtFrom.AddMinutes(10);
  143. if (!string.IsNullOrEmpty(recipe.EndTime))
  144. {
  145. dtTo = Convert.ToDateTime(recipe.EndTime);
  146. }
  147. Dictionary<string, List<Tuple<DateTime, double>>> result;
  148. if (GetDbData(recipe.Chamber, dtFrom, dtTo, keys, out result, ref min, ref max))
  149. {
  150. foreach (var data in result)
  151. {
  152. ChartDataLine line = new ChartDataLine(data.Key);
  153. line.DataSource = recipe.Recipe;
  154. foreach (var tuple in data.Value)
  155. {
  156. line.Append(tuple.Item1, tuple.Item2);
  157. }
  158. SelectedData.Add(line);
  159. }
  160. }
  161. }
  162. public bool GetDbData(string chamber, DateTime from, DateTime to, IEnumerable<string> dataIdList, out Dictionary<string, List<Tuple<DateTime, double>>> returnDatas, ref double min, ref double max)
  163. {
  164. returnDatas = new Dictionary<string, List<Tuple<DateTime, double>>>();
  165. for (DateTime dfrom = new DateTime(from.Year, from.Month, from.Day); dfrom < to; dfrom += new TimeSpan(1, 0, 0, 0))
  166. {
  167. DateTime begin = (dfrom.Year == from.Year && dfrom.Month == from.Month && dfrom.Day == from.Day) ? from : new DateTime(dfrom.Year, dfrom.Month, dfrom.Day, 0, 0, 0, 0);
  168. DateTime end = (dfrom.Date == to.Date) ? to : new DateTime(dfrom.Year, dfrom.Month, dfrom.Day, 23, 59, 59, 999);
  169. //if (begin.Date > DateTime.Today)
  170. // continue;
  171. try
  172. {
  173. string sql = "select time AS InternalTimeStamp";
  174. foreach (var dataId in dataIdList)
  175. {
  176. if (!returnDatas.Keys.Contains(dataId) && dataId.StartsWith($"{chamber}."))
  177. {
  178. returnDatas[dataId] = new List<Tuple<DateTime, double>>();
  179. sql += "," + string.Format("\"{0}\"", dataId);
  180. }
  181. }
  182. sql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc;",
  183. begin.ToString("yyyyMMdd") + "." + chamber, begin.Ticks, end.Ticks);
  184. using (var table = QueryDataClient.Instance.Service.QueryData(sql))
  185. {
  186. if (table == null || table.Rows.Count == 0) continue;
  187. DateTime dt = new DateTime();
  188. Dictionary<int, string> colName = new Dictionary<int, string>();
  189. for (int colNo = 0; colNo < table.Columns.Count; colNo++)
  190. colName.Add(colNo, table.Columns[colNo].ColumnName);
  191. for (int rowNo = 0; rowNo < table.Rows.Count; rowNo++)
  192. {
  193. var row = table.Rows[rowNo];
  194. for (int i = 0; i < table.Columns.Count; i++)
  195. {
  196. if (i == 0)
  197. {
  198. long ticks = (long)row[i];
  199. dt = new DateTime(ticks);
  200. }
  201. else
  202. {
  203. string dataId = colName[i];
  204. double value = 0.0;
  205. if (row[i] is DBNull || row[i] == null)
  206. {
  207. value = 0.0;
  208. }
  209. else if (row[i] is bool)
  210. {
  211. value = (bool)row[i] ? 1.0 : 0;
  212. }
  213. else
  214. {
  215. value = (double)float.Parse(row[i].ToString());
  216. }
  217. returnDatas[dataId].Add(Tuple.Create(dt, value));
  218. if (value < min)
  219. min = value;
  220. if (value > max)
  221. max = value;
  222. }
  223. }
  224. }
  225. table.Clear();
  226. }
  227. }
  228. catch (Exception ex)
  229. {
  230. LOG.Write(ex);
  231. return false;
  232. }
  233. }
  234. return true;
  235. }
  236. public void SearchRecipe()
  237. {
  238. if (MenuPermission != 3) return;
  239. this.StartDateTime = this.view.wfTimeFrom.Value;
  240. this.EndDateTime = this.view.wfTimeTo.Value;
  241. Recipes.Clear();
  242. //ObservableCollection<RecipeItem> items = ProcessHistoryProvider.Instance.SearchRecipe();
  243. //foreach (RecipeItem item in items)
  244. // Recipes.Add(item);
  245. try
  246. {
  247. 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")}' ";
  248. if (!string.IsNullOrEmpty(SelectedValuePM))
  249. {
  250. string[] pms = SelectedValuePM.Split(',');
  251. if (pms.Length > 0)
  252. {
  253. sql += " and (FALSE ";
  254. foreach (var pm in pms)
  255. {
  256. sql += $" OR \"process_in\"='{pm}' ";
  257. }
  258. sql += " ) ";
  259. }
  260. }
  261. if (!string.IsNullOrEmpty(RecipeName))
  262. {
  263. sql += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());
  264. }
  265. sql += " order by \"process_begin_time\" ASC;";
  266. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  267. Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  268. {
  269. if (dbData == null || dbData.Rows.Count == 0) return;
  270. for (int i = 0; i < dbData.Rows.Count; i++)
  271. {
  272. RecipeItem item = new RecipeItem();
  273. item.Recipe = dbData.Rows[i]["recipe_name"].ToString();
  274. item.Guid = dbData.Rows[i]["guid"].ToString();
  275. item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();
  276. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  277. item.Status = dbData.Rows[i]["process_status"].ToString();
  278. item.SlotID = dbData.Rows[i]["slot_id"].ToString();
  279. item.LotID = dbData.Rows[i]["lot_id"].ToString();
  280. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  281. item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss.fff");
  282. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  283. item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss.fff");
  284. Recipes.Add(item);
  285. }
  286. }));
  287. }
  288. catch (Exception e)
  289. {
  290. LOG.Write(e);
  291. }
  292. }
  293. public void CheckRecipe(RecipeItem recipe)
  294. {
  295. if (recipe.Selected)
  296. {
  297. SelectedRecipes.Add(recipe);
  298. }
  299. else
  300. {
  301. RecipeItem item = SelectedRecipes.FirstOrDefault(t => t.Recipe == recipe.Recipe);
  302. if (item != null)
  303. SelectedRecipes.Remove(item);
  304. }
  305. }
  306. public void CheckAllRecipe()
  307. {
  308. }
  309. public void UpdateData(RecipeItem dataLog)
  310. {
  311. if (dataLog == null)
  312. {
  313. ProcessChartData.ClearData();
  314. return;
  315. }
  316. List<string> keys = new List<string>();
  317. Application.Current.Dispatcher.Invoke(new Action(() =>
  318. {
  319. string type = "A";
  320. if (dataLog.Chamber == "PMA")
  321. {
  322. if ((bool) QueryDataClient.Instance.Service.GetConfig($"PMA.BiasRf.EnableBiasRF"))
  323. type = "B";
  324. }else if (dataLog.Chamber == "PMB")
  325. {
  326. if ((bool)QueryDataClient.Instance.Service.GetConfig($"PMB.BiasRf.EnableBiasRF"))
  327. type = "B";
  328. }
  329. Dictionary<string, Tuple<string, string, bool>> dicItems = GetDataElements("zh-CN", type, dataLog.Chamber);
  330. keys = dicItems.Keys.ToList();
  331. ProcessChartData.UpdateColumns(dicItems);
  332. }));
  333. ProcessData = QueryDataClient.Instance.Service.GetHistoryData(keys, dataLog.Guid, "Data");
  334. Application.Current.Dispatcher.Invoke(new Action(() =>
  335. {
  336. ProcessChartData.SetInfo(dataLog.Recipe);
  337. ProcessChartData.UpdateData(ProcessData);
  338. QueryRecipe(dataLog.Guid);
  339. if (DateTime.TryParse(dataLog.EndTime, out DateTime result))
  340. {
  341. ProcessChartData.Annotations.Add(VerLine(Brushes.Blue, result, Brushes.Blue, $"Recipe End"));
  342. }
  343. }));
  344. }
  345. public static VerticalLineAnnotation VerLine(Brush stroke, DateTime x, Brush color, string text)
  346. {
  347. var label = new AnnotationLabel()
  348. {
  349. LabelPlacement = LabelPlacement.TopRight,
  350. FontSize = 12,
  351. RotationAngle = 0,
  352. Foreground = color,
  353. Text = text
  354. };
  355. var line = new VerticalLineAnnotation()
  356. {
  357. Stroke = stroke,
  358. StrokeThickness = 1,
  359. X1 = x,
  360. IsEditable = false,
  361. VerticalAlignment = VerticalAlignment.Stretch,
  362. AnnotationLabels = new ObservableCollection<AnnotationLabel>() { label },
  363. };
  364. return line;
  365. }
  366. public void QueryRecipe(string recipeGuid)
  367. {
  368. AnnotationCollection annotation = new AnnotationCollection();
  369. string sql = $"SELECT * FROM \"recipe_step_data\" where \"process_data_guid\" = '{recipeGuid}' order by step_number ASC;";
  370. var dbData = QueryDataClient.Instance.Service.QueryData(sql);
  371. List<RecipeStep> steps = new List<RecipeStep>();
  372. if (dbData != null && dbData.Rows.Count > 0)
  373. {
  374. for (int i = 0; i < dbData.Rows.Count; i++)
  375. {
  376. RecipeStep item = new RecipeStep();
  377. item.No = int.Parse(dbData.Rows[i]["step_number"].ToString());
  378. item.Name = dbData.Rows[i]["step_name"].ToString();
  379. if (!dbData.Rows[i]["step_begin_time"].Equals(DBNull.Value))
  380. item.StartTime = (DateTime)dbData.Rows[i]["step_begin_time"];
  381. if (!dbData.Rows[i]["step_end_time"].Equals(DBNull.Value))
  382. item.EndTime = (DateTime)dbData.Rows[i]["step_end_time"];
  383. item.ActualTime = item.EndTime.CompareTo(item.StartTime) <= 0 ? "" : item.EndTime.Subtract(item.StartTime).TotalSeconds.ToString();
  384. item.SettingTime = dbData.Rows[i]["step_time"].ToString();
  385. annotation.Add(VerLine(Brushes.Blue, item.StartTime, Brushes.Blue, $"{item.No}:{item.Name}"));
  386. }
  387. }
  388. ProcessChartData.Annotations = annotation;
  389. }
  390. public void DeleteAll()
  391. {
  392. SelectedData.Clear();
  393. }
  394. public void Delete(ChartDataLine cp)
  395. {
  396. if (cp != null && SelectedData.Contains(cp))
  397. {
  398. SelectedData.Remove(cp);
  399. }
  400. }
  401. public void ExportAll()
  402. {
  403. try
  404. {
  405. Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  406. dlg.DefaultExt = ".xlsx"; // Default file extension
  407. dlg.Filter = "Excel数据表格文件(*.xlsx)|*.xlsx"; // Filter files by extension
  408. dlg.FileName = $"Export_{DateTime.Now:yyyyMMdd_HHmmss}";
  409. Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  410. if (result == true) // Process open file dialog box results
  411. {
  412. System.Data.DataSet ds = new System.Data.DataSet();
  413. ds.Tables.Add(new System.Data.DataTable($"Export_{DateTime.Now:yyyyMMdd_HHmmss}"));
  414. ds.Tables[0].Columns.Add("Time");
  415. ds.Tables[0].Columns[0].DataType = typeof(DateTime);
  416. Dictionary<DateTime, double[]> timeValue = new Dictionary<DateTime, double[]>();
  417. for (int i = 0; i < SelectedData.Count; i++)
  418. {
  419. List<Tuple<DateTime, double>> data = (SelectedData[i] as ChartDataLine).Points;
  420. foreach (var tuple in data)
  421. {
  422. if (!timeValue.ContainsKey(tuple.Item1))
  423. timeValue[tuple.Item1] = new double[SelectedData.Count];
  424. timeValue[tuple.Item1][i] = tuple.Item2;
  425. }
  426. ds.Tables[0].Columns.Add((SelectedData[i] as ChartDataLine).DataName);
  427. ds.Tables[0].Columns[i + 1].DataType = typeof(double);
  428. }
  429. foreach (var item in timeValue)
  430. {
  431. var row = ds.Tables[0].NewRow();
  432. row[0] = item.Key;
  433. for (int j = 0; j < item.Value.Length; j++)
  434. {
  435. row[j + 1] = item.Value[j];
  436. }
  437. ds.Tables[0].Rows.Add(row);
  438. }
  439. if (!ExcelHelper.ExportToExcel(dlg.FileName, ds, out string reason))
  440. {
  441. MessageBox.Show($"Export failed, {reason}", "Export", MessageBoxButton.OK,
  442. MessageBoxImage.Warning);
  443. return;
  444. }
  445. MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK,
  446. MessageBoxImage.Information);
  447. }
  448. }
  449. catch (Exception ex)
  450. {
  451. LOG.Write(ex);
  452. MessageBox.Show("Write failed," + ex.Message, "export failed", MessageBoxButton.OK, MessageBoxImage.Warning);
  453. }
  454. }
  455. public void Export(ChartDataLine cp)
  456. {
  457. try
  458. {
  459. Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
  460. dlg.DefaultExt = ".xlsx"; // Default file extension
  461. dlg.Filter = "Excel数据表格文件(*.xlsx)|*.xlsx"; // Filter files by extension
  462. dlg.FileName = $"{cp.DataSource}_{DateTime.Now:yyyyMMdd_HHmmss}";
  463. Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
  464. if (result == true) // Process open file dialog box results
  465. {
  466. System.Data.DataSet ds = new System.Data.DataSet();
  467. ds.Tables.Add(new System.Data.DataTable(cp.DataName));
  468. ds.Tables[0].Columns.Add("Time");
  469. ds.Tables[0].Columns[0].DataType = typeof(DateTime);
  470. ds.Tables[0].Columns.Add(cp.DataName);
  471. ds.Tables[0].Columns[1].DataType = typeof(double);
  472. foreach (var item in cp.Points)
  473. {
  474. var row = ds.Tables[0].NewRow();
  475. row[0] = item.Item1;
  476. row[1] = item.Item2;
  477. ds.Tables[0].Rows.Add(row);
  478. }
  479. if (!ExcelHelper.ExportToExcel(dlg.FileName, ds, out string reason))
  480. {
  481. MessageBox.Show($"Export failed, {reason}", "Export", MessageBoxButton.OK, MessageBoxImage.Warning);
  482. return;
  483. }
  484. MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK, MessageBoxImage.Information);
  485. }
  486. }
  487. catch (Exception ex)
  488. {
  489. LOG.Write(ex);
  490. MessageBox.Show("Write failed," + ex.Message, "export failed", MessageBoxButton.OK, MessageBoxImage.Warning);
  491. }
  492. }
  493. public void SelectColor(ChartDataLine cp)
  494. {
  495. if (cp == null) return;
  496. var dlg = new System.Windows.Forms.ColorDialog();
  497. if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  498. {
  499. cp.Stroke = new System.Windows.Media.Color() { A = dlg.Color.A, B = dlg.Color.B, G = dlg.Color.G, R = dlg.Color.R };
  500. }
  501. }
  502. protected override void OnViewLoaded(object _view)
  503. {
  504. base.OnViewLoaded(_view);
  505. this.view = (ProcessHistoryView)_view;
  506. this.view.wfTimeFrom.Value = this.StartDateTime;
  507. this.view.wfTimeTo.Value = this.EndDateTime;
  508. //this.AppendData();
  509. }
  510. public void Query(object parameter)
  511. {
  512. WaferHistoryWafer waferHistoryRecipe = parameter as WaferHistoryWafer;
  513. if (waferHistoryRecipe != null)
  514. {
  515. Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  516. {
  517. if (waferHistoryRecipe.StartTime != DateTime.MinValue)
  518. this.view.wfTimeFrom.Value = waferHistoryRecipe.StartTime;
  519. if (waferHistoryRecipe.EndTime != DateTime.MinValue)
  520. this.view.wfTimeTo.Value = waferHistoryRecipe.EndTime;
  521. else
  522. this.view.wfTimeTo.Value = waferHistoryRecipe.StartTime.AddHours(1);
  523. SearchRecipe(waferHistoryRecipe);
  524. }));
  525. }
  526. }
  527. private void SearchRecipe(WaferHistoryWafer waferHistoryRecipe)
  528. {
  529. if (MenuPermission != 3) return;
  530. this.StartDateTime = this.view.wfTimeFrom.Value;
  531. this.EndDateTime = this.view.wfTimeTo.Value;
  532. Recipes.Clear();
  533. //ObservableCollection<RecipeItem> items = ProcessHistoryProvider.Instance.SearchRecipe();
  534. //foreach (RecipeItem item in items)
  535. // Recipes.Add(item);
  536. try
  537. {
  538. 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")}' ";
  539. if (!string.IsNullOrEmpty(SelectedValuePM))
  540. {
  541. string[] pms = SelectedValuePM.Split(',');
  542. if (pms.Length > 0)
  543. {
  544. sql += " and (FALSE ";
  545. foreach (var pm in pms)
  546. {
  547. sql += $" OR \"process_in\"='{pm}' ";
  548. }
  549. sql += " ) ";
  550. }
  551. }
  552. if (!string.IsNullOrEmpty(RecipeName))
  553. {
  554. sql += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());
  555. }
  556. sql += " order by \"process_begin_time\" ASC;";
  557. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  558. Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  559. {
  560. if (dbData == null || dbData.Rows.Count == 0) return;
  561. for (int i = 0; i < dbData.Rows.Count; i++)
  562. {
  563. RecipeItem item = new RecipeItem();
  564. item.Recipe = dbData.Rows[i]["recipe_name"].ToString();
  565. item.Guid = dbData.Rows[i]["guid"].ToString();
  566. item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();
  567. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  568. item.Status = dbData.Rows[i]["process_status"].ToString();
  569. item.SlotID = dbData.Rows[i]["slot_id"].ToString();
  570. item.LotID = dbData.Rows[i]["lot_id"].ToString();
  571. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  572. item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss.fff");
  573. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  574. {
  575. item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss.fff");
  576. if ((DateTime)dbData.Rows[i]["process_begin_time"] == waferHistoryRecipe.StartTime)
  577. {
  578. Recipes.Add(item);
  579. break;
  580. }
  581. }
  582. if(item.SlotID == waferHistoryRecipe.SlotID)
  583. {
  584. Recipes.Add(item);
  585. break;
  586. }
  587. }
  588. }));
  589. }
  590. catch (Exception e)
  591. {
  592. LOG.Write(e);
  593. }
  594. }
  595. }
  596. }