alielie
2025-11-24 9211ec11c112e18cd99e77f889a01110a70031ce
Plugin.DataBoard/DataBoard.xaml.cs
@@ -1,4 +1,6 @@
using HMI.Base;
using HMI.Core.Entity;
using HMI.Core.Manager;
using HMI.Core.Util;
using HMI.UI.Util;
using HMI.Util;
@@ -10,6 +12,7 @@
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -40,9 +43,78 @@
            set { Set(ref _options, value); }
        }
        private string iniFile;
        public override void InitFinish()
        {
            iniFile = Path.Combine(BaseFolder, "Config.ini");
            if (!File.Exists(iniFile))
            {
                File.Create(iniFile);
            }
            LoadProduct();
        }
        private void PluginControl_Loaded(object sender, RoutedEventArgs e)
        {
        }
        private void LoadProduct()
        {
            List<ProductData> products = ProductManager.GetProducts<List<ProductData>>()
               ?? new List<ProductData>();
            this.modelSelect.Items.Clear();
            List<string> productSource = new List<string>();
            foreach (var prd in products)
            {
                this.modelSelect.Items.Add(prd.Name);
                productSource.Add(prd.Name);
            }
            string model = IniFileHelper.ReadIniData("Config", "Model", "", iniFile);
            if (!string.IsNullOrEmpty(model))
            {
                this.modelSelect.SelectedItem = model;
            }
            else if (products.Count > 0)
            {
                this.modelSelect.SelectedIndex = 0;
            }
        }
        private void RefreshAll()
        {
            try
            {
                var start0 = dtp00.SelectedDateTime ?? DateTime.Now;
                var end0 = dtp01.SelectedDateTime ?? DateTime.Now;
                RefreshChart0(start0, end0);
            }
            catch { }
            try
            {
                var start1 = dtp10.SelectedDateTime ?? DateTime.Now;
                var end1 = dtp11.SelectedDateTime ?? DateTime.Now;
                RefreshChart1(start1, end1);
            }
            catch { }
            try
            {
                var start2 = dtp20.SelectedDateTime ?? DateTime.Now;
                var end2 = dtp21.SelectedDateTime ?? DateTime.Now;
                RefreshChart2(start2, end2);
            }
            catch { }
            try
            {
                var start3 = dtp30.SelectedDateTime ?? DateTime.Now;
                var end3 = dtp31.SelectedDateTime ?? DateTime.Now;
                RefreshChart3(start3, end3);
            }
            catch { }
        }
        private void Button_Click(object sender, RoutedEventArgs e)
@@ -51,6 +123,9 @@
            DateTime start, end;
            switch (btn.Name)
            {
                case "btnAll":
                    RefreshAll();
                    break;
                case "btn0":
                    start = dtp00.SelectedDateTime ?? DateTime.Now;
                    end = dtp01.SelectedDateTime ?? DateTime.Now;
@@ -76,14 +151,44 @@
            }
        }
        private List<SerialData> SelectSerialDataByTime(DateTime start, DateTime end)
        public static string[] GetDbFiles(string folderPath, DateTime startTime, DateTime endTime)
        {
            string[] files = DbFileHelper.GetDbFiles(BaseFolder, start, end);
            if (!Directory.Exists(folderPath))
            {
                return new string[0];
            }
            string startName = $"Data_{startTime.ToString("yyyyMMdd")}";
            string endName = $"Data_{endTime.ToString("yyyyMMdd")}";
            var oldFiles = Directory.GetFiles(folderPath, "Data_*.db");
            oldFiles = oldFiles.Where(file =>
            {
                var fileName = Path.GetFileNameWithoutExtension(file);
                bool flag = true;
                if (startTime != null) flag &= (string.Compare(fileName, startName) == 1 || fileName == startName);
                if (endTime != null) flag &= (string.Compare(endName, fileName) == 1 || fileName == endName);
                return flag;
            }).ToArray();
            return oldFiles;
        }
        private List<SerialData> SelectSerialDataByTime(string model, DateTime start, DateTime end)
        {
            var s1 = DateTime.Now;
            string[] files = GetDbFiles(BaseFolder, start, end);
            if (files == null || files.Length <= 0)
            {
                return new List<SerialData>();
            }
            string sql = $"SELECT * FROM serialData WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}';";
            string segment = string.Empty;
            if (!string.IsNullOrEmpty(model))
            {
                segment = $"AND model = '{model}'";
            }
            string sql = $@"SELECT * FROM serialData WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}'
{segment} ORDER BY time DESC;";
            DataTable dt = new DataTable();
            foreach (string file in files)
@@ -93,24 +198,36 @@
                    dt.Merge(helper.GetDataTable(sql));
                }
            }
            return BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
            var s2 = DateTime.Now;
            log.Info($"SelectSerialDataByTime Cast: {(s2 - s1).TotalMilliseconds}");
            var data = BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
            log.Info($"Bean Cast: {(DateTime.Now - s2).TotalMilliseconds}");
            return data;
        }
        private List<SerialData> SelectResultDataByTime(DateTime start, DateTime end)
        private List<SerialData> SelectResultDataByTime(string model, DateTime start, DateTime end)
        {
            string[] files = DbFileHelper.GetDbFiles(BaseFolder, start, end);
            string[] files = GetDbFiles(BaseFolder, start, end);
            if (files == null || files.Length <= 0)
            {
                return new List<SerialData>();
            }
            string sql = $"SELECT * FROM testResult WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}';";
            string segment = string.Empty;
            if (!string.IsNullOrEmpty(model))
            {
                segment = $"AND model = '{model}'";
            }
            string sql = $@"SELECT * FROM testResult WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}' {segment};";
            DataTable dt = new DataTable();
            foreach (string file in files)
            {
                using (SqliteHelper helper = new SqliteHelper(file))
                {
                    dt.Merge(helper.GetDataTable(sql));
                    var temp = helper.GetDataTable(sql);
                    dt.Merge(temp);
                }
            }
            return BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
@@ -137,81 +254,137 @@
            webview2.CoreWebView2?.ExecuteScriptAsync($"resize({width},{height})");
        }
        //private void RefreshChart0(DateTime start, DateTime end)
        //{
        //    dtp00.SelectedDateTime = start;
        //    dtp01.SelectedDateTime = end;
        //    Task.Run(() =>
        //    {
        //        try
        //        {
        //            var st = DateTime.Now;
        //            List<SerialData> datas = SelectSerialDataByTime(start, end);
        //            log.Info($"0 Select Data cast: {(DateTime.Now-st).TotalMilliseconds}");
        //            datas.OrderByDescending(e => e.time);
        //            int all = 0, output = 0;
        //            HashSet<string> snCache = new HashSet<string>();
        //            foreach (var data in datas)
        //            {
        //                if (snCache.Contains(data.sn)) continue;
        //                snCache.Add(data.sn);
        //                all++;
        //                if (data.status == "Passed") output++;
        //            }
        //            var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
        //            Dispatcher.BeginInvoke(new Action(() =>
        //            {
        //                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
        //            }));
        //        }
        //        catch (Exception ex)
        //        {
        //            log.Error("RefreshChart0 Error.", ex);
        //            ToastHelper.Error("表1刷新失败!");
        //        }
        //    });
        //}
        private void RefreshChart0(DateTime start, DateTime end)
        {
            try
            dtp00.SelectedDateTime = start;
            dtp01.SelectedDateTime = end;
            string model = modelSelect.SelectedItem?.ToString();
            Task.Run(() =>
            {
                dtp00.SelectedDateTime = start;
                dtp01.SelectedDateTime = end;
                List<SerialData> datas = SelectSerialDataByTime(start, end);
                datas.OrderByDescending(e => e.time);
                int all = 0, output = 0;
                HashSet<string> snCache = new HashSet<string>();
                foreach (var data in datas)
                try
                {
                    if (snCache.Contains(data.sn)) continue;
                    snCache.Add(data.sn);
                    all++;
                    if (data.status == "Passed") output++;
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        webview2.CoreWebView2?.ExecuteScriptAsync($"loading0('加载中,请稍后...')");
                    }));
                    List<SerialData> datas = SelectResultDataByTime(model, start, end);
                    datas.OrderByDescending(e => e.time);
                    int all = 0, output = 0;
                    HashSet<string> snCache = new HashSet<string>();
                    foreach (var data in datas)
                    {
                        if (snCache.Contains(data.sn)) continue;
                        snCache.Add(data.sn);
                        all++;
                        if (data.result == "Passed") output++;
                    }
                    var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
                    }));
                }
                var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
            }
            catch (Exception ex)
            {
                log.Error("RefreshChart0 Error.", ex);
                ToastHelper.Error("表1刷新失败!");
            }
                catch (Exception ex)
                {
                    log.Error("RefreshChart0 Error.", ex);
                    ToastHelper.Error("表1刷新失败!");
                }
            });
        }
        private void RefreshChart1(DateTime start, DateTime end)
        {
            try
            dtp10.SelectedDateTime = start;
            dtp11.SelectedDateTime = end;
            string model = modelSelect.SelectedItem?.ToString();
            Task.Run(() =>
            {
                dtp10.SelectedDateTime = start;
                dtp11.SelectedDateTime = end;
                List<SerialData> datas = SelectResultDataByTime(start, end);
                try
                {
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        webview2.CoreWebView2?.ExecuteScriptAsync($"loading1('加载中,请稍后...')");
                    }));
                    List<SerialData> datas = SelectResultDataByTime(model, start, end);
                datas = datas.OrderByDescending(e => e.time).ToList();
                Dictionary<string, int?> pieData = new Dictionary<string, int?> {
                    datas = datas.OrderByDescending(e => e.time).ToList();
                    Dictionary<string, int?> pieData = new Dictionary<string, int?> {
                { "Passed",0},
                { "Failed",0},
                //{ "Action",0},
                //{ "Wait",0},
            };
                //if (datas == null || datas.Count <= 0)
                //{
                //    pieData = new Dictionary<string, int?> {
                //    { "Passed",null},
                //    { "Failed",null},
                //};
                //}
                    //if (datas == null || datas.Count <= 0)
                    //{
                    //    pieData = new Dictionary<string, int?> {
                    //    { "Passed",null},
                    //    { "Failed",null},
                    //};
                    //}
                HashSet<string> snCache = new HashSet<string>();
                foreach (var data in datas)
                {
                    if (snCache.Contains(data.sn)) continue;
                    snCache.Add(data.sn);
                    if (pieData.ContainsKey(data.result))
                    HashSet<string> snCache = new HashSet<string>();
                    foreach (var data in datas)
                    {
                        pieData[data.result]++;
                        if (snCache.Contains(data.sn)) continue;
                        snCache.Add(data.sn);
                        if (pieData.ContainsKey(data.result))
                        {
                            pieData[data.result]++;
                        }
                    }
                    string res = "[";
                    foreach (var key in pieData.Keys)
                    {
                        res += $"{{name:'{key}',value:{pieData[key]}}},";
                    }
                    res += "]";
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
                    }));
                }
                string res = "[";
                foreach (var key in pieData.Keys)
                catch (Exception ex)
                {
                    res += $"{{name:'{key}',value:{pieData[key]}}},";
                    log.Error("RefreshChart1 Error.", ex);
                    ToastHelper.Error("表2刷新失败!");
                }
                res += "]";
                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
            }
            catch (Exception ex)
            {
                log.Error("RefreshChart1 Error.", ex);
                ToastHelper.Error("表2刷新失败!");
            }
            });
        }
        //private void RefreshChart2(DateTime start, DateTime end)
@@ -282,129 +455,149 @@
        private void RefreshChart2(DateTime start, DateTime end)
        {
            try
            dtp20.SelectedDateTime = start;
            dtp21.SelectedDateTime = end;
            string model = modelSelect.SelectedItem?.ToString();
            Task.Run(() =>
            {
                dtp20.SelectedDateTime = start;
                dtp21.SelectedDateTime = end;
                List<SerialData> datas = SelectResultDataByTime(start, end);
                var groups =
                    datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
                Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
                foreach (var group in groups)
                try
                {
                    Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
                    double all = 0, oneTimePass = 0, passed = 0;
                    var groupDatas = group.ToList();
                    groupDatas = groupDatas.OrderByDescending(e => e.time).ToList();
                    foreach (var data in groupDatas)
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        if (!snStatusCache.ContainsKey(data.sn))
                        webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('加载中,请稍后...')");
                    }));
                    List<SerialData> datas = SelectResultDataByTime(model, start, end);
                    var groups =
                        datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
                    Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
                    foreach (var group in groups)
                    {
                        Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
                        double all = 0, oneTimePass = 0, passed = 0;
                        var groupDatas = group.ToList();
                        groupDatas = groupDatas.OrderByDescending(e => e.time).ToList();
                        foreach (var data in groupDatas)
                        {
                            snStatusCache.Add(data.sn, data.result);
                            all++;
                            if (data.result == "Passed")
                            if (!snStatusCache.ContainsKey(data.sn))
                            {
                                passed++;
                                oneTimePass++;
                                snStatusCache.Add(data.sn, data.result);
                                all++;
                                if (data.result == "Passed")
                                {
                                    passed++;
                                    oneTimePass++;
                                }
                            }
                            else
                            {
                                if (snStatusCache[data.sn] == "Passed")
                                {
                                    if (oneTimePass > 0) oneTimePass--;
                                    snStatusCache[data.sn] = "NoOnePass";
                                }
                            }
                        }
                        else
                        res.Add(group.Key, new PassRateData
                        {
                            if (snStatusCache[data.sn] == "Passed")
                            {
                                if (oneTimePass > 0) oneTimePass--;
                                snStatusCache[data.sn] = "NoOnePass";
                            }
                        }
                            time = group.Key,
                            onePassRate = oneTimePass / all * 100,
                            passRate = passed / all * 100,
                        });
                    }
                    res.Add(group.Key, new PassRateData
                    string fields = "[", vals0 = "[", vals1 = "[";
                    foreach (var key in res.Keys)
                    {
                        time = group.Key,
                        onePassRate = oneTimePass / all * 100,
                        passRate = passed / all * 100,
                    });
                        fields += $"'{key}',";
                        vals0 += $"{res[key].onePassRate},";
                        vals1 += $"{res[key].passRate},";
                    }
                    fields += "]";
                    vals0 += "]";
                    vals1 += "]";
                    var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
                    }));
                }
                string fields = "[", vals0 = "[", vals1 = "[";
                foreach (var key in res.Keys)
                catch (Exception ex)
                {
                    fields += $"'{key}',";
                    vals0 += $"{res[key].onePassRate},";
                    vals1 += $"{res[key].passRate},";
                    log.Error("RefreshChart2 Error.", ex);
                    ToastHelper.Error("表3刷新失败!");
                }
                fields += "]";
                vals0 += "]";
                vals1 += "]";
                var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
            }
            catch (Exception ex)
            {
                log.Error("RefreshChart2 Error.", ex);
                ToastHelper.Error("表3刷新失败!");
            }
            });
        }
        private void RefreshChart3(DateTime start, DateTime end)
        {
            try
            dtp30.SelectedDateTime = start;
            dtp31.SelectedDateTime = end;
            string model = modelSelect.SelectedItem?.ToString();
            Task.Run(() =>
            {
                dtp30.SelectedDateTime = start;
                dtp31.SelectedDateTime = end;
                List<SerialData> datas = SelectSerialDataByTime(start, end);
                datas = datas.OrderByDescending(e => e.time).ToList();
                Dictionary<string, SimpleData> pieData = new Dictionary<string, SimpleData>();
                List<SimpleData> datasource = new List<SimpleData>();
                //HashSet<string> snCache = new HashSet<string>();
                foreach (var data in datas)
                try
                {
                    //if (snCache.Contains(data.sn)) continue;
                    if (data.status != "Failed") continue;
                    if (pieData.ContainsKey(data.step))
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        pieData[data.step].Value++;
                    }
                    else
                        webview2.CoreWebView2?.ExecuteScriptAsync($"loading3('加载中,请稍后...')");
                    }));
                    var st = DateTime.Now;
                    List<SerialData> datas = SelectSerialDataByTime(model, start, end);
                    var s2 = DateTime.Now;
                    log.Info($"RefreshChart3 Data Cast {(s2 - st).TotalMilliseconds}");
                    Dictionary<string, SimpleData> pieData = new Dictionary<string, SimpleData>();
                    List<SimpleData> datasource = new List<SimpleData>();
                    //HashSet<string> snCache = new HashSet<string>();
                    foreach (var data in datas)
                    {
                        pieData[data.step] = new SimpleData
                        //if (snCache.Contains(data.sn)) continue;
                        if (data.status != "Failed") continue;
                        if (pieData.ContainsKey(data.step))
                        {
                            Name = data.step,
                            Value = 1
                        };
                        datasource.Add(pieData[data.step]);
                            pieData[data.step].Value++;
                        }
                        else
                        {
                            pieData[data.step] = new SimpleData
                            {
                                Name = data.step,
                                Value = 1
                            };
                            datasource.Add(pieData[data.step]);
                        }
                    }
                }
                datasource = datasource.OrderByDescending(e => e.Value).ToList();
                if (datasource.Count > 10)
                {
                    datasource = datasource.Take(10).ToList();
                }
                    datasource = datasource.OrderByDescending(e => e.Value).ToList();
                    if (datasource.Count > 10)
                    {
                        datasource = datasource.Take(10).ToList();
                    }
                    var s3 = DateTime.Now;
                    log.Info($"RefreshChart3 Build {(s3 - s2).TotalMilliseconds}");
                string names = string.Empty, vals = string.Empty;
                foreach (var data in datasource)
                {
                    names += $"'{data.Name}',";
                    vals += $"{data.Value},";
                    string names = string.Empty, vals = string.Empty;
                    foreach (var data in datasource)
                    {
                        names += $"'{data.Name}',";
                        vals += $"{data.Value},";
                    }
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
                    }));
                }
                webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
            }
            catch (Exception ex)
            {
                log.Error("RefreshChart3 Error.", ex);
                ToastHelper.Error("表4刷新失败!");
            }
                catch (Exception ex)
                {
                    log.Error("RefreshChart3 Error.", ex);
                    ToastHelper.Error("表4刷新失败!");
                }
            });
        }
        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -443,5 +636,13 @@
                    break;
            }
        }
        private void modelSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                IniFileHelper.WriteIniData("Config", "Model", e.AddedItems[0].ToString(), iniFile);
            }
        }
    }
}