WaferHistoryDBViewModel.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Windows.Forms;
  8. using System.Windows.Input;
  9. using Aitex.Sorter.Common;
  10. using MECF.Framework.Common.CommonData;
  11. using MECF.Framework.Common.DataCenter;
  12. using OpenSEMI.ClientBase;
  13. using OpenSEMI.ClientBase.Command;
  14. using SciChart.Core.Extensions;
  15. namespace VirgoUI.Client.Models.DataLog.WaferHistory
  16. {
  17. public class WaferHistoryDBViewModel : BaseModel
  18. {
  19. public WaferHistoryDBViewModel()
  20. {
  21. SelectionChangedCommand = new BaseCommand<WaferHistoryItem>(SelectionChanged);
  22. QueryCommand = new BaseCommand<object>(QueryLots);
  23. ToChartCommand = new BaseCommand<object>(GoToChart);
  24. HistoryData = new ObservableCollection<LazyTreeItem<WaferHistoryItem>>();
  25. InitTime();
  26. }
  27. private ObservableCollection<LazyTreeItem<WaferHistoryItem>> _historyData;
  28. public ObservableCollection<LazyTreeItem<WaferHistoryItem>> HistoryData
  29. {
  30. get { return _historyData; }
  31. set
  32. {
  33. _historyData = value;
  34. NotifyOfPropertyChange("HistoryData");
  35. }
  36. }
  37. private WaferHistoryItem _selectedItem;
  38. public WaferHistoryItem SelectedItem
  39. {
  40. get { return _selectedItem; }
  41. set
  42. {
  43. _selectedItem = value;
  44. NotifyOfPropertyChange("SelectedItem");
  45. }
  46. }
  47. private ObservableCollection<WaferHistoryLot> _lots = new ObservableCollection<WaferHistoryLot>();
  48. public ObservableCollection<WaferHistoryLot> Lots
  49. {
  50. get { return _lots; }
  51. set
  52. {
  53. _lots = value;
  54. NotifyOfPropertyChange("Lots");
  55. }
  56. }
  57. private ObservableCollection<WaferHistoryWafer> _wafers = new ObservableCollection<WaferHistoryWafer>();
  58. public ObservableCollection<WaferHistoryWafer> Wafers
  59. {
  60. get { return _wafers; }
  61. set
  62. {
  63. _wafers = value;
  64. NotifyOfPropertyChange("Wafers");
  65. }
  66. }
  67. private ObservableCollection<WaferHistoryMovement> _movements = new ObservableCollection<WaferHistoryMovement>();
  68. public ObservableCollection<WaferHistoryMovement> Movements
  69. {
  70. get { return _movements; }
  71. set
  72. {
  73. _movements = value;
  74. NotifyOfPropertyChange("Movements");
  75. }
  76. }
  77. private WaferHistoryRecipe _recipe;
  78. public WaferHistoryRecipe Recipe
  79. {
  80. get { return _recipe; }
  81. set
  82. {
  83. _recipe = value;
  84. NotifyOfPropertyChange("Recipe");
  85. }
  86. }
  87. public ObservableCollection<WaferHistoryRecipe> _recipes = new ObservableCollection<WaferHistoryRecipe>();
  88. public ObservableCollection<WaferHistoryRecipe> Recipes
  89. {
  90. get { return _recipes; }
  91. set
  92. {
  93. _recipes = value;
  94. NotifyOfPropertyChange("Recipes");
  95. }
  96. }
  97. private DateTime _searchBeginTime;
  98. public DateTime SearchBeginTime
  99. {
  100. get { return _searchBeginTime; }
  101. set
  102. {
  103. _searchBeginTime = value;
  104. NotifyOfPropertyChange("SearchBeginTime");
  105. }
  106. }
  107. private DateTime _searchEndTime;
  108. public DateTime SearchEndTime
  109. {
  110. get { return _searchEndTime; }
  111. set
  112. {
  113. _searchEndTime = value;
  114. NotifyOfPropertyChange("SearchEndTime");
  115. }
  116. }
  117. private string keyWord;
  118. private WaferHistoryDBView view;
  119. public string KeyWord
  120. {
  121. get { return keyWord; }
  122. set
  123. {
  124. keyWord = value;
  125. NotifyOfPropertyChange("KeyWord");
  126. }
  127. }
  128. public ICommand SelectionChangedCommand { get; set; }
  129. public ICommand QueryCommand { get; set; }
  130. public ICommand ToChartCommand { get; set; }
  131. void InitTime()
  132. {
  133. SearchBeginTime = DateTime.Now.Date;
  134. SearchEndTime = DateTime.Now.Date.AddDays(1).Date;
  135. }
  136. void QueryLots(object e)
  137. {
  138. this.SearchBeginTime = this.view.wfTimeFrom.Value;
  139. this.SearchEndTime = this.view.wfTimeTo.Value;
  140. if (SearchBeginTime > SearchEndTime)
  141. {
  142. MessageBox.Show("Time range invalid, start time should be early than end time");
  143. return;
  144. }
  145. Lots = new ObservableCollection<WaferHistoryLot>(QueryLot(SearchBeginTime, SearchEndTime, KeyWord));//.OrderByDescending(lot => lot.StartTime).ToArray();
  146. HistoryData.Clear();
  147. var lotsItem = new WaferHistoryItem() { Name = "Lots", };
  148. var root = new LazyTreeItem<WaferHistoryItem>(lotsItem, x => LoadSubItem(x));
  149. root.SubItems = new ObservableCollection<LazyTreeItem<WaferHistoryItem>>(Lots.Select(x => new LazyTreeItem<WaferHistoryItem>(new WaferHistoryItem() { ID = x.ID, Name = x.Name, StartTime = x.StartTime, EndTime = x.EndTime, Type = WaferHistoryItemType.Lot }, LoadSubItem)));
  150. root.IsExpanded = true;
  151. HistoryData.Add(root);
  152. SelectedItem = lotsItem;
  153. }
  154. /// <summary>
  155. /// Notify chart page to prepare datas
  156. /// </summary>
  157. /// <param name="o"></param>
  158. void GoToChart(object o)
  159. {
  160. WaferHistoryItem item = o as WaferHistoryItem;
  161. if (o is WaferHistoryLot waferLot)
  162. {
  163. item.Type = WaferHistoryItemType.Lot;
  164. SelectionChanged(item);
  165. WaferHistoryItem selectItem = null;
  166. foreach (var root in HistoryData)
  167. {
  168. foreach (var subroot in root.SubItems)
  169. {
  170. var data = subroot.Data as WaferHistoryItem;
  171. if (data != null && data.Name != null && data.Name == item.Name)
  172. {
  173. selectItem = data;
  174. subroot.IsExpanded = true;
  175. break;
  176. }
  177. }
  178. if (selectItem != null)
  179. break;
  180. }
  181. }
  182. else if (o is WaferHistoryWafer wafer)
  183. {
  184. item.Type = WaferHistoryItemType.Wafer;
  185. //导航切换到chart页面
  186. BaseApp.Instance.SwitchPage("DataLog", "ProcessHistory", wafer);
  187. return;
  188. }
  189. else if (o is WaferHistoryRecipe)
  190. {
  191. item.Type = WaferHistoryItemType.Recipe;
  192. }
  193. else if (o is string name)
  194. {
  195. var query = _recipes.FirstOrDefault(t => t.Recipe == name);
  196. if (query is null) return;
  197. WaferHistoryWafer wafer1 = new WaferHistoryWafer();
  198. wafer1.StartTime = query.StartTime;
  199. wafer1.EndTime = query.EndTime;
  200. BaseApp.Instance.SwitchPage("DataLog", "ProcessHistory", wafer1);
  201. }
  202. //
  203. //WaferHistoryRecipe chartQuery = null;
  204. //if (o is string name)
  205. //{
  206. // var query = _recipes.FirstOrDefault(t => t.Recipe == name);
  207. // if (query is null) return;
  208. // chartQuery = query;
  209. //}
  210. //if (o is WaferHistoryLot waferLot)
  211. //{
  212. // DateTime start = waferLot.StartTime;
  213. // double.TryParse(waferLot.Duration, out double duration);
  214. // DateTime end = start.AddSeconds(duration);
  215. // chartQuery = new WaferHistoryRecipe() { StartTime = start, EndTime = end, /*Chamber = waferLot.CarrierID */};
  216. //}
  217. //else if (o is WaferHistoryWafer wafer)
  218. //{
  219. // chartQuery = new WaferHistoryRecipe() { StartTime = wafer.StartTime, EndTime = wafer.EndTime/*,Chamber = waferLot.CarrierID*/ };
  220. //}
  221. //导航切换到chart页面
  222. //BaseApp.Instance.SwitchPage("DataLog", "DataHistory", chartQuery);
  223. }
  224. public List<WaferHistoryLot> QueryLot(DateTime from, DateTime to, string key)
  225. {
  226. List<WaferHistoryLot> result = new List<WaferHistoryLot>();
  227. string sql = $"SELECT * FROM \"lot_data\" where \"start_time\" >= '{from:yyyy/MM/dd HH:mm:ss.fff}' and \"start_time\" <= '{to:yyyy/MM/dd HH:mm:ss.fff}' order by \"start_time\" ASC;";
  228. //Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  229. //{
  230. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  231. if (dbData != null && dbData.Rows.Count > 0)
  232. {
  233. for (int i = 0; i < dbData.Rows.Count; i++)
  234. {
  235. WaferHistoryLot item = new WaferHistoryLot();
  236. string name = dbData.Rows[i]["name"].ToString();
  237. string time = "";
  238. item.WaferCount = (int)dbData.Rows[i]["total_wafer_count"];
  239. item.ID = dbData.Rows[i]["guid"].ToString();
  240. if (!dbData.Rows[i]["start_time"].Equals(DBNull.Value))
  241. {
  242. item.StartTime = ((DateTime)dbData.Rows[i]["start_time"]);
  243. time = item.StartTime.ToString("yyyy-MM-dd HH:mm:ss");
  244. }
  245. if (!dbData.Rows[i]["end_time"].Equals(DBNull.Value))
  246. {
  247. item.EndTime = ((DateTime)dbData.Rows[i]["end_time"]);
  248. }
  249. item.InputPort = dbData.Rows[i]["input_port"].ToString();
  250. item.Name = $"{name}-{time}";
  251. item.LotID = $"{name}";
  252. result.Add(item);
  253. }
  254. }
  255. //}));
  256. return result;
  257. }
  258. public List<WaferHistoryWafer> QueryLotWafer(string lotGuid)
  259. {
  260. List<WaferHistoryWafer> result = new List<WaferHistoryWafer>();
  261. //string sql = $"select data.*,process_data.process_status from (SELECT * FROM wafer_data,lot_wafer_data where lot_wafer_data.lot_data_guid = '{lotGuid}' and lot_wafer_data.wafer_data_guid = wafer_data.guid order by wafer_data.create_time ASC; as data )" +
  262. // $" LEFT JOIN process_data ON process_data.wafer_data_guid=data.wafer_id";
  263. string sql = $"SELECT wafer_data.*,lot_wafer_data.*,process_data.process_status as status FROM wafer_data LEFT JOIN lot_wafer_data ON lot_wafer_data.wafer_data_guid = wafer_data.guid " +
  264. $"LEFT JOIN process_data ON process_data.wafer_data_guid = wafer_data.guid where lot_wafer_data.lot_data_guid = '{lotGuid}' order by wafer_data.create_time ASC";
  265. Wafers.Clear();
  266. //Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  267. //{
  268. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  269. if (dbData != null && dbData.Rows.Count > 0)
  270. {
  271. for (int i = 0; i < dbData.Rows.Count; i++)
  272. {
  273. WaferHistoryWafer item = new WaferHistoryWafer();
  274. item.ID = dbData.Rows[i]["guid"].ToString();
  275. var itemLoadPort = dbData.Rows[i]["create_station"].ToString();
  276. var itemSlot = dbData.Rows[i]["create_slot"].ToString();
  277. //item.CarrierID = dbData.Rows[i]["rfid"].ToString();
  278. item.LotID = dbData.Rows[i]["lot_id"].ToString();
  279. item.SlotID = dbData.Rows[i]["create_slot"].ToString();
  280. var itemWaferID = dbData.Rows[i]["wafer_id"].ToString();
  281. item.Sequence = dbData.Rows[i]["sequence_name"].ToString();
  282. item.Status = dbData.Rows[i]["status"].ToString();
  283. List<DateTime> resultMovement = new List<DateTime>();
  284. sql = $"SELECT * FROM \"wafer_move_history\" where \"wafer_data_guid\" = '{item.ID}' order by \"arrive_time\" ASC limit 1000;";
  285. DataTable dbDataMovement = QueryDataClient.Instance.Service.QueryData(sql);
  286. if (dbDataMovement != null && dbDataMovement.Rows.Count > 0)
  287. {
  288. for (int j = 0; j < dbDataMovement.Rows.Count - 1; j++)
  289. {
  290. resultMovement.Add((DateTime)dbDataMovement.Rows[j]["arrive_time"]);
  291. }
  292. }
  293. if (resultMovement.Count >= 2)
  294. {
  295. item.StartTime = resultMovement[0];
  296. item.EndTime = resultMovement[resultMovement.Count - 1];
  297. }
  298. else
  299. {
  300. if (!dbData.Rows[i]["create_time"].Equals(DBNull.Value))
  301. {
  302. item.StartTime = ((DateTime)dbData.Rows[i]["create_time"]);
  303. }
  304. if (!dbData.Rows[i]["delete_time"].Equals(DBNull.Value))
  305. item.EndTime = ((DateTime)dbData.Rows[i]["delete_time"]);
  306. }
  307. item.Name = $"{itemLoadPort} - {itemSlot} - {itemWaferID}";
  308. item.Type = WaferHistoryItemType.Wafer;
  309. Wafers.Add(item);
  310. result.Add(item);
  311. }
  312. }
  313. //}));
  314. return result;
  315. }
  316. public List<WaferHistoryRecipe> QueryWaferRecipe(string waferGuid)
  317. {
  318. List<WaferHistoryRecipe> result = new List<WaferHistoryRecipe>();
  319. string sql = $"SELECT * FROM \"process_data\" where \"wafer_data_guid\" = '{waferGuid}';";
  320. Recipes.Clear();
  321. //Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  322. //{
  323. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  324. if (dbData != null && dbData.Rows.Count > 0)
  325. {
  326. for (int i = 0; i < dbData.Rows.Count; i++)
  327. {
  328. WaferHistoryRecipe item = new WaferHistoryRecipe();
  329. item.ID = dbData.Rows[i]["guid"].ToString();
  330. var itemName = dbData.Rows[i]["recipe_name"].ToString();
  331. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  332. item.StartTime = (DateTime)dbData.Rows[i]["process_begin_time"];
  333. if (dbData.Rows[i].Table.Columns.Contains("process_end_time") && !dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  334. item.EndTime = (DateTime)dbData.Rows[i]["process_end_time"];
  335. if (dbData.Rows[i].Table.Columns.Contains("recipe_setting_time") && !dbData.Rows[i]["recipe_setting_time"].Equals(DBNull.Value))
  336. item.SettingTime = dbData.Rows[i]["recipe_setting_time"].ToString();
  337. item.ActualTime = item.Duration;
  338. item.Recipe = itemName;
  339. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  340. item.Name = itemName;
  341. item.Type = WaferHistoryItemType.Recipe;
  342. Recipes.Add(item);
  343. result.Add(item);
  344. }
  345. }
  346. //}));
  347. return result;
  348. }
  349. public List<WaferHistoryMovement> QueryWaferMovement(string waferGuid)
  350. {
  351. List<WaferHistoryMovement> result = new List<WaferHistoryMovement>();
  352. string sql = $"SELECT * FROM \"wafer_move_history\" where \"wafer_data_guid\" = '{waferGuid}' order by \"arrive_time\" ASC limit 1000;";
  353. Movements.Clear();
  354. //Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  355. //{
  356. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  357. if (dbData != null && dbData.Rows.Count > 0)
  358. {
  359. for (int i = 0; i < dbData.Rows.Count - 1; i++)
  360. {
  361. WaferHistoryMovement item = new WaferHistoryMovement();
  362. item.Source = $"station : {dbData.Rows[i]["station"]} slot : {dbData.Rows[i]["slot"]}";
  363. item.Destination = $"station : {dbData.Rows[i + 1]["station"]} slot : {dbData.Rows[i + 1]["slot"]}";
  364. item.InTime = dbData.Rows[i]["arrive_time"].ToString();
  365. result.Add(item);
  366. Movements.Add(item);
  367. }
  368. }
  369. //}));
  370. return result;
  371. }
  372. public WaferHistoryRecipe QueryRecipe(string recipeGuid)
  373. {
  374. WaferHistoryRecipe result = new WaferHistoryRecipe();
  375. string sql = $"SELECT * FROM \"process_data\" where \"guid\" = '{recipeGuid}';";
  376. //Application.Current.Dispatcher.BeginInvoke(new Action(() =>
  377. //{
  378. DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
  379. if (dbData != null && dbData.Rows.Count > 0)
  380. {
  381. for (int i = 0; i < dbData.Rows.Count; i++)
  382. {
  383. WaferHistoryRecipe item = new WaferHistoryRecipe();
  384. item.ID = dbData.Rows[i]["guid"].ToString();
  385. var itemName = dbData.Rows[i]["recipe_name"].ToString();
  386. if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
  387. item.StartTime = (DateTime)dbData.Rows[i]["process_begin_time"];
  388. if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
  389. item.EndTime = (DateTime)dbData.Rows[i]["process_end_time"];
  390. if (dbData.Rows[i].Table.Columns.Contains("recipe_setting_time") && !dbData.Rows[i]["recipe_setting_time"].Equals(DBNull.Value))
  391. item.SettingTime = dbData.Rows[i]["recipe_setting_time"].ToString();
  392. item.ActualTime = item.Duration;
  393. item.Recipe = itemName;
  394. item.Chamber = dbData.Rows[i]["process_in"].ToString();
  395. item.Name = itemName;
  396. item.Type = WaferHistoryItemType.Recipe;
  397. result = item;
  398. }
  399. }
  400. sql = $"SELECT * FROM \"recipe_step_data\" where \"process_data_guid\" = '{recipeGuid}' order by step_number ASC;";
  401. dbData = QueryDataClient.Instance.Service.QueryData(sql);
  402. List<RecipeStep> steps = new List<RecipeStep>();
  403. if (dbData != null && dbData.Rows.Count > 0)
  404. {
  405. for (int i = 0; i < dbData.Rows.Count; i++)
  406. {
  407. RecipeStep item = new RecipeStep();
  408. item.No = int.Parse(dbData.Rows[i]["step_number"].ToString());
  409. item.Name = dbData.Rows[i]["step_name"].ToString();
  410. if (!dbData.Rows[i]["step_begin_time"].Equals(DBNull.Value))
  411. item.StartTime = (DateTime)dbData.Rows[i]["step_begin_time"];
  412. if (!dbData.Rows[i]["step_end_time"].Equals(DBNull.Value))
  413. item.EndTime = (DateTime)dbData.Rows[i]["step_end_time"];
  414. item.ActualTime = item.EndTime.CompareTo(item.StartTime) <= 0 ? "" : item.EndTime.Subtract(item.StartTime).TotalSeconds.ToString();
  415. item.SettingTime = dbData.Rows[i]["step_time"].ToString();
  416. steps.Add(item);
  417. }
  418. }
  419. sql = $"SELECT * FROM \"step_fdc_data\" where \"process_data_guid\" = '{recipeGuid}' order by step_number ASC;";
  420. dbData = QueryDataClient.Instance.Service.QueryData(sql);
  421. List<RecipeStepFdcData> fdcs = new List<RecipeStepFdcData>();
  422. if (dbData != null && dbData.Rows.Count > 0)
  423. {
  424. for (int i = 0; i < dbData.Rows.Count; i++)
  425. {
  426. RecipeStepFdcData item = new RecipeStepFdcData();
  427. item.StepNumber = int.Parse(dbData.Rows[i]["step_number"].ToString());
  428. item.Name = dbData.Rows[i]["parameter_name"].ToString();
  429. foreach (var name in _mapGasNameKey)
  430. {
  431. if (item.Name.Contains(name.Value) && _mapGasNameValue.ContainsKey(name.Key))
  432. item.Name = item.Name.Replace(name.Value, (string)_mapGasNameValue[name.Key]);
  433. }
  434. if (!dbData.Rows[i]["sample_count"].Equals(DBNull.Value))
  435. item.SampleCount = (int)dbData.Rows[i]["sample_count"];
  436. if (!dbData.Rows[i]["setpoint"].Equals(DBNull.Value))
  437. item.SetPoint = (float)dbData.Rows[i]["setpoint"];
  438. if (!dbData.Rows[i]["min_value"].Equals(DBNull.Value))
  439. item.MinValue = (float)dbData.Rows[i]["min_value"];
  440. if (!dbData.Rows[i]["max_value"].Equals(DBNull.Value))
  441. item.MaxValue = (float)dbData.Rows[i]["max_value"];
  442. if (!dbData.Rows[i]["std_value"].Equals(DBNull.Value))
  443. item.StdValue = (float)dbData.Rows[i]["std_value"];
  444. if (!dbData.Rows[i]["mean_value"].Equals(DBNull.Value))
  445. item.MeanValue = (float)dbData.Rows[i]["mean_value"];
  446. fdcs.Add(item);
  447. }
  448. }
  449. result.Steps = steps;
  450. result.Fdcs = fdcs;
  451. Recipe = result;
  452. return result;
  453. }
  454. private void SelectionChanged(WaferHistoryItem item)
  455. {
  456. switch (item.Type)
  457. {
  458. case WaferHistoryItemType.Lot:
  459. QueryLotWafer(item.ID);
  460. break;
  461. case WaferHistoryItemType.Wafer:
  462. QueryWaferRecipe(item.ID);
  463. QueryWaferMovement(item.ID);
  464. break;
  465. case WaferHistoryItemType.Recipe:
  466. QueryRecipe(item.ID);
  467. break;
  468. default:
  469. break;
  470. }
  471. SelectedItem = item;
  472. }
  473. protected List<LazyTreeItem<WaferHistoryItem>> LoadSubItem(WaferHistoryItem item)
  474. {
  475. switch (item.Type)
  476. {
  477. case WaferHistoryItemType.Lot:
  478. var wafers = QueryLotWafer(item.ID);
  479. return wafers.Select(x => new LazyTreeItem<WaferHistoryItem>(x, y => LoadSubItem(y))).OrderBy(s => s.Data.StartTime).ToList();
  480. case WaferHistoryItemType.Wafer:
  481. var recipes = QueryWaferRecipe(item.ID);
  482. return recipes.Select(x => new LazyTreeItem<WaferHistoryItem>(x, y => LoadSubItem(y))).OrderBy(s => s.Data.StartTime).ToList();
  483. default:
  484. break;
  485. }
  486. return new List<LazyTreeItem<WaferHistoryItem>> { };
  487. }
  488. protected override void OnViewLoaded(object _view)
  489. {
  490. base.OnViewLoaded(_view);
  491. this.view = (WaferHistoryDBView)_view;
  492. this.view.wfTimeFrom.Value = this.SearchBeginTime;
  493. this.view.wfTimeTo.Value = this.SearchEndTime;
  494. QueryLots(new object());
  495. SelectionChanged(SelectedItem);
  496. }
  497. private Dictionary<string, object> _mapGasNameValue = new Dictionary<string, object>();
  498. private Dictionary<string, string> _mapGasNameKey = new Dictionary<string, string>()
  499. {
  500. {"PMA.MfcGas1.GasName", "PMA.IoMfc.MfcGas1"},
  501. {"PMA.MfcGas2.GasName", "PMA.IoMfc.MfcGas2"},
  502. {"PMA.MfcGas3.GasName", "PMA.IoMfc.MfcGas3"},
  503. {"PMA.MfcGas4.GasName", "PMA.IoMfc.MfcGas4"},
  504. {"PMA.MfcGas5.GasName", "PMA.IoMfc.MfcGas5"},
  505. {"PMB.MfcGas1.GasName", "PMB.IoMfc.MfcGas1"},
  506. {"PMB.MfcGas2.GasName", "PMB.IoMfc.MfcGas2"},
  507. {"PMB.MfcGas3.GasName", "PMB.IoMfc.MfcGas3"},
  508. {"PMB.MfcGas4.GasName", "PMB.IoMfc.MfcGas4"},
  509. {"PMB.MfcGas5.GasName", "PMB.IoMfc.MfcGas5"},
  510. };
  511. protected override void OnActivate()
  512. {
  513. base.OnActivate();
  514. _mapGasNameValue = QueryDataClient.Instance.Service.PollConfig(_mapGasNameKey.Keys);
  515. }
  516. }
  517. public class LazyTreeItem<T> : INotifyPropertyChanged where T : ITreeItem<T>, new()
  518. {
  519. private LazyTreeItem<T> dummyChild;
  520. private T data;
  521. private Func<T, List<LazyTreeItem<T>>> loader;
  522. private LazyTreeItem()
  523. {
  524. data = new T();
  525. data.ID = Guid.NewGuid().ToString();
  526. }
  527. public LazyTreeItem(T data, Func<T, List<LazyTreeItem<T>>> loader)
  528. {
  529. this.data = data;
  530. this.loader = loader;
  531. dummyChild = new LazyTreeItem<T>();
  532. SubItems = new ObservableCollection<LazyTreeItem<T>>();
  533. SubItems.Add(dummyChild);
  534. }
  535. public T Data
  536. {
  537. get
  538. {
  539. return data;
  540. }
  541. }
  542. public ObservableCollection<LazyTreeItem<T>> SubItems
  543. {
  544. get; set;
  545. }
  546. private bool isExpanded;
  547. public event PropertyChangedEventHandler PropertyChanged;
  548. private void OnPropertyChanged(string name)
  549. {
  550. if (PropertyChanged != null)
  551. {
  552. PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
  553. }
  554. }
  555. public bool HasDummyChild
  556. {
  557. get { return SubItems.Count == 1 && SubItems.First().data.ID == dummyChild.data.ID; }
  558. }
  559. public bool IsExpanded
  560. {
  561. get { return isExpanded; }
  562. set
  563. {
  564. if (value != isExpanded)
  565. {
  566. isExpanded = value;
  567. OnPropertyChanged("IsExpanded");
  568. }
  569. if (HasDummyChild)
  570. {
  571. SubItems.Remove(dummyChild);
  572. var items = loader(data);
  573. items.ForEachDo(x => SubItems.Add(x));
  574. }
  575. }
  576. }
  577. }
  578. }