| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- 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
- */
|