| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 | using MECF.Framework.Common.DataCenter;using System;using System.Collections.Generic;using System.Data;using System.Windows.Media;using System.Linq;using System.Text;using System.Threading.Tasks;using Venus_Core;using Prism.Commands;using Prism.Mvvm;using Venus_MainPages.Unity;using Venus_MainPages.Views;using System.Collections.ObjectModel;using System.Windows.Threading;using System.Windows;using Aitex.Core.RT.Log;using Aitex.Core.UI.ControlDataContext;using WPF.Themes.UserControls;using System.IO;using System.Diagnostics;using Aitex.Core.RT.Routine;using System.Xml.Linq;using System.Windows.Forms;using ExcelLibrary.BinaryFileFormat;using Aitex.Core.UI.View.Common;using Aitex.Core.RT.DataCenter;using System.Xml;using System.Security.Cryptography.X509Certificates;using System.Reflection;using Newtonsoft.Json;using Venus_Themes.UserControls;using Aitex.Core.UI.Control;using System.Windows.Annotations;using System.Runtime.Serialization;namespace Venus_MainPages.ViewModels{    public class ProcessHistoryViewModel : BindableBase    {        #region 私有字段        private ProcessHistoryView view;        List<string> keys = new List<string>();        RealtimeProvider _provider = new RealtimeProvider();        private ObservableCollection<ParameterNode> _ParameterNodes;        DispatcherTimer timer = new DispatcherTimer();        ObservableCollection<PdKeyData> _PdKeyDataObservation = new ObservableCollection<PdKeyData>();        public List<string> RecipesAdd = new List<string>();        public List<SolidColorBrush> solidColorBrushes = new List<SolidColorBrush>();        DateTime currentTime;        private RecipeItem selectedRecipeItem;        #endregion        #region 属性        public List<HistoryDataItem> ProcessData { get; set; }        public List<Recipeslist> CheboxRecipes { get; set; }        public ProcessDataChartDataItem ProcessChartData { get; set; }        public DateTime StartDateTime { get; set; }        public DateTime EndDateTime { get; set; }        public string SelectedValuePM { get; set; }        public string RecipeName { get; set; }        public ObservableCollection<PdKeyData> OldPdKeyDataCollection { get; set; }        public ObservableCollection<RecipeItem> Recipes { get; set; }        public class Recipeslist        {            public string BoxName { get; set; }        }        public class RecipeAdd        {            public string Recipesname { get; set; }        }        public ObservableCollection<ParameterNode> ParameterNodes        {            get { return _ParameterNodes; }            set { SetProperty(ref _ParameterNodes, value); }        }        public ObservableCollection<PdKeyData> PdKeyDataCollection        {            get { return _PdKeyDataObservation; }            set { SetProperty(ref _PdKeyDataObservation, value); }        }        #endregion        #region 命令        private DelegateCommand<object> _LoadCommandPD;        public DelegateCommand<object> LoadCommandPD =>            _LoadCommandPD ?? (_LoadCommandPD = new DelegateCommand<object>(OnLoadPd));        private DelegateCommand _SearchRecipeCommand;        public DelegateCommand SearchRecipeCommand =>        _SearchRecipeCommand ?? (_SearchRecipeCommand = new DelegateCommand(SearchRecipes));        private DelegateCommand<object> _PdParameterCheckCommand;        public DelegateCommand<object> PdParameterCheckCommand =>           _PdParameterCheckCommand ?? (_PdParameterCheckCommand = new DelegateCommand<object>(OnParameterCheck));        private DelegateCommand<object> _DataGridSelectionChangedCommand;        public DelegateCommand<object> DataGridSelectionChangedCommand =>           _DataGridSelectionChangedCommand ?? (_DataGridSelectionChangedCommand = new DelegateCommand<object>(OnDataGridSelectionChanged));        private DelegateCommand _SearchDataCommand;        public DelegateCommand SearchDataCommand =>        _SearchDataCommand ?? (_SearchDataCommand = new DelegateCommand(OnSearchData));        private DelegateCommand _ClearDataCommand;        public DelegateCommand ClearDataCommand =>        _ClearDataCommand ?? (_ClearDataCommand = new DelegateCommand(OnClearData));        #endregion        #region 构造函数        public ProcessHistoryViewModel()        {            ProcessData = new List<HistoryDataItem>() { };            ProcessChartData = new ProcessDataChartDataItem(60000);            Recipes = new ObservableCollection<RecipeItem>();            timer.Interval = TimeSpan.FromSeconds(0.5);            OldPdKeyDataCollection = new ObservableCollection<PdKeyData>();            CheboxRecipes = new List<Recipeslist>();            solidColorBrushes.Add(new SolidColorBrush(Colors.Green));            solidColorBrushes.Add(new SolidColorBrush(Colors.Red));            solidColorBrushes.Add(new SolidColorBrush(Colors.Blue));            solidColorBrushes.Add(new SolidColorBrush(Colors.Orange));            solidColorBrushes.Add(new SolidColorBrush(Colors.Yellow));            solidColorBrushes.Add(new SolidColorBrush(Colors.YellowGreen));            solidColorBrushes.Add(new SolidColorBrush(Colors.AliceBlue));            solidColorBrushes.Add(new SolidColorBrush(Colors.Chocolate));            solidColorBrushes.Add(new SolidColorBrush(Colors.Cyan));            solidColorBrushes.Add(new SolidColorBrush(Colors.DarkGreen));        }        #endregion        #region 命令方法        private void OnLoadPd(Object eventView)        {            this.view = (ProcessHistoryView)eventView;            this.view.wfTimeFrom.Value = DateTime.Today;            this.view.wfTimeTo.Value = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 23, 59, 59, 999);            this.LoadRecipeCheckBox();        }        private void LoadRecipeCheckBox()        {            List<string> chamber = new List<string>() { "PMA", "PMB", "PMC", "PMD" };            CheboxRecipes.Clear();            foreach (string item in chamber)            {                string path = Path.Combine(QueryDataClient.Instance.Service.GetData("GetRTPath").ToString(), "Recipes", item);                if (Directory.Exists(path))                {                    string[] dir = Directory.GetFiles(path);                    for (int i = 0; i < dir.Length; i++)                    {                        CheboxRecipes.Add(new Recipeslist { BoxName = Path.GetFileName(dir[i]) });                    }                }            }        }        public void SearchRecipes()        {            SearchRecipe(this.view.wfTimeFrom.Value, this.view.wfTimeTo.Value);        }        public void searchlot(string id)        {            Recipes.Clear();            try            {                string sql1 = string.Format($"SELECT * FROM \"lot_wafer_data\" where  guid ='{id}'; ");                DataTable dbData1 = QueryDataClient.Instance.Service.QueryData(sql1);                string lot_data_guid = dbData1.Rows[0]["wafer_data_guid"].ToString();                string sql = string.Format($"SELECT * FROM \"process_data\" where  wafer_data_guid ='{lot_data_guid}'");                if (!string.IsNullOrEmpty(SelectedValuePM))                {                    string[] pms = SelectedValuePM.Split(',');                    if (pms.Length > 0)                    {                        sql += " and (FALSE ";                        foreach (var pm in pms)                        {                            sql += $" OR \"process_in\"='{pm}' ";                        }                        sql += " ) ";                    }                }                if (!string.IsNullOrEmpty(RecipeName))                {                    sql += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());                }                sql += " order by \"process_begin_time\" ASC;";                DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);                System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>                {                    if (dbData == null || dbData.Rows.Count == 0) return;                    for (int i = 0; i < dbData.Rows.Count; i++)                    {                        RecipeItem item = new RecipeItem();                        item.Selected = false;                        item.Recipe = dbData.Rows[i]["recipe_name"].ToString();                        item.Guid = dbData.Rows[i]["guid"].ToString();                        item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();                        item.Chamber = dbData.Rows[i]["process_in"].ToString();                        item.Status = dbData.Rows[i]["process_status"].ToString();                        item.SlotID = dbData.Rows[i]["slot_id"].ToString();                        item.LotID = dbData.Rows[i]["lot_id"].ToString();                        if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))                            item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss");                        if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))                            item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss");                        Recipes.Add(item);                    }                }));            }            catch (Exception e)            {                LOG.WriteExeption(e);            }        }        public void SearchRecipe(DateTime start, DateTime end)        {            this.StartDateTime = start;            this.EndDateTime = end;            Recipes.Clear();            try            {                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")}' ";                if (!string.IsNullOrEmpty(SelectedValuePM))                {                    string[] pms = SelectedValuePM.Split(',');                    if (pms.Length > 0)                    {                        sql += " and (FALSE ";                        foreach (var pm in pms)                        {                            sql += $" OR \"process_in\"='{pm}' ";                        }                        sql += " ) ";                    }                }                if (!string.IsNullOrEmpty(RecipeName))                {                    sql += string.Format(" and lower(\"recipe_name\") like '%{0}%'", RecipeName.ToLower());                }                sql += " order by \"process_begin_time\" ASC;";                DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);                System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>                {                    if (dbData == null || dbData.Rows.Count == 0) return;                    for (int i = 0; i < dbData.Rows.Count; i++)                    {                        RecipeItem item = new RecipeItem();                        item.Selected = false;                        item.Recipe = dbData.Rows[i]["recipe_name"].ToString();                        item.Guid = dbData.Rows[i]["guid"].ToString();                        item.RecipeRunGuid = dbData.Rows[i]["wafer_data_guid"].ToString();                        item.Chamber = dbData.Rows[i]["process_in"].ToString();                        item.Status = dbData.Rows[i]["process_status"].ToString();                        item.SlotID = dbData.Rows[i]["slot_id"].ToString();                        item.LotID = dbData.Rows[i]["lot_id"].ToString();                        if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))                            item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy-MM-dd HH:mm:ss");                        if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))                            item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy-MM-dd HH:mm:ss");                        Recipes.Add(item);                    }                }));            }            catch (Exception e)            {                LOG.WriteExeption(e);            }        }        private void CalKeys(ParameterNode parameterNode)        {            if (parameterNode.ChildNodes.Count > 0)            {                foreach (var item in parameterNode.ChildNodes)                {                    CalKeys(item);                }            }            else            {                if (parameterNode.Selected == true)                {                    keys.Add(parameterNode.Name);                }            }        }        private Dictionary<string, List<HistoryDataItem>> GetData(List<string> keys, DateTime from, DateTime to)        {            string sql = "select time AS InternalTimeStamp";            foreach (var dataId in keys)            {                sql += "," + string.Format("\"{0}\"", dataId);            }            sql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",                from.ToString("yyyyMMdd") + "." + "Data", from.Ticks, to.Ticks);            DataTable dataTable = QueryDataClient.Instance.Service.QueryData(sql);            Dictionary<string, List<HistoryDataItem>> historyData = new Dictionary<string, List<HistoryDataItem>>();            if (dataTable == null || dataTable.Rows.Count == 0)                return null;            DateTime dt = new DateTime();            Dictionary<int, string> colName = new Dictionary<int, string>();            for (int colNo = 0; colNo < dataTable.Columns.Count; colNo++)            {                colName.Add(colNo, dataTable.Columns[colNo].ColumnName);                historyData[dataTable.Columns[colNo].ColumnName] = new List<HistoryDataItem>();            }            for (int rowNo = 0; rowNo < dataTable.Rows.Count; rowNo++)            {                PointCollection points = new PointCollection();                var row = dataTable.Rows[rowNo];                for (int i = 0; i < dataTable.Columns.Count; i++)                {                    HistoryDataItem data = new HistoryDataItem();                    if (i == 0)                    {                        long ticks = (long)row[i];                        dt = new DateTime(ticks);                        continue;                    }                    else                    {                        string dataId = colName[i];                        if (row[i] is DBNull || row[i] == null)                        {                            data.dateTime = dt;                            data.dbName = colName[i];                            data.value = 0;                        }                        else if (row[i] is bool)                        {                            data.dateTime = dt;                            data.dbName = colName[i];                            data.value = (bool)row[i] ? 1 : 0;                        }                        else                        {                            data.dateTime = dt;                            data.dbName = colName[i];                            data.value = float.Parse(row[i].ToString());                        }                    }                    historyData[data.dbName].Add(data);                }            }            foreach (var item in historyData)            {                item.Value.Sort((x, y) => DateTime.Compare(x.dateTime, y.dateTime));            }            return historyData;        }        private bool RefreshTreeStatusToChild(ParameterNode node)        {            if (node.ChildNodes.Count > 0)            {                for (int i = 0; i < node.ChildNodes.Count; i++)                {                    ParameterNode n = node.ChildNodes[i];                    n.Selected = node.Selected;                    if (!RefreshTreeStatusToChild(n))                    {                        //uncheck left node                        for (int j = i; j < node.ChildNodes.Count; j++)                        {                            node.ChildNodes[j].Selected = !node.Selected;                        }                        //node.Selected = !node.Selected;                        return false;                    }                }            }            //else            //{            //    if (node.Selected == true)            //    {            //        keys.Add(node.Name);            //    }            //    else            //    {             //    keys.Remove(node.Name);            //    }            //}                 return true;        }        private void RefreshTreeStatusToParent(ParameterNode node)        {            if (node.ParentNode != null)            {                if (node.Selected)                {                    bool flag = true;                    for (int i = 0; i < node.ParentNode.ChildNodes.Count; i++)                    {                        if (!node.ParentNode.ChildNodes[i].Selected)                        {                            flag = false;  //as least one child is unselected                            break;                        }                    }                    if (flag)                        node.ParentNode.Selected = true;                }                else                {                    node.ParentNode.Selected = false;                }                RefreshTreeStatusToParent(node.ParentNode);            }        }        public static T DeepCopyJson<T>(T obj)        {            // 序列化            string json = JsonConvert.SerializeObject(obj);            // 反序列化            return JsonConvert.DeserializeObject<T>(json);        }        private void OnParameterCheck(object obj)        {            ParameterNode node = obj as ParameterNode;            if (!RefreshTreeStatusToChild(node))            {                node.Selected = !node.Selected;            }            else            {                RefreshTreeStatusToParent(node);            }            keys.Clear();            for (int i = 0; i < ParameterNodes.Count; i++)            {                CalKeys(ParameterNodes[i]);            }            if (keys.Count > 10)            {                WPFMessageBox.ShowWarning("最多显示10个数据");                return;            }            OldPdKeyDataCollection.Clear();            OldPdKeyDataCollection = DeepCopyJson(PdKeyDataCollection);            PdKeyDataCollection.Clear();            for (int i = 0; i < keys.Count; i++)            {                if (i == 10)                {                    break;                }                PdKeyDataCollection.Add(new PdKeyData() { Key = keys[i], Color = solidColorBrushes[i], UniqueId = i });            }            Compare(OldPdKeyDataCollection, PdKeyDataCollection);            PdKeyDataCollection = DeepCopyJson(OldPdKeyDataCollection);        }        public void Compare(ObservableCollection<PdKeyData> olddata, ObservableCollection<PdKeyData> newdata)        {            if (newdata != null)            {                for (int i = 0; i < newdata.Count; i++)                {                    var lists = olddata.ToList().Find(t => t.Key == newdata[i].Key);                    if (lists == null)                    {                        olddata.Add(new PdKeyData() { Key = newdata[i].Key, Color = solidColorBrushes[i], UniqueId = olddata.Count + 1 });                    }                }                for (int i = 0; i < olddata.Count; i++)                {                    var lists = newdata.ToList().Find(t => t.Key == olddata[i].Key);                    if (lists == null)                    {                        olddata.Remove(olddata[i]);                    }                }            }        }        public void UpdateData(RecipeItem dataLog)        {           OnClearData();           //CheckRecipe(dataLog.Guid);        }        public void CheckRecipe(string RecipeGuid)        {            string sql = $"SELECT * FROM \"recipe_step_data\" where \"process_data_guid\" = '{RecipeGuid}' order by step_number ASC;";            var dbData = QueryDataClient.Instance.Service.QueryData(sql);            List<StepData> steps = new List<StepData>();            if (dbData != null && dbData.Rows.Count > 0)            {                for (int i = 0; i < dbData.Rows.Count; i++)                {                    StepData item = new StepData();                    item.No = int.Parse(dbData.Rows[i]["step_number"].ToString());                    item.Name = dbData.Rows[i]["step_name"].ToString();                    if (!dbData.Rows[i]["step_begin_time"].Equals(DBNull.Value))                        item.StartTime = (DateTime)dbData.Rows[i]["step_begin_time"];                    if (!dbData.Rows[i]["step_end_time"].Equals(DBNull.Value))                        item.EndTime = (DateTime)dbData.Rows[i]["step_end_time"];                    item.ActualTime = item.EndTime.CompareTo(item.StartTime) <= 0 ? "" : item.EndTime.Subtract(item.StartTime).TotalSeconds.ToString();                    item.SettingTime = dbData.Rows[i]["step_time"].ToString();                    //annotation.Add(VerLine(Brushes.Blue, item.StartTime, Brushes.Blue, $"{item.No}:{item.Name}"));                }            }        }        public void OnDataGridSelectionChanged(object obj)        {            selectedRecipeItem = obj as RecipeItem;            ParameterNodes = new ObservableCollection<ParameterNode>(_provider.GetParameters().Where(x => x.Name == selectedRecipeItem?.Chamber));        }        public void OnSearchData()        {            ProcessData.Clear();            this.view.MyDrawGraphicsControl.ClearPlotPoints();            var Keys = new List<string>();            PdKeyDataCollection.ToList().ForEach(key =>            {                Keys.Add(key.Key);            });            if (keys.Count == 0)            {                return;            }            var result = GetData(Keys.Distinct().ToList(), Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));            if (result == null)            {                return;            }            List<PointCollection> cls = new List<PointCollection>();            for (int i = 0; i < Keys.Count; i++)            {                PointCollection points = new PointCollection();                int k = 1;                result[Keys[i]].ForEach(point =>                {                    ProcessData.Add(new HistoryDataItem() { dateTime= point.dateTime, dbName= Keys[i],value= point.value });                    points.Add(new Point() { X = point.dateTime.ToOADate(), Y = point.value });                    k += 1;                });                cls.Add(points);            }            for (int i = 0; i <PdKeyDataCollection.Count(); i++)            {                var _color = PdKeyDataCollection[i].Color.Color;                view.MyDrawGraphicsControl.m_PenCollencteions[i] = new System.Drawing.Pen(System.Drawing.Color.FromArgb(_color.A, _color.R, _color.G, _color.B), 2);            }            this.view.MyDrawGraphicsControl.PointCollections = cls;            this.view.MyDrawGraphicsControl.FitControl();            this.view.MyDrawGraphicsControl.YPoints.Clear();            var item = QueryDataClient.Instance.Service.GetHistorySteps(Convert.ToDateTime(selectedRecipeItem?.StartTime), Convert.ToDateTime(selectedRecipeItem?.EndTime));            if (item!=null)            {                item.ForEach(x =>                {                    this.view.MyDrawGraphicsControl.YPoints.Add(new Venus_Core.StepItem() { StartValue = x.StartTime.ToOADate(), Information = $"{x.RecipeId}:{x.StepNo}" });                });            }        }        private void CloseAll(ObservableCollection<ParameterNode> parameterNodes)        {            if (parameterNodes != null)            {                foreach (var item in parameterNodes)                {                    item.Selected = false;                    if (item.ChildNodes.Count > 0)                    {                        CloseAll(item.ChildNodes);                    }                }            }        }        private void OnClearData()        {            this.view.MyDrawGraphicsControl.YPoints.Clear();            PdKeyDataCollection.Clear();            this.view.MyDrawGraphicsControl.ClearPlotPoints();            CloseAll(ParameterNodes);                   }    }        #endregion        #region 数据类        public class RecipeItem : BindableBase        {            public bool Selected { get; set; }            public string Recipe { get; set; }            public string Guid { get; set; }            public string RecipeRunGuid { get; set; }            public string Chamber { get; set; }            public string Status { get; set; }            public string StartTime { get; set; }            public string EndTime { get; set; }            public string LotID { get; set; }            public string SlotID { get; set; }        }    public class StepData    {        [DataMember]        public int No { get; set; }        [DataMember]        public string Name { get; set; }        [DataMember]        public DateTime StartTime { get; set; }        [DataMember]        public DateTime EndTime { get; set; }        [DataMember]        public string ActualTime { get; set; }        [DataMember]        public string SettingTime { get; set; }    }    public class PdKeyData : BindableBase, ICloneable        {            public string Key { get; set; }            public SolidColorBrush _Color;            public SolidColorBrush Color            {                get { return _Color; }                set { SetProperty(ref _Color, value); }            }            public int UniqueId { get; set; }            public object Clone()            {                return MemberwiseClone();            }        }        #endregion    }
 |