From ef52fd6fd07508883dce4eb002acda59f0169e59 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期四, 23 四月 2026 10:19:33 +0800
Subject: [PATCH] 优化;

---
 Plugin.TestResult/SingleCell.xaml.cs | 1062 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 1,014 insertions(+), 48 deletions(-)

diff --git a/Plugin.TestResult/SingleCell.xaml.cs b/Plugin.TestResult/SingleCell.xaml.cs
index 60b55c7..b9a6ab0 100644
--- a/Plugin.TestResult/SingleCell.xaml.cs
+++ b/Plugin.TestResult/SingleCell.xaml.cs
@@ -1,10 +1,22 @@
-锘縰sing Plugin.TestResult_WPF.Constant;
+锘縰sing CSVHelper;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using HMI.Util;
+using PLCHelper;
+using Plugin.TestResult;
+using Plugin.TestResult.Util;
+using Plugin.TestResult_WPF.Constant;
 using Plugin.TestResult_WPF.Model;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.ComponentModel;
+using System.Dynamic;
+using System.IO;
 using System.Runtime.CompilerServices;
 using System.Windows;
 using System.Windows.Controls;
@@ -33,32 +45,105 @@
         }
         #endregion
 
+        private static readonly HashSet<string> IgnoreTestItem = new HashSet<string> {
+            "浜у搧鏉$爜","checkin","棰勬鐢垫祦","precheckresult","checkout",
+        };
+
         private InfoWindow window;
         private int maxSize;
 
-        public SingleCell()
-        {
-            DataContext = this;
-            InitializeComponent();
-        }
+        public DataTable table { get; private set; }
 
-        public SingleCell(string parentName, int index, int maxSize)
+        public SingleCell(DataTable table, string title, int index, int maxSize, string iniFile)
         {
-            this.parentName = parentName;
+            this.table = table;
+            this.title = title;
             this.index = index;
             this.maxSize = maxSize;
+            this.countIniPath = iniFile;
             DataContext = this;
             InitializeComponent();
+            RefreshProbe();
         }
 
-        private string _parentName;
-        public string parentName
+        public void RefreshProbe()
         {
-            get { return _parentName; }
+            try
+            {
+                string key = string.Empty;
+                ParameterData value;
+                if (ParamSetting.ProbeByModel)
+                {
+                    string model = table.CbProduct?.SelectedItem?.ToString();
+                    key = $"{title}_{model}";
+                    value = ProductManager.GetParameterByProductAndName(model, "ProbeWarn");
+                    if (value == null)
+                    {
+                        value = ParameterManager.GetCommonParameterByName("ProbeWarn");
+                    }
+                    ProbeWarn = value != null ? int.Parse(value.Value) : 1000;
+                }
+                else
+                {
+                    key = $"{title}";
+                    value = ParameterManager.GetCommonParameterByName("ProbeWarn");
+                    ProbeWarn = value != null ? int.Parse(value.Value) : 1000;
+                }
+                string temp = IniFileHelper.ReadIniData(key, "ProbeCount", "0", countIniPath);
+                int count = Convert.ToInt32(temp);
+                ProbeCount = count;
+            }
+            catch
+            {
+                ProbeWarn = 1000;
+            }
+            if (window != null) window.UpdateProbeCount(ProbeCount, ProbeWarn);
+        }
+
+        public void RefreshCharts()
+        {
+            charts = new LiveChart[3];
+            try
+            {
+                ParameterData value;
+                string model = table.CbProduct?.SelectedItem?.ToString();
+
+                for (int i = 0; i < charts.Length; i++)
+                {
+                    value = ProductManager.GetParameterByProductAndName(model, $"ChartConfig_{i}");
+                    if (value == null)
+                    {
+                        value = ParameterManager.GetCommonParameterByName($"ChartConfig_{i}");
+                    }
+                    var config = value != null ? value.Value : null;
+
+                    if (string.IsNullOrEmpty(config))
+                    {
+                        charts[i] = null;
+                    }
+                    else
+                    {
+                        charts[i] = new LiveChart(config) //new string[] { "娓╁害(鈩�)", "娴侀噺(L/m)" }
+                        {
+                            MinHeight = 120
+                        };
+                    }
+                }
+            }
+            catch
+            {
+                charts = new LiveChart[0];
+            }
+        }
+
+        private string _sn;
+        public string sn
+        {
+            get { return _sn; }
             set
             {
-                RaiseAndSetIfchanged(ref _parentName, value);
-                RaisePropertyChanged("title");
+                RaiseAndSetIfchanged(ref _sn, value);
+                RaisePropertyChanged("sn");
             }
         }
 
@@ -74,7 +159,36 @@
             }
         }
 
-        public string title => $"{parentName}{index + 1}";
+        private bool cellIsDisabled;
+
+        public bool CellIsDisabled
+        {
+            get { return cellIsDisabled; }
+            set
+            {
+                RaiseAndSetIfchanged(ref cellIsDisabled, value);
+            }
+        }
+
+        private string _title;
+        public string title
+        {
+            get => _title;
+            set
+            {
+                RaiseAndSetIfchanged(ref _title, value);
+            }
+        }
+
+        private int _probeWarn;
+        public int ProbeWarn
+        {
+            get => _probeWarn;
+            set
+            {
+                RaiseAndSetIfchanged(ref _probeWarn, value);
+            }
+        }
 
         private string _status = CommonStatus.WAITING;
 
@@ -102,7 +216,9 @@
 
         private ConcurrentQueue<Info> queue = new ConcurrentQueue<Info>();
 
-        private ObservableCollection<Info> _infos;
+        private List<Info> allInfos = new List<Info>();
+
+        private ObservableCollection<Info> _infos = new ObservableCollection<Info>();
 
         public ObservableCollection<Info> infos
         {
@@ -114,12 +230,51 @@
             }
         }
 
+        private string countIniPath;
+        /// <summary>
+        /// 鎺㈤拡瀵垮懡
+        /// </summary>
+        private int probeCount;
+        public int ProbeCount
+        {
+            get => probeCount;
+            set
+            {
+                RaiseAndSetIfchanged(ref probeCount, value);
+                probeAlarm = value >= ProbeWarn;
+            }
+        }
+
+        private bool _probeAlarm;
+        public bool probeAlarm
+        {
+            get => _probeAlarm;
+            set
+            {
+                RaiseAndSetIfchanged(ref _probeAlarm, value);
+            }
+        }
+
+        private void UpdateProbeCount(int count)
+        {
+            ProbeCount = count;
+            string key = $"{title}";
+            if (ParamSetting.ProbeByModel)
+            {
+                string model = table?.CbProduct?.SelectedItem?.ToString();
+                key = $"{title}_{model}";
+            }
+            IniFileHelper.WriteIniData(key, "ProbeCount", ProbeCount.ToString(), countIniPath);
+            if (window != null) window.UpdateProbeCount(ProbeCount, ProbeWarn);
+        }
+
         private void UserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e)
         {
             if (window == null)
             {
-                window = new InfoWindow(title, infos);
+                window = new InfoWindow(title, infos, charts, ProbeCount, ProbeWarn);
                 window.Closed += Window_Closed;
+                window.ClearProbeCountEvent += Window_ClearProbeCountEvent;
                 window.Owner = Window.GetWindow(this);
                 window.Show();
             }
@@ -129,67 +284,878 @@
             }
         }
 
+        private void Window_ClearProbeCountEvent(object sender, EventArgs e)
+        {
+            UpdateProbeCount(0);
+        }
+
         private void Window_Closed(object sender, EventArgs e)
         {
             this.window = null;
         }
 
+        private string visualTestId;
+        private Sqlite3Helper helper;
+
         public void SetStatus(string status)
         {
-            this.status = status;
-        }
-
-        public void SetInfos(List<Info> infos)
-        {
-            this.infos = new ObservableCollection<Info>(infos);
-            if (window != null) window.UpdateSource(this.infos);
-        }
-
-        public void SetInfos(string[,] infos)
-        {
-            var data = new ObservableCollection<Info>();
-            for (int i = 0; i < infos.GetLength(0); i++)
+            Dispatcher.Invoke(() =>
             {
-                data.Add(new Info
+                var oldStatus = this.status;
+                this.status = status;
+                if (oldStatus != "testing" && status == "testing")
                 {
-                    step = infos[i, 0],
-                    result = infos[i, 1]
-                });
+                    UpdateProbeCount(ProbeCount + 1);
+                    var now = DateTime.Now;
+                    string dateStr = now.ToString("yyyyMMdd");
+                    visualTestId = $"{title}_{now.ToString("yyyyMMddHHmmssfff")}";
+                    helper = CheckSqlHelper(dateStr);
+                    InsertARecourd();
+                }
+
+                if (oldStatus != "ok" && status == "ok")
+                {
+                    SaveInfoToDB();
+                }
+
+                if (oldStatus != "ng" && status == "ng")
+                {
+                    SaveInfoToDB();
+                }
+            });
+        }
+
+        private void InsertARecourd()
+        {
+            try
+            {
+                string model = table?.CbProduct?.SelectedItem?.ToString();
+                var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+                var sql = $"INSERT INTO testResult (sn,model,station,position,result,time,resultId) VALUES ('{sn}','{model}','','{title}','{this.status}','{timestr}','{visualTestId}');";
+                helper.Execute(sql);
             }
-            this.infos = data;
-            if (window != null) window.UpdateSource(this.infos);
+            catch (Exception ex)
+            {
+                ViewControl.Logger.Error($"Cell[{title}] SaveToDB Error.", ex);
+            }
+        }
+
+        public void WriteCSV(Info info)
+        {
+            //try
+            //{
+            //    if (ParamSetting.CustomerCode != "LIXUN")
+            //    {
+            //        return;
+            //    }
+            //    string fileName = this.sn?.Replace("/", "#")?.Replace("\\", "#") + ".csv";
+            //    string dir = Path.Combine(ParamSetting.DataLogFolder, "csv", this.title);
+            //    string title = $"{this.lang("Test.Name")},{this.lang("Test.Value")},{this.lang("Test.LimitDown")},{this.lang("Test.LimitUp")},{this.lang("Test.Unit")},{this.lang("Test.Result")},{this.lang("Test.TestTime")}";
+            //    string line = $"{info.step},{info.value},{info.limitDown},{info.limitUp},{info.unit},{info.result},{info.updateTime}";
+
+            //    CSVPrinter.Print(dir, fileName, title, line);
+            //    // ReverseCSV(Path.Combine(dir, fileName));
+            //}
+            //catch (Exception ex)
+            //{
+            //}
+        }
+
+        public void SendToChart(Info info)
+        {
+            try
+            {
+                foreach (var chart in charts)
+                {
+                    if (chart?.CanHandle(info.step) == true)
+                    {
+                        chart.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+                    }
+                }
+                //if (electricChart.CanHandle(info.step))
+                //{
+                //    electricChart.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+                //}
+
+                //if (vChart.CanHandle(info.step))
+                //{
+                //    vChart.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+                //}
+
+                //if (waterChart?.CanHandle(info.step) == true)
+                //{
+                //    waterChart?.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+                //}
+            }
+            catch (Exception ex)
+            {
+            }
         }
 
         public void SetInfos(Info info)
         {
-            if (queue.Count >= maxSize)
+            string sql = string.Empty;
+            try
             {
-                queue.TryDequeue(out var first);
+                allInfos.Add(info);
+                SendToChart(info);
+                WriteCSV(info);
+
+                /// 鐩墠鍏堜笉闄愬埗鏁伴噺锛屽悗缁鏋滄暟鎹繃澶氬鑷存�ц兘闂鍐嶈�冭檻闄愬埗鏁伴噺
+                //if (queue.Count >= maxSize)
+                //{
+                //    queue.TryDequeue(out var first);
+                //    queue.Enqueue(info);
+                //    this.infos = new ObservableCollection<Info>(queue);
+                //    if (window != null) window.UpdateSource(this.infos);
+                //}
+                //else
+                //{
+                //    queue.Enqueue(info);
+                //    if (window != null)
+                //    {
+                //        window.Dispatcher.Invoke(() =>
+                //        {
+                //            this.infos.Add(info);
+                //        });
+                //    }
+                //    else
+                //    {
+                //        Dispatcher.Invoke(() =>
+                //        {
+                //            this.infos.Add(info);
+                //        });
+                //    }
+                //}
+
+                if (window != null)
+                {
+                    window.Dispatcher.Invoke(() =>
+                    {
+                        this.infos.Add(info);
+                    });
+                }
+                else
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        this.infos.Add(info);
+                    });
+                }
+
+                Dispatcher.Invoke(() =>
+                {
+                    string dateStr = string.Empty;
+                    try
+                    {
+                        dateStr = DateTime.Parse(info.updateTime).ToString("yyyy-MM-dd HH:mm:ss");
+                    }
+                    catch
+                    {
+                        dateStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+                    }
+
+                    try
+                    {
+                        string model = table?.CbProduct?.SelectedItem?.ToString();
+                        sql = $@"INSERT INTO serialData (sn,model,station,position,step,limitDown,limitUp,unit,value,status,finalStatus,time,resultId) 
+VALUES ('{sn}','{model}','','{this.title}','{info.step}','{info.limitDown}','{info.limitUp}','{info.unit}','{info.value}','{info.result}',
+NULL,'{dateStr}','{visualTestId}');";
+                        helper.Execute(sql);
+                    }
+                    catch (Exception ex)
+                    {
+                        ViewControl.Logger.Error($"Save DB Test Data Error. {sql}", ex);
+                    }
+                });
             }
-            queue.Enqueue(info);
-            var list = new ObservableCollection<Info>(queue);
-            this.infos = list;
-            if (window != null) window.UpdateSource(this.infos);
+            catch (Exception ex)
+            {
+                ViewControl.Logger.Error($"Add Test Data Error. {sql}", ex);
+            }
         }
 
         public void ClearInfo()
         {
+            allInfos.Clear();
             queue = new ConcurrentQueue<Info>();
             var list = new ObservableCollection<Info>(queue);
             this.infos = list;
             if (window != null) window.UpdateSource(this.infos);
         }
 
-        public void SetInfos(string step, string result)
+        //private Chart waterChart = null;
+        //private Chart electricChart = new Chart(LangUtil.Get("Tr.CurrentChart"), false, 20)
+        //{
+        //    Height = 120
+        //};
+
+        //private Chart vChart = new Chart(LangUtil.Get("Tr.VoltChart"), false, 20)
+        //{
+        //    Height = 120
+        //};
+
+        private LiveChart[] charts = new LiveChart[0];
+
+        //private LiveChart waterChart = null;
+        //private LiveChart electricChart = new LiveChart("瀛愭澘鐢垫祦,鐢垫祦(A);姣嶆澘鐢垫祦,鐢垫祦(A)") //new string[] { "瀛愭澘鐢垫祦", "妯℃澘鐢垫祦" }
+        //{
+        //    MinHeight = 120
+        //};
+
+        //private LiveChart vChart = new LiveChart("瀛愭澘鐢靛帇,鐢靛帇(V);姣嶆澘鐢靛帇,鐢靛帇(V)") //new string[] { "瀛愭澘鐢靛帇", "妯℃澘鐢靛帇" }
+        //{
+        //    MinHeight = 120
+        //};
+
+        public void AddWaterData(double temp, double backTemp, double pressure)
         {
-            if (queue.Count >= maxSize)
+            //waterChart?.AddData(0, "姘寸娓╁害", temp);
+            //waterChart?.AddData(0, "鍥炴按娓╁害", backTemp);
+            //waterChart?.AddData(1, "娴侀噺", pressure);
+
+            //waterChart?.AddData("姘寸娓╁害", temp);
+            //waterChart?.AddData("鍥炴按娓╁害", backTemp);
+            //waterChart?.AddData("娴侀噺", pressure);
+        }
+
+        public void AddElectricData(double data)
+        {
+            //electricChart.AddData("", data);
+        }
+
+        public void AddVData(double data)
+        {
+            //vChart.AddData("", data);
+        }
+
+        public void ClearChart()
+        {
+            foreach (var chart in charts)
             {
-                queue.TryDequeue(out var info);
+                chart?.Clear();
             }
-            queue.Enqueue(new Info() { step = step, result = result });
-            var list = new ObservableCollection<Info>(queue);
-            this.infos = list;
-            if (window != null) window.UpdateSource(this.infos);
+        }
+
+        //public void ClearWaterData()
+        //{
+        //    waterChart?.Clear();
+        //}
+
+        //public void ClearElectricData()
+        //{
+        //    electricChart.Clear();
+        //}
+
+        //public void ClearVData()
+        //{
+        //    vChart.Clear();
+        //}
+
+
+        public void SaveElectricDataToCSV(string filePath)
+        {
+            try
+            {
+                List<double> datas = charts[1]?.GetSingleData("");
+
+                FileInfo fi = new FileInfo(filePath);
+                if (!fi.Directory.Exists)
+                {
+                    fi.Directory.Create();  //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+                }
+
+                using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+                {
+                    string title = this.lang("Tr.CurrentChart");
+                    sw.WriteLine(title);
+                    if (datas != null)
+                    {
+                        for (int i = 0; i < datas.Count; i++)
+                        {
+                            sw.WriteLine(datas[i].ToString());
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.ToString());
+            }
+        }
+
+        public void SaveVDataToCSV(string filePath)
+        {
+            try
+            {
+                List<double> datas = charts[2]?.GetSingleData("");
+
+                FileInfo fi = new FileInfo(filePath);
+                if (!fi.Directory.Exists)
+                {
+                    fi.Directory.Create();  //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+                }
+
+                using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+                {
+                    string title = this.lang("Tr.VoltChart");
+                    sw.WriteLine(title);
+                    if (datas != null)
+                    {
+                        for (int i = 0; i < datas.Count; i++)
+                        {
+                            sw.WriteLine(datas[i].ToString());
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.ToString());
+            }
+        }
+
+        public void NormalCSV(string filePath)
+        {
+            try
+            {
+                FileInfo fi = new FileInfo(filePath);
+                if (!fi.Directory.Exists)
+                {
+                    fi.Directory.Create();  //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+                }
+
+                using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+                {
+                    string title = $"{this.lang("Test.Name")},{this.lang("Test.Value")},{this.lang("Test.LimitDown")},{this.lang("Test.LimitUp")},{this.lang("Test.Unit")},{this.lang("Test.Result")},{this.lang("Test.TestTime")}";
+                    sw.WriteLine(title);
+                    foreach (var info in allInfos)
+                    {
+                        string row = $"{info.step},{info.value},{info.limitDown},{info.limitUp},{info.unit},{info.result},{info.updateTime}";
+                        sw.WriteLine(row);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                ViewControl.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex);
+            }
+        }
+
+        public void ReverseCSV_Bak(string filePath)
+        {
+            try
+            {
+                if (allInfos == null || allInfos.Count < 4) return;
+
+                Dictionary<string, int> columnMap = new Dictionary<string, int>();
+                int colPoint = 0;
+                List<string> titleRow = new List<string>();
+                List<string[]> datas = new List<string[]>();
+
+                void AddTitle(string title)
+                {
+                    if (titleRow.IndexOf(title) < 0)
+                    {
+                        titleRow.Add(title);
+                    }
+                }
+
+                // 鍏堣缃〃澶�
+                for (int row = 0; row < allInfos.Count; row++)
+                {
+                    var info = allInfos[row];
+                    if (IgnoreTestItem.Contains(info.step.ToLower()))
+                    {
+                        continue;
+                    }
+
+                    string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+                    AddTitle("娴嬭瘯鏃堕棿");
+                    AddTitle(title);
+                    if (!string.IsNullOrEmpty(info.limitDown))
+                    {
+                        string key2 = $"{info.step}涓嬮檺";
+                        AddTitle(key2);
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}涓婇檺";
+                        AddTitle(key2);
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}娴嬭瘯缁撴灉";
+                        AddTitle(key2);
+                    }
+
+                    //if (!string.IsNullOrEmpty(info.updateTime))
+                    //{
+                    //    string key2 = $"{info.step}娴嬭瘯鏃堕棿";
+                    //    AddTitle(key2);
+                    //}
+                }
+
+                int rowPoint = -1;
+                for (int row = 0; row < allInfos.Count; row++)
+                {
+                    var info = allInfos[row];
+                    if (IgnoreTestItem.Contains(info.step.ToLower()))
+                    {
+                        continue;
+                    }
+
+                    string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+                    int col = titleRow.IndexOf(title);
+                    if (col == 1)
+                    {
+                        rowPoint++;
+                    }
+                    if (datas.Count <= rowPoint)
+                    {
+                        datas.Add(new string[titleRow.Count]);
+                    }
+                    var arr = datas[rowPoint];
+                    arr[col] = info.value;
+
+
+                    if (!string.IsNullOrEmpty(info.limitDown))
+                    {
+                        string key2 = $"{info.step}涓嬮檺";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.limitDown;
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}涓婇檺";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.limitUp;
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}娴嬭瘯缁撴灉";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.result;
+                    }
+
+                    if (!string.IsNullOrEmpty(info.updateTime))
+                    {
+                        string key2 = "娴嬭瘯鏃堕棿";// $"{info.step}娴嬭瘯鏃堕棿";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.updateTime;
+                    }
+                }
+
+
+                FileInfo fi = new FileInfo(filePath);
+                if (!fi.Directory.Exists)
+                {
+                    fi.Directory.Create();  //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+                }
+
+                using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+                {
+                    string title = string.Join(",", titleRow);
+                    sw.WriteLine(title);
+                    foreach (var info in datas)
+                    {
+                        string row = string.Join(",", info);
+                        sw.WriteLine(row);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                ViewControl.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex);
+            }
+        }
+
+        public void ReverseCSV(string filePath)
+        {
+            try
+            {
+                if (allInfos == null || allInfos.Count < 4) return;
+
+                Dictionary<string, int> columnMap = new Dictionary<string, int>();
+                int colPoint = 0;
+                List<string> titleRow = new List<string>();
+                List<string[]> datas = new List<string[]>();
+                List<string> timeRow = new List<string>();
+
+                void AddTitle(string title)
+                {
+                    if (titleRow.IndexOf(title) < 0)
+                    {
+                        titleRow.Add(title);
+                    }
+                }
+
+                // 鍏堣缃〃澶�
+                for (int i = 0; i < allInfos.Count; i++)
+                {
+                    var info = allInfos[i];
+                    if (IgnoreTestItem.Contains(info.step.ToLower()))
+                    {
+                        continue;
+                    }
+                    string testTime = info.updateTime;
+                    int rowIndex = timeRow.IndexOf(testTime);
+                    if (rowIndex < 0)
+                    {
+                        timeRow.Add(testTime);
+                    }
+
+                    string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+                    AddTitle("娴嬭瘯鏃堕棿");
+                    AddTitle(title);
+                    if (!string.IsNullOrEmpty(info.limitDown))
+                    {
+                        string key2 = $"{info.step}涓嬮檺";
+                        AddTitle(key2);
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}涓婇檺";
+                        AddTitle(key2);
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}娴嬭瘯缁撴灉";
+                        AddTitle(key2);
+                    }
+
+                    //if (!string.IsNullOrEmpty(info.updateTime))
+                    //{
+                    //    string key2 = $"{info.step}娴嬭瘯鏃堕棿";
+                    //    AddTitle(key2);
+                    //}
+                }
+
+                for (int i = 0; i < allInfos.Count; i++)
+                {
+                    var info = allInfos[i];
+                    if (IgnoreTestItem.Contains(info.step.ToLower()))
+                    {
+                        continue;
+                    }
+                    string testTime = info.updateTime;
+                    int row = timeRow.IndexOf(testTime);
+                    if (row < 0)
+                    {
+                        continue;
+                    }
+
+
+
+                    string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+                    int col = titleRow.IndexOf(title);
+
+                    if (datas.Count <= row)
+                    {
+                        datas.Add(new string[titleRow.Count]);
+                    }
+                    var arr = datas[row];
+                    arr[col] = info.value;
+
+
+                    if (!string.IsNullOrEmpty(info.limitDown))
+                    {
+                        string key2 = $"{info.step}涓嬮檺";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.limitDown;
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}涓婇檺";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.limitUp;
+                    }
+
+                    if (!string.IsNullOrEmpty(info.limitUp))
+                    {
+                        string key2 = $"{info.step}娴嬭瘯缁撴灉";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.result;
+                    }
+
+                    if (!string.IsNullOrEmpty(info.updateTime))
+                    {
+                        string key2 = "娴嬭瘯鏃堕棿";// $"{info.step}娴嬭瘯鏃堕棿";
+                        int col2 = titleRow.IndexOf(key2);
+                        arr[col2] = info.updateTime;
+                    }
+                }
+
+
+                FileInfo fi = new FileInfo(filePath);
+                if (!fi.Directory.Exists)
+                {
+                    fi.Directory.Create();  //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+                }
+
+                using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+                using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+                {
+                    string title = string.Join(",", titleRow);
+                    sw.WriteLine(title);
+                    foreach (var info in datas)
+                    {
+                        string row = string.Join(",", info);
+                        sw.WriteLine(row);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                ViewControl.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex);
+            }
+        }
+
+        /// <summary>
+        /// 淇濆瓨娴嬭瘯鏁版嵁鍒癈SV
+        /// </summary>
+        /// <param name="filePath"></param>
+        public void SaveInfoToCSV(string filePath)
+        {
+            if (ParamSetting.ReverseCSV)
+            {
+                ReverseCSV(filePath);
+            }
+            else
+            {
+                NormalCSV(filePath);
+            }
+        }
+
+        private Sqlite3Helper CheckSqlHelper(string dateStr = null)
+        {
+            dateStr = string.IsNullOrEmpty(dateStr) ? DateTime.Now.ToString("yyyyMMdd") : dateStr;
+            string dbPath = Path.Combine(ParamSetting.DataLogFolder, $"Data_{dateStr}.db");
+            if (!File.Exists(dbPath))
+            {
+                Sqlite3Helper.CreateDatabase(dbPath);
+            }
+            var sqliteHelper = new Sqlite3Helper(dbPath);
+            sqliteHelper.Execute(@"CREATE TABLE IF NOT EXISTS serialData (
+                    id INTEGER PRIMARY KEY AUTOINCREMENT,
+                    sn TEXT NOT NULL,
+                    model TEXT,
+                    station TEXT NOT NULL,
+                    step TEXT NOT NULL,
+                    position TEXT,
+                    limitDown TEXT,
+                    limitUp TEXT,
+                    unit TEXT,
+                    offset TEXT,
+                    value TEXT,
+                    status TEXT,
+                    finalStatus TEXT,
+                    consumeTime TEXT, 
+                    totalConsumeTime TEXT, 
+                    resultId TEXT,
+                    time DATETIME NOT NULL);");
+            sqliteHelper.Execute(@"CREATE TABLE IF NOT EXISTS testResult (
+                    id INTEGER PRIMARY KEY AUTOINCREMENT,
+                    sn TEXT NOT NULL,
+                    model TEXT,
+                    station TEXT NOT NULL,
+                    position TEXT,
+                    status TEXT,
+                    result TEXT NOT NULL,
+                    resultId TEXT,
+                    time DATETIME NOT NULL);");
+            if (!sqliteHelper.HasData("SELECT 1 FROM pragma_table_info('serialData') WHERE name = 'resultId';"))
+            {
+                sqliteHelper.Execute("ALTER TABLE serialData ADD resultId TEXT;");
+            }
+            if (!sqliteHelper.HasData("SELECT 1 FROM pragma_table_info('testResult') WHERE name = 'resultId';"))
+            {
+                sqliteHelper.Execute("ALTER TABLE testResult ADD resultId TEXT;");
+            }
+            return sqliteHelper;
+        }
+
+        /// <summary>
+        /// 淇濆瓨娴嬭瘯鏁版嵁鍒癝qlite
+        /// </summary>
+        /// <param name="filePath"></param>
+        public void SaveInfoToDB()
+        {
+            Dispatcher.BeginInvoke(new Action(() =>
+            {
+                try
+                {
+                    string model = table?.CbProduct?.SelectedItem?.ToString();
+                    var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+                    //var sql = $"INSERT INTO testResult (sn,model,station,position,result,time,resultId) VALUES ('{sn}','{model}','','{title}','{this.status}','{timestr}','{visualTestId}');";
+                    var sql = $"UPDATE testResult SET time = '{timestr}', result = '{this.status}' WHERE resultId = '{visualTestId}'";
+                    helper.Execute(sql);
+                    helper.Dispose();
+                    helper = null;
+                    //                using (var helper = CheckSqlHelper())
+                    //                {
+                    //                    List<string> sqls = new List<string>();
+                    //                    var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+                    //                    foreach (var info in allInfos)
+                    //                    {
+                    //                        string sql = $@"INSERT INTO serialData (sn,station,step,limitDown,limitUp,unit,value,status,finalStatus,time) 
+                    //VALUES ('{sn}','','{info.step}','{info.limitDown}','{info.limitUp}','{info.unit}','{info.value}','{info.result}','{this.status}','{timestr}');";
+                    //                        sqls.Add(sql);
+                    //                    }
+                    //                    sqls.Add($"INSERT INTO testResult (sn,station,position,result,time) VALUES ('{sn}','','{title}','{this.status}','{timestr}');");
+                    //                    helper.ExecuteBatchSql(sqls);
+                    //                }
+                }
+                catch (Exception ex)
+                {
+                    ViewControl.Logger.Error($"Cell[{title}] SaveToDB Error.", ex);
+                }
+            }));
+        }
+
+        private void MenuItem_Click(object sender, RoutedEventArgs e)
+        {
+            var item = sender as MenuItem;
+            switch (item?.Name)
+            {
+                case "clearSNRItem":
+                    table.TryClearCellSN(this.index);
+                    break;
+                case "exportCSVItem":
+                    TryExportCSV();
+                    break;
+                case "manualDebugItem":
+                    OpenManualDebugWindow();
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// 鎵撳紑鎵嬪姩璋冭瘯绐楀彛
+        /// </summary>
+        private void OpenManualDebugWindow()
+        {
+            string manualDebugSeq = ParameterManager.GetCommonParameterByName("ManualDebugSeqPath")?.Value;
+            if (string.IsNullOrEmpty(manualDebugSeq))
+            {
+                MsgBoxHelper2.Error("璇峰厛璁剧疆鎵嬪姩璋冭瘯搴忓垪璺緞[ManualDebugSeqPath]!");
+                return;
+            }
+            string modelPath = table.parent.testModelFile;
+            int dutNo = table.index * table.cellCount + this.index;
+            var win = new ManualDebugWindow(manualDebugSeq, modelPath)
+            {
+                Title = $"{this.title}鎵嬪姩璋冭瘯",
+                Owner = Window.GetWindow(this),
+                OvenIndex = this.table.index,
+                OvenName = this.table.title,
+
+                CellIndex = dutNo,
+                CellName = this.title
+            };
+            win.ShowDialog();
+        }
+
+        /// <summary>
+        /// 灏濊瘯瀵煎嚭CSV
+        /// </summary>
+        private void TryExportCSV()
+        {
+            System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog
+            {
+                Filter = "CSV (*.csv)|*.csv"
+            };
+            if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+            {
+                this.NormalCSV(sfd.FileName);
+            }
+        }
+
+        public void ClearSN()
+        {
+            sn = string.Empty;
+            LightGreen(false, out _);
+            LightRed(false, out _);
+        }
+
+        public bool LightGreen(bool on, out string msg)
+        {
+            return S7Context.WriteData(RunTimeVariablePool.DEFAULT_PLC_NAME,
+                $"Oven{table.index + 1}_Cell{index + 1}_Light_OK", on, out msg);
+        }
+
+        public bool LightRed(bool on, out string msg)
+        {
+            return S7Context.WriteData(RunTimeVariablePool.DEFAULT_PLC_NAME,
+                $"Oven{table.index + 1}_Cell{index + 1}_Light_NG", on, out msg);
+        }
+
+        private void OnPreviewMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+
+            ContextMenu contextMenu = new ContextMenu();
+            contextMenu.Closed += ContextMenu_Closed;
+
+            //<  />
+            //<
+            //< MenuItem IsCheckable = "False" x: Name = "manualDebugItem" Click = "MenuItem_Click" Header = "鎵嬪姩璋冭瘯" >
+            //    < MenuItem.Style >
+            //        < Style TargetType = "MenuItem" BasedOn = "{StaticResource {x:Static pu:StyleKeys.MenuItemStyle}}" >
+
+            //        </ Style >
+            //    </ MenuItem.Style >
+            //</ MenuItem >
+
+            var item = new MenuItem
+            {
+                IsCheckable = false,
+                IsEnabled = !table.IsTesting,
+                Name = "clearSNRItem",
+                Header = this.lang("Tr.ClearSNR"),
+            };
+            item.Click += MenuItem_Click;
+            contextMenu.Items.Add(item);
+
+            item = new MenuItem
+            {
+                IsCheckable = false,
+                Name = "exportCSVItem",
+                Header = this.lang("App.ExportCSV"),
+            };
+            item.Click += MenuItem_Click;
+            contextMenu.Items.Add(item);
+
+            if (table.parent.inManualDebugMode)
+            {
+                item = new MenuItem
+                {
+                    IsCheckable = false,
+                    Name = "manualDebugItem",
+                    Header = this.lang("鎵嬪姩璋冭瘯"),
+                };
+                item.Click += MenuItem_Click;
+                contextMenu.Items.Add(item);
+            }
+
+            this.ContextMenu = contextMenu;
+        }
+
+        private void ContextMenu_Closed(object sender, RoutedEventArgs e)
+        {
+            this.ContextMenu = null;
         }
     }
 }

--
Gitblit v1.9.1