diff --git a/SamplePre.Common/ConcurrentQueueExt.cs b/SamplePre.Common/ConcurrentQueueExt.cs new file mode 100644 index 0000000..5186a93 --- /dev/null +++ b/SamplePre.Common/ConcurrentQueueExt.cs @@ -0,0 +1,75 @@ +using System.Collections.Concurrent; +using System.Collections.Generic; + +namespace SamplePre.Common +{ + public class ConcurrentQueueExt + { + + private readonly ConcurrentQueue queue = new ConcurrentQueue(); + + public void Enqueue(T msgData) + { + if (msgData != null) + { + queue.Enqueue(msgData); + } + } + + //public void Enqueue(List msgDatas) + //{ + // if (msgDatas.IsNullOrEmpty()) return; + // foreach (var msgData in msgDatas) + // { + // queue.Enqueue(msgData); + // } + //} + + public T GetOne() + { + if (queue.TryDequeue(out T result)) + { + return result; + } + else + { + return default; + } + } + + public List GetAll() + { + List result = new List(); + int count = queue.Count; + if (count > 0) + { + for (int i = 0; i < count; i++) + { + if (queue.TryDequeue(out T t)) + { + result.Add(t); + } + } + } + return result; + } + + + public void Clear() + { + while (!queue.IsEmpty) + { + queue.TryDequeue(out _); + } + } + + public int Count + { + get + { + return queue.Count; + } + } + + } +} diff --git a/SamplePre.Common/Helper/ObjectCopyHelper.cs b/SamplePre.Common/Helper/ObjectCopyHelper.cs new file mode 100644 index 0000000..ca84f64 --- /dev/null +++ b/SamplePre.Common/Helper/ObjectCopyHelper.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Common.Helper +{ + /// + /// 实体对象复制工具类(反射实现) + /// 适配.NET Framework 4.8,支持同实体/不同实体间同名字段值复制(浅拷贝) + /// + public static class ObjectCopyHelper + { + /// + /// 核心方法:将源对象的同名字段值复制到目标对象 + /// + /// 源对象类型 + /// 目标对象类型 + /// 源对象(提供值) + /// 目标对象(接收值,需提前实例化) + /// 是否忽略属性名大小写(默认true:Name和name视为同一个) + /// 是否忽略源对象的null值(默认false:源null会覆盖目标值) + public static void CopyProperties(this TSource source, TTarget target, + bool ignoreCase = true, bool ignoreNull = false) + where TSource : class // 源对象不能为空引用类型 + where TTarget : class // 目标对象不能为空引用类型 + { + // 空值校验 + if (source == null) throw new ArgumentNullException(nameof(source), "源对象不能为null"); + if (target == null) throw new ArgumentNullException(nameof(target), "目标对象不能为null"); + + // 获取源对象和目标对象的属性信息(仅获取公共可读写属性) + PropertyInfo[] sourceProps = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance); + PropertyInfo[] targetProps = typeof(TTarget).GetProperties(BindingFlags.Public | BindingFlags.Instance); + + // 遍历源对象的所有属性,匹配目标对象的同名字段 + foreach (PropertyInfo sourceProp in sourceProps) + { + // 跳过源对象中不可读的属性(无getter) + if (!sourceProp.CanRead) continue; + + // 获取源对象当前属性的值 + object sourceValue = sourceProp.GetValue(source, null); + + // 忽略源对象的null值(若开启该配置) + if (ignoreNull && sourceValue == null) continue; + + // 在目标对象中查找同名字段(支持忽略大小写) + PropertyInfo targetProp = Array.Find(targetProps, p => + string.Equals(p.Name, sourceProp.Name, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)); + + // 目标对象无该属性/目标属性不可写/类型不匹配 → 跳过 + if (targetProp == null || !targetProp.CanWrite + || !sourceProp.PropertyType.IsAssignableFrom(targetProp.PropertyType)) + { + continue; + } + + // 给目标对象的属性赋值 + targetProp.SetValue(target, sourceValue, null); + } + } + + /// + /// 重载方法:快速复制(默认忽略大小写、不忽略null) + /// + public static void CopyProperties(this TSource source, TTarget target) + where TSource : class + where TTarget : class + { + CopyProperties(source, target, true, false); + } + + /// + /// 便捷方法:创建目标对象并完成复制(一步到位,无需提前实例化目标对象) + /// + public static TTarget CopyToNew(this TSource source, + bool ignoreCase = true, bool ignoreNull = false) + where TSource : class + where TTarget : class, new() // 目标对象必须有无参构造函数 + { + if (source == null) throw new ArgumentNullException(nameof(source)); + // 实例化目标对象并赋值 + TTarget target = new TTarget(); + source.CopyProperties(target, ignoreCase, ignoreNull); + return target; + } + } +} diff --git a/SamplePre.Common/Helper/ReflectionCommHelper.cs b/SamplePre.Common/Helper/ReflectionCommHelper.cs new file mode 100644 index 0000000..237b54e --- /dev/null +++ b/SamplePre.Common/Helper/ReflectionCommHelper.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Common +{ + public class ReflectionCommHelper + { + + /// + /// 根据属性名获取对象的属性值(支持公共/非公共属性) + /// + /// 目标对象(不能为null) + /// 属性名(大小写敏感) + /// 是否忽略大小写(默认false) + /// 属性值(不存在返回null) + public static object GetPropertyValue(object obj, string propertyName, bool ignoreCase = false) + { + // 空值校验 + if (obj == null) + throw new ArgumentNullException(nameof(obj), "目标对象不能为null"); + if (string.IsNullOrEmpty(propertyName)) + throw new ArgumentNullException(nameof(propertyName), "属性名不能为空"); + + // 获取对象类型 + Type type = obj.GetType(); + // 获取属性信息(BindingFlags控制是否查找非公共/实例成员) + PropertyInfo propInfo = type.GetProperty( + propertyName, + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | + (ignoreCase ? BindingFlags.IgnoreCase : BindingFlags.Default) + ); + + // 属性不存在返回null + if (propInfo == null) + return null; + + // 获取属性值 + return propInfo.GetValue(obj); + } + + } +} diff --git a/SamplePre.Common/Helper/XmlSerializerHelper.cs b/SamplePre.Common/Helper/XmlSerializerHelper.cs new file mode 100644 index 0000000..9b80f84 --- /dev/null +++ b/SamplePre.Common/Helper/XmlSerializerHelper.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace SamplePre.Common.Helper +{ + /// + /// XML序列化/反序列化工具类(强类型读取) + /// + public static class XmlSerializerHelper + { + /// + /// 从XML文件反序列化为指定类型的对象 + /// + /// 目标实体类型 + /// XML文件路径 + /// 实体对象 + public static T DeserializeFromXml(string filePath) where T : class, new() + { + // 检查文件是否存在 + if (!File.Exists(filePath)) + { + throw new FileNotFoundException("XML配置文件不存在", filePath); + } + + try + { + // 初始化序列化器 + XmlSerializer serializer = new XmlSerializer(typeof(T)); + // 读取文件并反序列化 + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return serializer.Deserialize(fs) as T; + } + } + catch (Exception ex) + { + throw new Exception("XML反序列化失败,检查XML格式和实体类是否匹配", ex); + } + } + + /// + /// 将对象序列化为XML并保存到文件 + /// + /// 实体类型 + /// 实体对象 + /// 保存路径 + public static void SerializeToXml(T obj, string filePath) where T : class + { + if (obj == null) + { + throw new ArgumentNullException(nameof(obj), "序列化对象不能为null"); + } + + try + { + XmlSerializer serializer = new XmlSerializer(typeof(T)); + // 写入文件(UTF8编码,避免中文乱码) + using (StreamWriter sw = new StreamWriter(filePath, false, System.Text.Encoding.UTF8)) + { + serializer.Serialize(sw, obj); + } + } + catch (Exception ex) + { + throw new Exception("XML序列化失败", ex); + } + } + } +} diff --git a/SamplePre.Common/LoggerHelper.cs b/SamplePre.Common/LoggerHelper.cs new file mode 100644 index 0000000..4a473e9 --- /dev/null +++ b/SamplePre.Common/LoggerHelper.cs @@ -0,0 +1,100 @@ +using NLog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Common +{ + /// + /// nLog使用帮助类 + /// + public class LoggerHelper + { + /// + /// 实例化nLog,即为获取配置文件相关信息(获取以当前正在初始化的类命名的记录器) + /// + private readonly NLog.Logger _logger = LogManager.GetCurrentClassLogger(); + + private static LoggerHelper _obj; + + public static LoggerHelper Logger + { + get => _obj ?? (new LoggerHelper()); + set => _obj = value; + } + + #region Debug,调试 + public void Debug(string msg) + { + _logger.Debug(msg); + } + + public void Debug(string msg, Exception err) + { + _logger.Debug(err, msg); + } + #endregion + + #region Info,信息 + public void Info(string msg) + { + _logger.Info(msg); + } + + public void Info(string msg, Exception err) + { + _logger.Info(err, msg); + } + #endregion + + #region Warn,警告 + public void Warn(string msg) + { + _logger.Warn(msg); + } + + public void Warn(string msg, Exception err) + { + _logger.Warn(err, msg); + } + #endregion + + #region Trace,追踪 + public void Trace(string msg) + { + _logger.Trace(msg); + } + + public void Trace(string msg, Exception err) + { + _logger.Trace(err, msg); + } + #endregion + + #region Error,错误 + public void Error(string msg) + { + _logger.Error(msg); + } + + public void Error(string msg, Exception err) + { + _logger.Error(err, msg); + } + #endregion + + #region Fatal,致命错误 + public void Fatal(string msg) + { + _logger.Fatal(msg); + } + + public void Fatal(string msg, Exception err) + { + _logger.Fatal(err, msg); + } + #endregion + } +} diff --git a/SamplePre.Common/SamplePre.Common.csproj b/SamplePre.Common/SamplePre.Common.csproj new file mode 100644 index 0000000..e32c1b7 --- /dev/null +++ b/SamplePre.Common/SamplePre.Common.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/SamplePre.Communication/CommEnum.cs b/SamplePre.Communication/CommEnum.cs new file mode 100644 index 0000000..305e23a --- /dev/null +++ b/SamplePre.Communication/CommEnum.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Communication +{ + + /// + /// 通讯协议类型枚举 + /// + public enum CommProtocolType + { + S7 = 0, + ModbusTcp = 1, + ModbusRtu = 2 + } + + /// + /// 通讯状态枚举 + /// + public enum CommunicationState + { + Disconnected = 0, + Connected = 1, + Connecting = 2, + Error = 3 + } + + /// + /// 通讯数据类型枚举 + /// + public enum CommDataType + { + Bit, // 位 + Byte, // 字节 + Int16, // 16位整数 + Int32, // 32位整数 + Float // 浮点型 + } + +} diff --git a/SamplePre.Communication/Communication/ICommunication.cs b/SamplePre.Communication/Communication/ICommunication.cs new file mode 100644 index 0000000..cb0fcef --- /dev/null +++ b/SamplePre.Communication/Communication/ICommunication.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Communication +{ + public interface ICommunication + { + + /// + /// 下发下位机指令 + /// + /// + /// + /// + /// + bool WriteArraysBtye(int Dbno, int start, T[] bytes); + + + + /// + /// 读取监控数据,读取数组 + /// + /// + ushort[] ReadArraysShort(int Dbno, int start, int lenth); + + + /// + /// 写入数据 + /// + /// 地址(如"M0.0", "DB1.DBW2") + /// 要写入的值 + /// 是否写入成功 + public bool WriteSingleData(string address, object value); + + + } +} diff --git a/SamplePre.Communication/Communication/ModbusTcpCommunicator.cs b/SamplePre.Communication/Communication/ModbusTcpCommunicator.cs new file mode 100644 index 0000000..7fd61cb --- /dev/null +++ b/SamplePre.Communication/Communication/ModbusTcpCommunicator.cs @@ -0,0 +1,236 @@ +using Modbus.Device; +using S7.Net; +using SamplePre.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Communication.Communication +{ + + public class ModbusTcpCommunicator : ICommunication, IDisposable + { + IModbusMaster _modbusMaster = null; + TcpClient _tcpClient = null; + private readonly string _ipAddress; + private readonly int _port; + + + /// + /// 是否连接 + /// + private bool _isConnected = false; + + /// + /// 是否连接 + /// + public bool IsConnected + { + get => _isConnected; + set + { + if (_isConnected != value) + { + _isConnected = value; + ConnectionStatusChanged?.Invoke(value); + } + } + } + + /// + /// 连接状态变化事件 + /// + public event Action ConnectionStatusChanged; + + /// + /// 构造函数 + /// + /// IP地址 + /// 端口号 + public ModbusTcpCommunicator(string ipAddress, int port=502) + { + + try + { + _ipAddress = ipAddress; + _port = port; + + _tcpClient = new TcpClient(ipAddress, port);//Modbus主设备 + + _modbusMaster = ModbusIpMaster.CreateIp(_tcpClient); + _modbusMaster.Transport.ReadTimeout = 2000; + _modbusMaster.Transport.Retries = 3; + + IsConnected = true; + } + catch (Exception ex) + { + LoggerHelper.Logger.Error("初始化ModbusTcpCommunicator失败!" + ex.Message); + + } + + } + + /// + /// 连接PLC + /// + /// 是否连接成功 + public bool Connect() + { + try + { + if (IsConnected) + { + LoggerHelper.Logger.Info("已经处于连接状态!"); + return true; + } + + // 如果之前的连接对象已释放,创建新的 + if (_modbusMaster == null) + { + _tcpClient = new TcpClient(_ipAddress, _port);//Modbus主设备 + + _modbusMaster = ModbusIpMaster.CreateIp(_tcpClient); + _modbusMaster.Transport.ReadTimeout = 2000; // + _modbusMaster.Transport.Retries = 3; + + + } + + + + LoggerHelper.Logger.Info("PLC连接成功"); + IsConnected = true; + + return IsConnected; + } + catch (Exception ex) + { + + LoggerHelper.Logger.Info($"连接PLC失败: {ex.Message}"); + IsConnected = false; + + return false; + } + } + + /// + /// 断开连接 + /// + public void Disconnect() + { + try + { + if (IsConnected) + { + + _modbusMaster.Dispose(); + _tcpClient.Close(); + + IsConnected = false; + LoggerHelper.Logger.Info("PLC连接已断开"); + + } + } + catch (Exception ex) + { + LoggerHelper.Logger.Info($"断开PLC连接失败: {ex.Message}"); + } + } + + + + /// + /// 写入数组数据 + /// + /// + /// + /// + /// + public bool WriteArraysBtye(int Dbno, int start, T[] data) + { + + + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + ushort[] ushorts = data.Cast().ToArray(); + + _modbusMaster.WriteMultipleRegisters((byte)Dbno, (ushort)start, ushorts); + + + return true; + } + catch (Exception ex) + { + LoggerHelper.Logger.Info($"写入数组失败: {ex.Message}"); + return false; + } + + + + + } + + + /// + /// 读取数组 + /// + /// + public ushort[] ReadArraysShort(int Dbno, int start, int lenth) + { + + //try + //{ + // if (!IsConnected && !Connect()) + // { + // return null; + // } + + // //public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0) + // ushort[] datas = _plc.Read(DataType.DataBlock, Dbno, start, VarType.Word, lenth) as ushort[]; + // return datas; + //} + //catch (Exception ex) + //{ + + // LoggerHelper.Logger.Info($"读取数组失败: {ex.Message}"); + // return null; + //} + + return null; + + + } + + + /// + /// 释放资源 + /// + public void Dispose() + { + // 释放托管资源 + Disconnect(); + + } + + public bool WriteSingleData(string address, object value) + { + throw new NotImplementedException(); + } + + ~ModbusTcpCommunicator() + { + Dispose(); + } + + } + +} diff --git a/SamplePre.Communication/Communication/S7PlcCommunicator.cs b/SamplePre.Communication/Communication/S7PlcCommunicator.cs new file mode 100644 index 0000000..0831148 --- /dev/null +++ b/SamplePre.Communication/Communication/S7PlcCommunicator.cs @@ -0,0 +1,236 @@ + +using S7.Net; +using S7.Net.Types; +using SamplePre.Common; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +namespace SamplePre.Communication +{ + public class S7PlcCommunicator : ICommunication, IDisposable + { + public Plc _plc; + private readonly string _ipAddress; + private readonly int _rack; + private readonly int _slot; + private readonly CpuType _cpuType; + + /// + /// 是否连接 + /// + private bool _isConnected = false; + + /// + /// 是否连接 + /// + public bool IsConnected + { + get => _isConnected; + set + { + if (_isConnected != value) + { + _isConnected = value; + ConnectionStatusChanged?.Invoke(value); + } + } + } + + /// + /// 连接状态变化事件 + /// + public event Action ConnectionStatusChanged; + + /// + /// 构造函数 + /// + /// PLC型号 + /// IP地址 + /// 机架号 + /// 插槽号 + public S7PlcCommunicator(CpuType cpuType, string ipAddress, int rack = 0, int slot = 1) + { + _cpuType = cpuType; + _ipAddress = ipAddress; + _rack = rack; + _slot = slot; + _plc = new Plc(cpuType, ipAddress, (short)rack, (short)slot); + } + + /// + /// 连接PLC + /// + /// 是否连接成功 + public bool Connect() + { + try + { + if (IsConnected) + { + LoggerHelper.Logger.Info("已经处于连接状态!"); + return true; + } + + // 如果之前的连接对象已释放,创建新的 + if (_plc == null) + { + _plc = new Plc(_cpuType, _ipAddress, (short)_rack, (short)_slot); + } + + _plc.Open(); + bool connected = _plc.IsConnected; + LoggerHelper.Logger.Info(connected ? "PLC连接成功" : "PLC连接失败"); + IsConnected = connected; + + return connected; + } + catch (Exception ex) + { + + LoggerHelper.Logger.Info($"连接PLC失败: {ex.Message}"); + IsConnected = false; + + return false; + } + } + + /// + /// 断开连接 + /// + public void Disconnect() + { + try + { + if (IsConnected) + { + _plc.Close(); + IsConnected = false; + LoggerHelper.Logger.Info("PLC连接已断开"); + + } + } + catch (Exception ex) + { + LoggerHelper.Logger.Info($"断开PLC连接失败: {ex.Message}"); + } + } + + /// + /// 写入数组数据 + /// + /// + /// + /// + /// + public bool WriteArraysBtye(int Dbno, int start, T[] bytes) + { + + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + byte[] data = bytes.Cast().ToArray(); + + + _plc.WriteBytes(DataType.DataBlock, Dbno, start, data); + + return true; + } + catch (Exception ex) + { + LoggerHelper.Logger.Info($"写入数组失败: {ex.Message}"); + return false; + } + + + + + } + + + /// + /// 读取数组 + /// + /// + public ushort[] ReadArraysShort(int Dbno,int start,int lenth) + { + + try + { + if (!IsConnected && !Connect()) + { + return null; + } + + //public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0) + ushort[] datas = _plc.Read(DataType.DataBlock, Dbno, start, VarType.Word, lenth) as ushort[]; + return datas; + } + catch (Exception ex) + { + + LoggerHelper.Logger.Info($"读取数组失败: {ex.Message}"); + return null; + } + + + + + } + + + /// + /// 写入数据 + /// + /// 地址(如"M0.0", "DB1.DBW2") + /// 要写入的值 + /// 是否写入成功 + public bool WriteSingleData(string address, object value) + { + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + _plc.Write(address, value); + Console.WriteLine($"写入 {address} 成功: {value}"); + return true; + } + catch (Exception ex) + { + Console.WriteLine($"写入 {address} 失败: {ex.Message}"); + return false; + } + } + + + /// + /// 释放资源 + /// + public void Dispose() + { + // 释放托管资源 + Disconnect(); + //_plc?.Dispose(); + _plc = null; + } + + ~S7PlcCommunicator() + { + Dispose(); + } + + } + + +} diff --git a/SamplePre.Communication/Communication/S7PlcCommunicatorBack.cs b/SamplePre.Communication/Communication/S7PlcCommunicatorBack.cs new file mode 100644 index 0000000..a06b100 --- /dev/null +++ b/SamplePre.Communication/Communication/S7PlcCommunicatorBack.cs @@ -0,0 +1,424 @@ + +using S7.Net; +using S7.Net.Types; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +namespace SamplePre.Communication +{ + public class S7PlcCommunicatorBack : IDisposable + { + public Plc _plc; + private readonly string _ipAddress; + private readonly int _rack; + private readonly int _slot; + private readonly CpuType _cpuType; + + /// + /// 是否连接 + /// + public bool IsConnected => _plc?.IsConnected ?? false; + + /// + /// 连接状态变化事件 + /// + public event Action ConnectionStatusChanged; + + /// + /// 构造函数 + /// + /// PLC型号 + /// IP地址 + /// 机架号 + /// 插槽号 + public S7PlcCommunicatorBack(CpuType cpuType, string ipAddress, int rack = 0, int slot = 1) + { + _cpuType = cpuType; + _ipAddress = ipAddress; + _rack = rack; + _slot = slot; + _plc = new Plc(cpuType, ipAddress, (short)rack, (short)slot); + } + + /// + /// 连接PLC + /// + /// 是否连接成功 + public bool Connect() + { + try + { + if (IsConnected) + { + Console.WriteLine("已经处于连接状态"); + return true; + } + + // 如果之前的连接对象已释放,创建新的 + if (_plc == null) + { + _plc = new Plc(_cpuType, _ipAddress, (short)_rack, (short)_slot); + } + + _plc.Open(); + bool connected = _plc.IsConnected; + Console.WriteLine(connected ? "PLC连接成功" : "PLC连接失败"); + ConnectionStatusChanged?.Invoke(connected); + return connected; + } + catch (Exception ex) + { + Console.WriteLine($"连接PLC失败: {ex.Message}"); + ConnectionStatusChanged?.Invoke(false); + return false; + } + } + + /// + /// 断开连接 + /// + public void Disconnect() + { + try + { + if (IsConnected) + { + _plc.Close(); + Console.WriteLine("PLC连接已断开"); + ConnectionStatusChanged?.Invoke(false); + } + } + catch (Exception ex) + { + Console.WriteLine($"断开PLC连接失败: {ex.Message}"); + } + } + + + + /// + /// 读取数据 + /// + /// 地址(如"M0.0", "DB1.DBW2") + /// 读取的值 + public object ReadData(string address) + { + try + { + if (!IsConnected && !Connect()) + { + return null; + } + + object value = _plc.Read(address); + Console.WriteLine($"a读取 {address} 成功: {value}"); + return value; + } + catch (Exception ex) + { + Console.WriteLine($"读取 {address} 失败: {ex.Message}"); + return null; + } + + + + } + + /// + /// 写入数据 + /// + /// 地址(如"M0.0", "DB1.DBW2") + /// 要写入的值 + /// 是否写入成功 + public bool WriteData(string address, object value) + { + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + _plc.Write(address, value); + Console.WriteLine($"写入 {address} 成功: {value}"); + return true; + } + catch (Exception ex) + { + Console.WriteLine($"写入 {address} 失败: {ex.Message}"); + return false; + } + } + + /// + /// 批量读取数据 + /// + /// 地址数组 + /// 值数组,与地址数组顺序对应 + public object[] ReadMultipleData(string[] addresses) + { + if (addresses == null || addresses.Length == 0) + return new object[0]; + + try + { + if (!IsConnected && !Connect()) + { + return null; + } + + var values = new object[addresses.Length]; + for (int i = 0; i < addresses.Length; i++) + { + values[i] = _plc.Read(addresses[i]); + } + Console.WriteLine($"批量读取 {addresses.Length} 个地址成功"); + return values; + } + catch (Exception ex) + { + Console.WriteLine($"批量读取失败: {ex.Message}"); + return null; + } + } + + /// + /// 写入数组数据 + /// + /// + /// + /// + /// + public bool WriteArraysBtye(int Dbno, int start, byte[] bytes) + { + + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + + _plc.WriteBytes(DataType.DataBlock, Dbno, start, bytes); + + return true; + } + catch (Exception ex) + { + Console.WriteLine($"写入数组: {ex.Message}"); + return false; + } + + + + + } + + + /// + /// 读取数组 + /// + /// + public ushort[] ReadArraysShort(int Dbno,int start,int lenth) + { + + try + { + if (!IsConnected && !Connect()) + { + return null; + } + + //public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0) + ushort[] datas = _plc.Read(DataType.DataBlock, Dbno, start, VarType.Word, lenth) as ushort[]; + return datas; + } + catch (Exception ex) + { + Console.WriteLine($"读取数组: {ex.Message}"); + return null; + } + + + + + } + + + + + /// + /// 读结构体 + /// + public T ReadStruct(int dbno, int start) + { + + T t; + try + { + if (!IsConnected && !Connect()) + { + return default(T); + } + + + t = (T)_plc.ReadStruct(typeof(T), dbno, start); + return t; + } + catch (Exception) + { + + Console.WriteLine($"读结构体失败!"); + return default(T); + } + + } + + /// + /// 写结构体 + /// + public bool WriteStruct(T t,int dbno,int start) + { + + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + _plc.WriteStruct(t, dbno, start); + return true; + } + catch (Exception) + { + + Console.WriteLine($"写入失败!"); + return false; + } + + } + /// + /// 读取字符串 + /// + /// + /// + /// + public string ReadString(int DBno, int startNo) + { + + try + { + if (!IsConnected && !Connect()) + { + return ""; + } + + int totalLenth = (byte)_plc.Read(S7.Net.DataType.DataBlock, DBno, startNo, VarType.Byte, 1); + int len = (byte)_plc.Read(S7.Net.DataType.DataBlock, DBno, startNo + 1, VarType.Byte, 1); + byte[] bytes = _plc.ReadBytes(S7.Net.DataType.DataBlock, DBno, startNo + 2, len); + string mesg = Encoding.ASCII.GetString(bytes); + + + return mesg; + } + catch (Exception ex) + { + Console.WriteLine($"读取字符串失败!"); + return ""; + } + + + } + + + /// + /// 写入字符串 + /// + /// + /// + /// + /// + public bool WriteString(int DBno,int startNo, string contextStr) + { + + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + _plc.Write(S7.Net.DataType.DataBlock, DBno, startNo + 1, (byte)contextStr.Length); + _plc.Write(S7.Net.DataType.DataBlock, DBno, startNo + 2, contextStr); + + Console.WriteLine($"写入字符串成功!"); + return true; + } + catch (Exception ex) + { + Console.WriteLine($"写入字符串失败!"); + return false; + } + + + } + + + /// + /// 写入bool + /// + /// + /// + /// + /// + public bool WriteBoolen(int DBno, int startByteAdr, int bitAdr, bool val) + { + + try + { + if (!IsConnected && !Connect()) + { + return false; + } + + _plc.WriteBit(DataType.DataBlock, DBno, startByteAdr, bitAdr, val); + + + Console.WriteLine($"写入成功!"); + return true; + } + catch (Exception ex) + { + Console.WriteLine($"写入失败!"); + return false; + } + + + } + + /// + /// 释放资源 + /// + public void Dispose() + { + Disconnect(); + //_plc?.Dispose(); + _plc = null; + } + } + + struct TestA + { + public ushort value1; + public ushort value2; + } + + +} diff --git a/SamplePre.Communication/Communication/SocketClient.cs b/SamplePre.Communication/Communication/SocketClient.cs new file mode 100644 index 0000000..cb54a78 --- /dev/null +++ b/SamplePre.Communication/Communication/SocketClient.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Communication.Communication +{ + public class SocketClient + { + // 服务端 IP 和端口(和你服务端一致) + private const string ServerIp = "127.0.0.1"; + private const int ServerPort = 8888; + + private Socket _clientSocket; + + public Action ReceiveMsgAction; + + //static async Task Main(string[] args) + //{ + // var client = new SocketClient(); + // await client.StartClientAsync(); + //} + + /// + /// 启动客户端 + /// + public async Task StartClientAsync() + { + try + { + // 创建客户端 Socket + _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + ReceiveMsgAction?.Invoke("正在连接服务端..."); + + // 连接服务端 + await _clientSocket.ConnectAsync(IPAddress.Parse(ServerIp), ServerPort); + ReceiveMsgAction?.Invoke("✅ 连接服务端成功!"); + + // 启动接收消息任务(后台异步监听) + _ = Task.Run(ReceiveMsgAsync); + + + } + catch (Exception ex) + { + ReceiveMsgAction?.Invoke($"连接失败:{ex.Message}"); + } + + } + + public void CloseConnect() + { + _clientSocket.Close(); + ReceiveMsgAction?.Invoke("客户端已断开"); + } + + /// + /// 发送消息 + /// + public async Task SendMsgAsync(string msg) + { + if (string.IsNullOrEmpty(msg)) return; + + byte[] data = Encoding.UTF8.GetBytes(msg); + await _clientSocket.SendAsync(data, SocketFlags.None); + } + + /// + /// 接收服务端消息 + /// + private async Task ReceiveMsgAsync() + { + byte[] buffer = new byte[1024]; + + while (true) + { + try + { + int len = await _clientSocket.ReceiveAsync(buffer, SocketFlags.None); + if (len == 0) break; + + string recMsg = Encoding.UTF8.GetString(buffer, 0, len); + + //回调函数 + ReceiveMsgAction?.Invoke($"\n📩 服务端回复:{recMsg}"); + + } + catch + { + break; + } + } + } + } +} diff --git a/SamplePre.Communication/CommunicationFactory.cs b/SamplePre.Communication/CommunicationFactory.cs new file mode 100644 index 0000000..e3dceda --- /dev/null +++ b/SamplePre.Communication/CommunicationFactory.cs @@ -0,0 +1,64 @@ +using S7.Net; +using SamplePre.Communication.Communication; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Communication +{ + public class CommunicationFactory + { + /// + /// 创建通讯实例 + /// + /// 协议类型 + /// 连接参数 + /// + /// + public static ICommunication CreateCommunication(CommProtocolType protocolType, string connectionParams) + { + ICommunication comm = null; + + switch (protocolType) + { + case CommProtocolType.S7: + comm = CreateS7(connectionParams); + break; + case CommProtocolType.ModbusTcp: + comm = CreateModbusTcp(connectionParams); + break; + case CommProtocolType.ModbusRtu: + break; + default: + break; + } + + + return comm; + } + + + public static ICommunication CreateS7(string connectionParams) + { + string[] params1 = connectionParams.Split(':'); + if(params1 == null || params1.Length < 3) return null; + //ICommunication comm = new S7PlcCommunicator(CpuType.S71500, "192.168.10.2", 0, 1); + ICommunication comm = new S7PlcCommunicator(CpuType.S71500, params1[0], int.Parse( params1[1]), int.Parse( params1[2])); + + return comm; + } + + public static ICommunication CreateModbusTcp(string connectionParams) + { + string[] params1 = connectionParams.Split(':'); + if (params1 == null || params1.Length < 2) return null; + ICommunication comm = new ModbusTcpCommunicator(params1[0], int.Parse(params1[1])); + + return comm; + } + + } +} diff --git a/SamplePre.Communication/SamplePre.Communication.csproj b/SamplePre.Communication/SamplePre.Communication.csproj new file mode 100644 index 0000000..51bb875 --- /dev/null +++ b/SamplePre.Communication/SamplePre.Communication.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + diff --git a/SamplePre.DAL/DAL/LogDal.cs b/SamplePre.DAL/DAL/LogDal.cs new file mode 100644 index 0000000..bffc80b --- /dev/null +++ b/SamplePre.DAL/DAL/LogDal.cs @@ -0,0 +1,96 @@ +using Dapper; +using Models.Models; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +//using System.Windows.Documents; + +namespace DataDAL.DBContext +{ + public class LogDal + { + + public LogDal() + { + + } + + + + /// + /// 保存日志 + /// + /// + /// + /// + public int SaveLog(run_log_info runLogInfo) + { + + //using (IDbConnection dbConnection = new DapperDBContext().Connection) + //{ + // dbConnection.Open(); + + // string insertSql = @"insert into run_log_info ( id,run_date + // ,log_level + // ,log_content,log_type + // ) + // values(@id,@run_date + // ,@log_level + // ,@log_content ,@log_type + // )"; + + + // var item = dbConnection.QueryFirstOrDefault(insertSql, runLogInfo); + + return 1; + //} + + + } + + /// + /// 查询日志信息 + /// + public List QueryLogByDate(DateTime dt1,DateTime dt2) + { + using (IDbConnection dbConnection = new DapperDBContext().Connection) + { + dbConnection.Open(); + + string querySql = "select * from run_log_info where run_date >= @dt1 and run_date <= @dt2"; + + List data = dbConnection.Query(querySql, new { dt1 = dt1,dt2 = dt2 }).ToList(); + + return data; + + } + } + + ///// + ///// 查询二维码开始编号 + ///// + //public string QueryQrcode() + //{ + // using (IDbConnection dbConnection = new BaseDBContext().Connection) + // { + // dbConnection.Open(); + + // string qrcode = ""; + + // List data = dbConnection.Query("select * from sys_dict where data_type='二维码编号'").ToList(); + // if (data.Count > 0) + // { + // qrcode = (int.Parse(data[0].data_value) + 1).ToString("0000"); + // } + // return qrcode; + + // } + //} + + + + } +} diff --git a/SamplePre.DAL/DAL/SOPDal.cs b/SamplePre.DAL/DAL/SOPDal.cs new file mode 100644 index 0000000..5539f0d --- /dev/null +++ b/SamplePre.DAL/DAL/SOPDal.cs @@ -0,0 +1,72 @@ +using Dapper; +using DataDAL.DBContext; +using Models.Models; +using SamplePre.Common; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Dapper.SqlMapper; + +namespace SamplePre.DAL +{ + public class SOPDal + { + + /// + /// 获取标准下的动作,动作中包含参数 + /// + /// + /// + public List QueryStandardProcessByStandardId(string standId) + { + using (IDbConnection dbConnection = new DapperDBContext().Connection) + { + dbConnection.Open(); + + string querySql = @" + SELECT + a.*, + b.action_name, + b.action_unit, + e.data_value AS action_unit_name, + b.remark, + c.all_param + FROM + sys_standard_action a + LEFT JOIN sys_action b ON a.process_id = b.id + LEFT JOIN sys_dict e ON b.action_unit = e.id + LEFT JOIN ( + SELECT + x.action_id, + x.action_seqno, + GROUP_CONCAT( CONCAT( y.title, ':', x.data_value, y.unit ) SEPARATOR ',' ) AS all_param + FROM + sys_standard_action_parm x + LEFT JOIN sys_parm y ON x.parm_id = y.id + WHERE + x.standard_id = @standId + GROUP BY + x.action_id, + x.action_seqno + ) c ON a.process_id = c.action_id + AND a.process_no = c.action_seqno + WHERE + a.standard_id = @standId + ORDER BY a.process_no + "; + + List data = dbConnection.Query(querySql, new { standId = standId }).ToList(); + + return data; + + } + } + + } +} diff --git a/SamplePre.DAL/DAL/SampleSequenceDal.cs b/SamplePre.DAL/DAL/SampleSequenceDal.cs new file mode 100644 index 0000000..e2503ab --- /dev/null +++ b/SamplePre.DAL/DAL/SampleSequenceDal.cs @@ -0,0 +1,24 @@ +using Dapper; +using DataDAL.DBContext; +using Models.Models; +using SamplePre.Common; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using SamplePre.Models.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Dapper.SqlMapper; + +namespace SamplePre.DAL +{ + public class SampleSequenceDal + { + + + } +} diff --git a/SamplePre.DAL/DAL/SystemDal.cs b/SamplePre.DAL/DAL/SystemDal.cs new file mode 100644 index 0000000..a5a40e1 --- /dev/null +++ b/SamplePre.DAL/DAL/SystemDal.cs @@ -0,0 +1,59 @@ +using Dapper; +using DataDAL.DBContext; +using Models.Models; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using SamplePre.Models.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.DAL +{ + public class SystemDal + { + /// + /// 获取用户数据 + /// + /// + /// + public List QueryUserData() + { + using (IDbConnection dbConnection = new DapperDBContext().Connection) + { + dbConnection.Open(); + + string querySql = @" + SELECT a.*,b.all_role_names from config_user a + LEFT JOIN ( + + SELECT + x.user_id, + + GROUP_CONCAT(x.role_id SEPARATOR ',') AS all_role_ids, + + GROUP_CONCAT(y.`name` SEPARATOR ',') AS all_role_names + FROM + config_user_role x + LEFT JOIN config_role y ON x.role_id = y.id + + GROUP BY + x.user_id + + ) b on a.id = b.user_id + "; + + List data = dbConnection.Query(querySql).ToList(); + + return data; + + } + } + + + } +} diff --git a/SamplePre.DAL/DBContext/DBFactory.cs b/SamplePre.DAL/DBContext/DBFactory.cs new file mode 100644 index 0000000..81aa1bd --- /dev/null +++ b/SamplePre.DAL/DBContext/DBFactory.cs @@ -0,0 +1,108 @@ +using Models.Const; +using SamplePre.Common; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.DAL.DBContext +{ + public class DBFactory + { + + #region 单例实例 + private static readonly Lazy _lazySqlSugarClient = new Lazy(() => + { + return CreateSqlSugarClient(); + }); + + /// + /// 获取默认数据库的SqlSugarClient单例实例 + /// + public static SqlSugarClient Instance => _lazySqlSugarClient.Value; + #endregion + + #region 从App.config读取的配置项(静态构造函数初始化,仅执行一次) + private static readonly string _connStr; // 数据库连接字符串 + private static readonly bool _isAutoCloseConn; // 是否自动关闭连接 + + /// + /// 静态构造函数:读取App.config配置,初始化全局参数 + /// + static DBFactory() + { + try + { + // 1. 读取数据库连接字符串(MySQL) + + _connStr = SystemConst.SysConfigInfo.DbConfig.MySql.ConnStr;//"Data Source=localhost;Database=fanghuayuan;AllowLoadLocalInfile=true;User ID=root;Password=123;allowPublicKeyRetrieval=true;pooling=true;port=3306;"; + + // 2. 读取SqlSugar全局配置(AppSettings节点) + _isAutoCloseConn = true;//Convert.ToBoolean(ConfigurationManager.AppSettings["SqlSugar_IsAutoCloseConnection"]); + + } + catch (Exception ex) + { + throw new Exception("SqlSugar工厂类配置读取失败:" + ex.Message); + } + } + #endregion + + #region 核心方法:创建SqlSugarClient并配置全局参数 + /// + /// 封装SqlSugarClient的创建、数据库配置、全局AOP + /// + /// 配置完成的SqlSugarClient实例 + private static SqlSugarClient CreateSqlSugarClient() + { + // 1. 数据库连接核心配置(按需修改DbType:对应连接字符串) + var connectionConfig = new ConnectionConfig + { + ConnectionString = _connStr, // 连接字符串 + DbType = SqlSugar.DbType.MySql, // 数据库类型: + IsAutoCloseConnection = _isAutoCloseConn, // 自动关闭连接(必开,避免连接泄漏) + InitKeyType = InitKeyType.Attribute, // 从实体类特性读取主键/自增配置(核心) + + }; + + // 2. 创建SqlSugarClient实例 + var db = new SqlSugarClient(connectionConfig); + + db.Aop.OnError = (ex) => + { + string errorLog = $@"【SQL执行异常】{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} + 【异常信息】{ex.Message} + 【SQL语句】{ex.Sql}"; + // 异常日志写入本地文件 + LoggerHelper.Logger.Error(errorLog); + + }; + + return db; + } + #endregion + + + + #region 辅助:手动释放资源(单例模式一般无需调用,程序退出时可选) + /// + /// 手动释放SqlSugarClient资源(仅特殊场景使用) + /// + public static void DisposeInstance() + { + if (_lazySqlSugarClient.IsValueCreated) + { + Instance.Dispose(); + } + } + #endregion + + + + } +} diff --git a/SamplePre.DAL/DBContext/DapperDBContext.cs b/SamplePre.DAL/DBContext/DapperDBContext.cs new file mode 100644 index 0000000..1e2cd2b --- /dev/null +++ b/SamplePre.DAL/DBContext/DapperDBContext.cs @@ -0,0 +1,27 @@ +using Models.Const; +using MySql.Data.MySqlClient; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DataDAL.DBContext +{ + public class DapperDBContext + { + public IDbConnection Connection { get; set; } + + //string connectionString = "Data Source=localhost;Database=fanghuayuan;AllowLoadLocalInfile=true;User ID=root;Password=123;allowPublicKeyRetrieval=true;pooling=true;port=3306;"; //"Data Source=DESKTOP-T4SGEQ7;Initial Catalog=防化院毒素;Integrated Security=True;TrustServerCertificate=True"; + + public DapperDBContext() + { + + Connection = new MySqlConnection(SystemConst.SysConfigInfo.DbConfig.MySql.ConnStr); + } + + + } +} diff --git a/SamplePre.DAL/SamplePre.DAL.csproj b/SamplePre.DAL/SamplePre.DAL.csproj new file mode 100644 index 0000000..db251e2 --- /dev/null +++ b/SamplePre.DAL/SamplePre.DAL.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/SamplePre.Models/Const/SystemConst.cs b/SamplePre.Models/Const/SystemConst.cs new file mode 100644 index 0000000..62eac60 --- /dev/null +++ b/SamplePre.Models/Const/SystemConst.cs @@ -0,0 +1,67 @@ +using Models.Models; +using SamplePre.Common; +using SamplePre.Communication; +using SamplePre.Models.Ext; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Const +{ + public class SystemConst + { + + /// + /// 运行、成功色-绿色 + /// + public static Color SuccessColor = Color.FromArgb(40, 167, 69); // 运行、成功色-绿色 + + /// + /// 待机-浅绿色 + /// + public static Color AwaitColor = Color.FromArgb(66, 202, 171); // 待机-浅绿色 + + /// + /// 结束 + /// + public static Color FinishColor = Color.FromArgb(22, 167, 169); // 运行、成功色-绿色 + + /// + /// 警告色-黄色 + /// + public static Color WarningColor = Color.FromArgb(255, 193, 7); // 停止、警告色-黄色 + /// + /// 危险色-红色 + /// + public static Color DangerColor = Color.FromArgb(220, 53, 69); // 危险色-红色 + + + + + /// + /// 主PLC对象 + /// + public static ICommunication MasterPLC; + + /// + /// 字典数据 + /// + public static List dictDatas = new List(); + + + public static SysConfigData SysConfigInfo = new SysConfigData(); + + /// + /// 当前通信协议类型 + /// + public static CommProtocolType ProtocolType = CommProtocolType.ModbusTcp; + + /// + /// 当前登录用户信息 + /// + public static LoginUserInfo loginUserInfo = new LoginUserInfo(); + } +} diff --git a/SamplePre.Models/EnumType.cs b/SamplePre.Models/EnumType.cs new file mode 100644 index 0000000..9e67cc0 --- /dev/null +++ b/SamplePre.Models/EnumType.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models +{ + + + + public enum LiXinJiEnum + { + //待机 + Wait = 0, + //运行 + Run = 1, + //故障 + Err = 2 + + } + + + + +} diff --git a/SamplePre.Models/Ext/LogQuery.cs b/SamplePre.Models/Ext/LogQuery.cs new file mode 100644 index 0000000..e6e4d6e --- /dev/null +++ b/SamplePre.Models/Ext/LogQuery.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Ext +{ + public class LogQuery + { + public string runDate { get; set; } + public string errType { get; set; } + public string errlevel { get; set; } + public string content { get; set; } + + + + } +} diff --git a/SamplePre.Models/Ext/LoginUserInfo.cs b/SamplePre.Models/Ext/LoginUserInfo.cs new file mode 100644 index 0000000..82d41a0 --- /dev/null +++ b/SamplePre.Models/Ext/LoginUserInfo.cs @@ -0,0 +1,23 @@ +using SamplePre.Models.Tables; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class LoginUserInfo + { + + /// + /// 用户信息 + /// + public config_user user { get; set; } + + /// + /// 功能权限 + /// + public List functions { get; set; } + } +} diff --git a/SamplePre.Models/Ext/MenuNode.cs b/SamplePre.Models/Ext/MenuNode.cs new file mode 100644 index 0000000..c6d28c4 --- /dev/null +++ b/SamplePre.Models/Ext/MenuNode.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Ext +{ + public class MenuNode + { + public string Id { get; set; } + public string Name { get; set; } + public string Icon { get; set; } + public List Children { get; set; } + + //public MenuNode(string id, string name, List children = null) + //{ + // Id = id; + // Name = name; + + // Children = children ?? new List(); + //} + } + + +} diff --git a/SamplePre.Models/Ext/config_function_ext.cs b/SamplePre.Models/Ext/config_function_ext.cs new file mode 100644 index 0000000..552a3ea --- /dev/null +++ b/SamplePre.Models/Ext/config_function_ext.cs @@ -0,0 +1,17 @@ +using SamplePre.Models.Tables; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class config_function_ext : config_function + { + + public bool IsChecked { get; set; } + + + } +} diff --git a/SamplePre.Models/Ext/config_role_ext.cs b/SamplePre.Models/Ext/config_role_ext.cs new file mode 100644 index 0000000..f21335c --- /dev/null +++ b/SamplePre.Models/Ext/config_role_ext.cs @@ -0,0 +1,16 @@ +using SamplePre.Models.Tables; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class config_role_ext : config_role + { + + public bool IsSelected { get; set; } + + } +} diff --git a/SamplePre.Models/Ext/config_user_ext.cs b/SamplePre.Models/Ext/config_user_ext.cs new file mode 100644 index 0000000..75319bd --- /dev/null +++ b/SamplePre.Models/Ext/config_user_ext.cs @@ -0,0 +1,16 @@ +using SamplePre.Models.Tables; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class config_user_ext : config_user + { + + public string all_role_names { get; set; } + + } +} diff --git a/SamplePre.Models/Ext/sample_exec_detail_ext.cs b/SamplePre.Models/Ext/sample_exec_detail_ext.cs new file mode 100644 index 0000000..55594b1 --- /dev/null +++ b/SamplePre.Models/Ext/sample_exec_detail_ext.cs @@ -0,0 +1,25 @@ +using SamplePre.Models.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class sample_exec_detail_ext : sample_exec_detail + { + + public string exec_state { get; set; } + public string item_name { get; set; } + + public string standrad_id { get; set; } + public string standrad { get; set; } + public DateTime input_date { get; set; } + public string input_user { get; set; } + public string tube_type_name { get; set; } + + + + } +} diff --git a/SamplePre.Models/Ext/sample_exec_ext.cs b/SamplePre.Models/Ext/sample_exec_ext.cs new file mode 100644 index 0000000..65cfe25 --- /dev/null +++ b/SamplePre.Models/Ext/sample_exec_ext.cs @@ -0,0 +1,17 @@ +using SamplePre.Models.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class sample_exec_ext : sample_exec + { + public string standradName { get; set; } + + + public List sampleExecDetails { get; set; } + } +} diff --git a/SamplePre.Models/Ext/sys_action_ext.cs b/SamplePre.Models/Ext/sys_action_ext.cs new file mode 100644 index 0000000..a8ce5b0 --- /dev/null +++ b/SamplePre.Models/Ext/sys_action_ext.cs @@ -0,0 +1,15 @@ +using Models.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class sys_action_ext : sys_action + { + public string action_unitname { get; set; } + + } +} diff --git a/SamplePre.Models/Ext/sys_action_parm_map_ext.cs b/SamplePre.Models/Ext/sys_action_parm_map_ext.cs new file mode 100644 index 0000000..4f9e2fc --- /dev/null +++ b/SamplePre.Models/Ext/sys_action_parm_map_ext.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Ext +{ + public class sys_action_parm_map_ext + { + public int id { get; set; } + public string process_id { get; set; } + public string parm_id { get; set; } + public string process_name { get; set; } + public string title { get; set; } + public string unit { get; set; } + public string data_type { get; set; } + public string data_value { get; set; } + + public string plc_type { get; set; } + + } +} diff --git a/SamplePre.Models/Ext/sys_standard_action_ext.cs b/SamplePre.Models/Ext/sys_standard_action_ext.cs new file mode 100644 index 0000000..31c8507 --- /dev/null +++ b/SamplePre.Models/Ext/sys_standard_action_ext.cs @@ -0,0 +1,27 @@ +using Models.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class sys_standard_action_ext : sys_standard_action + { + public string action_name { get; set; } + public string remark { get; set; } + + public string all_param { get; set; } + + public string action_unit { get; set; } + public string action_unit_name { set; get; } + + public int new_action_seqno { set; get; } + + /// + /// 执行完成标识 + /// + public bool ExecFinishFlag { set; get; } = false; + } +} diff --git a/SamplePre.Models/Ext/sys_standard_action_parm_ext.cs b/SamplePre.Models/Ext/sys_standard_action_parm_ext.cs new file mode 100644 index 0000000..f83e62a --- /dev/null +++ b/SamplePre.Models/Ext/sys_standard_action_parm_ext.cs @@ -0,0 +1,21 @@ +using Models.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class sys_standard_action_parm_ext : sys_standard_action_parm + { + public string action_name { get; set; } + public string title { get; set; } + public string unit { get; set; } + public string data_type { get; set; } + public string plc_type { get; set; } + + public string actionAndseqno { get; set; } + + } +} diff --git a/SamplePre.Models/Ext/sys_standard_ext.cs b/SamplePre.Models/Ext/sys_standard_ext.cs new file mode 100644 index 0000000..9c68ab1 --- /dev/null +++ b/SamplePre.Models/Ext/sys_standard_ext.cs @@ -0,0 +1,38 @@ +using Models.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class sys_standard_ext : sys_standard ,INotifyPropertyChanged + { + + //public bool IsSelected { get; set; } + + + private bool _isSelected; + + public bool IsSelected + { + get { return _isSelected; } + set { _isSelected = value; + + OnPropertyChanged(); + } + } + protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + + + + public event PropertyChangedEventHandler? PropertyChanged; + } +} diff --git a/SamplePre.Models/Ext/tube_input_ext.cs b/SamplePre.Models/Ext/tube_input_ext.cs new file mode 100644 index 0000000..1430342 --- /dev/null +++ b/SamplePre.Models/Ext/tube_input_ext.cs @@ -0,0 +1,40 @@ +using Models.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Ext +{ + public class tube_input_ext : tube_input,INotifyPropertyChanged + { + //public bool isChecked { get; set; } = false; + + public string tube_type_name { get; set; } + + + private bool isSelected = false; + + public event PropertyChangedEventHandler? PropertyChanged; + + public bool IsSelected + { + get { return isSelected; } + set + { + isSelected = value; + + OnPropertyChanged(); + } + } + + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + } +} diff --git a/SamplePre.Models/Models/ComboBoxListItem.cs b/SamplePre.Models/Models/ComboBoxListItem.cs new file mode 100644 index 0000000..94f487c --- /dev/null +++ b/SamplePre.Models/Models/ComboBoxListItem.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models +{ + public class ComboBoxListItem : Object + { + public string Text { get; set; } + + public object Value { get; set; } + + public ComboBoxListItem(string text, object value) + { + this.Text = text; + this.Value = value; + } + + public override string ToString() + { + return this.Text; + } + } +} diff --git a/SamplePre.Models/Models/SopDataInfo.cs b/SamplePre.Models/Models/SopDataInfo.cs new file mode 100644 index 0000000..bf73d56 --- /dev/null +++ b/SamplePre.Models/Models/SopDataInfo.cs @@ -0,0 +1,18 @@ +using Models.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models +{ + public class SopDataInfo + { + public sys_standard sysStandard { get; set; } = new sys_standard(); + + public List sysStandActions { get; set; } = new List(); + + public List sysStandardActionParms { get; set; } = new List(); + } +} diff --git a/SamplePre.Models/Models/SysConfigData.cs b/SamplePre.Models/Models/SysConfigData.cs new file mode 100644 index 0000000..fc610dc --- /dev/null +++ b/SamplePre.Models/Models/SysConfigData.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models +{ + using System.Xml.Serialization; + + /// + /// 系统配置根实体类(对应XML根节点SystemConfig) + /// + [XmlRoot("SystemConfig")] + public class SysConfigData + { + /// + /// 数据库配置(对应DbConfig节点) + /// + [XmlElement("DbConfig")] + public DbConfigModel DbConfig { get; set; } + + /// + /// 应用配置(对应AppConfig节点) + /// + [XmlElement("AppConfig")] + public AppConfigModel AppConfig { get; set; } + } + + + /// + /// 数据库配置实体(对应DbConfig节点) + /// + public class DbConfigModel + { + /// + /// SQL Server配置(对应SqlServer节点,含属性) + /// + [XmlElement("SqlServer")] + public DbItemModel SqlServer { get; set; } + + /// + /// MySQL配置(对应MySql节点,含属性) + /// + [XmlElement("MySql")] + public DbItemModel MySql { get; set; } + } + + /// + /// 数据库子项配置(对应SqlServer/MySql节点,含属性) + /// + public class DbItemModel + { + /// + /// 连接串(对应ConnStr属性) + /// + [XmlAttribute("ConnStr")] + public string ConnStr { get; set; } + + /// + /// 超时时间(对应TimeOut属性) + /// + [XmlAttribute("TimeOut")] + public int TimeOut { get; set; } + } + + /// + /// 应用配置实体(对应AppConfig节点) + /// + public class AppConfigModel + { + [XmlElement("AppName")] + public string AppName { get; set; } + + [XmlElement("Version")] + public string Version { get; set; } + + [XmlElement("MaxLoginCount")] + public int MaxLoginCount { get; set; } + + [XmlElement("IsDebug")] + public bool IsDebug { get; set; } + } +} diff --git a/SamplePre.Models/Models/TreeListItem.cs b/SamplePre.Models/Models/TreeListItem.cs new file mode 100644 index 0000000..d6faaff --- /dev/null +++ b/SamplePre.Models/Models/TreeListItem.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models +{ + // 定义树节点数据模型 + public class TreeListItem + { + // 节点唯一ID(主键) + public string ID { get; set; } + // 父节点ID(根节点的ParentID为0,子节点对应父节点的ID) + public string ParentID { get; set; } + // 节点显示的文本 + public string DisplayText { get; set; } + + } +} diff --git a/SamplePre.Models/SamplePre.Models.csproj b/SamplePre.Models/SamplePre.Models.csproj new file mode 100644 index 0000000..25a17f8 --- /dev/null +++ b/SamplePre.Models/SamplePre.Models.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/SamplePre.Models/Tables/QRcode.cs b/SamplePre.Models/Tables/QRcode.cs new file mode 100644 index 0000000..5aca20f --- /dev/null +++ b/SamplePre.Models/Tables/QRcode.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class QRcode + { + public string code { get; set; } + public string checkItem { get; set; } //检测项目 + public string jizhi { get; set; } // 基质 + public string sqno { get; set; } // 序号 + public string position { get; set; } // 试管位置 + public string stand { get; set; } // 标准 + public string user { get; set; } //录入人员 + public string inputDate { get; set; } //录入日期 + + + + + + } +} diff --git a/SamplePre.Models/Tables/config_function.cs b/SamplePre.Models/Tables/config_function.cs new file mode 100644 index 0000000..d506117 --- /dev/null +++ b/SamplePre.Models/Tables/config_function.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Tables +{ + public class config_function + { + public int id { get; set; } // 功能ID + public string name { get; set; } // 功能名称(如:用户管理、角色新增) + public string code { get; set; } // 功能编码(唯一标识,如:User_Manage) + public int parent_id { get; set; } // 父功能编码(用于构建菜单层级) + public string description { get; set; } // 功能描述 + + } +} diff --git a/SamplePre.Models/Tables/config_role.cs b/SamplePre.Models/Tables/config_role.cs new file mode 100644 index 0000000..e6b622a --- /dev/null +++ b/SamplePre.Models/Tables/config_role.cs @@ -0,0 +1,21 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Tables +{ + public class config_role + { + + [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] + public string id { get; set; } // 角色ID + public string name { get; set; } // 角色名称(如:管理员、普通用户) + public string description { get; set; } // 角色描述 + + + + } +} diff --git a/SamplePre.Models/Tables/config_role_permisson.cs b/SamplePre.Models/Tables/config_role_permisson.cs new file mode 100644 index 0000000..13ab012 --- /dev/null +++ b/SamplePre.Models/Tables/config_role_permisson.cs @@ -0,0 +1,20 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Tables +{ + public class config_role_permisson + { + + [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] + public int id { get; set; } + public string role_id { get; set; } + public int function_id { get; set; } + + + } +} diff --git a/SamplePre.Models/Tables/config_user.cs b/SamplePre.Models/Tables/config_user.cs new file mode 100644 index 0000000..8aed73d --- /dev/null +++ b/SamplePre.Models/Tables/config_user.cs @@ -0,0 +1,25 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Tables +{ + public class config_user + { + [SugarColumn(IsPrimaryKey = true, IsIdentity = false)] + public string id { get; set; } // 用户ID + public string username { get; set; } // 用户名 + public string password { get; set; } // 密码(实际项目需加密存储) + public bool is_enabled { get; set; } // 是否启用 + + + + + + + + } +} diff --git a/SamplePre.Models/Tables/config_user_role.cs b/SamplePre.Models/Tables/config_user_role.cs new file mode 100644 index 0000000..3f06167 --- /dev/null +++ b/SamplePre.Models/Tables/config_user_role.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Tables +{ + public class config_user_role + { + + public int id { get; set; } + public string user_id { get; set; } + public string role_id { get; set; } + + + + + } +} diff --git a/SamplePre.Models/Tables/run_log_info.cs b/SamplePre.Models/Tables/run_log_info.cs new file mode 100644 index 0000000..4811bfb --- /dev/null +++ b/SamplePre.Models/Tables/run_log_info.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class run_log_info + { + public string id { get; set; } + + public DateTime run_date { get; set; } + + /// + /// 信息,警告,故障 + /// + public string log_level { get; set; } + + public string log_content { get; set; } + + public string log_type { get; set; } + + /// + /// 运行时间 + /// + public string run_time { get; set; } + + } +} diff --git a/SamplePre.Models/Tables/sample_exec.cs b/SamplePre.Models/Tables/sample_exec.cs new file mode 100644 index 0000000..cf1b4b4 --- /dev/null +++ b/SamplePre.Models/Tables/sample_exec.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Models +{ + public class sample_exec + { + public string id { get; set; } + public string standrad_id { get; set; } + public string cmd_content { get; set; } + public string cmd_content2 { get; set; } + public string qrcodes { get; set; } + public int sample_count { get; set; } + public string exec_state { get; set; } + + public DateTime exec_date { get; set; } + + } +} diff --git a/SamplePre.Models/Tables/sample_exec_detail.cs b/SamplePre.Models/Tables/sample_exec_detail.cs new file mode 100644 index 0000000..1fd7990 --- /dev/null +++ b/SamplePre.Models/Tables/sample_exec_detail.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Models +{ + public class sample_exec_detail + { + + public int id { get; set; } + public string master_id { get; set; } + public string qrcode { get; set; } + + + } +} diff --git a/SamplePre.Models/Tables/sample_record.cs b/SamplePre.Models/Tables/sample_record.cs new file mode 100644 index 0000000..a1f7e49 --- /dev/null +++ b/SamplePre.Models/Tables/sample_record.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + /// + /// 样本记录 + /// + public class sample_record + { + + public int id { get; set; } + public string qrcode { get; set; } + public string check_item { get; set; } + public string jizhi { get; set; } + public string xuhao { get; set; } + public string standard_id { get; set; } + public string input_user { get; set; } + public DateTime inpu_date { get; set; } + public string weight { get; set; } + + } +} diff --git a/SamplePre.Models/Tables/sys_action.cs b/SamplePre.Models/Tables/sys_action.cs new file mode 100644 index 0000000..03ccaf9 --- /dev/null +++ b/SamplePre.Models/Tables/sys_action.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class sys_action + { + + public string id { get; set; } + public string action_name { get; set; } + + public string action_unit { get; set; } + + public string action_adress { get; set; } + public string plc_type { get; set; } + public string remark { get; set; } + + } +} diff --git a/SamplePre.Models/Tables/sys_action_parm_map.cs b/SamplePre.Models/Tables/sys_action_parm_map.cs new file mode 100644 index 0000000..1407c2c --- /dev/null +++ b/SamplePre.Models/Tables/sys_action_parm_map.cs @@ -0,0 +1,21 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class sys_action_parm_map + { + + [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public int id { get; set; } + public string process_id { get; set; } + public string parm_id { get; set; } + + //public string parm_name { get; set; } + + } +} diff --git a/SamplePre.Models/Tables/sys_dict.cs b/SamplePre.Models/Tables/sys_dict.cs new file mode 100644 index 0000000..63dbc5d --- /dev/null +++ b/SamplePre.Models/Tables/sys_dict.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class sys_dict + { + public string id { get; set; } + public string data_type { get; set; } + public string data_value { get; set; } + + public int class_id { get;set; } + + public string remark { get; set; } + } +} diff --git a/SamplePre.Models/Tables/sys_dict_class.cs b/SamplePre.Models/Tables/sys_dict_class.cs new file mode 100644 index 0000000..01ba1b6 --- /dev/null +++ b/SamplePre.Models/Tables/sys_dict_class.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.Models.Models +{ + public class sys_dict_class + { + + public int id { get; set; } + public string dict_type { get; set; } + public string remark { get; set; } + + + } +} diff --git a/SamplePre.Models/Tables/sys_parm.cs b/SamplePre.Models/Tables/sys_parm.cs new file mode 100644 index 0000000..dee02bc --- /dev/null +++ b/SamplePre.Models/Tables/sys_parm.cs @@ -0,0 +1,25 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class sys_parm + { + [SugarColumn(IsPrimaryKey = true)] + //[SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + public string id { get; set; } + public string title { get; set; } + public string unit { get; set; } + public string data_type { get; set; } + public string data_value { get; set; } + + public string plc_type { get; set; } + + public string param_type { get;set; } + + } +} diff --git a/SamplePre.Models/Tables/sys_standard.cs b/SamplePre.Models/Tables/sys_standard.cs new file mode 100644 index 0000000..0de8d98 --- /dev/null +++ b/SamplePre.Models/Tables/sys_standard.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class sys_standard + { + + public string id { get; set; } + public string sample_id { get; set; } + + //public string sample_name { get; set; } + public string standard_name { get; set; } + + } +} diff --git a/SamplePre.Models/Tables/sys_standard_action.cs b/SamplePre.Models/Tables/sys_standard_action.cs new file mode 100644 index 0000000..3ec590f --- /dev/null +++ b/SamplePre.Models/Tables/sys_standard_action.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class sys_standard_action + { + + + public string id { get; set; } + public string standard_id { get; set; } + public string process_id { get; set; } + //public string process_name { get; set; } + public int process_no { get; set; } + + } +} diff --git a/SamplePre.Models/Tables/sys_standard_action_parm.cs b/SamplePre.Models/Tables/sys_standard_action_parm.cs new file mode 100644 index 0000000..3ebe4a3 --- /dev/null +++ b/SamplePre.Models/Tables/sys_standard_action_parm.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class sys_standard_action_parm + { + //[SugarColum(IsPrimaryKey = true)] + public string id { get; set; } + + public string standard_id { get; set; } + + public string action_id { get; set; } + + public int action_seqno { get; set; } + + public string parm_id { get; set; } + + public int parm_seqno { get; set; } + + public int standard_process_id { get; set; } + + public string data_value { get; set; } + + + + } +} diff --git a/SamplePre.Models/Tables/tube_input.cs b/SamplePre.Models/Tables/tube_input.cs new file mode 100644 index 0000000..c595680 --- /dev/null +++ b/SamplePre.Models/Tables/tube_input.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.Models +{ + public class tube_input + { + public string qrcode { get; set; } + public string item_name { get; set; } + public string tube_type { get; set; } + public string standrad_id { get; set; } + public string standrad { get; set; } + public string input_user { get; set; } + public DateTime input_date { get; set; } + public string weight { get; set; } + public int tube_count { get; set; } + public string bach_no { get; set; } + + } +} diff --git a/SamplePre.ProcessBll/BLL/ActionMangerBll.cs b/SamplePre.ProcessBll/BLL/ActionMangerBll.cs new file mode 100644 index 0000000..cb6413c --- /dev/null +++ b/SamplePre.ProcessBll/BLL/ActionMangerBll.cs @@ -0,0 +1,178 @@ +using DataDAL; +using Models.Ext; +using Models.Models; +using SamplePre.Common; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.ProcessBll.BLL +{ + public class ActionMangerBll + { + + + + public int DelProcessParmMap(int id) + { + + + int val = DBFactory.Instance.Deleteable().Where(p=>p.id == id).ExecuteCommand(); + return val; + } + + public int DelSysActionData(string actionId) + { + var _db = DBFactory.Instance; + + + + try + { + _db.BeginTran(); + + int val = _db.Deleteable().Where(p => p.id == actionId).ExecuteCommand(); + + int val2 = _db.Deleteable().Where(p => p.process_id == actionId).ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + + + return 1; + } + + public List GetProcess_parm_mapByProcessId(string processId) + { + + var result = DBFactory.Instance.Queryable() + .LeftJoin((a, b) => a.parm_id == b.id) + .Where((a, b) => a.process_id == processId && b.title != null) + .Select((a, b) => new sys_action_parm_map_ext + { + id = a.id, + process_id = a.process_id, + parm_id = a.parm_id, + title = b.title, + unit = b.unit, + data_type = b.data_type, + data_value = b.data_value, + plc_type = b.plc_type + + + }) + .ToList(); + + + + return result;//standardDal.GetProcess_parm_mapByProcessId(processId); + } + + /// + /// 获取系统动作字典 + /// + /// + /// + public List GetTreeListSysAction() + { + + List treeListItems = new List(); + + + //获取动作 + List actions = QuerySysAction(); + + //拼装组 + var groups = actions.GroupBy(p => new { p.action_unitname, p.action_unit }).ToList(); + foreach (var item in groups) + { + treeListItems.Add(new sys_action_ext() + { + id = item.Key.action_unit, + action_name = item.Key.action_unitname, + action_unit = "0" + }); + } + + //组织数据 + foreach (var item in actions) + { + treeListItems.Add(item); + } + + + return treeListItems; + + } + + public bool IsExtisPlCcode(string text) + { + var val = DBFactory.Instance.Queryable().Where(p=>p.plc_type == text).ToList(); + if(val.Count > 0) return true; + + return false; + + } + + public List QuerySysAction() + { + var result = DBFactory.Instance.Queryable() + .LeftJoin((a, s) => a.action_unit == s.id) + .Where((a, s) => s.class_id == 2) + .Select((a, s) => new sys_action_ext + { + id = a.id, + action_name = a.action_name, + action_unit = a.action_unit, + action_adress = a.action_adress, + plc_type = a.plc_type, + remark = a.remark, + action_unitname = s.data_value + }) + .ToList(); + + return result; + } + + /// + /// 查询系统动作参数 + /// + /// + public List QuerySysParm() + { + //string querySql = "select * from sys_parm "; + List data = DBFactory.Instance.Queryable().ToList(); + + return data; + } + + /// + /// 保存动作中的参数 + /// + /// + public int SaveActionParm(List actionParams) + { + + int val = DBFactory.Instance.Insertable(actionParams).ExecuteCommand(); + return val; + } + + public int SaveSysAction(sys_action process) + { + int val = DBFactory.Instance.Insertable(process).ExecuteCommand(); + return val; + } + } +} diff --git a/SamplePre.ProcessBll/BLL/CommunicationBll.cs b/SamplePre.ProcessBll/BLL/CommunicationBll.cs new file mode 100644 index 0000000..4ca69e4 --- /dev/null +++ b/SamplePre.ProcessBll/BLL/CommunicationBll.cs @@ -0,0 +1,80 @@ +using Models.Const; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.ProcessBll.BLL +{ + public class CommunicationBll + { + + + /// + /// 读取PLC状态数据-数组 + /// + /// + /// + /// + /// + public ushort[] ReadSateData(int Dbno, int start, int lenth) + { + + if (SystemConst.ProtocolType == Communication.CommProtocolType.S7) + { + //读取下位机状态 + ushort[] data1 = SystemConst.MasterPLC.ReadArraysShort(Dbno, start, lenth); + + return data1; + } + + //这里应该增加一个协议数据解析层,解析后的格式返回给UI,后续完善 + /// + + return null; + } + + /// + /// 写入plc指令,字节数组 + /// + /// + /// + /// + /// + /// + public bool WritePlcData(int Dbno, int start, T[] bytes) + { + bool val = false; + //if (SystemConst.ProtocolType == Communication.CommProtocolType.S7) + //{ + //写入PLC + val = SystemConst.MasterPLC.WriteArraysBtye(Dbno, start, bytes); + //} + //else if (SystemConst.ProtocolType == Communication.CommProtocolType.ModbusTcp) + //{ + // //写入PLC + // val = SystemConst.MasterPLC.WriteArraysBtye(Dbno, start, bytes); + //} + + + return val; + } + + /// + /// 写plc数据,单数据 + /// + /// + /// + /// + public bool WriteSingleData(string Dbno, object obj) + { + //写入PLC + var val = SystemConst.MasterPLC.WriteSingleData(Dbno, obj); + + return val; + } + + + } +} diff --git a/SamplePre.ProcessBll/BLL/MonitorBll.cs b/SamplePre.ProcessBll/BLL/MonitorBll.cs new file mode 100644 index 0000000..c1608b3 --- /dev/null +++ b/SamplePre.ProcessBll/BLL/MonitorBll.cs @@ -0,0 +1,50 @@ +using DataDAL; +using DataDAL.DBContext; +using Models.Const; +using Models.Models; +using Org.BouncyCastle.Utilities; +using SamplePre.Common; +using SamplePre.Communication; +using SamplePre.DAL; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using SamplePre.Models.Models; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.ProcessBll.SampleSequence +{ + /// + /// 样本序列管理业务逻辑 + /// + public class MonitorBll + { + SampleSequenceDal sampleSequenceDal = new SampleSequenceDal(); + + + + SOPDal sopDal = new SOPDal(); + + + public List GetSampleType() + { + + + List data = DBFactory.Instance.Queryable().Where(p => p.class_id == 3).ToList(); + + return data; + + + } + + + } + + +} diff --git a/SamplePre.ProcessBll/BLL/SOPManagerBll.cs b/SamplePre.ProcessBll/BLL/SOPManagerBll.cs new file mode 100644 index 0000000..e7fcd1e --- /dev/null +++ b/SamplePre.ProcessBll/BLL/SOPManagerBll.cs @@ -0,0 +1,518 @@ +using DataDAL; +using Models.Const; +using Models.Ext; +using Models.Models; +using Newtonsoft.Json; +using SamplePre.Common; +using SamplePre.DAL; +using SamplePre.DAL.DBContext; +using SamplePre.Models; +using SamplePre.Models.Ext; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using static System.Collections.Specialized.BitVector32; + +namespace SamplePre.ProcessBll.BLL +{ + public class SOPManagerBll + { + + SOPDal sopDal = new SOPDal(); + + public List GetActionParmById(string actionID) + { + + var result = DBFactory.Instance.Queryable() + .LeftJoin((a, b) => a.parm_id == b.id) + .Where((a, b) => a.process_id == actionID && b.title != null) + .Select((a, b) => new sys_action_parm_map_ext + { + id = a.id, + process_id = a.process_id, + parm_id = a.parm_id, + title = b.title, + unit = b.unit, + data_type = b.data_type, + data_value = b.data_value, + plc_type = b.plc_type + + + }) + .ToList(); + + + //List paramsList = standardDal.GetProcess_parm_mapByProcessId(actionID); + return result;//paramsList; + } + + + public List GetStrandActionParamByStrandId(string standId) + { + + var result = DBFactory.Instance.Queryable() + .LeftJoin< sys_action >((a,b)=>a.action_id == b.id) + .LeftJoin< sys_parm >((a,b,c)=>a.parm_id == c.id) + .Where((a,b,c)=>a.standard_id == standId) + .OrderBy((a,b,c)=>a.action_seqno) + .Select((a,b,c)=> new sys_standard_action_parm_ext { + id = a.id, + standard_id = a.standard_id, + action_id = a.action_id, + action_seqno = a.action_seqno, + parm_id = a.parm_id, + parm_seqno = a.parm_seqno, + standard_process_id = a.standard_process_id, + data_value = a.data_value, + action_name = b.action_name, + title = c.title, + unit = c.unit, + data_type = c.data_type, + plc_type = c.plc_type + }) + .ToList(); + + + //List paramsList = sopDal.GetStrandActionParamByStrandId(standId); + return result; //paramsList; + } + + /// + /// 删除动作下的参数配置 + /// + /// + /// + /// + public int removeActionParmByActionId(string standId, string actionId, int seqno) + { + + var val = DBFactory.Instance.Deleteable(p => p.standard_id == standId && p.action_id == actionId && p.action_seqno == seqno) + .ExecuteCommand(); + return val; + //sopDal.removeActionParmByActionId(standId, actionId, seqno); + } + + /// + /// 删除动作下的参数配置byid + /// + /// + /// + /// + public int removeActionParmByParamId(string standId, string actionId, int seqno,string paramId) + { + + var val = DBFactory.Instance.Deleteable(p => p.standard_id == standId && p.action_id == actionId && p.action_seqno == seqno && p.parm_id == paramId) + .ExecuteCommand(); + return val; + //sopDal.removeActionParmByActionId(standId, actionId, seqno); + } + + + + public int updateStandardActionParm(sys_standard_action_parm item) + { + //sopDal.updateStandardActionParm(item); + + int val = DBFactory.Instance.Updateable() + .SetColumns(p=> new sys_standard_action_parm() { data_value = item.data_value }) + .Where(p=>p.id == item.id) + .ExecuteCommand(); + + return val; + } + + public bool IsExisAction(string actionId) + { + + List data = DBFactory.Instance.Queryable().Where(p => p.action_id == actionId).ToList(); + + return data.Count() > 0 ? true : false; + + } + + + + public List QueryStandardActionByStandardId(string standId) + { + + var result = DBFactory.Instance.Queryable(). + LeftJoin((a, b) => a.process_id == b.id). + Where((a, b) => a.standard_id == standId). + Select((a, b) => new sys_standard_action_ext { + id = a.id, + standard_id = a.standard_id, + process_id = a.process_id, + process_no = a.process_no, + action_name = b.action_name, + remark = b.remark + }).ToList(); + + + return result;//standardDal.QueryStandardActionByStandardId(standId); + } + + + + /// + /// 更新动作序号 + /// + /// + /// + public int UpdateActionSeqno(sys_standard_action_ext action) + { + // return sopDal.UpdateActionSeqno(action); + + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + var val = _db.Updateable() + .SetColumns(it => new sys_standard_action() { process_no = action.new_action_seqno }) + .Where(p => p.standard_id == action.standard_id && p.process_id == action.process_id && p.process_no == action.process_no) + .ExecuteCommand(); + + + ////参数里的动作顺序 + var val2 = _db.Updateable() + .SetColumns(it => new sys_standard_action_parm() { action_seqno = action.new_action_seqno }) + .Where(p => p.standard_id == action.standard_id && p.action_id == action.process_id && p.action_seqno == action.process_no) + .ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + return 1; + } + + /// + /// 删除标准,及标准下的所有配置 + /// + /// + /// + public int DelStandardActionParamByStandId(string standardId) + { + + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + + _db.Deleteable().Where(p => p.id == standardId).ExecuteCommand(); + _db.Deleteable().Where(p => p.standard_id == standardId).ExecuteCommand(); + _db.Deleteable().Where(p => p.standard_id == standardId).ExecuteCommand(); + + _db.CommitTran(); + + + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + return 1; + //return sopDal.DelStandardActionParamByStandId(iD); + } + + /// + /// 获取标准下的动作,动作中包含参数的预览 + /// + /// + /// + public List QueryStandardProcessByStandardId(string standID) + { + return sopDal.QueryStandardProcessByStandardId(standID); + } + + + /// + /// 保存标准动作表、动作参数表 + /// + /// + /// + public int SaveStandardAction_param(sys_standard_action action) + { + //return standardDal.Save_standard_process_map(procemodel); + + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + //保存标准动作 + _db.Insertable(action).ExecuteCommand(); + + + //保存标准动作参数表 + //获取动作下的参数 + List paramList = GetActionParmById(action.process_id); + List new_parms = new List(); + foreach (var item in paramList) + { + //保存标准动作参数表 + sys_standard_action_parm parmmodel = new sys_standard_action_parm() + { + id = Guid.NewGuid().ToString(), + standard_id = action.standard_id, + action_id = action.process_id, + action_seqno = action.process_no, + parm_id = item.parm_id, + data_value = item.data_value, + parm_seqno = item.id + }; + new_parms.Add(parmmodel); + } + _db.Insertable(new_parms).ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + + return 1; + } + + + /// + /// sop导出 + /// + /// + public void ExprotSop(string sysStandardId ,string filePath) + { + //标准信息 + sys_standard sysStandard = DBFactory.Instance.Queryable().Where(p=>p.id == sysStandardId).Single(); + + //标准动作信息 + List standardActions = DBFactory.Instance.Queryable().Where(p => p.standard_id == sysStandardId).ToList(); + + //标准动作信息 + List standardActionsParams = DBFactory.Instance.Queryable().Where(p => p.standard_id == sysStandardId).ToList(); + + + SopDataInfo sopDataInfo = new SopDataInfo(); + sopDataInfo.sysStandard = sysStandard; + sopDataInfo.sysStandActions = standardActions; + sopDataInfo.sysStandardActionParms = standardActionsParams; + + + // 2. 序列化:格式化易读、保留中文 + string jsonStr = JsonConvert.SerializeObject(sopDataInfo); + + // 3. 写入TXT文件 + File.WriteAllText(filePath, jsonStr); + + + } + + /// + /// 导入SOP + /// + /// + /// + public bool ImportSop(string selectFilePath) + { + + string fileContent = File.ReadAllText(selectFilePath, System.Text.Encoding.UTF8); + + SopDataInfo sopDataInfo = JsonConvert.DeserializeObject(fileContent); + + var _db = DBFactory.Instance; + + try + { + //开始事务 + _db.BeginTran(); + + //标准 + sopDataInfo.sysStandard.id = Guid.NewGuid().ToString(); + sopDataInfo.sysStandard.standard_name = sopDataInfo.sysStandard.standard_name + "_imp"; + DBFactory.Instance.Insertable(sopDataInfo.sysStandard).ExecuteCommand(); + + + //标准动作 + foreach (var item in sopDataInfo.sysStandActions) + { + item.id = Guid.NewGuid().ToString(); + item.standard_id = sopDataInfo.sysStandard.id; + } + DBFactory.Instance.Insertable(sopDataInfo.sysStandActions).ExecuteCommand(); + //标准动作参数 + foreach (var item in sopDataInfo.sysStandardActionParms) + { + item.id = Guid.NewGuid().ToString(); + item.standard_id = sopDataInfo.sysStandard.id; + } + DBFactory.Instance.Insertable(sopDataInfo.sysStandardActionParms).ExecuteCommand(); + + //提交事务 + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + + LoggerHelper.Logger.Error(ex.Message); + return false; + } + + + return true; + } + + /// + /// 获取左侧标准树 + /// + /// + /// + public List GetStandardData() + { + List treeListItems = new List(); + + //获取样本 + List yangbens = SystemConst.dictDatas.Where(p => p.class_id == 3).ToList(); //sopBll.QueryGyData(); //standardDal.QueryGyData(); + + foreach (var item in yangbens) + { + treeListItems.Add(new TreeListItem() { ID = item.id, DisplayText = item.data_value, ParentID = "0" }); + } + + //获取标准 + List SopList = QueryAllGyStandards(); //standardDal.QueryAllGyStandards(); + foreach (var item in SopList) + { + treeListItems.Add(new TreeListItem() { ID = item.id, DisplayText = item.standard_name, ParentID = item.sample_id }); + } + + return treeListItems; + } + + /// + /// 获取所有标准 + /// + /// + public List QueryAllGyStandards() + { + List data = DBFactory.Instance.Queryable().ToList(); + return data; + } + + /// + /// 获取动作字典 + /// + /// + /// + public List QuerySysAction() + { + var result = DBFactory.Instance.Queryable() + .LeftJoin((a, s) => a.action_unit == s.id) + .Where((a, s) => s.class_id == 2) + .Select((a, s) => new sys_action_ext + { + id = a.id, + action_name = a.action_name, + action_unit = a.action_unit, + action_adress = a.action_adress, + plc_type = a.plc_type, + remark = a.remark, + action_unitname = s.data_value + }) + .ToList(); + + + return result; + } + + /// + /// 移除标准的动作 + /// + /// + public void removeStandAction(sys_standard_action_ext sysStandardAction) + { + //移除动作 + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + + var va11 = _db.Deleteable(p => p.id == sysStandardAction.id).ExecuteCommand(); + + //移除动作下的参数配置 + var val2 = _db.Deleteable(p => p.standard_id == sysStandardAction.standard_id + && p.action_id == sysStandardAction.process_id + && p.action_seqno == sysStandardAction.process_no).ExecuteCommand(); + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + + } + + } + + /// + /// 保存动作参数配置 + /// + /// + /// + public int SaveStandardActionParam(List actionParms) + { + int val = DBFactory.Instance.Insertable(actionParms).ExecuteCommand(); + + return val; + } + + public int SaveStandardCopy(sys_standard new_sysStandard, List newStandActions, List sysStandardActionParms) + { + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + + _db.Insertable(new_sysStandard).ExecuteCommand(); + + _db.Insertable(newStandActions).ExecuteCommand(); + + _db.Insertable(sysStandardActionParms).ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + + return 1; + } + } +} diff --git a/SamplePre.ProcessBll/BLL/SampleSequenceBll.cs b/SamplePre.ProcessBll/BLL/SampleSequenceBll.cs new file mode 100644 index 0000000..4297158 --- /dev/null +++ b/SamplePre.ProcessBll/BLL/SampleSequenceBll.cs @@ -0,0 +1,539 @@ +using DataDAL; +using DataDAL.DBContext; +using Models.Models; +using SamplePre.Common; +using SamplePre.DAL; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using SamplePre.Models.Models; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.ProcessBll.SampleSequence +{ + /// + /// 样本序列管理业务逻辑 + /// + public class SampleSequenceBll + { + SampleSequenceDal sampleSequenceDal = new SampleSequenceDal(); + + + + SOPDal sopDal = new SOPDal(); + + + public List GetSampleType() + { + + + List data = DBFactory.Instance.Queryable().Where(p => p.class_id == 3).ToList(); + + return data; + + + } + + + /// + /// 获取标准动作参数 + /// + /// + /// + public List GetStrandActionParamByStrandId(string standId) + { + var result = DBFactory.Instance.Queryable() + .LeftJoin((a, b) => a.action_id == b.id) + .LeftJoin((a, b, c) => a.parm_id == c.id) + .LeftJoin((a, b, c,d) => a.standard_id == d.id) + .Where((a, b, c, d) => a.standard_id == standId) + .OrderBy((a, b, c, d) => a.action_seqno) + .Select((a, b, c, d) => new sys_standard_action_parm_ext + { + id = a.id, + standard_id = a.standard_id, + action_id = a.action_id, + action_seqno = a.action_seqno, + parm_id = a.parm_id, + parm_seqno = a.parm_seqno, + standard_process_id = a.standard_process_id, + data_value = a.data_value, + action_name = b.action_name, + title = c.title, + unit = c.unit, + data_type = c.data_type, + plc_type = c.plc_type, + actionAndseqno = $"{d.standard_name}: {a.action_seqno}{b.action_name}" + }) + .ToList(); + + + + //List datas = sopDal.GetStrandActionParamByStrandId(standId); + + return result; + } + + public List QuerySysAction() + { + var result = DBFactory.Instance.Queryable() + .LeftJoin((a, s) => a.action_unit == s.id) + .Where((a, s) => s.class_id == 2) + .Select((a, s) => new sys_action_ext + { + id = a.id, + action_name = a.action_name, + action_unit = a.action_unit, + action_adress = a.action_adress, + plc_type = a.plc_type, + remark = a.remark, + action_unitname = s.data_value + }) + .ToList(); + + //List sysActions = standardDal.QuerySysAction(); + + return result; + } + + public int DelTubeInputByCode(string code) + { + + + int val = DBFactory.Instance.Deleteable().Where(p => p.qrcode == code).ExecuteCommand(); + + return val; + } + + /// + /// 保存下发命令记录 + /// + /// + /// + public int SaveCmdExec(sample_exec_ext cmdExec) + { + + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + + //主记录 + int val = _db.Insertable(cmdExec).ExecuteCommand(); + //明细 + int val2 = _db.Insertable(cmdExec.sampleExecDetails).ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + + return 1; + + } + + public List QuerySysStandards(string sampleId) + { + + List data = DBFactory.Instance.Queryable().Where(p => p.sample_id == sampleId).ToList(); + + return data; + } + + public string QueryQrcode() + { + string qrcode = ""; + + List data = DBFactory.Instance.Queryable().Where(p => p.class_id == 1).ToList(); + if (data.Count > 0) + { + qrcode = (int.Parse(data[0].data_value) + 1).ToString("0000"); + } + return qrcode; + + } + + public int SaveDataAndQrcode(tube_input qRcode, sys_dict sys_Dict) + { + + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + + //保存样品记录 + _db.Insertable(qRcode).ExecuteCommand(); + + //更新二维码 + int val = _db.Updateable() + .SetColumns(p => new sys_dict() { data_value = sys_Dict.data_value }) + .Where(p => p.class_id == 1) + .ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + + return 1; + } + + public List GetTubeData(DateTime dt1, DateTime dt2) + { + List data = DBFactory.Instance.Queryable().Where(p => p.input_date >= dt1 && p.input_date <= dt2).ToList(); + + + return data;; + } + + /// + /// 生成指令字节数组byte + /// + /// + /// + /// + public List CreateCmdBytes(List sysAction, List sopIds, List standardProcessParms) + { + string cmdReamrk = ""; + + List sop = new List(); + + try + { + //起始位 + sop.Insert(0, 0xCC); + cmdReamrk += $"【0 开始:{sop[0]}】 "; + + //插入总字节数-占位 + sop.Insert(1, 0); + //cmdReamrk += $"【1 总字节数:{Convert.ToByte(seq + 1)}】 "; + + //插入总动作数 + sop.Insert(2, 0); + //cmdReamrk += $"【2 总动作数:0】 "; + + int seq = 3; + + //总动作数 + int actionCount = 0; + //=============== + foreach (string standrad_id in sopIds) + { + //查询标准下的动作 + var standardActions = GetStrandActionByStrandId(standrad_id); + //动作排序 + standardActions = standardActions.OrderBy(p => p.process_no).ToList(); + + actionCount += standardActions.Count(); + + foreach (var actionItem in standardActions) + { + //int start = seq; //记录起始位置 + + //转换PLC映射名称 + string action_plc = sysAction.FirstOrDefault(p => p.id == actionItem.process_id)?.plc_type; + //动作类型(如:离心) + byte action_byte = Convert.ToByte(action_plc); + sop.Insert(seq, action_byte); + cmdReamrk += $"【{seq} 动作:{sop[seq]}】 "; + seq++; + + //查询动作下的参数 + var paramData = standardProcessParms.Where(p => p.action_id == actionItem.process_id && p.action_seqno == actionItem.process_no && p.standard_id == standrad_id).ToList(); + //插入动作字节长度 + int actionLenth = (int)(paramData.Count() * 5 + 2); + sop.Insert(seq, (byte)actionLenth); + cmdReamrk += $"【{seq} 动作字节长度:{sop[seq]}】 "; + seq++; + + foreach (var item in paramData) + { + //转换plc参数类型 + string param_plc = item.plc_type;//parms.FirstOrDefault(p => p.title == item.title).plc_type; + + //参数类型(如:时间) + byte parm_byte = Convert.ToByte(param_plc); + sop.Insert(seq, parm_byte); + cmdReamrk += $"【{seq} 参数类型:{sop[seq]}】 "; + seq++; + + + sys_standard_action_parm_ext actionParm = standardProcessParms.FirstOrDefault(p => p.title == item.title); + string param_val = actionParm.data_value; + if (actionParm.unit.ToUpper() == "ML") //都转换成最小单位ul + { + param_val = (float.Parse(param_val) * 1000).ToString(); + } + + + //参数值 + float paramval = 0; + paramval = float.Parse(param_val); + + cmdReamrk += $"【{seq} 参数值float:{paramval}】 "; + + + byte[] paramval_bytes = BitConverter.GetBytes(paramval); + + sop.Insert(seq, paramval_bytes[0]); + cmdReamrk += $"【{seq} 参数值byte:{sop[seq]}-"; + seq++; + sop.Insert(seq, paramval_bytes[1]); + cmdReamrk += $"{sop[seq]}-"; + seq++; + sop.Insert(seq, paramval_bytes[2]); + cmdReamrk += $"{sop[seq]}-"; + seq++; + sop.Insert(seq, paramval_bytes[3]); + cmdReamrk += $"{sop[seq]}】 "; + seq++; + + } + + + } + + } + + + //================= + + + + + + + //结束 + sop.Insert(seq, 0xEE); + cmdReamrk += $"【{seq} 结束:{sop[seq]}-"; + seq++; + sop.Insert(seq, 0xEE); + cmdReamrk += $"{sop[seq]}】 "; + seq++; + + + //修改总字节数 + sop[1] = (byte)sop.Count; + cmdReamrk += $"【1 总字节数:{sop[1]}】 "; + + //修改总动作数据 + sop[2] = (byte)actionCount; + cmdReamrk += $"【2 总动作数:{sop[2]}】 "; + + LoggerHelper.Logger.Info($"{cmdReamrk}"); + + + return sop; + } + catch (Exception ex) + { + + LoggerHelper.Logger.Error(ex.StackTrace); + + + return null; + } + } + + + /// + /// 生成指令字节数组ushort + /// + /// + /// + /// + public List CreateCmdUshorts(List sysAction, List standardActions, List standardProcessParms) + { + string cmdReamrk = ""; + + List sop = new List(); + + try + { + //起始位 + sop.Insert(0, 0xCC); + cmdReamrk += $"【0 开始:{sop[0]}】 "; + + //插入总字节数 + sop.Insert(1, 0); + //cmdReamrk += $"【1 总字节数:{0}】 "; + + //插入总动作数 + sop.Insert(2, Convert.ToByte(standardActions.Count())); + cmdReamrk += $"【2 总动作数:{Convert.ToByte(standardActions.Count())}】 "; + + + + int seq = 3; + foreach (var actionItem in standardActions) + { + int start = seq; //记录起始位置 + + //转换PLC映射名称 + string action_plc = sysAction.FirstOrDefault(p => p.id == actionItem.process_id)?.plc_type; + //动作类型(如:离心) + ushort action_byte = Convert.ToUInt16(action_plc); + sop.Insert(seq, action_byte); + cmdReamrk += $"【{seq} 动作:{sop[seq]}】 "; + seq++; + + //查询动作下的参数 + var paramData = standardProcessParms.Where(p => p.action_id == actionItem.process_id && p.action_seqno == actionItem.process_no).ToList(); + //插入动作寄存器长度 + int actionLenth = (int)(paramData.Count() * 3 + 2); + sop.Insert(seq, (byte)actionLenth); + cmdReamrk += $"【{seq} 动作长度:{sop[seq]}】 "; + seq++; + + foreach (var item in paramData) + { + //转换plc参数类型 + string param_plc = item.plc_type;//parms.FirstOrDefault(p => p.title == item.title).plc_type; + + //参数类型(如:时间) + ushort parm_byte = Convert.ToUInt16(param_plc); + sop.Insert(seq, parm_byte); + cmdReamrk += $"【{seq} 参数类型:{sop[seq]}】 "; + seq++; + + + sys_standard_action_parm_ext actionParm = standardProcessParms.FirstOrDefault(p => p.title == item.title); + string param_val = actionParm.data_value; + if (actionParm.unit.ToUpper() == "ML") //都转换成最小单位ul + { + param_val = (float.Parse(param_val) * 1000).ToString(); + } + + + //参数值 + float paramval = 0; + paramval = float.Parse(param_val); + + cmdReamrk += $"【{seq} 参数值float:{paramval}】 "; + + //===float转ushort数组 + byte[] bytes = BitConverter.GetBytes(paramval); + var a = BitConverter.ToUInt16(new byte[] { bytes[0], bytes[1] }, 0); + var b = BitConverter.ToUInt16(new byte[] { bytes[2], bytes[3] }, 0); + + ushort[] ushorts = { b, a }; + + sop.Insert(seq, ushorts[0]); + cmdReamrk += $"【{seq} 参数值ushort:{sop[seq]}-"; + seq++; + + sop.Insert(seq, ushorts[1]); + cmdReamrk += $"{sop[seq]}】 "; + seq++; + + //============ + + + } + + + } + + + + //结束 + sop.Insert(seq, 0xEE); + cmdReamrk += $"【{seq} 结束:{sop[seq]}-"; + seq++; + sop.Insert(seq, 0xEE); + cmdReamrk += $"{sop[seq]}】 "; + seq++; + + + //修改总寄存器数量 + sop[1] = (ushort)sop.Count; + cmdReamrk += $"【1 总寄存器数:{sop[1]}】 "; + + LoggerHelper.Logger.Info($"{cmdReamrk}"); + + + return sop; + } + catch (Exception ex) + { + + LoggerHelper.Logger.Error(ex.StackTrace); + + + return null; + } + } + + + + public List GetSampleExecDetails() + { + var result = DBFactory.Instance.Queryable() + .LeftJoin((a, b) => a.master_id == b.id) + .LeftJoin((a, b, c) => a.qrcode == c.qrcode) + .Where((a, b, c) => b.exec_state == "执行中") + .Select((a, b, c) => new sample_exec_detail_ext { + id = a.id, + master_id = a.master_id, + qrcode = a.qrcode, + exec_state = b.exec_state, + item_name= c.item_name, + standrad_id = c.standrad_id, + standrad = c.standrad, + input_date = c.input_date, + input_user = c.input_user + + }) + .ToList(); + + + return result;// sampleSequenceDal.GetSampleExecDetails(); + } + + public List QueryTubeInputByBachNo(string bachNo) + { + return DBFactory.Instance.Queryable().Where(p => p.bach_no == bachNo).ToList(); + } + + public List GetStrandActionByStrandId(string standrad_id) + { + + + List data = DBFactory.Instance.Queryable() + .LeftJoin((a, b) => a.process_id == b.id) + .Where((a, b) => a.standard_id == standrad_id) + .Select((a, b) => new sys_standard_action_ext + { + id = a.id, + standard_id = a.standard_id, + process_id = a.process_id, + process_no = a.process_no, + action_name = b.action_name, + remark = b.remark + }) + .ToList(); + + return data; + } + } + + +} diff --git a/SamplePre.ProcessBll/BLL/SysParamBll.cs b/SamplePre.ProcessBll/BLL/SysParamBll.cs new file mode 100644 index 0000000..c6559cd --- /dev/null +++ b/SamplePre.ProcessBll/BLL/SysParamBll.cs @@ -0,0 +1,86 @@ +using Models.Models; +using SamplePre.DAL; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.ProcessBll.BLL +{ + public class SysParamBll + { + public int DelSysParm(string id) + { + + int val = DBFactory.Instance.Deleteable().Where(p => p.id == id).ExecuteCommand(); + + return val; + } + + /// + /// 判断该参数是否被使用,已使用不能删除 + /// + /// + /// + /// + public bool IsExtisActionParam(string parmId) + { + + //动作参数 + List data = DBFactory.Instance.Queryable() + .Where(p=>p.parm_id == parmId).ToList(); + if(data.Count > 0) return true; + + //标准动作参数配置表 + List data2 = DBFactory.Instance.Queryable() + .Where(p => p.parm_id == parmId).ToList(); + if (data2.Count > 0) return true; + + + return false; + } + + /// + /// 判断plc编码是否存在 + /// + /// + /// + public bool IsExtisPlCcode(string plcCode) + { + List data2 = DBFactory.Instance.Queryable() + .Where(p => p.plc_type == plcCode).ToList(); + if (data2.Count > 0) return true; + + return false; + } + + public List QuerySysParm() + { + + List data = DBFactory.Instance.Queryable().ToList(); + + return data; + } + + public int SaveSysParm(sys_parm parm) + { + int val = DBFactory.Instance.Insertable(parm).ExecuteCommand(); + return val; + } + + /// + /// 更新参数数据 + /// + /// + /// + public int UpdateSysParm(sys_parm parm) + { + int val = DBFactory.Instance.Updateable(parm).ExecuteCommand(); + + return val; + } + } +} diff --git a/SamplePre.ProcessBll/BLL/SystemBll.cs b/SamplePre.ProcessBll/BLL/SystemBll.cs new file mode 100644 index 0000000..b97ac72 --- /dev/null +++ b/SamplePre.ProcessBll/BLL/SystemBll.cs @@ -0,0 +1,107 @@ +using DataDAL; +using Models.Ext; +using Models.Models; +using S7.Net.Types; +using SamplePre.DAL; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using SamplePre.Models.Models; +using SamplePre.Models.Tables; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SamplePre.ProcessBll.BLL +{ + public class SystemBll + { + + + SystemDal systemDal = new SystemDal(); + + + public int DelDictClassById(int classid) + { + var val = DBFactory.Instance.Deleteable(p => p.id == classid).ExecuteCommand(); + return val; + } + + public int DelSysDictByid(sys_dict sys_Dict) + { + var val = DBFactory.Instance.Deleteable(p => p.id == sys_Dict.id).ExecuteCommand(); + + return val; + } + + + /// + /// 根据分类id查询字典明细 + /// + /// + /// + public List QueryDictByClassId(int classid) + { + List data = DBFactory.Instance.Queryable().Where(p => p.class_id == classid).ToList(); + + return data; + } + + /// + /// 查询字典分类 + /// + /// + public List QueryDictClassData() + { + List data = DBFactory.Instance.Queryable().ToList(); + return data; + } + + public List QueryDictData() + { + List data = DBFactory.Instance.Queryable().ToList(); + + return data; + } + + public int SaveSysDict(sys_dict sysDict) + { + var val = DBFactory.Instance.Insertable(sysDict).ExecuteCommand(); + return val; + } + + public int SaveSysDictClass(sys_dict_class sysDictClass) + { + var val = DBFactory.Instance.Insertable(sysDictClass).ExecuteCommand(); + return val; + } + + + + /// + /// 查询系统功能 + /// + /// + /// + public List QueryFunctionList() + { + List data = DBFactory.Instance.Queryable().ToList(); + + List newData = new List(); + foreach (var item in data.Where(p=>p.parent_id == 0)) + { + foreach(var newItem in data.Where(p => p.parent_id == item.id).ToList()) + { + newItem.description = item.name; + newData.Add(newItem); + } + + } + + return newData; + } + + } +} diff --git a/SamplePre.ProcessBll/ConfigManagerBLL/RolesBll.cs b/SamplePre.ProcessBll/ConfigManagerBLL/RolesBll.cs new file mode 100644 index 0000000..ab49f93 --- /dev/null +++ b/SamplePre.ProcessBll/ConfigManagerBLL/RolesBll.cs @@ -0,0 +1,159 @@ +using DataDAL; +using Models.Const; +using Models.Ext; +using Models.Models; +using SamplePre.Common; +using SamplePre.Common.Helper; +using SamplePre.DAL; +using SamplePre.DAL.DBContext; +using SamplePre.Models; +using SamplePre.Models.Ext; +using SamplePre.Models.Tables; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static System.Collections.Specialized.BitVector32; + +namespace SamplePre.ProcessBll.BLL +{ + public class RolesBll + { + + + /// + /// 删除角色 + /// + /// + /// + /// + public int DeleteRole(config_role role) + { + + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + var val = _db.Deleteable(role) + .Where(p => p.id == role.id) + .ExecuteCommand(); + + + //// + //删除角色权限 + _db.Deleteable().Where(p => p.role_id == role.id).ExecuteCommand(); + + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + return 1; + + } + + /// + /// 获取功能树 + /// + /// + /// + public List GetFuncDataTree() + { + List funcList = DBFactory.Instance.Queryable().ToList(); + List funcList2 = new List(); + + foreach(var item in funcList) + { + config_function_ext ext = new config_function_ext(); + ext.code = item.code; + ext.id = item.id; + ext.name = item.name; + ext.description = item.description; + ext.IsChecked = false; + ext.parent_id = item.parent_id; + + funcList2.Add(ext); + } + + return funcList2; + + } + + /// + /// 获取角色的权限id集合 + /// + /// + /// + public List GetPermission(string id) + { + var list = DBFactory.Instance.Queryable() + .Where(p => p.role_id == id) + .Select(p => p.function_id) + .ToList(); + + return list; + } + + public List GetRoles() + { + List roles = DBFactory.Instance.Queryable().ToList(); + + return roles; + } + + public int SavePermission(List rolePermissonList) + { + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + + //先删除 + var val = _db.Deleteable() + .Where(p => p.role_id == rolePermissonList[0].role_id) + .ExecuteCommand(); + + + ///保存权限 + DBFactory.Instance.Insertable(rolePermissonList).ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + return 1; + + + + } + + public int SaveRoleData(config_role configRole) + { + var val = DBFactory.Instance.Insertable(configRole).ExecuteCommand(); + + return val; + } + + public int UpdateRoleData(config_role configRole) + { + var val = DBFactory.Instance.Updateable(configRole).ExecuteCommand(); + + return val; + } + } +} diff --git a/SamplePre.ProcessBll/ConfigManagerBLL/UsersBll.cs b/SamplePre.ProcessBll/ConfigManagerBLL/UsersBll.cs new file mode 100644 index 0000000..0b7ec0b --- /dev/null +++ b/SamplePre.ProcessBll/ConfigManagerBLL/UsersBll.cs @@ -0,0 +1,176 @@ +using DataDAL; +using Models.Const; +using Models.Ext; +using Models.Models; +using SamplePre.Common; +using SamplePre.DAL; +using SamplePre.DAL.DBContext; +using SamplePre.Models.Ext; +using SamplePre.Models.Tables; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static System.Collections.Specialized.BitVector32; + +namespace SamplePre.ProcessBll.BLL +{ + public class UsersBll + { + + SystemDal systemDal = new SystemDal(); + + /// + /// 获取用户数据 + /// + /// + public List GetUsers() + { + //List users = DBFactory.Instance.Queryable().ToList(); + + var users = systemDal.QueryUserData(); + return users; + } + + + public List GetRoles() + { + List roles = DBFactory.Instance.Queryable() + .ToList(); + + return roles; + } + + public int SaveUserData(config_user configUser, List roles) + { + //throw new NotImplementedException(); + + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + var val = _db.Insertable(configUser).ExecuteCommand(); + + var val2 = _db.Insertable(roles).ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + return 1; + + + } + + public int UpdateUserData(config_user configUser, List roles) + { + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + var val = _db.Updateable() + .SetColumns(it => new config_user() { username = configUser.username + ,password = configUser.password + ,is_enabled = configUser.is_enabled }) + .Where(p => p.id == configUser.id) + .ExecuteCommand(); + + + ////用户角色 + //先删除,后插入 + _db.Deleteable().Where(p => p.user_id == configUser.id).ExecuteCommand(); + var val2 = _db.Insertable(roles).ExecuteCommand(); + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + return 1; + } + + public int DeleteUser(config_user user) + { + var _db = DBFactory.Instance; + + try + { + _db.BeginTran(); + var val = _db.Deleteable(user) + .Where(p => p.id == user.id) + .ExecuteCommand(); + + + //// + //先删除用户角色 + _db.Deleteable().Where(p => p.user_id == user.id).ExecuteCommand(); + + + _db.CommitTran(); + } + catch (Exception ex) + { + _db.RollbackTran(); + LoggerHelper.Logger.Error(ex.Message); + return -1; + } + + return 1; + } + + public List GetUserRoles(string userId) + { + + var result = DBFactory.Instance.Queryable() + .Where(a=> a.user_id == userId) + .ToList(); + + + + return result; + } + + + public bool CheckUser(string userName, string pwd) + { + var users = DBFactory.Instance.Queryable().Where(p => p.username == userName && p.password == pwd).Single(); + if(users == null || string.IsNullOrEmpty(users.username)) return false; + + SystemConst.loginUserInfo.user = users; + + //查询用户权限 + var result = DBFactory.Instance.Queryable() + .RightJoin((a, b) => a.role_id == b.role_id) + .LeftJoin((a, b, c) => b.function_id == c.id) + .Where((a, b, c) => a.user_id == users.id) + .Select((a, b, c) => new config_function + { + id = c.id, + name = c.name, + code = c.code, + parent_id = c.parent_id, + description = c.description + }) + .ToList(); + + SystemConst.loginUserInfo.functions = result; + + return true; + } + + + } +} diff --git a/SamplePre.ProcessBll/SamplePre.ProcessBll.csproj b/SamplePre.ProcessBll/SamplePre.ProcessBll.csproj new file mode 100644 index 0000000..163a4e6 --- /dev/null +++ b/SamplePre.ProcessBll/SamplePre.ProcessBll.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/SamplePre.ViewModel/Class1.cs b/SamplePre.ViewModel/Class1.cs new file mode 100644 index 0000000..d67b6bd --- /dev/null +++ b/SamplePre.ViewModel/Class1.cs @@ -0,0 +1,7 @@ +namespace SamplePre.ViewModel +{ + public class Class1 + { + + } +} diff --git a/SamplePre.ViewModel/SamplePre.ViewModel.csproj b/SamplePre.ViewModel/SamplePre.ViewModel.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/SamplePre.ViewModel/SamplePre.ViewModel.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/SamplePreSystem.UI/Assets/App.png b/SamplePreSystem.UI/Assets/App.png new file mode 100644 index 0000000..d281cd4 Binary files /dev/null and b/SamplePreSystem.UI/Assets/App.png differ diff --git a/SamplePreSystem.UI/Assets/Warning.png b/SamplePreSystem.UI/Assets/Warning.png new file mode 100644 index 0000000..04e242b Binary files /dev/null and b/SamplePreSystem.UI/Assets/Warning.png differ diff --git a/SamplePreSystem.UI/Assets/login.png b/SamplePreSystem.UI/Assets/login.png new file mode 100644 index 0000000..73df206 Binary files /dev/null and b/SamplePreSystem.UI/Assets/login.png differ diff --git a/SamplePreSystem.UI/Assets/progressBar.png b/SamplePreSystem.UI/Assets/progressBar.png new file mode 100644 index 0000000..4d332d0 Binary files /dev/null and b/SamplePreSystem.UI/Assets/progressBar.png differ diff --git a/SamplePreSystem.UI/Assets/分液1.png b/SamplePreSystem.UI/Assets/分液1.png new file mode 100644 index 0000000..49f856b Binary files /dev/null and b/SamplePreSystem.UI/Assets/分液1.png differ diff --git a/SamplePreSystem.UI/Assets/加液1.png b/SamplePreSystem.UI/Assets/加液1.png new file mode 100644 index 0000000..c1a4411 Binary files /dev/null and b/SamplePreSystem.UI/Assets/加液1.png differ diff --git a/SamplePreSystem.UI/Assets/固相萃取1.png b/SamplePreSystem.UI/Assets/固相萃取1.png new file mode 100644 index 0000000..0b9b779 Binary files /dev/null and b/SamplePreSystem.UI/Assets/固相萃取1.png differ diff --git a/SamplePreSystem.UI/Assets/机器人1.png b/SamplePreSystem.UI/Assets/机器人1.png new file mode 100644 index 0000000..b64f374 Binary files /dev/null and b/SamplePreSystem.UI/Assets/机器人1.png differ diff --git a/SamplePreSystem.UI/Assets/样品管理.png b/SamplePreSystem.UI/Assets/样品管理.png new file mode 100644 index 0000000..f2603ac Binary files /dev/null and b/SamplePreSystem.UI/Assets/样品管理.png differ diff --git a/SamplePreSystem.UI/Assets/氮吹1.png b/SamplePreSystem.UI/Assets/氮吹1.png new file mode 100644 index 0000000..a5b202b Binary files /dev/null and b/SamplePreSystem.UI/Assets/氮吹1.png differ diff --git a/SamplePreSystem.UI/Assets/离心机1.png b/SamplePreSystem.UI/Assets/离心机1.png new file mode 100644 index 0000000..d31ef9d Binary files /dev/null and b/SamplePreSystem.UI/Assets/离心机1.png differ diff --git a/SamplePreSystem.UI/BaseControls/BaseWindow.cs b/SamplePreSystem.UI/BaseControls/BaseWindow.cs new file mode 100644 index 0000000..eac6395 --- /dev/null +++ b/SamplePreSystem.UI/BaseControls/BaseWindow.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace SamplePre.UIWpf.BaseWindows +{ + public class BaseWindow : Window + { + public BaseWindow() + { + //InitializeStyle(); + //this.Loaded += delegate + //{ + // InitializeEvent(); + //}; + + InitializeStyle(); + // 一定要在 Loaded 里执行,确保模板已加载 + Loaded += (s, e) => InitializeEvent(); + + + } + + + private void InitializeEvent() + { + // ✅ 关键:从可视化树查找模板内的元素 + Button btnMin = FindChild