383 lines
15 KiB
C#
383 lines
15 KiB
C#
using System;
|
|
using System.Collections.ObjectModel;
|
|
using System.Data;
|
|
using System.Windows;
|
|
using Aitex.Core.RT.Log;
|
|
using MECF.Framework.Common.DataCenter;
|
|
using MECF.Framework.Common.Utilities;
|
|
using MECF.Framework.UI.Client.ClientBase;
|
|
using OpenSEMI.ClientBase;
|
|
using SciChart.Charting.Model.DataSeries;
|
|
using SciChart.Charting.Visuals.Annotations;
|
|
using SciChart.Charting.Visuals.RenderableSeries;
|
|
using SciChart.Data.Model;
|
|
|
|
namespace MECF.Framework.UI.Client.CenterViews.DataLogs.WaferHistory
|
|
{
|
|
public class WaferHistoryDetail
|
|
{
|
|
public string Guid { get; set; }
|
|
public string CreateTime { get; set; }
|
|
public string DeleteTime { get; set; }
|
|
public string LoadPort { get; set; }
|
|
public string Slot { get; set; }
|
|
public string CarrierID { get; set; }
|
|
public string LotID { get; set; }
|
|
public string WaferID { get; set; }
|
|
public string Status { get; set; }
|
|
|
|
public string LotId { get; set; }
|
|
public string SequenceName { get; set; }
|
|
public string NotchAngle { get; set; }
|
|
}
|
|
|
|
public class WaferMovement
|
|
{
|
|
public string Time { get; set; }
|
|
public string Station { get; set; }
|
|
public string Slot { get; set; }
|
|
public string Status { get; set; }
|
|
public string WaferID { get; set; }
|
|
}
|
|
|
|
public class WaferHistoryViewModel : BaseModel
|
|
{
|
|
public bool IsPermission { get => this.Permission == 3; }
|
|
|
|
public DateTime BeginDate { get; set; }
|
|
public DateTime StartDateTime { get; set; }
|
|
public DateTime EndDateTime { get; set; }
|
|
public DateTime UIEndTime { get; set; }
|
|
|
|
|
|
public ObservableCollection<WaferHistoryDetail> Wafers { get; set; }
|
|
public ObservableCollection<WaferMovement> Movements { get; set; }
|
|
|
|
public ObservableCollection<string> SourceLP { get; set; }
|
|
public string SelectedValueLP { get; set; }
|
|
|
|
public WaferHistoryViewModel()
|
|
{
|
|
this.DisplayName = "Wafer History";
|
|
var now = DateTime.Now;
|
|
this.StartDateTime = now;
|
|
this.BeginDate = now;
|
|
this.StartDateTime = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0, 0);
|
|
this.EndDateTime = new DateTime(now.Year, now.Month, now.Day, 23, 59, 59, 999);
|
|
this.Wafers = new ObservableCollection<WaferHistoryDetail>();
|
|
this.Movements = new ObservableCollection<WaferMovement>();
|
|
|
|
|
|
SourceLP = new ObservableCollection<string>(new[] { "LP1", "LP2", "LP3" });
|
|
}
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
base.OnInitialize();
|
|
this.YLabelProvider = new YAxisLabelProvider();
|
|
this.RenderableSeries = new ObservableCollection<IRenderableSeries>();
|
|
this.RenderableSeries.Add(new FastLineRenderableSeries() { DataSeries = new XyDataSeries<int, int>() });
|
|
this.Annotations = new AnnotationCollection();
|
|
}
|
|
|
|
private WaferHistoryView view;
|
|
public void Query(string loadport, string waferid, string lotid, string carrierid, string sequencename, string processchamber, string processrecipe)
|
|
{
|
|
try
|
|
{
|
|
this.StartDateTime = this.view.wfTimeFrom.Value;
|
|
this.EndDateTime = this.view.wfTimeTo.Value;
|
|
|
|
if (StartDateTime > EndDateTime)
|
|
{
|
|
MessageBox.Show("Time range invalid, start time should be early than end time");
|
|
return;
|
|
}
|
|
|
|
string sql = string.Format(
|
|
"SELECT * FROM \"wafer_data\",\"carrier_data\" where \"create_time\" >= '{0}' and \"create_time\" <= '{1}' and \"wafer_data\".\"carrier_data_guid\"=\"carrier_data\".\"guid\"",
|
|
StartDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff"), EndDateTime.ToString("yyyy/MM/dd HH:mm:ss.fff"));
|
|
|
|
if (!string.IsNullOrWhiteSpace(loadport))
|
|
{
|
|
sql += " and (FALSE ";
|
|
var loadPorts = loadport.Split(',');
|
|
for (int i = 0; i < loadPorts.Length; i++)
|
|
{
|
|
sql += $" OR \"create_station\"='{loadPorts[i]}'";
|
|
}
|
|
sql += " )";
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(waferid))
|
|
sql += $" and lower(\"wafer_id\") like '%{waferid.ToLower()}%'";
|
|
|
|
if (!string.IsNullOrWhiteSpace(lotid))
|
|
sql += $" and lower(\"wafer_data\".\"lot_id\") like '%{lotid.ToLower()}%'";
|
|
|
|
if (!string.IsNullOrWhiteSpace(carrierid))
|
|
sql += $" and lower(\"rfid\") like '%{carrierid.ToLower()}%'";
|
|
|
|
sql += " order by \"create_time\" ASC, \"create_station\" ASC,\"create_slot\" ASC";
|
|
|
|
DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
|
|
|
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
{
|
|
Wafers.Clear();
|
|
try
|
|
{
|
|
if (dbData == null || dbData.Rows.Count == 0)
|
|
return;
|
|
|
|
for (int i = 0; i < dbData.Rows.Count; i++)
|
|
{
|
|
WaferHistoryDetail item = new WaferHistoryDetail();
|
|
|
|
item.Guid = dbData.Rows[i]["guid"].ToString();
|
|
item.LoadPort = dbData.Rows[i]["create_station"].ToString();
|
|
item.Slot = dbData.Rows[i]["create_slot"].ToString();
|
|
|
|
item.CarrierID = dbData.Rows[i]["rfid"].ToString();
|
|
|
|
item.LotID = dbData.Rows[i]["lot_id"].ToString();
|
|
item.WaferID = dbData.Rows[i]["wafer_id"].ToString();
|
|
|
|
item.Status = dbData.Rows[i]["process_status"].ToString();
|
|
|
|
if (!dbData.Rows[i]["create_time"].Equals(DBNull.Value))
|
|
item.CreateTime = ((DateTime)dbData.Rows[i]["create_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
|
|
|
|
if (!dbData.Rows[i]["delete_time"].Equals(DBNull.Value))
|
|
item.DeleteTime = ((DateTime)dbData.Rows[i]["delete_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
|
|
|
|
Wafers.Add(item);
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LOG.Write(ex);
|
|
}
|
|
|
|
}));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LOG.Write(e);
|
|
}
|
|
}
|
|
public void WaferHistoryChanged(WaferHistoryDetail detail)
|
|
{
|
|
try
|
|
{
|
|
if (detail == null)
|
|
{
|
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
{
|
|
Movements.Clear();
|
|
}));
|
|
return;
|
|
}
|
|
|
|
string sql = string.Format(
|
|
"SELECT * FROM \"wafer_move_history\" where \"wafer_data_guid\" = '{0}' order by \"arrive_time\" ASC;",
|
|
detail.Guid);
|
|
|
|
DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
|
|
|
|
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
{
|
|
Movements.Clear();
|
|
|
|
if (dbData == null || dbData.Rows.Count == 0)
|
|
return;
|
|
|
|
for (int i = 0; i < dbData.Rows.Count; i++)
|
|
{
|
|
WaferMovement item = new WaferMovement();
|
|
|
|
item.Station = dbData.Rows[i]["station"].ToString();
|
|
item.Slot = dbData.Rows[i]["slot"].ToString();
|
|
item.Status = dbData.Rows[i]["status"].ToString();
|
|
item.WaferID = detail.WaferID;
|
|
|
|
if (!dbData.Rows[i]["arrive_time"].Equals(DBNull.Value))
|
|
item.Time = ((DateTime)dbData.Rows[i]["arrive_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
|
|
|
|
Movements.Add(item);
|
|
}
|
|
|
|
|
|
}));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LOG.Write(e);
|
|
}
|
|
}
|
|
|
|
public void Export()
|
|
{
|
|
try
|
|
{
|
|
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
|
|
dlg.DefaultExt = ".xlsx"; // Default file extension
|
|
dlg.FileName = $"{DisplayName}_{DateTime.Now:yyyyMMdd_HHmmss}";
|
|
dlg.Filter = "Excel数据表格文件(*.xlsx)|*.xlsx"; // Filter files by extension
|
|
Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
|
|
if (result == true) // Process open file dialog box results
|
|
{
|
|
System.Data.DataSet ds = new System.Data.DataSet();
|
|
ds.Tables.Add(new System.Data.DataTable("系统运行日志"));
|
|
ds.Tables[0].Columns.Add("CreateTime");
|
|
ds.Tables[0].Columns.Add("DeleteTime");
|
|
ds.Tables[0].Columns.Add("LoadPort");
|
|
ds.Tables[0].Columns.Add("Slot");
|
|
ds.Tables[0].Columns.Add("CarrierID");
|
|
ds.Tables[0].Columns.Add("LotID");
|
|
ds.Tables[0].Columns.Add("WaferID");
|
|
ds.Tables[0].Columns.Add("Status");
|
|
foreach (var item in Wafers)
|
|
{
|
|
var row = ds.Tables[0].NewRow();
|
|
row[0] = item.CreateTime;
|
|
row[1] = item.DeleteTime;
|
|
row[2] = item.LoadPort;
|
|
row[3] = item.Slot;
|
|
row[4] = item.CarrierID;
|
|
row[5] = item.LotID;
|
|
row[6] = item.WaferID;
|
|
row[7] = item.Status;
|
|
ds.Tables[0].Rows.Add(row);
|
|
}
|
|
|
|
if (!ExcelHelper.ExportToExcel(dlg.FileName, ds, out string reason))
|
|
{
|
|
MessageBox.Show($"Export failed, {reason}", "Export", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
return;
|
|
}
|
|
|
|
MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LOG.Write(ex);
|
|
MessageBox.Show("导出系统日志发生错误", "导出失败", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
}
|
|
}
|
|
|
|
public void ExportMove()
|
|
{
|
|
try
|
|
{
|
|
if (Movements.Count == 0)
|
|
{
|
|
DialogBox.ShowDialog(DialogButton.OK, DialogType.INFO, "No wafer move history to export.");
|
|
return;
|
|
}
|
|
|
|
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
|
|
dlg.DefaultExt = ".xlsx"; // Default file extension
|
|
dlg.FileName = $"Wafer_Move_History_{DateTime.Now:yyyyMMdd_HHmmss}";
|
|
dlg.Filter = "Excel数据表格文件(*.xlsx)|*.xlsx"; // Filter files by extension
|
|
Nullable<bool> result = dlg.ShowDialog();// Show open file dialog box
|
|
if (result == true) // Process open file dialog box results
|
|
{
|
|
System.Data.DataSet ds = new System.Data.DataSet();
|
|
ds.Tables.Add(new System.Data.DataTable("系统运行日志"));
|
|
ds.Tables[0].Columns.Add("Time");
|
|
ds.Tables[0].Columns.Add("Station");
|
|
ds.Tables[0].Columns.Add("Slot");
|
|
ds.Tables[0].Columns.Add("Status");
|
|
ds.Tables[0].Columns.Add("WaferId");
|
|
foreach (var item in Movements)
|
|
{
|
|
var row = ds.Tables[0].NewRow();
|
|
row[0] = item.Time;
|
|
row[1] = item.Station;
|
|
row[2] = item.Slot;
|
|
row[3] = item.Status;
|
|
row[4] = item.WaferID;
|
|
ds.Tables[0].Rows.Add(row);
|
|
}
|
|
|
|
if (!ExcelHelper.ExportToExcel(dlg.FileName, ds, out string reason))
|
|
{
|
|
MessageBox.Show($"Export failed, {reason}", "Export", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
return;
|
|
}
|
|
|
|
MessageBox.Show($"Export succeed, file save as {dlg.FileName}", "Export", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LOG.Write(ex);
|
|
MessageBox.Show($"导出系统日志发生错误", "导出失败", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
}
|
|
}
|
|
|
|
#region scichart
|
|
|
|
public ObservableCollection<IRenderableSeries> RenderableSeries
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
private AnnotationCollection _annotations = new AnnotationCollection();
|
|
public AnnotationCollection Annotations
|
|
{
|
|
get { return _annotations; }
|
|
set { _annotations = value; }
|
|
}
|
|
|
|
private IRange _TimeRange;
|
|
public IRange TimeRange
|
|
{
|
|
get { return _TimeRange; }
|
|
set
|
|
{
|
|
_TimeRange = value;
|
|
NotifyOfPropertyChange("TimeRange");
|
|
|
|
}
|
|
}
|
|
|
|
private IRange _YTimeRange;
|
|
public IRange YTimeRange
|
|
{
|
|
get { return _YTimeRange; }
|
|
set { _YTimeRange = value; }
|
|
}
|
|
|
|
|
|
public YAxisLabelProvider YLabelProvider { get; set; }
|
|
public void AppendData()
|
|
{
|
|
(this.RenderableSeries[0].DataSeries as XyDataSeries<int, int>).Clear();
|
|
|
|
for (var index = 1; index <= 8; index++)
|
|
{
|
|
(this.RenderableSeries[0].DataSeries as XyDataSeries<int, int>).Append(index * 5, index);
|
|
|
|
this.Annotations.Add(new LineArrowAnnotation() { X1 = index * 5, Y1 = index, X2 = index * 5, Y2 = index + 2, });
|
|
}
|
|
|
|
}
|
|
|
|
protected override void OnViewLoaded(object _view)
|
|
{
|
|
base.OnViewLoaded(_view);
|
|
this.view = (WaferHistoryView)_view;
|
|
this.view.wfTimeFrom.Value = this.StartDateTime;
|
|
this.view.wfTimeTo.Value = this.EndDateTime;
|
|
this.AppendData();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|