From b544d5cccd76735e034c8055918a50927b437474 Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期二, 10 十一月 2026 08:29:04 +0800
Subject: [PATCH] fix: 维护模式重复进入失败与按钮灰死 + Broker 并发验证用例

---
 HMI.LogViewer/LogViewer.xaml.cs |  380 ++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 283 insertions(+), 97 deletions(-)

diff --git a/HMI.LogViewer/LogViewer.xaml.cs b/HMI.LogViewer/LogViewer.xaml.cs
index 272d886..72f3461 100644
--- a/HMI.LogViewer/LogViewer.xaml.cs
+++ b/HMI.LogViewer/LogViewer.xaml.cs
@@ -1,10 +1,14 @@
 锘縰sing HMI.Base;
 using HMI.Core.Util;
 using HMI.UI.Util;
+using HMI.Util;
+using Microsoft.Win32;
 using System;
 using System.Collections.Generic;
 using System.Data;
 using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
 using System.Timers;
 using System.Windows;
 using System.Windows.Controls;
@@ -16,8 +20,6 @@
     /// </summary>
     public partial class LogViewer : PluginControl
     {
-        private string logDir;
-        private string todayLogFile;
 
         private bool autoRfh;
 
@@ -33,56 +35,72 @@
 
         private Timer autoRfhTimer;
 
+        private long pageSize = 50;
+
+        private long currentPage = 1;
+        public long CurrentPage
+        {
+            get => currentPage;
+            set
+            {
+                Set(ref currentPage, value);
+                Filtrate(value, pageSize);
+            }
+        }
+
+        private long maxPage = 1;
+        public long MaxPage
+        {
+            get => maxPage;
+            set
+            {
+                Set(ref maxPage, value);
+            }
+        }
+
 
         public LogViewer()
         {
-            string logDir = Path.Combine(PathHelper.AppFolder, "Log");
-            todayLogFile = Path.Combine(logDir, $"log{DateTime.Now.ToString("yyyy-MM-dd")}.db");
-
-            if (!Directory.Exists(logDir))
-            {
-                Directory.CreateDirectory(logDir);
-            }
-            this.logDir = logDir;
             DataContext = this;
+            autoRfhTimer = new Timer
+            {
+                Enabled = false,
+                Interval = 1500,
+                AutoReset = false
+            };
+            autoRfhTimer.Elapsed += AutoRfhTimer_Elapsed;
             InitializeComponent();
+            QueryReset();
         }
 
         public override void InitFinish()
         {
-            base.InitFinish();
-            string baseFile = Path.Combine(logDir, "log.db");
+            //base.InitFinish();
+            //string baseFile = Path.Combine(logDir, "log.db");
 
-            try
-            {
-                if (!File.Exists(baseFile))
-                {
-                    SqliteHelper.CreateDatabase(baseFile);
-                }
-                SqliteHelper sqliteHelper = new SqliteHelper(baseFile);
-                sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS log (
-                    id INTEGER PRIMARY KEY AUTOINCREMENT,
-                    type TEXT NOT NULL,
-                    text TEXT NOT NULL,
-                    source TEXT,
-                    time TIME
-                    );");
-            }
-            catch (Exception ex)
-            {
-                log.Error("Create Log File Failed.", ex);
-            }
+            //try
+            //{
+            //    if (!File.Exists(baseFile))
+            //    {
+            //        SqliteHelper.CreateDatabase(baseFile);
+            //    }
+            //    SqliteHelper sqliteHelper = new SqliteHelper(baseFile);
+            //    sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS log (
+            //        id INTEGER PRIMARY KEY AUTOINCREMENT,
+            //        level TEXT NOT NULL,
+            //        text TEXT NOT NULL,
+            //        source TEXT,
+            //        time TIME
+            //        );");
+            //}
+            //catch (Exception ex)
+            //{
+            //    log.Error("Create Log File Failed.", ex);
+            //}
         }
-
 
         private void UserControl_Loaded(object sender, RoutedEventArgs e)
         {
-            autoRfhTimer = new Timer
-            {
-                Enabled = false,
-                Interval = 1000
-            };
-            autoRfhTimer.Elapsed += AutoRfhTimer_Elapsed;
             Loaded -= UserControl_Loaded;
         }
 
@@ -90,6 +108,10 @@
         {
             Refresh100items();
         }
+
+        //private void RefreshTable() { 
+        //    if(CurrentPage == )
+        //}
 
         private void Button_Click(object sender, RoutedEventArgs e)
         {
@@ -101,11 +123,35 @@
                     break;
                 case "resetBtn":
                     QueryReset();
+                    CurrentPage = 1;
                     break;
                 case "exportBtn":
+                    DoExport();
                     break;
                 default:
                     break;
+            }
+        }
+
+        private void DoExport()
+        {
+            try
+            {
+                SaveFileDialog sfd = new SaveFileDialog
+                {
+                    Filter = "Excel Files (*.xls)|*.xls",
+                };
+                if (sfd.ShowDialog() == true)
+                {
+                    var dt = GetDataTable(false, 1, 1, out long totalPage);
+                    ExcelHelper.ExportExcel<LogData>(sfd.FileName, dt);
+                    ToastHelper.Success(this.lang("App.ExportSuccess"));
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error("Export Log Failed.", ex);
+                MsgBoxHelper2.Error($"瀵煎嚭澶辫触: {ex.Message}");
             }
         }
 
@@ -113,75 +159,200 @@
         {
             try
             {
-                queryBtn.IsEnabled = false;
-                autoRfhInput.IsEnabled = false;
-                Filtrate();
-                queryBtn.IsEnabled = true;
-                autoRfhInput.IsEnabled = true;
+                if (startTimeInput.SelectedDateTime == null && endTimeInput.SelectedDateTime == null)
+                {
+                    ToastHelper.Error(this.lang("log.timeCantBeNull"));
+                    return;
+                }
+
+                if (endTimeInput.SelectedDateTime != null && startTimeInput.SelectedDateTime != null &&
+                endTimeInput.SelectedDateTime < startTimeInput.SelectedDateTime)
+                {
+                    ToastHelper.Error(this.lang("log.timeRangeError"));
+                    return;
+                }
+
+                AutoRfh = false;
+                //queryBtn.IsEnabled = false;
+                //autoRfhInput.IsEnabled = false;
+                CurrentPage = 1;
             }
             catch (Exception ex)
             {
                 log.Error("Log Query Failed.", ex);
                 this.Error($"鏌ヨ澶辫触锛亄ex.Message}");
             }
+            finally
+            {
+                queryBtn.IsEnabled = true;
+                autoRfhInput.IsEnabled = true;
+            }
         }
 
         private void QueryReset()
         {
+            var today = DateTime.Now;
+            var start = DateTime.Parse(today.ToString("yyyy-MM-dd 00:00:00")).AddDays(-7);
+            var end = DateTime.Parse(today.ToString("yyyy-MM-dd 00:00:00")).AddDays(1);
+
             levelInput.Text = null;
-            startTimeInput.SelectedDateTime = null;
-            endTimeInput.SelectedDateTime = null;
-            startTimeInput.Text = null;
-            table.ItemsSource = null;
+            startTimeInput.SelectedDateTime = start;
+            endTimeInput.SelectedDateTime = end;
         }
 
-        private void Filtrate()
+        public DataTable GetDataTable(bool usePage, long page, long size, out long totalPage)
         {
-            string str = LoadSql();
-            DataTable dt = new DataTable();
-            var files = Directory.GetFiles(logDir, "*.db");
-            foreach (string file in files)
+            totalPage = 0;
+            var files = GetOldDbFiles(PathHelper.LogViewerDir, new DateTime?[] { startTimeInput.SelectedDateTime,
+                endTimeInput.SelectedDateTime });
+            if (files.Length <= 0)
             {
-                SqliteHelper sql = new SqliteHelper(file);
-                dt.Merge(sql.GetDataTable(str));
-                sql.Close();
+                return new DataTable();
             }
 
-            dt.DefaultView.Sort = "time Desc";
-            table.ItemsSource = dt.DefaultView;
+            using (Sqlite3Helper helper = new Sqlite3Helper(files[0]))
+            {
+                for (int i = 0; i < files.Length; i++)
+                {
+                    var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+                    helper.Execute(attach);
+                }
+
+                string sql = string.Join(" UNION ALL ", GetSqls(files));
+
+                string sortName = "time", sortDirection = "DESC";
+
+                string baseSql = $"SELECT level,time,source,text FROM ({sql}) as _temp";
+
+                string countSql = $"SELECT COUNT(1) FROM ({sql}) as __temp";
+
+                long total = (long)helper.SelectOne(countSql);
+                totalPage = (total / pageSize) + ((total % pageSize) > 0 ? 1 : 0);
+
+                if (usePage)
+                {
+                    sql = $"{baseSql} ORDER BY {sortName} {sortDirection} LIMIT {size} OFFSET {(page - 1) * size} ";
+                }
+                else
+                {
+                    sql = $"{baseSql} ORDER BY {sortName} {sortDirection}";
+                }
+
+                DataTable dt = helper.GetDataTable(sql);
+                return dt;
+            }
+        }
+
+        private void Filtrate(long page, long size)
+        {
+            try
+            {
+                //var files = GetOldDbFiles(PathHelper.LogViewerDir, new DateTime?[] { startTimeInput.SelectedDateTime,
+                //endTimeInput.SelectedDateTime });
+                //if (files.Length <= 0)
+                //{
+                //    table.ItemsSource = new DataTable().DefaultView;
+                //    return;
+                //}
+
+                //using (Sqlite3Helper helper = new Sqlite3Helper(files[0]))
+                //{
+                //    for (int i = 0; i < files.Length; i++)
+                //    {
+                //        var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+                //        helper.Execute(attach);
+                //    }
+
+                //    string sql = string.Join(" UNION ALL ", GetSqls(files));
+
+                //    string sortName = "time", sortDirection = "DESC";
+
+                //    string baseSql = $"SELECT level,time,source,text FROM ({sql}) as _temp";
+
+                //    string countSql = $"SELECT COUNT(1) FROM ({sql}) as __temp";
+
+                //    long total = (long)helper.SelectOne(countSql);
+                //    long pages = (total/pageSize)+ ((total % pageSize) > 0 ? 1 : 0);
+
+                //    sql = $"{baseSql} ORDER BY {sortName} {sortDirection} LIMIT {size} OFFSET {(page - 1) * size} ";
+
+                //    DataTable dt = helper.GetDataTable(sql);
+                //    table.ItemsSource = dt.DefaultView;
+
+                //    MaxPage = pages;
+                //}
+                table.ItemsSource = GetDataTable(true, page, size, out long totalPage).DefaultView;
+                MaxPage = totalPage;
+            }
+            catch (Exception ex)
+            {
+                log.Error("Select Log Error.", ex);
+                MsgBoxHelper2.Error($"鏌ヨ澶辫触: {ex.Message}");
+            }
+        }
+
+        public static string[] GetOldDbFiles(string folderPath, DateTime?[] range)
+        {
+            if (!Directory.Exists(folderPath))
+            {
+                return new string[0];
+            }
+            // 鑾峰彇鎵�鏈�.db鏂囦欢骞剁瓫閫夊嚭7澶╁墠鏇存柊鐨勬枃浠�
+            var oldFiles = Directory.GetFiles(folderPath, "*.db");
+            try
+            {
+                oldFiles = oldFiles.Where(file =>
+                {
+                    var lastWriteTime = File.GetLastWriteTime(file);
+                    bool flag = true;
+                    if (range[0] != null) flag &= lastWriteTime >= range[0];
+                    //if (range[1] != null) flag &= lastWriteTime <= range[1];
+                    return flag;
+                }).OrderByDescending(f => f).ToArray();
+
+                return oldFiles;
+            }
+            catch (Exception ex)
+            {
+                return new string[0];
+            }
         }
 
         /// <summary>
-        /// 鍔犺浇鐣岄潰鍒ゆ柇鏁版嵁搴撹鍙�
+        /// 
         /// </summary>
-        /// <returns> str鏁版嵁搴撶殑璇彞 </returns>
-        private string LoadSql()
+        /// <param name="files"></param>
+        /// <returns></returns>
+        private string[] GetSqls(string[] files)
         {
-            string sql = " select type,time,source,text from log";
+            string[] sqls = new string[files.Length];
+            for (int i = 0; i < files.Length; i++)
+            {
+                string sql = $"SELECT level,time,source,text FROM db{i}.log";
+                List<string> datas = new List<string>();
+                if (!string.IsNullOrEmpty(levelInput.Text))
+                {
+                    datas.Add($"level='{levelInput.Text}'");
+                }
+                if (!string.IsNullOrEmpty(startTimeInput.Text))
+                {
+                    datas.Add($"time>='{startTimeInput.Text}'");
+                }
+                if (!string.IsNullOrEmpty(endTimeInput.Text))
+                {
+                    datas.Add($"time<'{endTimeInput.Text}'");
+                }
+                if (!string.IsNullOrEmpty(sourceInput.Text))
+                {
+                    datas.Add($"source='{sourceInput.Text}'");
+                }
 
-            List<string> datas = new List<string>();
-            if (!string.IsNullOrEmpty(levelInput.Text))
-            {
-                datas.Add($"type='{levelInput.Text}'");
+                string condition = string.Join(" AND ", datas);
+                condition = string.IsNullOrEmpty(condition) ? string.Empty : $" WHERE {condition}";
+                sql = $"{sql}{condition}";
+                sqls[i] = sql;
             }
-            if (!string.IsNullOrEmpty(startTimeInput.Text))
-            {
-                datas.Add($"time>='{startTimeInput.Text}'");
-            }
-            if (!string.IsNullOrEmpty(endTimeInput.Text))
-            {
-                datas.Add($"time<='{endTimeInput.Text}'");
-            }
-            if (!string.IsNullOrEmpty(sourceInput.Text))
-            {
-                datas.Add($"source='{sourceInput.Text}'");
-            }
-
-            string condition = string.Join(" AND ", datas);
-            condition = string.IsNullOrEmpty(condition) ? string.Empty : $" WHERE {condition}";
-
-            sql = $"{sql}{condition} order by time desc";
-            return sql;
+            return sqls;
         }
 
         /// <summary>
@@ -189,22 +360,37 @@
         /// </summary>
         private void Refresh100items()
         {
-            try
+            autoRfhTimer.Enabled = false;
+            Task.Run(() =>
             {
-                if (!File.Exists(todayLogFile)) return;
-                string str = "select type,time,source,text from log order by time desc limit 100";
-                SqliteHelper sql = new SqliteHelper(todayLogFile);
-                var dt = sql.GetDataTable(str);
-                this.Dispatcher.BeginInvoke((Action)delegate ()
+                try
                 {
-                    table.ItemsSource = dt.DefaultView;
-                });
-            }
-            catch (Exception ex)
-            {
-                log.Error("Log Auto Refresh Failed.", ex);
-                this.Error($"鑷姩鍒锋柊澶辫触锛亄ex.Message}");
-            }
+                    string todayLogFile = Path.Combine(PathHelper.LogViewerDir, $"log_{DateTime.Today:yyyy-MM-dd}.db");
+                    if (!File.Exists(todayLogFile)) return;
+                    string str = "select level,time,source,text from log order by time desc limit 100";
+                    using (SqliteHelper sql = new SqliteHelper(todayLogFile))
+                    {
+                        var dt = sql.GetDataTable(str);
+                        this.Dispatcher.BeginInvoke((Action)delegate ()
+                        {
+                            table.ItemsSource = dt.DefaultView;
+                            MaxPage = 1;
+                        });
+                    }
+                }
+                catch (Exception ex)
+                {
+                    log.Error("Log Auto Refresh Failed.", ex);
+                    this.Error($"鑷姩鍒锋柊澶辫触锛亄ex.Message}");
+                }
+                finally
+                {
+                    this.Dispatcher.BeginInvoke((Action)delegate ()
+                    {
+                        autoRfhTimer.Enabled = AutoRfh;
+                    });
+                }
+            });
         }
     }
 }

--
Gitblit v1.9.1