2003 lines
81 KiB
C#
2003 lines
81 KiB
C#
using AntdUI;
|
||
using HML;
|
||
using JinYuan.ControlCenters;
|
||
using JinYuan.ControlLib;
|
||
using JinYuan.ControlLib.Models;
|
||
using JinYuan.Helper;
|
||
using JinYuan.MES.Models;
|
||
using JinYuan.Models;
|
||
using JinYuan.VirtualDataLibrary;
|
||
using Language;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Diagnostics;
|
||
using System.Drawing;
|
||
using System.Drawing.Text;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Runtime.InteropServices;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
|
||
namespace LargeSquareOne
|
||
{
|
||
|
||
public partial class FrmMain : MultiLanguageForm
|
||
{
|
||
// 窗体实例缓存
|
||
private readonly Dictionary<FormNames, Form> _formCache = new Dictionary<FormNames, Form>();
|
||
|
||
private ControlCenter _controlCenter;
|
||
|
||
//实时更新的定时器
|
||
private System.Timers.Timer updateTimer;
|
||
//定时存储定时器
|
||
private System.Timers.Timer storeTimer;
|
||
private DateTime _lastStoreTick = DateTime.MinValue;
|
||
private readonly TimeSpan _minStoreInterval = TimeSpan.FromMilliseconds(1000);
|
||
private DateTime _lastFullUpdate = DateTime.MinValue;
|
||
private string _cachedAlarmText = "";
|
||
private DateTime _lastScrollUpdate = DateTime.MinValue;
|
||
private readonly TimeSpan _scrollUpdateInterval = TimeSpan.FromMilliseconds(100);
|
||
//加载字体
|
||
private PrivateFontCollection font = new PrivateFontCollection();
|
||
|
||
/// <summary>
|
||
/// 时间更新委托
|
||
/// </summary>
|
||
/// <param name="time"></param>
|
||
public delegate void ShowTimeHandler(DateTime time);
|
||
|
||
//当前页面索引
|
||
private int CurrentIndex = 0;
|
||
private List<NaviButton2> naviButton2s = new List<NaviButton2>();
|
||
|
||
public bool IsNoOrg = false;
|
||
public bool IsSetParam = false;
|
||
private readonly object _statusLock = new object();
|
||
private DateTime _lastSafeInvoke = DateTime.MinValue;
|
||
|
||
// 添加一个上次更新电池状态的时间记录
|
||
private DateTime _lastBatteryStatusUpdate = DateTime.MinValue;
|
||
private readonly TimeSpan _batteryUpdateInterval = TimeSpan.FromMilliseconds(200); // 限制每 200ms 更新一次电池 UI
|
||
|
||
// 下拉框数据缓存(核心优化:避免频繁绑定)
|
||
private List<DropDownListPlusItem> _cachedModelItems = new List<DropDownListPlusItem>();
|
||
|
||
// 委托队列(核心优化:防委托堆积)
|
||
private List<IAsyncResult> _pendingInvokes = new List<IAsyncResult>();
|
||
|
||
// MES状态缓存(核心优化:降低更新频率)
|
||
private DateTime _lastMESUpdate = DateTime.MinValue;
|
||
private bool _lastMESValue = false;
|
||
|
||
public FrmMain()
|
||
{
|
||
InitializeComponent();
|
||
|
||
// 添加应用程序域异常处理
|
||
AppDomain.CurrentDomain.FirstChanceException += (sender, e) =>
|
||
{
|
||
if (e.Exception is System.InvalidOperationException)
|
||
{
|
||
Debug.WriteLine($"[全局异常] InvalidOperationException: {e.Exception.Message}");
|
||
Debug.WriteLine($"[堆栈] {e.Exception.StackTrace}");
|
||
|
||
// 检查是否是跨线程异常
|
||
if (e.Exception.StackTrace.Contains("System.Windows.Forms.Control"))
|
||
{
|
||
Debug.WriteLine("[诊断] 这是跨线程访问UI控件的异常!");
|
||
}
|
||
}
|
||
};
|
||
|
||
Application.AddMessageFilter(new InputMessageFilter(() =>
|
||
{
|
||
lastActivityTime = DateTime.Now;
|
||
}));
|
||
|
||
// 双缓冲全覆盖
|
||
this.DoubleBuffered = true;
|
||
InitializeOptimizedControlStyles();
|
||
InitializeLanguageSwitch();
|
||
SetCombOrg();
|
||
IsNoOrg = true;
|
||
|
||
this.Resize += FrmNewMain_Resize; // 关联 Resize 事件
|
||
|
||
#region 添加工具栏
|
||
naviButton2s.AddRange(new[]
|
||
{
|
||
nav_Monitor, nav_DataMonitor, nav_CPK, nav_BatteryStatus, nav_QRCode,
|
||
nav_AlarmLog, nav_HistotryData, nav_SetSystem, nav_System, nav_UserInfo
|
||
});
|
||
#endregion
|
||
|
||
InitializeTimersOptimized();
|
||
CommonMethods.listener.Start();
|
||
|
||
//刷卡模式
|
||
if (CommonMethods.sysConfig.SwipeCardMode)
|
||
{
|
||
CommonMethods.listener.ScanerEvent += Listener_ScanerEvent;
|
||
}
|
||
}
|
||
|
||
// 控件样式初始化提取
|
||
private void InitializeOptimizedControlStyles()
|
||
{
|
||
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer |
|
||
ControlStyles.OptimizedDoubleBuffer |
|
||
ControlStyles.ResizeRedraw | ControlStyles.Selectable |
|
||
ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
|
||
this.UpdateStyles();
|
||
|
||
// 容器控件启用双缓冲
|
||
SetControlDoubleBuffer(MainPanel, true);
|
||
SetControlDoubleBuffer(TopPanel, true);
|
||
}
|
||
|
||
// 通用双缓冲设置方法
|
||
private void SetControlDoubleBuffer(Control ctrl, bool enable)
|
||
{
|
||
// 空值校验,避免空引用异常
|
||
if (ctrl == null) return;
|
||
|
||
try
|
||
{
|
||
// 1. 设置 DoubleBuffered 私有属性
|
||
PropertyInfo doubleBufferedProp = ctrl.GetType().GetProperty(
|
||
"DoubleBuffered",
|
||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||
doubleBufferedProp?.SetValue(ctrl, enable, null);
|
||
|
||
// 2. 反射调用 SetStyle 受保护方法
|
||
MethodInfo setStyleMethod = typeof(Control).GetMethod(
|
||
"SetStyle",
|
||
BindingFlags.Instance | BindingFlags.NonPublic,
|
||
null,
|
||
new[] { typeof(ControlStyles), typeof(bool) },
|
||
null);
|
||
setStyleMethod?.Invoke(ctrl, new object[]
|
||
{
|
||
ControlStyles.AllPaintingInWmPaint |
|
||
ControlStyles.OptimizedDoubleBuffer |
|
||
ControlStyles.UserPaint,
|
||
enable
|
||
});
|
||
|
||
// 3. 反射调用 UpdateStyles 受保护方法
|
||
MethodInfo updateStylesMethod = typeof(Control).GetMethod(
|
||
"UpdateStyles",
|
||
BindingFlags.Instance | BindingFlags.NonPublic);
|
||
updateStylesMethod?.Invoke(ctrl, null);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 捕获反射调用可能出现的异常
|
||
MessageBox.Show($"设置双缓冲失败:{ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private DateTime lastActivityTime;
|
||
private System.Windows.Forms.Timer idleTimer;
|
||
|
||
// 定时器初始化优化
|
||
private void InitializeTimersOptimized()
|
||
{
|
||
// 实时更新定时器(1秒)
|
||
updateTimer = new System.Timers.Timer(1000);
|
||
updateTimer.Elapsed += UpdateTimer_Tick;
|
||
updateTimer.AutoReset = true;
|
||
updateTimer.Start();
|
||
|
||
// 定时存储定时器(1秒)
|
||
storeTimer = new System.Timers.Timer(1000);
|
||
storeTimer.Elapsed += StoreTimer_Elapsed;
|
||
storeTimer.AutoReset = true;
|
||
storeTimer.Start();
|
||
|
||
// 定时退出当前用户
|
||
idleTimer = new System.Windows.Forms.Timer();
|
||
idleTimer.Interval = 1000;
|
||
idleTimer.Tick += (s, e) =>
|
||
{
|
||
if ((DateTime.Now - lastActivityTime).TotalMinutes >= 1)
|
||
{
|
||
idleTimer.Stop();
|
||
|
||
// 处理用户超时
|
||
this.BeginInvoke(new Action(() => LoginLocalOut()));
|
||
}
|
||
};
|
||
idleTimer.Start();
|
||
}
|
||
|
||
|
||
private async void FrmNewMain_Load(object sender, EventArgs e)
|
||
{
|
||
InitReadInI();
|
||
UserTimeOut(30);
|
||
|
||
_controlCenter = ControlCenter.Instance;
|
||
//await ControlCenter.Instance.StartAsync().ConfigureAwait(false);
|
||
await ControlCenter.Instance.StartAsync();
|
||
|
||
// 回到UI线程更新用户信息
|
||
this.BeginInvoke(new Action(() =>
|
||
{
|
||
// 1.设置登录用户
|
||
this.lbl_LoginLevel.Text = CommonMethods.currentAdmin?.LoginLevel;
|
||
this.lbl_LoginName.Text = CommonMethods.currentAdmin?.LoginName;
|
||
|
||
// 2.打开初始窗体
|
||
CommonNaviButton_Click(this.nav_AlarmLog, null);
|
||
CommonNaviButton_Click(this.nav_Monitor, null);
|
||
CommonNaviButton_Click(this.nav_DataMonitor, null);
|
||
CommonNaviButton_Click(this.nav_QRCode, null);
|
||
CommonNaviButton_Click(this.nav_BatteryStatus, null);
|
||
|
||
// 登录日志
|
||
CommonMethods.AddOPLog(false, "登录成功,登录用户".Translated() + $":{CommonMethods.currentAdmin?.LoginName}," + "权限".Translated() + $":{CommonMethods.currentAdmin?.LoginLevel}");
|
||
}));
|
||
|
||
if (CommonMethods.sysConfig != null)
|
||
{
|
||
CommonMethods.AddLog(false, "加载系统配置成功".Translated());
|
||
}
|
||
else
|
||
{
|
||
CommonMethods.AddLog(true, "加载系统配置失败".Translated());
|
||
}
|
||
|
||
// 自动锁屏
|
||
if (CommonMethods.sysConfig.AutoLock)
|
||
{
|
||
Application.AddMessageFilter(new MessageFilter());
|
||
}
|
||
|
||
CheckMesLogin();
|
||
|
||
storeTimer.Enabled = true;
|
||
updateTimer.Enabled = true;
|
||
|
||
this.BeginInvoke(new MethodInvoker(() =>
|
||
{
|
||
AdjustUCRollTextFrequency();
|
||
}));
|
||
}
|
||
|
||
|
||
private void AdjustUCRollTextFrequency()
|
||
{
|
||
try
|
||
{
|
||
// 使用反射查找UCRollText的Timer并调整频率
|
||
var timerField = ucRollText1.GetType().GetField("_scrollTimer",
|
||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||
|
||
if (timerField != null)
|
||
{
|
||
var timer = timerField.GetValue(ucRollText1) as System.Windows.Forms.Timer;
|
||
if (timer != null)
|
||
{
|
||
timer.Interval = 80;
|
||
Debug.WriteLine($"UCRollText频率已调整为: {timer.Interval}ms");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"调整UCRollText频率失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void CheckMesLogin()
|
||
{
|
||
if (CommonMethods.sysConfig.MesModeSwitching && !CommonMethods.mesConfig.IsLoginMesOK)
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "当前为MES模式,请登录!".Translated(), "MES未登录".Translated()).ShowDialog();
|
||
using (var frmLoginMes = new FrmLoginMes())
|
||
{
|
||
frmLoginMes.ShowDialog();
|
||
}
|
||
}
|
||
}
|
||
|
||
#region PLC后台读取任务
|
||
/// <summary>
|
||
/// PLC后台读取专用任务(独立线程,不阻塞UI和其他操作)
|
||
/// </summary>
|
||
//private async Task PLCBackgroundReadTask()
|
||
//{
|
||
// while (!_cts.Token.IsCancellationRequested)
|
||
// {
|
||
// try
|
||
// {
|
||
// // 信号量确保同一时间只有一个PLC读取操作
|
||
// await _plcSemaphore.WaitAsync(_cts.Token).ConfigureAwait(false);
|
||
|
||
// if (CommonMethods.IsRun && CommonMethods.plcDevices != null && CommonMethods.plcDevices.Count > 0)
|
||
// {
|
||
// // 异步读取PLC数据,超时控制(避免卡死)
|
||
// var plcDevice = CommonMethods.plcDevices[0];
|
||
// await WaitWithTimeout(
|
||
// Task.Run(() =>
|
||
// {
|
||
// // PLC数据读取逻辑
|
||
// // plcDevice.ReadAllData();
|
||
// }, _cts.Token),
|
||
// TimeSpan.FromMilliseconds(500)
|
||
// ).ConfigureAwait(false);
|
||
// }
|
||
// }
|
||
// catch (OperationCanceledException)
|
||
// {
|
||
// // 任务取消,正常退出
|
||
// break;
|
||
// }
|
||
// catch (TimeoutException)
|
||
// {
|
||
// LogHelper.Instance.WriteLog("PLC读取超时,跳过本次读取");
|
||
// }
|
||
// catch (Exception ex)
|
||
// {
|
||
// LogHelper.Instance.WriteEX("PLC后台读取异常", ex);
|
||
// }
|
||
// finally
|
||
// {
|
||
// _plcSemaphore.Release();
|
||
// }
|
||
|
||
// // 控制PLC读取频率(50ms一次,可根据需要调整)
|
||
// await Task.Delay(50, _cts.Token).ConfigureAwait(false);
|
||
// }
|
||
//}
|
||
#endregion
|
||
|
||
#region 读取配置文件
|
||
|
||
/// <summary>
|
||
/// 读取配置文件
|
||
/// </summary>
|
||
public void InitReadInI()
|
||
{
|
||
#region 系统配置
|
||
CommonMethods.sysConfig = CommonMethods.GetSysConfig();
|
||
#endregion
|
||
|
||
#region MES配置
|
||
|
||
CommonMethods.mesConfig.RotueServerIP = CommonMethods.GetConfigValue(CommonMethods.Configxml, "MES_CONFIG", "StorageServerIP", "192.168.2.108");
|
||
///获取MES参数
|
||
CommonMethods.mesConfig = CommonMethods.GetMesConfig();
|
||
CommonMethods.LoadFDConfig();
|
||
CommonMethods.LoadFDConfigMappings();
|
||
//CommonMethods.btwConfig = CommonMethods.GetBtwConfig();
|
||
|
||
CommonMethods.mesConfig.electricMeterNum.Clear();
|
||
|
||
string str = CommonMethods.GetConfigValue(CommonMethods.Configxml, "MES_CONFIG", "SmartMeterCode", "1");
|
||
if (str.Contains(','))
|
||
{
|
||
CommonMethods.mesConfig.electricMeterNum.AddRange(str.Split(','));
|
||
}
|
||
|
||
CommonMethods.ChangeClassTime = CommonMethods.GetConfigValue(CommonMethods.Configxml, "MES_CONFIG", "ShiftChangeTime", "20:30:00");
|
||
|
||
string rootLogPath = CommonMethods.GetConfigValue(CommonMethods.Configxml, "MES_CONFIG", "MESLogPath", "D:\\APILog");
|
||
CommonMethods.strDeletepath = rootLogPath;
|
||
CommonMethods.strAlarmLogspath = Path.Combine(rootLogPath, "Logs", "AlarmLogs");
|
||
CommonMethods.strMesLogspath = Path.Combine(rootLogPath, "Logs", "MesLogs");
|
||
CommonMethods.strSystemLogspath = Path.Combine(rootLogPath, "Logs", "SystemLogs");
|
||
CommonMethods.strErrorLogspath = Path.Combine(rootLogPath, "Logs", "ErrorLogs");
|
||
CommonMethods.strsqlLogspath = Path.Combine(rootLogPath, "Logs", "SqlLogs");
|
||
CommonMethods.strWattrMeterpath = Path.Combine(rootLogPath, "Logs", "智能电表数据");
|
||
#endregion
|
||
|
||
CommonMethods.mesConfig.listAntiDustAirSpeedNum.Clear();
|
||
CommonMethods.mesConfig.AntiDustAirSpeedCount = Convert.ToInt32(CommonMethods.GetConfigValue(CommonMethods.Configxml, "ANEMOMETER", "AntiDustAirSpeedCount", "1"));
|
||
for (int i = 0; i < CommonMethods.mesConfig.AntiDustAirSpeedCount; i++)
|
||
{
|
||
CommonMethods.mesConfig.listAntiDustAirSpeedNum.Add(CommonMethods.GetConfigValue(CommonMethods.Configxml, "ANEMOMETER", $"AntiDustAirSpeed{i + 1}", "0"));
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 无操作 系统锁屏+切换到主监控界面
|
||
private async void UpdateTimer_Tick(object sender, EventArgs e)
|
||
{
|
||
Debug.WriteLine($"[UpdateTimer] {DateTime.Now:HH:mm:ss.fff} - 开始执行");
|
||
|
||
try
|
||
{
|
||
// 只处理锁屏和界面切换检查
|
||
if (CommonMethods.sysConfig.AutoLock)
|
||
{
|
||
CommonMethods.tickCount++;
|
||
int threshold = CommonMethods.sysConfig.LockPeriod * 60;
|
||
if (CommonMethods.tickCount >= threshold)
|
||
{
|
||
CommonMethods.tickCount = 0;
|
||
this.BeginInvoke(new Action(() => LockWorkStation()));
|
||
}
|
||
}
|
||
|
||
if (CommonMethods.sysConfig.AutoQieHuanM)
|
||
{
|
||
CommonMethods.tickHomeCount++;
|
||
int homeThreshold = CommonMethods.sysConfig.QieHuanMPeriod * 60;
|
||
if (CommonMethods.tickHomeCount >= homeThreshold)
|
||
{
|
||
CommonMethods.tickHomeCount = 0;
|
||
this.BeginInvoke((Action)(() =>
|
||
CommonNaviButton_Click(this.nav_Monitor, null)));
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"UpdateTimer异常: {ex.Message}");
|
||
}
|
||
|
||
Debug.WriteLine($"[UpdateTimer] {DateTime.Now:HH:mm:ss.fff} - 结束执行");
|
||
}
|
||
|
||
|
||
|
||
private void StoreTimer_Elapsed(object sender, EventArgs e)
|
||
{
|
||
Debug.WriteLine($"[StoreTimer] {DateTime.Now:HH:mm:ss.fff} - 开始执行");
|
||
|
||
try
|
||
{
|
||
// 防抖:800ms 内只执行一次
|
||
if (DateTime.Now - _lastSafeInvoke < TimeSpan.FromMilliseconds(800))
|
||
return;
|
||
|
||
_lastSafeInvoke = DateTime.Now;
|
||
|
||
// UI 操作必须封送回主线程
|
||
if (this.IsHandleCreated || !this.IsDisposed)
|
||
{
|
||
this.BeginInvoke((Action)(() =>
|
||
ShowButtonEven_Run(DateTime.Now)));
|
||
}
|
||
}
|
||
catch { }
|
||
|
||
Debug.WriteLine($"[StoreTimer] {DateTime.Now:HH:mm:ss.fff} - 结束执行");
|
||
|
||
//// 1. 异步执行,避免阻塞定时器线程
|
||
//Task.Run(() =>
|
||
//{
|
||
// // 2. 防抖:800ms内只执行一次,避免高频更新
|
||
// if (DateTime.Now - _lastSafeInvoke < TimeSpan.FromMilliseconds(800))
|
||
// return;
|
||
|
||
// lock (_statusLock)
|
||
// {
|
||
// _lastSafeInvoke = DateTime.Now;
|
||
// // 3. 安全更新UI:通过BeginInvoke,且只更新变化的数据
|
||
// SafeInvoke(() => ShowButtonEven_Run(DateTime.Now));
|
||
// }
|
||
//});
|
||
//Debug.WriteLine($"[StoreTimer] {DateTime.Now:HH:mm:ss.fff} - 结束执行");
|
||
}
|
||
|
||
|
||
[DllImport("user32", SetLastError = true)]
|
||
public static extern bool LockWorkStation();
|
||
|
||
#endregion
|
||
|
||
|
||
/// <summary>
|
||
/// 刷卡事件
|
||
/// </summary>
|
||
/// <param name="codes"></param>
|
||
private void Listener_ScanerEvent(ScanerHook.ScanerCodes codes)
|
||
{
|
||
// 非UI线程,必须切UI上下文
|
||
//if (this.InvokeRequired)
|
||
//{
|
||
// this.Invoke(new Action<void>(Listener_ScanerEvent), codes);
|
||
// return;
|
||
//}
|
||
|
||
if (string.IsNullOrWhiteSpace(codes.Result))
|
||
{
|
||
//AntdUI.Message.Warn(this, "读取卡片为空,请重新刷卡");
|
||
new FrmMsgBoxOutWithAck(3, "读取卡片为空,请重新刷卡".Translated(), "登录提示".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
|
||
//调用查询方法
|
||
var sysAdmin = CommonMethods.db.Query<SysAdmin>(it => it.LoginUid == codes.Result);
|
||
if (sysAdmin == null)
|
||
{
|
||
new FrmMsgBoxOutWithAck(3, "登录用户或密码错误".Translated(), "登录提示".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
|
||
CommonMethods.IsLoginOk = true;
|
||
//存储用户对象
|
||
CommonMethods.currentAdmin = sysAdmin;
|
||
//1.设置登录用户
|
||
this.lbl_LoginLevel.Text = CommonMethods.currentAdmin?.LoginLevel;
|
||
this.lbl_LoginName.Text = CommonMethods.currentAdmin?.LoginName;
|
||
//登录日志
|
||
CommonMethods.AddOPLog(false, "登录成功,登录用户".Translated() + $":{CommonMethods.currentAdmin?.LoginName}," + "权限".Translated() + $":{CommonMethods.currentAdmin?.LoginLevel}");
|
||
}
|
||
|
||
|
||
#region 获取日期/星期,班次信息,更新
|
||
|
||
private int _showButtonRunCount = 0;
|
||
private DateTime _lastDebugOutput = DateTime.Now;
|
||
|
||
|
||
private void ShowButtonEven_Run(DateTime time)
|
||
{
|
||
|
||
Debug.WriteLine($"ShowButtonEven_Run on Thread: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
|
||
|
||
|
||
_showButtonRunCount++;
|
||
|
||
// 确保至少间隔800ms
|
||
if (DateTime.Now - _lastDebugOutput < TimeSpan.FromMilliseconds(800))
|
||
return;
|
||
|
||
// 每5次输出一次调试信息
|
||
if (_showButtonRunCount % 5 == 0 && DateTime.Now - _lastDebugOutput > TimeSpan.FromSeconds(2))
|
||
{
|
||
Debug.WriteLine($"[ShowButtonEven_Run] 第{_showButtonRunCount}次执行,间隔: {(DateTime.Now - _lastDebugOutput).TotalMilliseconds:F0}ms");
|
||
_lastDebugOutput = DateTime.Now;
|
||
}
|
||
|
||
lock (_statusLock)
|
||
{
|
||
// 1. 先读取数据并缓存
|
||
bool currentEMCStatues = CommonMethods.EMCStatues;
|
||
bool currentZupanPLCConnected = false;
|
||
bool currentWuliuPLCConnected = false;
|
||
if (CommonMethods.plcDevices.Count() > 0)
|
||
{
|
||
for (int i = 0; i < CommonMethods.plcDevices.Count(); i++)
|
||
{
|
||
if (CommonMethods.plcDevices[i].IsConnected)
|
||
{
|
||
if (CommonMethods.plcDevices[i].Name == "PLC_1")
|
||
currentZupanPLCConnected = CommonMethods.plcDevices[i].IsConnected;
|
||
|
||
if (CommonMethods.plcDevices[i].Name == "PLC_2")
|
||
{
|
||
currentWuliuPLCConnected = CommonMethods.plcDevices[i].IsConnected;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
bool currentMESLoginStatus = CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.IsLoginMesOK;
|
||
string currentAlarmText = CommonMethods.SlideAlarmText ?? "";
|
||
List<bool> currentStatues = CommonMethods.Statues ?? new List<bool>();
|
||
|
||
// 2. 只更新变化的数据,避免无意义的UI刷新
|
||
this.lbl_DateTime.Text = CurrentTime + " " + week + " " + $"{CommonMethods.strClass}";
|
||
|
||
if (this.led_RunState.Value != currentEMCStatues)
|
||
this.led_RunState.Value = currentEMCStatues;
|
||
|
||
// PLC连接状态
|
||
if (this.led_PLC1State.Value != currentZupanPLCConnected)
|
||
this.led_PLC1State.Value = currentZupanPLCConnected;
|
||
|
||
if (this.led_PLC2State.Value != currentWuliuPLCConnected)
|
||
this.led_PLC2State.Value = currentWuliuPLCConnected;
|
||
|
||
|
||
|
||
// MES状态:3秒更新一次即可
|
||
if (DateTime.Now - _lastMESUpdate > TimeSpan.FromSeconds(3) && this.led_MESState.Value != currentMESLoginStatus)
|
||
{
|
||
_lastMESUpdate = DateTime.Now;
|
||
this.led_MESState.Value = currentMESLoginStatus;
|
||
avMesicon.Visible = currentMESLoginStatus;
|
||
lblMES.Visible = currentMESLoginStatus;
|
||
if (currentMESLoginStatus)
|
||
lblMES.Text = CommonMethods.mesConfig.mesUserName;
|
||
}
|
||
|
||
|
||
|
||
// 只有内容变化时才更新
|
||
if (currentStatues.Count > 2 && currentStatues[2])
|
||
{
|
||
if (this.ucRollText1.Text != currentAlarmText)
|
||
{
|
||
this.ucRollText1.Text = currentAlarmText;
|
||
this.ucRollText1.ForeColor = Color.Red;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
string noAlarmText = "当前无报警".Translated();
|
||
if (this.ucRollText1.Text != noAlarmText)
|
||
{
|
||
this.ucRollText1.Text = noAlarmText;
|
||
this.ucRollText1.ForeColor = Color.White;
|
||
CommonMethods.SlideAlarmText = "";
|
||
}
|
||
}
|
||
|
||
// LED状态:只在状态变化时更新
|
||
if (currentStatues.Count > 0)
|
||
{
|
||
if (this.led_State.Value != currentStatues[0])
|
||
{
|
||
this.led_State.Value = currentStatues[0];
|
||
this.led_State.BlinkColor = Color.Lime;
|
||
this.led_State.OnColor = Color.Lime;
|
||
}
|
||
|
||
bool needBlink = currentStatues.Count > 3 && (currentStatues[1] || currentStatues[2] || currentStatues[3]);
|
||
if (this.led_State.BlinkOn != needBlink)
|
||
{
|
||
this.led_State.BlinkOn = needBlink;
|
||
if (needBlink)
|
||
{
|
||
Color blinkColor = currentStatues[2] ? Color.Red : Color.Yellow;
|
||
this.led_State.BlinkColor = blinkColor;
|
||
this.led_State.OnColor = blinkColor;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 登录状态:只在状态变化时更新
|
||
bool isSwipeCardMode = CommonMethods.sysConfig.SwipeCardMode && !CommonMethods.IsLoginOk;
|
||
if (lbl_LoginName.Visible == isSwipeCardMode)
|
||
{
|
||
lbl_LoginName.Visible = !isSwipeCardMode;
|
||
if (isSwipeCardMode)
|
||
lbl_LoginLevel.Text = "未登录";
|
||
}
|
||
}
|
||
|
||
System.Diagnostics.Debug.Print("ShowButtonEven_Run end at " + DateTime.Now.ToString("HH:mm:ss.fff"));
|
||
}
|
||
|
||
|
||
private void SafeInvoke(Action action)
|
||
{
|
||
// 1. 基础防护:窗体已释放直接返回
|
||
if (this.IsDisposed || !this.IsHandleCreated || action == null)
|
||
return;
|
||
|
||
// 2. 提前声明result并初始化为null,解决“未赋值”编译错误
|
||
IAsyncResult result = null;
|
||
|
||
try
|
||
{
|
||
if (this.InvokeRequired)
|
||
{
|
||
// 3. 带超时的BeginInvoke,避免委托堆积
|
||
result = this.BeginInvoke(new MethodInvoker(() =>
|
||
{
|
||
try
|
||
{
|
||
if (!this.IsDisposed)
|
||
action();
|
||
}
|
||
catch
|
||
{
|
||
/* 忽略UI更新异常,不影响主线程 */
|
||
}
|
||
finally
|
||
{
|
||
// 4. 清理已完成的委托:增加null校验,避免空引用
|
||
lock (_pendingInvokes)
|
||
{
|
||
if (result != null && _pendingInvokes.Contains(result))
|
||
{
|
||
_pendingInvokes.Remove(result);
|
||
}
|
||
}
|
||
}
|
||
}));
|
||
|
||
// 5. 记录未完成的委托:增加null校验
|
||
lock (_pendingInvokes)
|
||
{
|
||
if (result != null)
|
||
{
|
||
_pendingInvokes.Add(result);
|
||
}
|
||
}
|
||
|
||
// 6. 超时清理:5秒未完成的委托强制取消,避免内存泄漏
|
||
Task.Delay(5000).ContinueWith(t =>
|
||
{
|
||
// 防护:任务取消/异常时不执行
|
||
if (t.IsCanceled || t.IsFaulted)
|
||
return;
|
||
|
||
lock (_pendingInvokes)
|
||
{
|
||
if (result != null && _pendingInvokes.Contains(result) && !result.IsCompleted)
|
||
{
|
||
try
|
||
{
|
||
this.EndInvoke(result); // 强制结束未完成的委托
|
||
}
|
||
catch
|
||
{
|
||
/* 忽略结束委托的异常(如委托已执行) */
|
||
}
|
||
_pendingInvokes.Remove(result);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
else
|
||
{
|
||
// 7. 无需跨线程:直接执行(加防护)
|
||
if (!this.IsDisposed)
|
||
action();
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
// 8. 忽略所有调用异常,避免SafeInvoke自身抛出错误
|
||
}
|
||
}
|
||
|
||
|
||
///// <summary>
|
||
///// 安全执行UI操作(增强版:解决跨线程问题)
|
||
///// </summary>
|
||
///// <param name="action">要执行的UI操作</param>
|
||
///// <param name="timeoutMs">超时时间(默认5000ms)</param>
|
||
//private void SafeInvoke(Action action, int timeoutMs = 5000)
|
||
//{
|
||
// if (action == null) return;
|
||
// if (this.IsDisposed || !this.IsHandleCreated) return;
|
||
|
||
// try
|
||
// {
|
||
// if (this.InvokeRequired)
|
||
// {
|
||
// var asyncResult = this.BeginInvoke(action);
|
||
|
||
// // 等待完成或超时
|
||
// if (asyncResult.AsyncWaitHandle.WaitOne(timeoutMs))
|
||
// {
|
||
// // 正常完成,必须调用EndInvoke
|
||
// this.EndInvoke(asyncResult);
|
||
// }
|
||
// else
|
||
// {
|
||
// // 超时处理
|
||
// Debug.WriteLine($"SafeInvoke超时({timeoutMs}ms)");
|
||
// // 超时也需要调用EndInvoke清理资源
|
||
// this.EndInvoke(asyncResult);
|
||
// }
|
||
// }
|
||
// else
|
||
// {
|
||
// action();
|
||
// }
|
||
// }
|
||
// catch (Exception ex)
|
||
// {
|
||
// Debug.WriteLine($"SafeInvoke异常:{ex.Message}");
|
||
// LogHelper.Instance.WriteEX("SafeInvoke异常", ex);
|
||
// }
|
||
//}
|
||
|
||
private string CurrentTime
|
||
{
|
||
get { return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); }
|
||
}
|
||
|
||
private string[] weeks = new string[] { "星期日".Translated(), "星期一".Translated(), "星期二".Translated(), "星期三".Translated(), "星期四".Translated(), "星期五".Translated(), "星期六".Translated() };
|
||
private string week
|
||
{
|
||
get { return weeks[Convert.ToInt32(DateTime.Now.DayOfWeek)]; }
|
||
}
|
||
#endregion
|
||
|
||
#region 窗体操作
|
||
#region 无边框拖动
|
||
private System.Drawing.Point mPoint;
|
||
private void Panel_MouseDown(object sender, MouseEventArgs e)
|
||
{
|
||
mPoint = new System.Drawing.Point(e.X, e.Y);
|
||
}
|
||
|
||
private void Panel_MouseMove(object sender, MouseEventArgs e)
|
||
{
|
||
if (e.Button == MouseButtons.Left)
|
||
{
|
||
this.Location = new System.Drawing.Point(this.Location.X + e.X - mPoint.X, this.Location.Y + e.Y - mPoint.Y);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
|
||
/// <summary>
|
||
/// 关闭程序
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void btExit_Click(object sender, EventArgs e)
|
||
{
|
||
// 关闭窗体
|
||
this.Close();
|
||
}
|
||
|
||
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
if (e.CloseReason == CloseReason.UserClosing)
|
||
{
|
||
e.Cancel = true; // 先取消关闭
|
||
|
||
DialogResult dialogResult = new FrmMsgBoxWithAck("是否确定要退出系统".Translated(), "退出系统".Translated()).ShowDialog();
|
||
if (dialogResult == DialogResult.OK)
|
||
{
|
||
try
|
||
{
|
||
// 1. 停止监听器
|
||
CommonMethods.listener.Stop();
|
||
|
||
// 2. 优雅取消CTS(关键修复:避免回调异常)
|
||
if (ControlCenter.Instance != null)
|
||
{
|
||
// 先取消订阅,避免回调执行
|
||
//ControlCenter.Instance.OnCancellationCompleted = null;
|
||
// 同步断开PLC(避免异步操作残留)
|
||
ControlCenter.Instance.DisconnectAllPlcs();
|
||
}
|
||
|
||
// 3. 取消后台任务
|
||
CommonMethods.IsExit = true;
|
||
//ControlCenter.Instance._cts?.Cancel();
|
||
// 4. 停止所有定时器
|
||
updateTimer?.Stop();
|
||
storeTimer?.Stop();
|
||
updateTimer?.Dispose();
|
||
storeTimer?.Dispose();
|
||
// 5. 清理委托队列
|
||
lock (_pendingInvokes)
|
||
{
|
||
foreach (var result in _pendingInvokes)
|
||
{
|
||
if (!result.IsCompleted)
|
||
this.EndInvoke(result);
|
||
}
|
||
_pendingInvokes.Clear();
|
||
}
|
||
// 6. 释放子窗体缓存
|
||
foreach (var frm in _formCache.Values)
|
||
{
|
||
frm?.Close();
|
||
frm?.Dispose();
|
||
}
|
||
_formCache.Clear();
|
||
// 7. 优雅退出
|
||
this.Dispose();
|
||
Application.Exit();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogHelper.Instance.WriteEX(ex);
|
||
// 仅在优雅退出失败时才强制退出
|
||
System.Environment.Exit(0);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
e.Cancel = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 窗体关闭时清理未完成的委托
|
||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||
{
|
||
lock (_pendingInvokes)
|
||
{
|
||
foreach (var result in _pendingInvokes)
|
||
{
|
||
if (!result.IsCompleted)
|
||
this.EndInvoke(result);
|
||
}
|
||
_pendingInvokes.Clear();
|
||
}
|
||
// 停止所有定时器
|
||
updateTimer?.Stop();
|
||
storeTimer?.Stop();
|
||
updateTimer?.Dispose();
|
||
storeTimer?.Dispose();
|
||
|
||
idleTimer?.Stop();
|
||
storeTimer?.Dispose();
|
||
|
||
if (ControlCenter.Instance != null)
|
||
{
|
||
ControlCenter.Instance.DisconnectAllPlcs(); // 假设存在断开PLC的方法
|
||
}
|
||
|
||
// 4. 延迟释放(给资源清理留时间)
|
||
Thread.Sleep(1000);
|
||
|
||
|
||
base.OnFormClosing(e);
|
||
}
|
||
|
||
private void btnScale_Click(object sender, EventArgs e)
|
||
{
|
||
// 手动触发窗体最小化的逻辑
|
||
this.WindowState = FormWindowState.Minimized; // 将窗体最小化
|
||
FrmNewMain_Resize(this, EventArgs.Empty); // 调用 Resize 事件处理程序
|
||
}
|
||
|
||
private void FrmNewMain_Resize(object sender, EventArgs e)
|
||
{
|
||
if (this.WindowState == FormWindowState.Minimized)
|
||
{
|
||
// 在这里编写窗体最小化时的逻辑
|
||
//MessageBox.Show("窗体已最小化");
|
||
// 例如:隐藏窗体、显示通知等
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 左右切换
|
||
private void btn_Left_Click(object sender, EventArgs e)
|
||
{
|
||
CurrentIndex--;
|
||
if (CurrentIndex >= 0)
|
||
{
|
||
CommonNaviButton_Click(naviButton2s[CurrentIndex], null);
|
||
}
|
||
else
|
||
{
|
||
CurrentIndex++;
|
||
}
|
||
}
|
||
|
||
private void btn_right_Click(object sender, EventArgs e)
|
||
{
|
||
CurrentIndex++;
|
||
if (CurrentIndex < naviButton2s.Count)
|
||
{
|
||
CommonNaviButton_Click(naviButton2s[CurrentIndex], null);
|
||
}
|
||
else
|
||
{
|
||
CurrentIndex--;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 通用窗体切换
|
||
/// <summary>
|
||
/// 通用窗体切换
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void CommonNaviButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (sender is NaviButton2 navi)
|
||
{
|
||
if (Enum.IsDefined(typeof(FormNames), navi.Tag.ToString()))
|
||
{
|
||
//拿到导航按钮对应的窗体枚举值
|
||
FormNames formNames = (FormNames)Enum.Parse(typeof(FormNames), navi.Tag.ToString(), true);
|
||
|
||
//用户权限处理
|
||
switch (formNames)
|
||
{
|
||
case FormNames.日志报警:
|
||
if (CommonMethods.IsLoginOk)
|
||
{
|
||
if (!CommonMethods.currentAdmin.SystemLog)
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "当前登录用户权限不足!".Translated(), "权限不足".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "请先刷卡登录!".Translated(), "登录系统".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
break;
|
||
case FormNames.数据追溯:
|
||
if (CommonMethods.IsLoginOk)
|
||
{
|
||
if (!CommonMethods.currentAdmin.HistoryData)
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "当前登录用户权限不足!".Translated(), "权限不足".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "请先刷卡登录!".Translated(), "登录系统".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
break;
|
||
case FormNames.参数设置:
|
||
if (CommonMethods.IsLoginOk)
|
||
{
|
||
if (!CommonMethods.currentAdmin.ParamSet)
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "当前登录用户权限不足!".Translated(), "权限不足".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "请先刷卡登录!".Translated(), "登录系统".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
break;
|
||
case FormNames.系统设置:
|
||
if (CommonMethods.IsLoginOk)
|
||
{
|
||
if (!CommonMethods.currentAdmin.UserManage)
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "当前登录用户权限不足!".Translated(), "权限不足".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "请先刷卡登录!".Translated(), "登录系统".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
break;
|
||
case FormNames.用户管理:
|
||
if (CommonMethods.IsLoginOk)
|
||
{
|
||
if (!CommonMethods.currentAdmin.SystemLog)
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "当前登录用户权限不足!".Translated(), "权限不足".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "请先刷卡登录!".Translated(), "登录系统".Translated()).ShowDialog();
|
||
return;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
//窗体切换
|
||
OpenForm(this.MainPanel, formNames);
|
||
|
||
//设置选中
|
||
SetNaviButtonSelected(this.TopPanel, navi);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通用打开窗体
|
||
/// </summary>
|
||
/// <param name="mainPanel">容器控件</param>
|
||
/// <param name="formNames">窗体枚举名称</param>
|
||
private void OpenForm(System.Windows.Forms.Panel mainPanel, FormNames formNames)
|
||
{
|
||
// 优先从缓存获取窗体
|
||
if (_formCache.TryGetValue(formNames, out Form cachedFrm) && !cachedFrm.IsDisposed)
|
||
{
|
||
cachedFrm.BringToFront();
|
||
SetNaviButtonSelected(this.TopPanel, naviButton2s.First(n => n.Tag.ToString() == formNames.ToString()));
|
||
return;
|
||
}
|
||
|
||
int total = mainPanel.Controls.Count;
|
||
//int closeCount = 0;
|
||
bool isFind = false;
|
||
|
||
foreach (Control ct in mainPanel.Controls)
|
||
{
|
||
if (ct is Form frm && frm.Text == formNames.ToString())
|
||
{
|
||
frm.BringToFront();
|
||
isFind = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
//for (int i = 0; i < total; i++)
|
||
//{
|
||
// Control ct = mainPanel.Controls[i - closeCount];
|
||
// if (ct is Form frm)
|
||
// {
|
||
// //如果当前Form是我们需要操作的窗体
|
||
// if (frm.Text == formNames.ToString())
|
||
// {
|
||
// frm.BringToFront();
|
||
// isFind = true;
|
||
// break;
|
||
// }
|
||
// //如果当前Form不是我们需要操作的窗体,然后判断是否为固定窗体,如果不是,则关闭,如果是,则不做处理
|
||
// else if ((FormNames)Enum.Parse(typeof(FormNames), frm.Text, true) >= FormNames.临界窗体)
|
||
// {
|
||
// frm.Close();
|
||
// closeCount++;
|
||
// }
|
||
// }
|
||
//}
|
||
|
||
if (!isFind)
|
||
{
|
||
Form frm = null;
|
||
|
||
switch (formNames)
|
||
{
|
||
case FormNames.集中监控:
|
||
frm = new FrmMonitor();
|
||
break;
|
||
case FormNames.数据监控:
|
||
frm = new FrmDataMonitor();
|
||
CommonMethods.AddDataMonitorDelegate += ((FrmDataMonitor)frm).AddDataMonitorLog;//日志记录显示
|
||
CommonMethods.ShowFeedingDelegate += ((FrmDataMonitor)frm).ShowFeedingData;//上料显示
|
||
CommonMethods.ShowReFeedingDelegate += ((FrmDataMonitor)frm).ShowReFeedingData;//组盘抽检显示
|
||
CommonMethods.ShowBlankingDelegate += ((FrmDataMonitor)frm).ShowBankdingData;//下料显示
|
||
CommonMethods.ShowTrayDataDelegate += ((FrmDataMonitor)frm).ShowTrayData;//料框码数据显示
|
||
CommonMethods.ChangeParamDelegate += ((FrmDataMonitor)frm).GetLocalParaData;//参数更新
|
||
break;
|
||
case FormNames.日志报警:
|
||
frm = new FrmAlarmLog();
|
||
CommonMethods.AddLogDelegate += ((FrmAlarmLog)frm).AddLog;//系统日志
|
||
CommonMethods.AddOPLogDelegate += ((FrmAlarmLog)frm).AddOPLog;//操作日志
|
||
CommonMethods.AddAlarmDelegate += ((FrmAlarmLog)frm).AddAlarm;//报警日志
|
||
//CommonMethods.ShowAlarmDelegate += ((FrmAlarmLog)frm).ShowAlarm;
|
||
break;
|
||
case FormNames.临界窗体:
|
||
break;
|
||
case FormNames.数据追溯:
|
||
frm = new FrmHistory();
|
||
break;
|
||
case FormNames.参数设置:
|
||
frm = new FrmRecipe();
|
||
break;
|
||
case FormNames.系统设置:
|
||
frm = new FrmSystemSet(CommonMethods.deviceConfigPath);
|
||
break;
|
||
case FormNames.用户管理:
|
||
frm = new FrmUserManage();
|
||
break;
|
||
case FormNames.电池状况:
|
||
frm = new FrmBatteryStatus();
|
||
CommonMethods.ShowBatteryStatusDelegate += ((FrmBatteryStatus)frm).ShowBatteryStatus;//电池状态显示
|
||
CommonMethods.ShowBatteryNGRsnDelegate += ((FrmBatteryStatus)frm).ShowBatteryNGRsn;//档位NG原因显示
|
||
CommonMethods.ShowBatteryReplaceDelegate += ((FrmBatteryStatus)frm).ShowBatteryReplace;
|
||
break;
|
||
//case FormNames.二维码:
|
||
// frm = new FrmQRCoder();
|
||
// CommonMethods.ShowBatteryQRCoderDelegate += ((FrmQRCoder)frm).ShowBatteryQRCoder;
|
||
// break;
|
||
default: break;
|
||
}
|
||
|
||
if (frm != null)
|
||
{
|
||
//设置非顶层窗体
|
||
frm.TopLevel = false;
|
||
|
||
//去除边框
|
||
frm.FormBorderStyle = FormBorderStyle.None;
|
||
//填充
|
||
frm.Dock = DockStyle.Fill;
|
||
//设置父容器为容器控件
|
||
frm.Parent = mainPanel;
|
||
|
||
//置前
|
||
frm.BringToFront();
|
||
frm.Show();
|
||
|
||
//// 强制刷新布局
|
||
//mainPanel.PerformLayout();
|
||
//frm.PerformLayout();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 设置导航按钮选中
|
||
/// </summary>
|
||
/// <param name="topPanel">导航按钮的容器</param>
|
||
/// <param name="naviButton">导航按钮</param>
|
||
private void SetNaviButtonSelected(System.Windows.Forms.Panel topPanel, NaviButton2 naviButton)
|
||
{
|
||
foreach (var item in topPanel.Controls.OfType<NaviButton2>())
|
||
{
|
||
// 仅状态变化时更新,避免无意义重绘
|
||
if (item.IsSelected != (item == naviButton))
|
||
{
|
||
item.IsSelected = (item == naviButton);
|
||
}
|
||
}
|
||
//naviButton.IsSelected = true;
|
||
}
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 获取鼠标光标的当前位置
|
||
/// </summary>
|
||
/// <param name="pt"></param>
|
||
/// <returns></returns>
|
||
[DllImport("user32.dll")]
|
||
public static extern bool GetCursorPos(out Point pt);
|
||
|
||
/// <summary>
|
||
/// 刷卡用户登录超时检查
|
||
/// </summary>
|
||
/// <param name="secTime"></param>
|
||
private async void UserTimeOut(int secTime)
|
||
{
|
||
int idleSeconds = 0;
|
||
Point lastCursorPos = Point.Empty;
|
||
GetCursorPos(out lastCursorPos);
|
||
|
||
// 忽略5像素内的微小移动
|
||
const int MOUSE_MOVE_THRESHOLD = 5;
|
||
|
||
while (!CommonMethods.LoginOut && idleSeconds < secTime)
|
||
{
|
||
// 异步延迟1秒,不阻塞线程
|
||
await Task.Delay(1000).ConfigureAwait(false);
|
||
|
||
GetCursorPos(out Point currentCursorPos);
|
||
|
||
// 检测鼠标是否移动(超过阈值才重置)
|
||
int dx = Math.Abs(currentCursorPos.X - lastCursorPos.X);
|
||
int dy = Math.Abs(currentCursorPos.Y - lastCursorPos.Y);
|
||
if (dx > MOUSE_MOVE_THRESHOLD || dy > MOUSE_MOVE_THRESHOLD)
|
||
{
|
||
idleSeconds = 0; // 鼠标移动,重置计时
|
||
lastCursorPos = currentCursorPos;
|
||
}
|
||
else
|
||
{
|
||
idleSeconds++; // 无操作,计时+1
|
||
}
|
||
}
|
||
|
||
// 回到UI线程执行退出逻辑
|
||
if (idleSeconds >= secTime)
|
||
{
|
||
this.BeginInvoke(new Action(() => LoginLocalOut()));
|
||
}
|
||
}
|
||
|
||
private void LoginLocalOut()
|
||
{
|
||
CommonMethods.AddOPLog(false, "退出成功".Translated() + "," + "退出用户".Translated() + $":{CommonMethods.currentAdmin?.LoginName}," + "权限".Translated() + $":{CommonMethods.currentAdmin?.LoginLevel}");
|
||
LogHelper.Instance.WriteLog("用户".Translated() + $":{CommonMethods.currentAdmin?.LoginName} - " + "退出".Translated());
|
||
CommonMethods.LoginOut = true;
|
||
CommonMethods.IsLoginOk = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 切换监控状态
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private async void btToggleMonitor_Click(object sender, EventArgs e)
|
||
{
|
||
AntdUI.Button btn = sender as AntdUI.Button;
|
||
// 先记录按钮的原始引用,避免异步操作中sender失效
|
||
var targetBtn = btn;
|
||
|
||
if (targetBtn.Text == "START")
|
||
{
|
||
// 1. 前置校验.通过SafeInvoke确保UI操作在主线程
|
||
bool isLoginOk = CommonMethods.IsLoginOk;
|
||
bool isMesLoginOk = CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.IsLoginMesOK;
|
||
string modelName = CommonMethods.mesConfig.ModelName;
|
||
string materialCode = "";
|
||
|
||
// 安全获取UI控件值
|
||
SafeInvoke(() =>
|
||
{
|
||
materialCode = txtMaterialCode.Text.Trim();
|
||
});
|
||
|
||
// 登录校验
|
||
if (!isLoginOk)
|
||
{
|
||
SafeInvoke(() =>
|
||
new FrmMsgBoxOutWithAck(2, "当前未登录,请登录!".Translated(), "未登录".Translated()).Show());
|
||
return;
|
||
}
|
||
|
||
// MES模式校验
|
||
if (CommonMethods.sysConfig.MesModeSwitching && !CommonMethods.mesConfig.IsLoginMesOK)
|
||
{
|
||
bool mesLoginSuccess = false;
|
||
SafeInvoke(() =>
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "当前为MES模式,请登录!".Translated(), "MES未登录".Translated()).ShowDialog();
|
||
using (FrmLoginMes frmLoginMes = new FrmLoginMes())
|
||
{
|
||
mesLoginSuccess = frmLoginMes.ShowDialog() == DialogResult.OK;
|
||
}
|
||
});
|
||
if (!mesLoginSuccess) return;
|
||
}
|
||
|
||
// 型号和物料编码校验
|
||
if (string.IsNullOrEmpty(modelName))
|
||
{
|
||
SafeInvoke(() =>
|
||
new FrmMsgBoxOutWithAck(2, "产品型号不能为空!".Translated(), "型号选择".Translated()).Show());
|
||
return;
|
||
}
|
||
if (string.IsNullOrEmpty(materialCode))
|
||
{
|
||
SafeInvoke(() =>
|
||
new FrmMsgBoxOutWithAck(2, "物料编码不能为空!".Translated(), "型号选择".Translated()).Show());
|
||
return;
|
||
}
|
||
|
||
#region MES下发参数
|
||
CommonMethods.mesConfig.MaterialCode = materialCode;
|
||
if (CommonMethods.sysConfig.MesModeSwitching && CommonMethods.mesConfig.IsMesParam)
|
||
{
|
||
var (res, mesg) = await GetMesParaDataAsync().ConfigureAwait(false);
|
||
SafeInvoke(() =>
|
||
{
|
||
if (!res)
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, mesg, "提示").Show();
|
||
}
|
||
else
|
||
{
|
||
CommonMethods.AddDataMonitorLog(1, "MES参数设置成功");
|
||
LogHelper.Instance.WriteLog("MES参数设置成功");
|
||
}
|
||
});
|
||
if (!res) return;
|
||
}
|
||
#endregion
|
||
|
||
// 安全更新UI:开始连接提示
|
||
SafeInvoke(() =>
|
||
{
|
||
CommonMethods.AddDataMonitorLog(0, "启动开始监控".Translated());
|
||
targetBtn.Text = "连接PLC".Translated();
|
||
});
|
||
|
||
// 异步连接PLC(ConfigureAwait(false) 避免捕获当前上下文)
|
||
bool IsLink = await ControlCenter.Instance.ConnectAllPlcsAsync().ConfigureAwait(false);
|
||
|
||
// 所有UI更新必须通过SafeInvoke在主线程执行
|
||
SafeInvoke(() =>
|
||
{
|
||
if (IsLink)
|
||
{
|
||
CommonMethods.IsRun = true;
|
||
targetBtn.Text = "STOP";
|
||
targetBtn.DefaultBack = Color.Red; // 按钮背景变为红色
|
||
targetBtn.IconSvg = Properties.Resources.StopPLC;
|
||
SetProductModelEnable(true);
|
||
}
|
||
else
|
||
{
|
||
targetBtn.Text = "START";
|
||
targetBtn.DefaultBack = Color.FromArgb(18, 184, 61); // 按钮背景恢复绿色
|
||
targetBtn.IconSvg = Properties.Resources.StartPLC;
|
||
CommonMethods.AddDataMonitorLog(2, "启动开始监控失败".Translated());
|
||
new FrmMsgBoxOutWithAck(2, "连接PLC失败,请检查PLC连接配置,网络".Translated(), "连接PLC".Translated()).Show();
|
||
}
|
||
});
|
||
}
|
||
else if (targetBtn.Text == "STOP")
|
||
{
|
||
// 执行停止监控的逻辑
|
||
if (CommonMethods.IsRun)
|
||
{
|
||
|
||
Debug.WriteLine($"Step 1: 开始停止 - {DateTime.Now:HH:mm:ss.fff}");
|
||
|
||
// 第一步:安全更新UI状态(禁用按钮避免重复点击)
|
||
SafeInvoke(() =>
|
||
{
|
||
targetBtn.Enabled = false;
|
||
targetBtn.Text = "停止中...";
|
||
SetProductModelEnable(false);
|
||
});
|
||
|
||
try
|
||
{
|
||
CommonMethods.IsRun = false;
|
||
CommonMethods.Statues = new List<bool> { false, false, false, false };
|
||
|
||
// 第二步:异步停止PLC连接(非UI线程执行)
|
||
await Task.Run(() =>
|
||
{
|
||
Debug.WriteLine($"Step 2: 进入后台线程 - {DateTime.Now:HH:mm:ss.fff}");
|
||
try
|
||
{
|
||
|
||
//ControlCenter.Instance.OnCancellationCompleted += cancellationHandler;
|
||
|
||
// 调用优化后的断开方法
|
||
ControlCenter.Instance.DisconnectAllPlcs();
|
||
Thread.Sleep(100);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"STOP时断开PLC异常:{ex.Message}");
|
||
LogHelper.Instance.WriteEX("STOP PLC异常", ex);
|
||
// 异常时也要取消订阅
|
||
//if (cancellationHandler != null)
|
||
//{
|
||
// ControlCenter.Instance.OnCancellationCompleted -= cancellationHandler;
|
||
//}
|
||
}
|
||
Debug.WriteLine($"Step 3: 断开完成 - {DateTime.Now:HH:mm:ss.fff}");
|
||
}).ConfigureAwait(false);
|
||
|
||
Debug.WriteLine($"Step 4: 返回UI线程 - {DateTime.Now:HH:mm:ss.fff}");
|
||
// 第三步:安全更新UI
|
||
SafeInvoke(() =>
|
||
{
|
||
Debug.WriteLine($"Step 5: 执行UI更新 - {DateTime.Now:HH:mm:ss.fff}");
|
||
CommonMethods.AddDataMonitorLog(0, "停止与PLC连接".Translated());
|
||
CommonMethods.AddOPLog(false, "停止与PLC连接".Translated());
|
||
|
||
// 恢复按钮状态
|
||
targetBtn.Text = "START";
|
||
targetBtn.DefaultBack = Color.FromArgb(18, 184, 61);
|
||
targetBtn.IconSvg = Properties.Resources.StartPLC;
|
||
targetBtn.Enabled = true;
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
CommonMethods.AddDataMonitorLog(2, $"停止失败: {ex.Message}");
|
||
|
||
// 恢复按钮状态
|
||
targetBtn.Text = "STOP";
|
||
targetBtn.DefaultBack = Color.Red;
|
||
targetBtn.IconSvg = Properties.Resources.StopPLC;
|
||
targetBtn.Enabled = true;
|
||
|
||
new FrmMsgBoxOutWithAck(2, "停止PLC失败,请重试".Translated(), "错误".Translated()).Show();
|
||
});
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
private void ToolStripMenuItem_Click(object sender, EventArgs e)
|
||
{
|
||
FrmLogin frmLogin = new FrmLogin();
|
||
if (frmLogin.ShowDialog() == DialogResult.OK)
|
||
{
|
||
CommonMethods.sysConfig.SwipeCardMode = false;
|
||
IniConfigHelper.WriteIniData("配置信息", "开启刷卡模式", CommonMethods.sysConfig.SwipeCardMode.ToString());
|
||
lbl_LoginLevel.Text = CommonMethods.currentAdmin?.LoginLevel;
|
||
lbl_LoginName.Text = CommonMethods.currentAdmin?.LoginName;
|
||
lbl_LoginName.Visible = true;
|
||
//登录日志
|
||
CommonMethods.AddOPLog(false, $"登录成功,登录用户:{CommonMethods.currentAdmin?.LoginName},权限:{CommonMethods.currentAdmin?.LoginLevel}");
|
||
}
|
||
}
|
||
|
||
private void cmbModelType_Enter(object sender, EventArgs e)
|
||
{
|
||
if (cmbModelType.SelectedItem != null)
|
||
{
|
||
int index = CommonMethods.DropDownItemList.IndexOf(cmbModelType.SelectedItem);
|
||
if (index == -1)
|
||
cmbModelType.SelectedItem = null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置产品型号和工单是否只读
|
||
/// </summary>
|
||
/// <param name="b"></param>
|
||
public void SetProductModelEnable(bool b)
|
||
{
|
||
cmbModelType.Enabled = b;
|
||
}
|
||
|
||
|
||
#region 获取参数
|
||
/// <summary>
|
||
/// 从数据库获取产品型号并绑定到下拉框中
|
||
/// </summary>
|
||
///
|
||
bool IsModelInit = false;
|
||
public void SetCombOrg()
|
||
{
|
||
try
|
||
{
|
||
txtMaterialCode.Text = "";
|
||
CommonMethods.mesConfig.MaterialCode = "";
|
||
var productList = CommonMethods.db.QuerySqlList<ProductModel>(CommonMethods.dBSQL.GetProdTypeSql());
|
||
if (!IsModelInit)
|
||
{
|
||
CommonMethods.DropDownItemList.Clear();
|
||
for (int i = 0; i < productList.Count; i++)
|
||
{
|
||
CommonMethods.DropDownItemList.Add(new DropDownListPlusItem() { Text = productList[i].ModelName, Tag = productList[i].MaterialCode });
|
||
}
|
||
this.cmbModelType.BindItemsSource(CommonMethods.DropDownItemList);
|
||
IsModelInit = true;
|
||
}
|
||
|
||
if (productList != null && productList.Count > 0)
|
||
{
|
||
CommonMethods.mesConfig.ModelName = "";
|
||
CommonMethods.mesConfig.MaterialCode = "";
|
||
DropDownListPlusItem gg = cmbModelType.SelectedItem;
|
||
if (gg != null)
|
||
{
|
||
CommonMethods.mesConfig.ModelName = gg.Text.ToString();
|
||
CommonMethods.mesConfig.MaterialCode = gg.Tag.ToString();
|
||
txtMaterialCode.Text = CommonMethods.mesConfig.MaterialCode;
|
||
}
|
||
}
|
||
}
|
||
|
||
catch (Exception ex)
|
||
{
|
||
//LogHelper.Instance.WriteEx("获取数据库型号异常", ex);
|
||
MessageBox.Show($"获取数据库型号异常:{ex}");
|
||
}
|
||
}
|
||
|
||
private void cmbModelType_SelectedItemsChanged(object sender, EventArgs e)
|
||
{
|
||
if (IsNoOrg && CommonMethods.IsLoginOk)
|
||
{
|
||
btToggleMonitor.Enabled = true;
|
||
IsSetParam = false;
|
||
SetCombOrg();
|
||
GetLocalParaData();
|
||
}
|
||
else
|
||
{
|
||
this.cmbModelType.BindItemsSource(null);
|
||
IsModelInit = false;
|
||
SetCombOrg();
|
||
new FrmMsgBoxOutWithAck(2, "当前未登录,请先登录再操作!", "提示").ShowDialog();
|
||
}
|
||
}
|
||
|
||
public void GetLocalParaData()
|
||
{
|
||
if (string.IsNullOrEmpty(CommonMethods.mesConfig.ModelName))
|
||
{
|
||
new FrmMsgBoxOutWithAck(2, "产品型号不能为空!", "型号选择").Show();
|
||
return;
|
||
}
|
||
try
|
||
{
|
||
var list = CommonMethods.db.QuerySqlList<ParamList>(CommonMethods.dBSQL.GetParamSql(CommonMethods.mesConfig.ModelName));
|
||
if (list != null && list.Count > 0)
|
||
{
|
||
CommonMethods.paramlists = list;
|
||
IsSetParam = false;
|
||
CommonMethods.ChangeParamData();
|
||
//GetParam();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogHelper.Instance.WriteEX(ex);
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 刷新参数
|
||
/// </summary>
|
||
//public void GetParam()
|
||
//{
|
||
// try
|
||
// {
|
||
// if (!IsSetParam && CommonMethods.paramlists != null)
|
||
// {
|
||
// System.Windows.Forms.ListViewItem listItem = null;
|
||
// lVConfigRange.Items.Clear();
|
||
// int j = 0;
|
||
// foreach (var ProductPara in CommonMethods.paramlists) //遍历list集合
|
||
// {
|
||
// string strRemark = ProductPara.Remark;
|
||
// string strName = ProductPara.ParaName;
|
||
// listItem = new System.Windows.Forms.ListViewItem(CommonMethods.paramlists[j].Remark);
|
||
// listItem.SubItems.Add("0");
|
||
// listItem.SubItems.Add("0");
|
||
// listItem.SubItems.Add("0");
|
||
// lVConfigRange.Items.Add(listItem);
|
||
// lVConfigRange.Items[j].SubItems[1].Text = ProductPara.ParaValueMin;
|
||
// lVConfigRange.Items[j].SubItems[2].Text = ProductPara.ParaValueMax;
|
||
// lVConfigRange.Items[j].SubItems[3].Text = ProductPara.Uint;
|
||
// switch (strName)
|
||
// {
|
||
// //case "intoShellPressure1SettingA07": //入壳压力1
|
||
// // CommonMethods.parRange.PrePressure1Max = Convert.ToDecimal(ProductPara.ParaValueMax == "" ? "0" : ProductPara.ParaValueMax);
|
||
// // break;
|
||
// //case "intoShellPressure2SettingA07": //入壳压力2
|
||
// // CommonMethods.parRange.PrePressure2Max = Convert.ToDecimal(ProductPara.ParaValueMax == "" ? "0" : ProductPara.ParaValueMax);
|
||
// // break;
|
||
// //case "intoShellPressure3SettingA07": //入壳压力3
|
||
// // CommonMethods.parRange.PrePressure3Max = Convert.ToDecimal(ProductPara.ParaValueMax == "" ? "0" : ProductPara.ParaValueMax);
|
||
// // break;
|
||
// //default:
|
||
// // break;
|
||
|
||
// }
|
||
// j++;
|
||
// }
|
||
// IsSetParam = true;
|
||
// }
|
||
// }
|
||
// catch (Exception ex)
|
||
// {
|
||
|
||
// LogHelper.Instance.WriteEX("获取参数失败", ex);
|
||
// }
|
||
//}
|
||
|
||
/// <summary>
|
||
/// 加载MES参数
|
||
/// </summary>
|
||
public async Task<(bool Success, string msg)> GetMesParaDataAsync()
|
||
{
|
||
bool Success = false; // 操作结果
|
||
string Message = ""; // 消息
|
||
|
||
try
|
||
{
|
||
bool isChangeParam = false;
|
||
var nowDate = DateTime.Now;
|
||
|
||
string filePath = $@"{CommonMethods.strMesLogspath}\参数设定值请求\变更记录\{nowDate.Year}\{nowDate.Month}";
|
||
string fileName = $@"{nowDate.Day}.csv";
|
||
string fileTitle = "时间,机台,MES账户,更改参数名称,更改前参数值,更改后参数值";
|
||
string fileContent = string.Empty;
|
||
|
||
DataTable dt = new DataTable();
|
||
dt.Columns.Add("MES账户");
|
||
dt.Columns.Add("更改参数名称");
|
||
dt.Columns.Add("更改前参数值");
|
||
dt.Columns.Add("更改后参数值");
|
||
|
||
var (resultData, Mesage) = await CommonMethods.hbgMes.GetParamSetRequestAsync(
|
||
CommonMethods.mesConfig.DeviceParamChange,
|
||
CommonMethods.mesConfig.equipNum,
|
||
CommonMethods.mesConfig.siteCode,
|
||
CommonMethods.mesConfig.lineCode,
|
||
CommonMethods.mesConfig.MaterialCode,
|
||
CommonMethods.mesConfig.mesUserName).ConfigureAwait(false);
|
||
|
||
//var resultData = JsonConvert.DeserializeObject<ParamReturnData>(Data);
|
||
if (!resultData.success)
|
||
{
|
||
// 获取参数未成功
|
||
Message = "获取MES参数不成功!";
|
||
return (Success, Message);
|
||
}
|
||
|
||
List<ParamList> NewParamlists = CommonMethods.paramlists;
|
||
for (int i = 0; i < resultData.total; i++)
|
||
{
|
||
List<RowsItem> rows = resultData.rows;
|
||
for (int j = 0; j < rows.Count; j++)
|
||
{
|
||
var tagList = rows[j].tagList;
|
||
for (int k = 0; k < NewParamlists.Count; k++)
|
||
{
|
||
for (int n = 0; n < rows[j].tagList.Count; n++)
|
||
{
|
||
if (NewParamlists[k].ParaName == tagList[n].tagCode)
|
||
{
|
||
string strMin = "0";
|
||
if (String.IsNullOrEmpty(tagList[n].minValue.Trim()) || tagList[n].minValue.Trim() == "null")
|
||
strMin = "0";
|
||
else
|
||
strMin = tagList[n].minValue.Trim();
|
||
if (NewParamlists[k].ParaValueMin != strMin)
|
||
{
|
||
fileContent += $"{nowDate.ToString("yyyy-MM-dd HH:mm:ss")},{CommonMethods.mesConfig.equipNum}," +
|
||
$"{CommonMethods.mesConfig.mesUserName},{tagList[n].tagDescription}最小值,{NewParamlists[k].ParaValueMin},{strMin}\n";
|
||
dt.Rows.Add(CommonMethods.mesConfig.mesUserName, $"{tagList[n].tagDescription}最小值", NewParamlists[k].ParaValueMin, strMin);
|
||
NewParamlists[k].ParaValueMin = strMin;
|
||
isChangeParam = true;
|
||
}
|
||
string strMax = "0";
|
||
if (String.IsNullOrEmpty(tagList[n].maxValue.Trim()) || tagList[n].maxValue.Trim() == "null")
|
||
strMax = "0";
|
||
else
|
||
strMax = tagList[n].maxValue.Trim();
|
||
if (NewParamlists[k].ParaValueMax != tagList[n].maxValue)
|
||
{
|
||
fileContent += $"{nowDate.ToString("yyyy-MM-dd HH:mm:ss")},{CommonMethods.mesConfig.equipNum}," +
|
||
$"{CommonMethods.mesConfig.mesUserName},{tagList[n].tagDescription}最大值,{NewParamlists[k].ParaValueMax},{strMax}\n";
|
||
dt.Rows.Add(CommonMethods.mesConfig.mesUserName, $"{tagList[n].tagDescription}最大值", NewParamlists[k].ParaValueMax, strMax);
|
||
NewParamlists[k].ParaValueMax = strMax;
|
||
isChangeParam = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (isChangeParam)
|
||
{
|
||
CustomMessageBox customMessageBox = new CustomMessageBox(dt, $"当前MES下发参数与设备本地参数不一致,请确认是否使用MES下发参数");
|
||
if (customMessageBox.ShowDialog() == DialogResult.OK)
|
||
{
|
||
// 写csv文件
|
||
fileContent = fileContent.Substring(0, fileContent.Length - 1);
|
||
CSVHelper<object>.WriterCSV(filePath, fileName, fileTitle, fileContent);
|
||
CommonMethods.paramlists = NewParamlists;
|
||
int res = CommonMethods.db.Delete<ParamList>(it => it.ModelName == CommonMethods.paramlists[0].ModelName);
|
||
if (res > 0)
|
||
{
|
||
CommonMethods.db.AddReturnBool<ParamList>(CommonMethods.paramlists);
|
||
}
|
||
Message = "变更成功并保存";
|
||
Success = true;
|
||
}
|
||
else
|
||
{
|
||
Message = "取消变更,采用本地参数配置";
|
||
}
|
||
LogHelper.Instance.WriteLog(Message);
|
||
}
|
||
}
|
||
}
|
||
|
||
Success = true; // 操作成功
|
||
Message = "参数获取成功";
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Message = "获取参数失败:" + ex.Message;
|
||
LogHelper.Instance.WriteEX("获取参数失败", ex);
|
||
}
|
||
|
||
return (Success, Message);
|
||
}
|
||
|
||
#endregion
|
||
|
||
private void InitializeLanguageSwitch()
|
||
{
|
||
SwitchLanguage.Items.Clear();
|
||
SwitchLanguage.Items.Add(new SelectItem(Properties.Resources.中国国旗, "中文"));
|
||
SwitchLanguage.Items.Add(new SelectItem(Properties.Resources.美国国旗, "English"));
|
||
SwitchLanguage.Items.Add(new SelectItem(Properties.Resources.匈牙利国旗, "Hungary"));
|
||
SwitchLanguage.Items.Add(new SelectItem(Properties.Resources.马来西亚国旗, "Malaysia"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 切换语言
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void SwitchLanguage_SelectedValueChanged(object sender, ObjectNEventArgs e)
|
||
{
|
||
if (e.Value is SelectItem selectedItem)
|
||
{
|
||
string selectedLanguage = selectedItem.Text;
|
||
string languageCode = selectedLanguage switch
|
||
{
|
||
"中文" => "zh",
|
||
"English" => "en",
|
||
"Hungary" => "hu",
|
||
"Malaysia" => "ms",
|
||
_ => "zh"
|
||
};
|
||
LanguageManager.ChangeLanguage(languageCode);
|
||
|
||
DgvColumnsClear();
|
||
//DgvShiftItemsChange();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清除dgv内容
|
||
/// </summary>
|
||
public void DgvColumnsClear()
|
||
{
|
||
//清除
|
||
if (FrmHistory._Form != null)
|
||
{
|
||
// 进出站
|
||
if (FrmHistory._Form.dgv_Main.Columns != null)
|
||
{
|
||
if (FrmHistory._Form.dgv_Main.Columns.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgv_Main.Columns.Clear();
|
||
}
|
||
}
|
||
if (FrmHistory._Form.dgv_Main.Rows != null)
|
||
{
|
||
if (FrmHistory._Form.dgv_Main.Rows.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgv_Main.Rows.Clear();
|
||
}
|
||
}
|
||
// 班次
|
||
if (FrmHistory._Form.dgvClass.Columns != null)
|
||
{
|
||
if (FrmHistory._Form.dgvClass.Columns.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvClass.Columns.Clear();
|
||
}
|
||
}
|
||
if (FrmHistory._Form.dgvClass.Rows != null)
|
||
{
|
||
if (FrmHistory._Form.dgvClass.Rows.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvClass.Rows.Clear();
|
||
}
|
||
}
|
||
// 日
|
||
if (FrmHistory._Form.dgvDays.Columns != null)
|
||
{
|
||
if (FrmHistory._Form.dgvDays.Columns.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvDays.Columns.Clear();
|
||
}
|
||
}
|
||
if (FrmHistory._Form.dgvDays.Rows != null)
|
||
{
|
||
if (FrmHistory._Form.dgvDays.Rows.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvDays.Rows.Clear();
|
||
}
|
||
}
|
||
// 月
|
||
if (FrmHistory._Form.dgvMonth.Columns != null)
|
||
{
|
||
if (FrmHistory._Form.dgvMonth.Columns.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvMonth.Columns.Clear();
|
||
}
|
||
}
|
||
if (FrmHistory._Form.dgvMonth.Rows != null)
|
||
{
|
||
if (FrmHistory._Form.dgvMonth.Rows.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvMonth.Rows.Clear();
|
||
}
|
||
}
|
||
// 周
|
||
if (FrmHistory._Form.dgvWeek.Columns != null)
|
||
{
|
||
if (FrmHistory._Form.dgvWeek.Columns.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvWeek.Columns.Clear();
|
||
}
|
||
}
|
||
if (FrmHistory._Form.dgvWeek.Rows != null)
|
||
{
|
||
if (FrmHistory._Form.dgvWeek.Rows.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgvWeek.Rows.Clear();
|
||
}
|
||
}
|
||
// 报警信息
|
||
if (FrmHistory._Form.dgv_AlarmData.Columns != null)
|
||
{
|
||
if (FrmHistory._Form.dgv_AlarmData.Columns.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgv_AlarmData.Columns.Clear();
|
||
}
|
||
}
|
||
if (FrmHistory._Form.dgv_AlarmData.Rows != null)
|
||
{
|
||
if (FrmHistory._Form.dgv_AlarmData.Rows.Count > 0)
|
||
{
|
||
FrmHistory._Form.dgv_AlarmData.Rows.Clear();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 下拉框语言切换
|
||
/// </summary>
|
||
public void DgvShiftItemsChange()
|
||
{
|
||
if (FrmHistory._Form != null)
|
||
{
|
||
FrmHistory._Form.cmb_SelectType.Items.Clear();
|
||
FrmHistory._Form.cmb_SelectType.Items.AddRange(new string[] { /*"托盘码打印".Translated(),*/ "电池进站".Translated(), "电池与托盘绑定".Translated(), "电池替换".Translated() });
|
||
FrmHistory._Form.cmb_SelectType.SelectedIndex = 0;
|
||
|
||
FrmHistory._Form.cmbClass.Items.Clear();
|
||
FrmHistory._Form.cmbClass.Items.AddRange(new string[] { "白班".Translated(), "夜班".Translated() });
|
||
FrmHistory._Form.cmbClass.SelectedIndex = 0;
|
||
|
||
FrmHistory._Form.cmb_AlarmType.Items.Clear();
|
||
FrmHistory._Form.cmb_AlarmType.Items.AddRange(new string[] { "全天".Translated(), "白班".Translated(), "夜班".Translated() });
|
||
FrmHistory._Form.cmb_AlarmType.SelectedIndex = 0;
|
||
}
|
||
}
|
||
|
||
|
||
private string FormatBarcode(string barcode)
|
||
{
|
||
if (string.IsNullOrEmpty(barcode)) return string.Empty;
|
||
int index = barcode.IndexOf('\0');
|
||
if (index >= 0)
|
||
barcode = barcode.Substring(0, index);
|
||
return barcode.Replace("\0", "").Replace("\r", "").Replace(" ", "").Trim();
|
||
}
|
||
}
|
||
|
||
#region 枚举定义
|
||
public enum FormNames
|
||
{
|
||
集中监控,
|
||
数据监控,
|
||
电池状况,
|
||
日志报警,
|
||
临界窗体,
|
||
数据追溯,
|
||
参数设置,
|
||
系统设置,
|
||
用户管理,
|
||
//二维码
|
||
}
|
||
#endregion
|
||
|
||
#region 消息筛选器
|
||
internal class MessageFilter : IMessageFilter
|
||
{
|
||
//0x0200:鼠标移动
|
||
//0x0202:鼠标左键UP
|
||
//0x201:鼠标左键Down
|
||
//0x0203:鼠标左键双击
|
||
//0x0205:鼠标右键UP
|
||
//0x0204:鼠标右键Down
|
||
//0x020a:鼠标滚轮
|
||
//0x100:键盘按下
|
||
public bool PreFilterMessage(ref System.Windows.Forms.Message m)
|
||
{
|
||
//throw new NotImplementedException();
|
||
if (m.Msg == 0x0200 || m.Msg == 0x0202 || m.Msg == 0x201 || m.Msg == 0x0203 || m.Msg == 0x0205 || m.Msg == 0x204 || m.Msg == 0x20a || m.Msg == 0x100)
|
||
{
|
||
CommonMethods.tickCount = 0;
|
||
CommonMethods.tickHomeCount = 0;
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
|
||
|
||
|
||
}
|