Эх сурвалжийг харах

Merge branch 'master' of http://49.235.130.76/XXF_1122/DaisyNPILine

wanghan 7 сар өмнө
parent
commit
86812c6e81

+ 3 - 2
TeamAAS-VM/Events/LockFinishNotification.cs

@@ -1,4 +1,5 @@
-using System;
+using Prism.Events;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -7,7 +8,7 @@ using TeamAAS_VP.Models;
 
 namespace TeamAAS_VP.Events
 {
-    public class LockFinishNotification: Prism.Events.PubSubEvent<LockResult>
+    public class LockFinishNotification: PubSubEvent<LockResult>
     {
     }
 }

+ 19 - 0
TeamAAS-VM/Events/WorkShiftChangedNotification.cs

@@ -0,0 +1,19 @@
+using Prism.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TeamAAS_VP.Events
+{
+    public class WorkShiftChangedNotification:PubSubEvent<ShiftChangedPayload>
+    {
+
+    }
+    public class ShiftChangedPayload
+    {
+        public string NewShiftName { get; set; }  // 中文注释:新班次名称
+        public DateTime SwitchTime { get; set; }  // 中文注释:切换时间
+    }
+}

+ 14 - 0
TeamAAS-VM/Events/WorkShiftUpdateNotification.cs

@@ -0,0 +1,14 @@
+using Prism.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TeamAAS_VP.Models.Torque;
+
+namespace TeamAAS_VP.Events
+{
+    public class WorkShiftUpdateNotification:PubSubEvent<WorkShift>
+    {
+            }
+}

+ 20 - 0
TeamAAS-VM/Models/Torque/WorkShift.cs

@@ -0,0 +1,20 @@
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TeamAAS_VP.Models.Torque
+{
+    public class WorkShift : BindableBase
+    {
+        public string DayShift { get; set; }
+
+        public string NightShift { get; set; }
+
+        public bool DayShiftSpotCheck { get; set; }
+
+        public bool NightShiftSpotCheck { get; set; }
+    }
+}

+ 464 - 0
TeamAAS-VM/Services/ShiftWatcherService.cs

@@ -0,0 +1,464 @@
+using Prism.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using TeamAAS_VP.Events;
+
+namespace TeamAAS_VP.Services
+{
+    public class ShiftWatcherService
+    {
+        private readonly IEventAggregator _eventAggregator;
+        private Timer _timer;
+        private string _lastShift;
+
+        public ShiftWatcherService(IEventAggregator  eventAggregator)
+        {
+            this._eventAggregator = eventAggregator;
+        }
+
+        public void Start()
+        {
+            // 中文注释:每秒检测一次
+            _timer = new Timer(_ => CheckShift(), null, 0, 1000);
+        }
+
+        private void CheckShift()
+        {
+            string currentShift =
+                (DateTime.Now.Hour >= 8 && DateTime.Now.Hour < 20) ? "Day" : "Night";
+
+            if (_lastShift == null)
+            {
+                _lastShift = currentShift;
+                return;
+            }
+
+            if (_lastShift != currentShift)
+            {
+                _lastShift = currentShift;
+
+                // 中文注释:只负责“通知”,不要弹窗
+                _eventAggregator.GetEvent<WorkShiftChangedNotification>().Publish(new ShiftChangedPayload
+                {
+                    NewShiftName = currentShift,
+                    SwitchTime = DateTime.Now
+                });
+            }
+        }
+    }
+}
+
+/*
+```csharp
+// ===========================
+// 文件1:ShiftChangedEvent.cs
+// ===========================
+using Prism.Events;
+using System;
+
+namespace YourApp.Shift
+{
+    // 中文注释:班次切换事件(发布/订阅用)
+    public class ShiftChangedEvent : PubSubEvent<ShiftChangedPayload> { }
+
+    // 中文注释:班次切换携带的数据
+    public class ShiftChangedPayload
+    {
+        public string NewShiftName { get; set; }  // 中文注释:新班次名称
+        public DateTime SwitchTime { get; set; }  // 中文注释:切换时间
+    }
+}
+```
+
+```csharp
+// ===========================
+// 文件2:IShiftWatcher.cs / ShiftWatcher.cs
+// ===========================
+using Prism.Events;
+using System;
+using System.Threading;
+
+namespace YourApp.Shift
+{
+    public interface IShiftWatcher
+    {
+        void Start();
+        void Stop();
+    }
+
+    public class ShiftWatcher : IShiftWatcher
+    {
+        private readonly IEventAggregator _ea;
+        private Timer _timer;
+        private string _lastShiftKey;
+
+        public ShiftWatcher(IEventAggregator ea)
+        {
+            _ea = ea;
+        }
+
+        public void Start()
+        {
+            // 中文注释:每秒检查一次(你可以改成 5s/10s)
+            _timer = new Timer(_ => CheckShift(), null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
+        }
+
+        public void Stop()
+        {
+            _timer?.Dispose();
+            _timer = null;
+        }
+
+        private void CheckShift()
+        {
+            // 中文注释:示例班次规则:白班 08:00-20:00,夜班 20:00-08:00
+            var now = DateTime.Now;
+            string currentShift = (now.Hour >= 8 && now.Hour < 20) ? "Day" : "Night";
+
+            if (_lastShiftKey == null)
+            {
+                _lastShiftKey = currentShift;
+                return;
+            }
+
+            if (_lastShiftKey != currentShift)
+            {
+                _lastShiftKey = currentShift;
+
+                // 中文注释:只发布事件,不在定时器线程里弹窗
+                _ea.GetEvent<ShiftChangedEvent>().Publish(new ShiftChangedPayload
+                {
+                    NewShiftName = currentShift,
+                    SwitchTime = now
+                });
+            }
+        }
+    }
+}
+```
+
+```csharp
+// ===========================
+// 文件3:IMainProcess.cs / MainProcess.cs
+// ===========================
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace YourApp.Process
+{
+    public interface IMainProcess
+    {
+        Task RunAsync(CancellationToken token);
+    }
+
+    public class MainProcess : IMainProcess
+    {
+        public async Task RunAsync(CancellationToken token)
+        {
+            // 中文注释:示例主流程循环(把你的采图/检测/运动控制逻辑放这里)
+            while (!token.IsCancellationRequested)
+            {
+                // TODO: 在这里写你的主流程逻辑(注意尊重 token)
+                await Task.Delay(100, token); // 中文注释:模拟工作
+            }
+        }
+    }
+}
+```
+
+```csharp
+// ===========================
+// 文件4:MainWindowViewModel.cs(整合:切班→停流程→隐藏主窗口→ShowDialog登录→恢复)
+// ===========================
+using Prism.Events;
+using Prism.Mvvm;
+using System;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using YourApp.Process;
+using YourApp.Shift;
+
+namespace YourApp.ViewModels
+{
+    public class MainWindowViewModel : BindableBase
+    {
+        private readonly IEventAggregator _ea;
+        private readonly IMainProcess _mainProcess;
+
+        private CancellationTokenSource _mainFlowCts;
+        private bool _loginShowing;
+
+        public MainWindowViewModel(IEventAggregator ea, IMainProcess mainProcess)
+        {
+            _ea = ea;
+            _mainProcess = mainProcess;
+
+            // 中文注释:订阅班次切换事件,强制在UI线程执行(这样可以安全Hide/Show主窗口和弹窗)
+            _ea.GetEvent<ShiftChangedEvent>()
+               .Subscribe(OnShiftChanged, ThreadOption.UIThread);
+        }
+
+        // 中文注释:你可以在程序启动后调用一次,启动主流程
+        public void StartMainFlow()
+        {
+            _mainFlowCts?.Cancel();
+            _mainFlowCts = new CancellationTokenSource();
+
+            // 中文注释:后台线程运行主流程,不阻塞UI
+            Task.Run(async () =>
+            {
+                try
+                {
+                    await _mainProcess.RunAsync(_mainFlowCts.Token);
+                }
+                catch (OperationCanceledException)
+                {
+                    // 中文注释:正常取消
+                }
+                catch (Exception ex)
+                {
+                    // 中文注释:实际项目里这里写日志
+                    Application.Current.Dispatcher.Invoke(() =>
+                    {
+                        MessageBox.Show(ex.Message, "主流程异常");
+                    });
+                }
+            });
+        }
+
+        // 中文注释:班次切换时触发:停流程→隐藏主窗口→弹登录→登录成功恢复
+        private void OnShiftChanged(ShiftChangedPayload payload)
+        {
+            if (_loginShowing)
+                return;
+
+            _loginShowing = true;
+
+            // 1️⃣ 中断主流程(取消后台任务,不动UI线程)
+            _mainFlowCts?.Cancel();
+
+            // 2️⃣ 隐藏主窗口
+            var mainWindow = Application.Current.MainWindow;
+            mainWindow?.Hide();
+
+            // 3️⃣ 弹出重新登录窗口(你当前是 Window.ShowDialog)
+            var loginWindow = new LoginWindow
+            {
+                Owner = mainWindow // 中文注释:设置Owner,防止窗口跑到后面
+            };
+
+            // 中文注释:可选,把提示原因传给登录窗口(你需要在LoginWindow里定义这个属性)
+            loginWindow.LoginReason = $"班次切换到 {payload.NewShiftName},请重新登录";
+
+            bool? result = loginWindow.ShowDialog();
+
+            // 4️⃣ 根据登录结果处理
+            if (result == true)
+            {
+                // 中文注释:登录成功 → 显示主窗口 → 重新启动主流程
+                mainWindow?.Show();
+                StartMainFlow();
+            }
+            else
+            {
+                // 中文注释:登录失败/取消:按需求决定(示例:仍显示主窗口但不启动流程)
+                mainWindow?.Show();
+
+                // 如果你想强制退出可以用:
+                // Application.Current.Shutdown();
+            }
+
+            _loginShowing = false;
+        }
+    }
+}
+```
+
+```csharp
+// ===========================
+// 文件5:App.xaml.cs(Prism启动:注册服务 + 启动初始化 + 启动班次监控)
+// ===========================
+using Prism.Ioc;
+using Prism.Unity; // 如果你用 DryIoc/Autofac,这里换对应的PrismApplication基类命名空间
+using System.Text;
+using System.Windows;
+using YourApp.Process;
+using YourApp.Shift;
+
+namespace YourApp
+{
+    public partial class App : PrismApplication
+    {
+        protected override Window CreateShell()
+        {
+            // 中文注释:支持GBK等编码(如果你有CSV/老设备编码需求)
+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+
+            // 中文注释:创建主窗口(MainWindowView)
+            return Container.Resolve<MainWindowView>();
+        }
+
+        protected override void RegisterTypes(IContainerRegistry containerRegistry)
+        {
+            // 中文注释:注册主流程服务
+            containerRegistry.RegisterSingleton<IMainProcess, MainProcess>();
+
+            // 中文注释:注册班次监控(定时器)
+            containerRegistry.RegisterSingleton<IShiftWatcher, ShiftWatcher>();
+
+            // 你原来这些也可以在这里注册或在别处注册
+            // containerRegistry.RegisterSingleton<IConfigService, ConfigService>();
+            // containerRegistry.RegisterSingleton<IDatabaseInitializer, DatabaseInitializer>();
+        }
+
+        protected override void OnInitialized()
+        {
+            base.OnInitialized();
+
+            // 中文注释:启动时初始化(你原来Resolve的配置、数据库初始化可以放这里)
+            var configService = Container.Resolve<IConfigService>();
+            var dbInit = Container.Resolve<IDatabaseInitializer>();
+            dbInit.Initialize();
+
+            // 中文注释:启动班次监控
+            var watcher = Container.Resolve<IShiftWatcher>();
+            watcher.Start();
+
+            // 中文注释:启动主流程(通过主窗口VM调用)
+            // 注意:主窗口已经显示后再启动更合理
+            if (Current.MainWindow?.DataContext is YourApp.ViewModels.MainWindowViewModel vm)
+            {
+                vm.StartMainFlow();
+            }
+        }
+    }
+}
+```
+
+```csharp
+// ===========================
+// 文件6:LoginWindow.xaml.cs(示例:让 MainWindowViewModel 能设置 LoginReason)
+// 说明:你已有LoginWindow就按需合并,不需要照搬UI
+// ===========================
+using System.Windows;
+
+namespace YourApp
+{
+    public partial class LoginWindow : Window
+    {
+        // 中文注释:给外部传入提示原因(可选)
+        public string LoginReason
+        {
+            get { return (string)GetValue(LoginReasonProperty); }
+            set { SetValue(LoginReasonProperty, value); }
+        }
+
+        public static readonly DependencyProperty LoginReasonProperty =
+            DependencyProperty.Register(nameof(LoginReason), typeof(string), typeof(LoginWindow), new PropertyMetadata(""));
+
+        public LoginWindow()
+        {
+            InitializeComponent();
+        }
+
+        // 中文注释:登录成功按钮
+        private void BtnOk_Click(object sender, RoutedEventArgs e)
+        {
+            // TODO:这里做你的账号密码校验
+            // 校验成功:
+            this.DialogResult = true;
+            this.Close();
+        }
+
+        // 中文注释:取消/关闭按钮
+        private void BtnCancel_Click(object sender, RoutedEventArgs e)
+        {
+            this.DialogResult = false;
+            this.Close();
+        }
+    }
+}
+```
+
+ */
+
+/*
+
+ ///// <summary>
+        ///// 判断在班次时间内是否是登录过点控
+        ///// </summary>
+        ///// <param name="DayShhift"></param>
+        ///// <param name="NightShift"></param>
+        ///// <returns></returns>
+        //public bool JudgeIsSpotCheck(string DayShhift, string NightShift)
+        //{
+        //    DateTime dateTimeDayShift = DateTime.Now;
+        //    DateTime dateTimeNightShift = DateTime.Now;
+        //    try
+        //    {
+        //        dateTimeDayShift = DateTime.Parse(DayShhift);
+        //        dateTimeNightShift = DateTime.Parse(NightShift);
+        //    }
+        //    catch (Exception)
+        //    {
+        //        AddLog(2, "Check Time格式输入错误,请参照 7:50 该格式进行填写");
+        //        MessageBox.Show("Check Time格式输入错误,请参照 7:50 该格式进行填写");
+        //        return false;
+        //    }
+
+        //    DateTime LoginTime = DateTime.Parse(IniConfigHelper.ReadIniData("CheckTime", "LoginTime", ""));
+
+        //    //在原有的基础上增加一天
+        //    DateTime endOfDateTimeDayShift = dateTimeDayShift.AddDays(1);
+
+        //    DateTime NowDataTime = DateTime.Now;
+
+        //    if (NowDataTime >= dateTimeDayShift && NowDataTime <= dateTimeNightShift)
+        //    {
+        //        if (!GlobalVariable.CheckTime.DayShiftSpotCheck && LoginTime >= dateTimeDayShift)
+        //        {
+        //            frmSpotCheck = new FrmSpotCheck(IniConfigHelper.ReadIniData("CheckTime", "LoginTime", ""), dateTimeDayShift, dateTimeNightShift);
+        //            if (frmSpotCheck.ShowDialog() == DialogResult.OK)
+        //            {
+        //                return true;
+        //            }
+        //            else
+        //            {
+        //                return false;
+        //            }
+        //        }
+        //    }
+        //    if (NowDataTime >= dateTimeNightShift && NowDataTime <= endOfDateTimeDayShift)
+        //    {
+        //        if (!GlobalVariable.CheckTime.NightShiftSpotCheck && LoginTime >= dateTimeNightShift)
+        //        {
+        //            frmSpotCheck = new FrmSpotCheck(IniConfigHelper.ReadIniData("CheckTime", "LoginTime", ""), dateTimeDayShift, dateTimeNightShift);
+        //            if (frmSpotCheck.ShowDialog() == DialogResult.OK)
+        //            {
+        //                return true;
+        //            }
+        //            else
+        //            {
+        //                return false;
+        //            }
+        //        }
+        //    }
+        //    return true;
+        //}
+
+        //[CheckTime]
+        //DayShift=7:50
+        //NightShift=19:50
+        //NtcTempSelectStore=NTC.xlsx
+        //LoginTime = 2025年8月14日 13:28
+        //DayShiftSpotCheck=1
+        //NightShiftSpotCheck=0
+        #endregion
+
+ */

+ 4 - 0
TeamAAS-VM/TeamAAS-VP.csproj

@@ -531,6 +531,8 @@
     </Compile>
     <Compile Include="Core\StabilityAnalyzer.cs" />
     <Compile Include="Events\MainTabSwitchNotification.cs" />
+    <Compile Include="Events\WorkShiftChangedNotification.cs" />
+    <Compile Include="Events\WorkShiftUpdateNotification.cs" />
     <Compile Include="Interfaces\IMesService.cs" />
     <Compile Include="Models\DeviceInfo.cs" />
     <Compile Include="Models\Feeder\ScrewFeederInfo.cs" />
@@ -543,12 +545,14 @@
     <Compile Include="Models\Torque\TorqueTest.cs" />
     <Compile Include="Models\Torque\Torque_TaskStatus.cs" />
     <Compile Include="Models\Torque\TorqueProduceModel.cs" />
+    <Compile Include="Models\Torque\WorkShift.cs" />
     <Compile Include="Resources\Languages\Lang.Designer.cs">
       <AutoGen>True</AutoGen>
       <DesignTime>True</DesignTime>
       <DependentUpon>Lang.resx</DependentUpon>
     </Compile>
     <Compile Include="Services\MesService.cs" />
+    <Compile Include="Services\ShiftWatcherService.cs" />
     <Compile Include="ViewModels\Product\PlcPointOffserParamsViewModel.cs" />
     <Compile Include="ViewModels\User\CardLoginWindowViewModel.cs" />
     <Compile Include="ViewModels\Home\ChangeNozzleViewModel.cs" />

+ 2 - 0
TeamAAS-VM/ViewModels/SettingViewModel.cs

@@ -1,4 +1,5 @@
 using ICSharpCode.AvalonEdit.Search;
+using log4net;
 using MaterialDesignThemes.Wpf;
 using NPOI.SS.Formula.Functions;
 using Opc.Ua;
@@ -15,6 +16,7 @@ using System.ComponentModel;
 using System.Drawing.Drawing2D;
 using System.Globalization;
 using System.Linq;
+using System.Reflection.Metadata;
 using System.Text;
 using System.Windows;
 using Team.FFFeederService.Interfaces;