diff --git a/BPASmartClient.ScreenALL/App.config b/BPASmartClient.ScreenALL/App.config new file mode 100644 index 00000000..04466302 --- /dev/null +++ b/BPASmartClient.ScreenALL/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/BPASmartClient.ScreenALL/App.xaml b/BPASmartClient.ScreenALL/App.xaml new file mode 100644 index 00000000..ac841497 --- /dev/null +++ b/BPASmartClient.ScreenALL/App.xaml @@ -0,0 +1,8 @@ + + + + + diff --git a/BPASmartClient.ScreenALL/App.xaml.cs b/BPASmartClient.ScreenALL/App.xaml.cs new file mode 100644 index 00000000..09a4aadc --- /dev/null +++ b/BPASmartClient.ScreenALL/App.xaml.cs @@ -0,0 +1,27 @@ +using BPASmartClient.ScreenLib; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace BPASmartClient.ScreenALL +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + AppMain appMain = new AppMain(MainWindow, this.GetType()); + } + protected override void OnExit(ExitEventArgs e) + { + base.OnExit(e); + } + } +} diff --git a/BPASmartClient.ScreenALL/AssemblyInfo.cs b/BPASmartClient.ScreenALL/AssemblyInfo.cs new file mode 100644 index 00000000..8b5504ec --- /dev/null +++ b/BPASmartClient.ScreenALL/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/BPASmartClient.ScreenALL/BPASmartClient.ScreenALL.csproj b/BPASmartClient.ScreenALL/BPASmartClient.ScreenALL.csproj new file mode 100644 index 00000000..e66c9b2f --- /dev/null +++ b/BPASmartClient.ScreenALL/BPASmartClient.ScreenALL.csproj @@ -0,0 +1,24 @@ + + + + WinExe + net6.0-windows + enable + true + 总监控大屏 + hbl.ico + + + + + + + + + + + + Always + + + diff --git a/BPASmartClient.ScreenALL/hbl.ico b/BPASmartClient.ScreenALL/hbl.ico new file mode 100644 index 00000000..cf89051a Binary files /dev/null and b/BPASmartClient.ScreenALL/hbl.ico differ diff --git a/BPASmartClient.ScreenLib/AppMain.cs b/BPASmartClient.ScreenLib/AppMain.cs new file mode 100644 index 00000000..d49e53f5 --- /dev/null +++ b/BPASmartClient.ScreenLib/AppMain.cs @@ -0,0 +1,56 @@ +using BPA.CustomResource.UserControls; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Forms; + +namespace BPASmartClient.ScreenLib +{ + public partial class AppMain + { + public AppMain(Window window, Type type) + { + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + FSystemHelper.GetInstance.CreateDesktopShortcut(); + WindowLargeScreen windowLarge = new WindowLargeScreen(); + #region 设置显示页面与标题 + string TitleName = $"{type.Assembly.ManifestModule.Name.Replace(".dll", "")}"; + string name= type.FullName.Split('.')[2]; + string sbmc=string.Empty; + switch (type.FullName) + { + case "BPASmartClient.ScreenALL.App": + windowLarge.Init(TitleName, new ScreenALLControl()); windowLarge.Show(); + break; + case "BPASmartClient.ScreenMaxWok.App": + windowLarge.Init(TitleName, new ScreenMaxWokControl()); windowLarge.Show(); + break; + case "BPASmartClient.ScreenMinWok.App": + windowLarge.Init(TitleName, new ScreenMinWokControl()); windowLarge.Show(); + break; + case "BPASmartClient.ScreenMorks.App": + windowLarge.Init(TitleName, new ScreenMorksControl()); windowLarge.Show(); + break; + case "BPASmartClient.ScreenSplitMeals.App": + ScreenSplitMealsControl1 ScreenSplit=new ScreenSplitMealsControl1(); + windowLarge.Init("一号" + TitleName, ScreenSplit); + windowLarge.Show(); + ScreenSplit.Start(TitleName); + break; + } + #endregion + window = windowLarge; + Main main = new Main(); + main.Start(); + } + + private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + + } + + } +} diff --git a/BPASmartClient.ScreenLib/AssemblyInfo.cs b/BPASmartClient.ScreenLib/AssemblyInfo.cs new file mode 100644 index 00000000..8b5504ec --- /dev/null +++ b/BPASmartClient.ScreenLib/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/BPASmartClient.ScreenLib/BPASmartClient.ScreenLib.csproj b/BPASmartClient.ScreenLib/BPASmartClient.ScreenLib.csproj new file mode 100644 index 00000000..1a104f1b --- /dev/null +++ b/BPASmartClient.ScreenLib/BPASmartClient.ScreenLib.csproj @@ -0,0 +1,26 @@ + + + + net6.0-windows + enable + true + + + + + tlbimp + 0 + 1 + f935dc20-1cf0-11d0-adb9-00c04fd58a0b + 0 + false + true + true + + + + + + + + diff --git a/BPASmartClient.ScreenLib/Helper/FSystemHelper.cs b/BPASmartClient.ScreenLib/Helper/FSystemHelper.cs new file mode 100644 index 00000000..79b3b61e --- /dev/null +++ b/BPASmartClient.ScreenLib/Helper/FSystemHelper.cs @@ -0,0 +1,238 @@ +using BPA.Helper; +using IWshRuntimeLibrary; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.ScreenLib +{ + /// + /// 系统操作类 + /// + public class FSystemHelper + { + private volatile static FSystemHelper _Instance; + public static FSystemHelper GetInstance => _Instance ?? (_Instance = new FSystemHelper()); + private FSystemHelper() { } + + /// + /// 获取当前应用程序名称,包括后缀名 + /// + public string GetApplicationName => $"{AppDomain.CurrentDomain.FriendlyName}.exe"; + + /// + /// 获取当前应用程序完整路径 + /// + public string GetApplicationPath => $"{AppDomain.CurrentDomain.BaseDirectory}{GetApplicationName}"; + + /// + /// 创建桌面快捷方式 + /// + /// 成功或失败 + public bool CreateDesktopShortcut() + { + //1、在COM对象中找到 Windows Script Host Object Model + //2、添加引用 using IWshRuntimeLibrary; + string deskTop = string.Empty; + try + { + deskTop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\"; + if (System.IO.File.Exists(deskTop + GetApplicationName + ".lnk")) // + { + return true; + //System.IO.File.Delete(deskTop + FileName + ".lnk");//删除原来的桌面快捷键方式 + } + WshShell shell = new WshShell(); + //快捷键方式创建的位置、名称 + IWshShortcut shortcut = shell.CreateShortcut(deskTop + GetApplicationName + ".lnk") as IWshShortcut; + shortcut.TargetPath = GetApplicationPath; //目标文件 + //该属性指定应用程序的工作目录,当用户没有指定一个具体的目录时,快捷方式的目标应用程序将使用该属性所指定的目录来装载或保存文件。 + shortcut.WorkingDirectory = System.Environment.CurrentDirectory; + shortcut.WindowStyle = 1; //目标应用程序的窗口状态分为普通、最大化、最小化【1,3,7】 + shortcut.Description = GetApplicationName; //描述 + //shortcut.IconLocation = exePath + "\\logo.ico"; //快捷方式图标 + shortcut.Arguments = ""; + //shortcut.Hotkey = "CTRL+ALT+F11"; // 快捷键 + shortcut.Save(); //必须调用保存快捷才成创建成功 + return true; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx(ex.ToString()); + return false; + } + } + + /// + /// 设置开机自启动 + /// + /// true:开机启动,false:不开机自启 + public void AutoStart(bool isAuto = true) + { + if (isAuto == true) + { + RegistryKey R_local = Registry.CurrentUser; + RegistryKey R_run = R_local.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + R_run.SetValue(GetApplicationName, GetApplicationPath); + R_run.Close(); + R_local.Close(); + } + else + { + RegistryKey R_local = Registry.CurrentUser; + RegistryKey R_run = R_local.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + R_run.DeleteValue(GetApplicationName, false); + R_run.Close(); + R_local.Close(); + } + } + + /// + /// 判断是否是自动启动 + /// + /// + public bool IsAutoStart() + { + RegistryKey R_local = Registry.CurrentUser; + RegistryKey R_run = R_local.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); + bool res = R_run.GetValueNames().Contains(GetApplicationName); + R_run.Close(); + R_local.Close(); + return res; + } + + #region U盘,串口插拔信息 + private const int WM_DEVICECHANGE = 0x219; //设备改变 + private const int DBT_DEVICEARRIVAL = 0x8000; //检测到新设备 + private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; //移除设备 + public const int DBT_DEVTYP_PORT = 0x00000003; + public const int DBT_DEVTYP_VOLUME = 0x00000002; + + public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + if (msg == WM_DEVICECHANGE) + { + //插入 + if (wParam.ToInt32() == DBT_DEVICEARRIVAL) + { + var volume = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_HDR)); + + switch (volume.dbch_devicetype) + { + case DBT_DEVTYP_PORT://串口设备 + string portName = Marshal.PtrToStringUni(lParam + Marshal.SizeOf(typeof(DEV_BROADCAST_PORT))); + MessageLog.GetInstance.Show($"插入串口:[{portName}]"); + break; + case DBT_DEVTYP_VOLUME: + var drive = GetDrive(lParam); + MessageLog.GetInstance.Show($"usb插入:[{drive}]"); + break; + default: + break; + } + } + + //拔出 + if (wParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE) + { + var volume = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_HDR)); + switch (volume.dbch_devicetype) + { + case DBT_DEVTYP_PORT://串口设备 + string portName = Marshal.PtrToStringUni(lParam + Marshal.SizeOf(typeof(DEV_BROADCAST_PORT))); + MessageLog.GetInstance.Show($"拔出串口:[{portName}]"); + break; + case DBT_DEVTYP_VOLUME: + var drive = GetDrive(lParam); + MessageLog.GetInstance.Show($"usb拔出:[{drive}]"); + break; + default: + break; + } + } + } + return IntPtr.Zero; + } + + private static string GetDrive(IntPtr lParam) + { + var volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_VOLUME)); + var letter = GetLetter(volume.dbcv_unitmask); + return string.Format("{0}:\\", letter); + } + + /// + /// 获得盘符 + /// + /// + /// 1 = A + /// 2 = B + /// 4 = C... + /// + /// 结果是A~Z的任意一个字符或者为'?' + private static char GetLetter(uint dbcvUnitmask) + { + const char nona = '?'; + const string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (dbcvUnitmask == 0) return nona; + var i = 0; + var pom = dbcvUnitmask >> 1; + while (pom != 0) + { + pom = pom >> 1; + i++; + } + if (i < drives.Length) + return drives[i]; + return nona; + } + + + #endregion + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_HDR + { + public UInt32 dbch_size; + public UInt32 dbch_devicetype; + public UInt32 dbch_reserved; + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_PORT + { + public uint dbcp_size; + public uint dbcp_devicetype; + public uint dbcp_reserved; + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_PORT_A + { + public uint dbcp_size; + public uint dbcp_devicetype; + public uint dbcp_reserved; + //public string dbcp_name; + } + + [StructLayout(LayoutKind.Sequential)] + struct DEV_BROADCAST_VOLUME + { + /// DWORD->unsigned int + public uint dbcv_size; + /// DWORD->unsigned int + public uint dbcv_devicetype; + /// DWORD->unsigned int + public uint dbcv_reserved; + /// DWORD->unsigned int + public uint dbcv_unitmask; + /// WORD->unsigned short + public ushort dbcv_flags; + } +} diff --git a/BPASmartClient.ScreenLib/Helper/Main.cs b/BPASmartClient.ScreenLib/Helper/Main.cs new file mode 100644 index 00000000..83d5f579 --- /dev/null +++ b/BPASmartClient.ScreenLib/Helper/Main.cs @@ -0,0 +1,206 @@ +using BPA.Communication; +using BPA.Helper; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BPASmartClient.ScreenLib +{ + /// + /// 主函数 + /// + public class Main + { + #region 接口继承变量 + /// + /// Redis连接信息 + /// + public string RedisConnection { get; set; } + /// + /// 业务名称 + /// + private string _Name = string.Empty; + public string Name + { + get { return _Name; } + set + { + _Name = value; + ThreadServer(); + } + } + /// + /// 是否自动重启(出现健康检查未通过时) + /// + public bool AutoRestart { get; set; } + #endregion + + #region 自建变量 + /// + /// 是否运行 + /// + public bool IsRunning { get; set; } + /// + /// Redis是否运行 + /// + public bool IsRunningReids => RedisHelper.GetInstance.IsConnected(); + /// + /// 主函数 + /// + private static volatile Main _Instance; + public static Main GetInstance => _Instance ?? (_Instance = new Main()); + public Main() { + RedisConnection= System.Configuration.ConfigurationManager.AppSettings["RedisConnection"].ToString(); + Name = System.Configuration.ConfigurationManager.AppSettings["DeviceMC"].ToString(); + } + /// + /// 设备数据 + /// + public List reeisDatas { get; set; } = new List(); + /// + /// 告警数据 + /// + public List reeisDatasAic { get; set; } = new List(); + #endregion + + #region 线程处理函数 + /// + /// 线程服务 + /// + public void ThreadServer() + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + try + { + if (IsRunning && IsRunningReids) + { + //1.读取Redis变量 + List Values = RedisHelper.GetInstance.Read>($"{Name}[Device]").Content; + List reeisDatasAic = RedisHelper.GetInstance.Read>($"{Name}[Alarm]").Content; + } + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"{Name}:线程服务异常,原因:{ex.Message}"); + } + Thread.Sleep(100); + }), $"{Name},线程服务"); + } + #endregion + + #region 启动、停止、健康检查 + /// + /// 开始服务 + /// + public void Start() + { + try + { + //连接MQTT、Redis + Connection(); + IsRunning = true; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"{Name}:MQTT或者Redis启动时,连接失败,原因:{ex.Message}"); + } + } + /// + /// 停止服务 + /// + public void Stop() + { + try + { + //0.设置运行标志 + IsRunning = false; + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"{Name}:MQTT或者Redis停止时异常,原因:{ex.Message}"); + } + } + /// + /// 健康检查 + /// + /// + /// + public bool Check(out string msg) + { + string msgage = string.Empty; + bool IsTrue = false; + if (IsRunningReids && IsRunning) + IsTrue = true; + else + { + if (!IsRunningReids) + msgage += "Redis断开连接."; + IsTrue = false; + msgage = $"{Name}:健康检查失败,原因:{msgage}"; + } + msg = msgage; + return IsTrue; + } + #endregion + + #region 调用事件 + /// + /// 初始化连接Redis MQTT + /// + public void Connection() + { + try + { + //1.连接Redis,如果已经连接过了 那么自动不会去连接 + if (!string.IsNullOrEmpty(this.RedisConnection) && this.RedisConnection.Contains(',')) + { + string[] rediscom = this.RedisConnection.Split(','); + if (rediscom != null && rediscom.Count() == 4) + RedisHelper.GetInstance.Connect(new ConfigurationOptions() + { + ServerAddress = $"{rediscom[0]}:{int.Parse(rediscom[1])}", + Password = rediscom[2] + }); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.ShowEx($"{Name}:初始化连接Redis MQTT,原因:{ex.Message}"); + } + + } + #endregion + } + + + /// + /// Redis 数据存储格式 + /// + public class RedisDataModel + { + public string VarName { get; set; } + public string VarVaule { get; set; } + public EDataType DataType { get; set; } + } + + /// + /// 数据类型枚举 + /// + public enum EDataType + { + Bool = 1, + Byte = 2, + Int = 3, + Word = 4, + Dint = 5, + Dword = 6, + Float = 7, + Double = 8, + String = 9, + } +} diff --git a/BPASmartClient.ScreenLib/Model/DevRunStatus.cs b/BPASmartClient.ScreenLib/Model/DevRunStatus.cs new file mode 100644 index 00000000..33366505 --- /dev/null +++ b/BPASmartClient.ScreenLib/Model/DevRunStatus.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.ScreenLib +{ + public enum DevRunStatus + { + 正常, + 异常 + } + + public enum DevIsRun + { + 运行, + 停止 + } +} diff --git a/BPASmartClient.ScreenLib/Model/OrderMakeModel.cs b/BPASmartClient.ScreenLib/Model/OrderMakeModel.cs new file mode 100644 index 00000000..42adb5b8 --- /dev/null +++ b/BPASmartClient.ScreenLib/Model/OrderMakeModel.cs @@ -0,0 +1,163 @@ +using BPA.Helper; +using BPA.Message.Enum; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace BPASmartClient.ScreenLib +{ + /// + /// 订单制作Model + /// + public class OrderMakeModel : NotifyBase + { + /// + /// 状态 + /// + private ORDER_STATUS _Status; + public ORDER_STATUS Status + { + get { return _Status; } + set { + _Status = value; + foreground = new SolidColorBrush(Color.FromArgb(255, 0, 204, 255)); + switch ((ORDER_STATUS)value) + { + case ORDER_STATUS.WAIT: + MakeStatus = "等待制作"; + + foreground = new SolidColorBrush(Color.FromArgb(255, 0, 204, 255)); + break; + case ORDER_STATUS.COOKING: + MakeStatus = "制作中"; + foreground = new SolidColorBrush(Color.FromArgb(255, 0, 255, 127)); + break; + case ORDER_STATUS.COMPLETED_COOK: + MakeStatus = "制作完成"; + foreground = new SolidColorBrush(Color.FromArgb(255, 255, 215, 00)); + break; + case ORDER_STATUS.COMPLETED_TAKE: + MakeStatus = "取餐完成"; + foreground = new SolidColorBrush(Color.FromArgb(255, 102, 204, 153)); + break; + case ORDER_STATUS.ERR_NOT_REPLY_WHEN_COOKING: + MakeStatus = "取餐完成"; + foreground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)); + break; + default: + MakeStatus = "异常订单"; + break; + } + OnPropertyChanged(); + } + } + /// + /// 制作状态 + /// + private string _MakeStatus; + public string MakeStatus + { + get { return _MakeStatus; } + set + { + _MakeStatus = value; + OnPropertyChanged(); + } + } + /// + /// 商品名称 + /// + public string GoodName { get; set; } + + /// + /// 订单排序号 + /// + public string SortNum { get; set; } + + /// + /// 开始时间 + /// + public string StartTime { get; set; } + + /// + /// 结束时间 + /// + public string StopTime { get; set; } + + private Brush _foreground; + public Brush foreground + { + get + { + return _foreground; + } + set + { + if (_foreground == value) + return; + _foreground = value; + OnPropertyChanged("foreground"); + } + } + } + + /// + /// 告警数据 + /// + public class AlarmMsModel : NotifyBase + { + private string _AlarmTime; + public string AlarmTime + { + get { return _AlarmTime; } + set + { + _AlarmTime = value; + OnPropertyChanged(); + } + } + + + private string _AlarmMs; + public string AlarmMs + { + get { return _AlarmMs; } + set + { + _AlarmMs = value; + OnPropertyChanged(); + } + } + } + + /// + /// 菜品类型 + /// + public class CookType : NotifyBase + { + private string _Name; + public string Name + { + get { return _Name; } + set + { + _Name = value; + OnPropertyChanged(); + } + } + + private string _Name1; + public string Name1 + { + get { return _Name1; } + set + { + _Name1 = value; + OnPropertyChanged(); + } + } + } +} diff --git a/BPASmartClient.ScreenLib/分餐机/ScreenSplitMealsControl1.xaml b/BPASmartClient.ScreenLib/分餐机/ScreenSplitMealsControl1.xaml new file mode 100644 index 00000000..57b7f60c --- /dev/null +++ b/BPASmartClient.ScreenLib/分餐机/ScreenSplitMealsControl1.xaml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 设备是否运行 + + + + + + + + 设备当前状态 + + + + + + + + + + + + 今日刷卡数 + + + + 异常刷卡数 + + + + + + + + + + + +