|
|
@@ -26,17 +26,17 @@ namespace TeamAAS_VP.Services
|
|
|
public void Start()
|
|
|
{
|
|
|
// 中文注释:每秒检测一次
|
|
|
- _timer = new Timer(_ => CheckShift(), null, 0, 1000);
|
|
|
- try
|
|
|
- {
|
|
|
- this.workShift = FileHelper.ReadJsonFile<WorkShift>(FilePath.WorkShiftParamPath);
|
|
|
- }
|
|
|
- catch (Exception)
|
|
|
- { }
|
|
|
- _eventAggregator.GetEvent<WorkShiftUpdateNotification>().Subscribe((p) =>
|
|
|
- {
|
|
|
- this.workShift = p;
|
|
|
- });
|
|
|
+ //_timer = new Timer(_ => CheckShift(), null, 0, 1000);
|
|
|
+ //try
|
|
|
+ //{
|
|
|
+ // this.workShift = FileHelper.ReadJsonFile<WorkShift>(FilePath.WorkShiftParamPath);
|
|
|
+ //}
|
|
|
+ //catch (Exception)
|
|
|
+ //{ }
|
|
|
+ //_eventAggregator.GetEvent<WorkShiftUpdateNotification>().Subscribe((p) =>
|
|
|
+ //{
|
|
|
+ // this.workShift = p;
|
|
|
+ //});
|
|
|
}
|
|
|
|
|
|
private void CheckShift()
|
|
|
@@ -77,415 +77,4 @@ namespace TeamAAS_VP.Services
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
-```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
|
|
|
-
|
|
|
- */
|
|
|
+}
|