林豪 左 2 years ago
parent
commit
77f801f3c3

+ 167 - 18
WCS.Core/BaseExtensions/TypeExtension.cs

@@ -1,4 +1,5 @@
-using SqlSugar;
+using FreeRedis;
+using SqlSugar;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
@@ -6,12 +7,13 @@ using System.Data;
 using System.Linq;
 using System.Reflection;
 using System.Security.Cryptography;
+using System.Text;
 using WCS.Core.Log;
 
 namespace WCS.Core.BaseExtensions
 {
     /// <summary>
-    ///
+    /// 类型转换扩展
     /// </summary>
     public static class TypeExtension
     {
@@ -84,13 +86,13 @@ namespace WCS.Core.BaseExtensions
         /// <returns></returns>
         public static D Mapper<D, S>(S s)
         {
-            D d = Activator.CreateInstance<D>();
+            var d = Activator.CreateInstance<D>();
 
-            var sType = s.GetType();
+            var sType = s?.GetType();
             var dType = typeof(D);
-            foreach (PropertyInfo sP in sType.GetProperties())
+            foreach (var sP in sType.GetProperties())
             {
-                foreach (PropertyInfo dP in dType.GetProperties())
+                foreach (var dP in dType.GetProperties())
                 {
                     if (dP.Name == sP.Name)
                     {
@@ -112,11 +114,11 @@ namespace WCS.Core.BaseExtensions
         /// <returns></returns>
         public static Dictionary<string, object> EntityClassToDictionary<T>(T t)
         {
-            Type type = typeof(SugarColumn);
+            var type = typeof(SugarColumn);
             Dictionary<string, object> d = new Dictionary<string, object>();
 
             var sType = t.GetType();
-            foreach (PropertyInfo sP in sType.GetProperties())
+            foreach (var sP in sType.GetProperties())
             {
                 if (sP.CustomAttributes.Any(v => v.AttributeType == type) && sP.Name != "VER" && sP.Name != "ID")
                 {
@@ -134,12 +136,12 @@ namespace WCS.Core.BaseExtensions
         /// <returns></returns>
         public static string GetMD5(this string myString)
         {
-            MD5 md5 = MD5.Create();
-            byte[] fromData = System.Text.Encoding.Unicode.GetBytes(myString);
-            byte[] targetData = md5.ComputeHash(fromData);
+            var md5 = MD5.Create();
+            var fromData = System.Text.Encoding.Unicode.GetBytes(myString);
+            var targetData = md5.ComputeHash(fromData);
             string byte2String = null;
 
-            for (int i = 0; i < targetData.Length; i++)
+            for (var i = 0; i < targetData.Length; i++)
             {
                 byte2String += targetData[i].ToString("x");
             }
@@ -155,15 +157,15 @@ namespace WCS.Core.BaseExtensions
         /// <returns></returns>
         public static List<object> TableToEntity(this DataTable dt, string typeName)
         {
-            List<object> list = new List<object>();
+            var list = new List<object>();
             try
             {
                 foreach (DataRow row in dt.Rows)
                 {
-                    Type entity = Type.GetType(typeName);
+                    var entity = Type.GetType(typeName);
                     PropertyInfo[] pArray = entity.GetType().GetProperties();
 
-                    foreach (PropertyInfo p in pArray)
+                    foreach (var p in pArray)
                     {
                         if (dt.Columns.Contains(p.Name))
                         {
@@ -171,12 +173,12 @@ namespace WCS.Core.BaseExtensions
                             var value = row[p.Name];
                             if (value != DBNull.Value)
                             {
-                                Type targetType = p.PropertyType;
-                                Type convertType = targetType;
+                                var targetType = p.PropertyType;
+                                var convertType = targetType;
                                 if (targetType.IsGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                                 {
                                     //可空类型
-                                    NullableConverter nullableConverter = new NullableConverter(targetType);
+                                    var nullableConverter = new NullableConverter(targetType);
                                     convertType = nullableConverter.UnderlyingType;
                                 }
                                 if (!string.IsNullOrEmpty(convertType.FullName) && !string.IsNullOrEmpty(value.ToString()))
@@ -233,5 +235,152 @@ namespace WCS.Core.BaseExtensions
             }
             return list;
         }
+
+        /// <summary>
+        /// 对象转换成二进制流
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public static byte[] ObjectToByte(this object obj)
+        {
+            var stream = new System.IO.MemoryStream();
+            System.Runtime.Serialization.IFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
+            bf.Serialize(stream, obj);
+            var bytes = stream.GetBuffer();
+            stream.Close();
+            return bytes;
+        }
+
+        /// <summary>
+        /// 反序列化二进制
+        /// </summary>
+        /// <param name="valueRaw"></param>
+        /// <param name="encoding"></param>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        public static T DeserializeRedisValue<T>(byte[] valueRaw, Encoding encoding)
+        {
+            if (valueRaw == null) return default(T);
+            var type = typeof(T);
+            var typename = type.ToString().TrimEnd(']');
+            switch (typename)
+            {
+                case "System.Byte[":
+                    return (T)Convert.ChangeType(valueRaw, type);
+                case "System.String":
+                    return (T)Convert.ChangeType(encoding.GetString(valueRaw), type);
+                case "System.Boolean[":
+                    return (T)Convert.ChangeType(valueRaw.Select(a => a == 49).ToArray(), type);
+            }
+
+            if (valueRaw.Length == 0) return default(T);
+
+            string valueStr = null;
+            if (type.IsValueType)
+            {
+                valueStr = encoding.GetString(valueRaw);
+                var isNullable = typename.StartsWith("System.Nullable`1[");
+                var basename = isNullable ? typename.Substring(18) : typename;
+
+                var isElse = false;
+                object obj = null;
+                switch (basename)
+                {
+                    case "System.Boolean":
+                        obj = valueStr switch
+                        {
+                            "1" => true,
+                            "0" => false,
+                            _ => obj
+                        };
+                        break;
+
+                    case "System.Byte":
+                        if (byte.TryParse(valueStr, out var trybyte)) obj = trybyte;
+                        break;
+
+                    case "System.Char":
+                        if (valueStr.Length > 0) obj = valueStr[0];
+                        break;
+
+                    case "System.Decimal":
+                        if (Decimal.TryParse(valueStr, out var trydec)) obj = trydec;
+                        break;
+
+                    case "System.Double":
+                        if (Double.TryParse(valueStr, out var trydb)) obj = trydb;
+                        break;
+
+                    case "System.Single":
+                        if (Single.TryParse(valueStr, out var trysg)) obj = trysg;
+                        break;
+
+                    case "System.Int32":
+                        if (Int32.TryParse(valueStr, out var tryint32)) obj = tryint32;
+                        break;
+
+                    case "System.Int64":
+                        if (Int64.TryParse(valueStr, out var tryint64)) obj = tryint64;
+                        break;
+
+                    case "System.SByte":
+                        if (SByte.TryParse(valueStr, out var trysb)) obj = trysb;
+                        break;
+
+                    case "System.Int16":
+                        if (Int16.TryParse(valueStr, out var tryint16)) obj = tryint16;
+                        break;
+
+                    case "System.UInt32":
+                        if (UInt32.TryParse(valueStr, out var tryuint32)) obj = tryuint32;
+                        break;
+
+                    case "System.UInt64":
+                        if (UInt64.TryParse(valueStr, out var tryuint64)) obj = tryuint64;
+                        break;
+
+                    case "System.UInt16":
+                        if (UInt16.TryParse(valueStr, out var tryuint16)) obj = tryuint16;
+                        break;
+
+                    case "System.DateTime":
+                        if (DateTime.TryParse(valueStr, out var trydt)) obj = trydt;
+                        break;
+
+                    case "System.DateTimeOffset":
+                        if (DateTimeOffset.TryParse(valueStr, out var trydtos)) obj = trydtos;
+                        break;
+
+                    case "System.TimeSpan":
+                        if (Int64.TryParse(valueStr, out tryint64)) obj = new TimeSpan(tryint64);
+                        break;
+
+                    case "System.Guid":
+                        if (Guid.TryParse(valueStr, out var tryguid)) obj = tryguid;
+                        break;
+
+                    default:
+                        isElse = true;
+                        break;
+                }
+
+                if (isElse == false)
+                {
+                    if (obj == null) return default(T);
+                    return (T)obj;
+                }
+            }
+
+            valueStr ??= encoding.GetString(valueRaw);
+            return valueStr.ConvertTo<T>();
+        }
+
+        /// <summary>
+        /// 转换到目标类型
+        /// </summary>
+        /// <param name="value"></param>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        public static T ConvertTo<T>(this object value) => (T)typeof(T).FromObject(value);
     }
 }

+ 49 - 5
WCS.Core/Configs.cs

@@ -1,20 +1,40 @@
 using System;
 using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
 using System.Text;
 using WCS.Entity;
 
 namespace WCS.Core
 {
+    /// <summary>
+    /// 配置中心
+    /// </summary>
     public static class Configs
     {
+
+        #region 配置中心
+
+       
+
+        #endregion
+
+        /// <summary>
+        /// ProtocolProxyBase在业务中具体实现类的Type
+        /// </summary>
         public static Type ProtocolProxyBaseType { get; set; }
 
+        #region 系统运行模式
+
+        /// <summary>
+        /// 系统运行模式
+        /// </summary>
         private static List<SystemMode> SystemModes { get; set; } = new List<SystemMode>();
 
         /// <summary>
         /// 添加一种模式
         /// </summary>
-        /// <param name="mode"></param>
+        /// <param name="mode">系统模式</param>
         public static void AddSystemMode(SystemMode mode)
         {
             if (SystemModes.Contains(mode)) return;
@@ -22,29 +42,50 @@ namespace WCS.Core
         }
 
         /// <summary>
-        /// 是否
+        /// 是否包含传入模式
         /// </summary>
-        /// <param name="mode"></param>
+        /// <param name="mode">系统模式</param>
         /// <returns></returns>
         public static bool Any(SystemMode mode)
         {
             return SystemModes.Contains(mode);
         }
 
+        #endregion
+
+        /// <summary>
+        /// 默认的字符串编码类型
+        /// </summary>
         public static Encoding StringEncoding { get; set; }
 
+        /// <summary>
+        /// 用户写入PLC记录
+        /// </summary>
         public static Action<Action<WCS_CMD>> DoCmds { get; set; }
 
-        public static string DebugRedisUrl { get; set; }
+        #region 异常上抛WMS
 
+        /// <summary>
+        /// 异常发布事件
+        /// </summary>
         public static event Action PublishEvent;
 
+        /// <summary>
+        /// 触发一下异常发布
+        /// </summary>
         internal static void Publish()
         {
             PublishEvent?.Invoke();
         }
 
+        /// <summary>
+        /// 待上传的WMS的异常信息队列
+        /// </summary>
         public static Action<string, string> UploadException { get; set; }
+
+        #endregion 异常上抛WMS
+
+
     }
 
     /// <summary>
@@ -52,6 +93,9 @@ namespace WCS.Core
     /// </summary>
     public enum SystemMode
     {
-        虚拟PLC = 1,
+        /// <summary>
+        /// 虚拟plc,启用该模式后,将在Redis中建立一个虚拟PLC用于流程测试
+        /// </summary>
+        虚拟plc = 1,
     }
 }

+ 63 - 26
WCS.Core/DataTrans/DataBlock.cs

@@ -12,39 +12,55 @@ namespace WCS.Core.DataTrans
 {
     public class DataBlock : EntityEx<WCS_DATABLOCK>
     {
+        /// <summary>
+        /// 从PLC中读出的字节组
+        /// </summary>
         protected byte[] Data;
-        //{
-        //    get { return DataServer.Get(Entity); }
-        //}
 
         private List<PlcItem> Values = new List<PlcItem>();
 
+        /// <summary>
+        /// 处理PLC变更数据的委托
+        /// </summary>
         internal event Action<Db, byte[]> DataChanged;
 
         /// <summary>
-        /// 是否失败,默认成功
+        /// 读取设备/PLC数据是否失败,默认成功
         /// </summary>
-        private bool failed = false;
+        private bool _failed = false;
 
         public DataBlock(WCS_DATABLOCK entity) : base(entity)
         {
         }
 
-        private DateTime AliveTime = DateTime.Now;
+        /// <summary>
+        /// 上一次设备数据读取失败并报错的时间,用于减少报错频率
+        /// </summary>
+        private DateTime _aliveTime = DateTime.Now;
 
+        /// <summary>
+        /// 刷新PLC数据
+        /// </summary>
+        /// <exception cref="Exception"></exception>
         public void DataRefresh()
         {
             var sw = new Stopwatch();
             try
             {
-                if (Entity.NOUPDATE && Data != null)
-                    return;
-                if (failed && (DateTime.Now - AliveTime).TotalMilliseconds < 3000)
+                if (Entity.NOUPDATE && Data != null) return;
+
+                //读取数据失败,并且已持续3秒钟
+                if (_failed && (DateTime.Now - _aliveTime).TotalMilliseconds < 3000)
                 {
-                    throw new Exception(Entity.NAME + "连接失败");
+                    throw new Exception(Entity.NAME + "设备数据读取失败,请检查网络或相关配置项是否正确");
                 }
-                AliveTime = DateTime.Now;
+                //更新时间
+                _aliveTime = DateTime.Now;
+
                 byte[] data = null;
+
+                #region 读取设备数据
+
                 lock (Entity.PLC)
                 {
                     sw.Start();
@@ -52,28 +68,49 @@ namespace WCS.Core.DataTrans
                     sw.Stop();
                 }
 
-                failed = false;
-                if (Data != null && data.SequenceEqual(Data)) return;
-                Data = data;
+                #endregion 读取设备数据
+
+                //Console.WriteLine($"{Entity.PLC.NAME}{Entity.PLC.IP}{Entity.NO}读取数据耗时:{sw.ElapsedMilliseconds}");
+                //Console.ResetColor();
+                //读取成功
 
-                Db.Do(db =>
+                _failed = false;
+                if (Data == null || !data.SequenceEqual(Data))
                 {
-                    DataChanged?.Invoke(db, Data);
-                });
+                    Data = data;
+                    Db.Do(db =>
+                    {
+                        DataChanged?.Invoke(db, Data);
+                    });
+                }
+                //_failed = false;
+
+                ////本次数据与上次一致时结束处理
+                ////if (Data != null && data.SequenceEqual(Data)) return;
+                //if (Data != null) return;
+                //Data = data;
+
+                //Db.Do(db =>
+                //{
+                //    //TODO:需要想办法处理一下
+                //    DataChanged?.Invoke(db,Data);
+                //    //DataChanged.Invoke(db, Data);
+                //});
             }
-            catch (Exception)
+            catch (Exception ex)
             {
                 sw.Stop();
-                failed = true;
+                _failed = true;
                 throw;
             }
             finally
             {
-                if (sw.ElapsedMilliseconds > 500)
+                //访问耗时大于50毫秒时记录
+                if (sw.ElapsedMilliseconds > 400)
                 {
-                    Console.ForegroundColor = ConsoleColor.Yellow;
-                    Console.WriteLine($"{Entity.PLC.NAME}{Entity.PLC.IP}访问耗时:{sw.ElapsedMilliseconds}");
-                    Console.ResetColor();
+                    //Console.ForegroundColor = ConsoleColor.Yellow;
+                    //Console.WriteLine($"{Entity.PLC.NAME}{Entity.PLC.IP}读取数据耗时:{sw.ElapsedMilliseconds}");
+                    //Console.ResetColor();
                 }
             }
         }
@@ -105,7 +142,7 @@ namespace WCS.Core.DataTrans
 
         private object Read(Type type, ref int bitStart, int strLength, int arrLength)
         {
-            if (failed)
+            if (_failed)
                 throw new Exception(Entity.NAME + "连接失败");
 
             if (type.IsArray)
@@ -117,7 +154,7 @@ namespace WCS.Core.DataTrans
                 }
                 var arr = Array.CreateInstance(t, arrLength);
 
-                for (int i = 0; i < arr.Length; i++)
+                for (var i = 0; i < arr.Length; i++)
                 {
                     var value = Read(t, ref bitStart, strLength, 0);
                     arr.SetValue(value, i);
@@ -131,7 +168,7 @@ namespace WCS.Core.DataTrans
                 while (bitStart < Entity.LENGTH * 8)
                 {
                     var value = Read(t, ref bitStart, strLength, 0);
-                    res.Add(value);
+                    res?.Add(value);
                 }
                 return res;
             }

+ 4 - 1
WCS.Core/DataTrans/Extentions.cs

@@ -482,11 +482,14 @@ namespace WCS.Core.DataTrans
         #endregion ulong
     }
 
+    /// <summary>
+    /// 扩展中心
+    /// </summary>
     public static class Extensions
     {
         private static ConcurrentDictionary<WCS_DEVICEPROTOCOL, object> Datas = new ConcurrentDictionary<WCS_DEVICEPROTOCOL, object>();
 
-        private static ConcurrentDictionary<object, object> ExObjs = new ConcurrentDictionary<object, object>();
+        public static ConcurrentDictionary<object, object> ExObjs = new ConcurrentDictionary<object, object>();
 
         public static T Data<T>(this WCS_DEVICEPROTOCOL obj)
         {

+ 127 - 80
WCS.Core/DataTrans/ProtocolProxyBase.cs

@@ -1,12 +1,13 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
+using System.Diagnostics;
 using System.Linq;
 using System.Reflection;
 using System.Runtime.InteropServices;
-using System.Threading.Tasks;
 using WCS.Core.DbHelper;
 using WCS.Core.IL;
+using WCS.Core.Log;
 using WCS.Entity;
 
 namespace WCS.Core.DataTrans
@@ -24,107 +25,132 @@ namespace WCS.Core.DataTrans
 
         public string Id { get; set; }
 
+        /// <summary>
+        /// 设备在DB块中所处位置所记录
+        /// </summary>
         public WCS_DEVICEPROTOCOL Protocol { get; private set; }
 
         /// <summary>
-        /// 起始便宜量,按字节算
+        /// 起始偏移量,按字节算
         /// </summary>
-        public readonly ushort _start;
+        public readonly ushort Start;
 
         /// <summary>
         /// 长度,按字节算
         /// </summary>
-        public readonly ushort _length;
+        public readonly ushort Length;
 
+        /// <summary>
+        ///
+        /// </summary>
         public WCS_DATABLOCK Db;
 
         private static readonly Dictionary<Type, object> LockObjs = new Dictionary<Type, object>();
 
+        /// <summary>
+        /// 对从PLC中读取出的数据进行处理
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="db"></param>
+        /// <param name="start"></param>
+        /// <param name="deviceItem"></param>
         protected ProtocolProxyBase(string id, WCS_DATABLOCK db, ushort start, WCS_DEVICEPROTOCOL deviceItem)
         {
-            var type = this.GetType();
-            if (!LockObjs.ContainsKey(type))
-                LockObjs[type] = new object();
-
-            this.Db = db;
-            db.Ex().DataChanged += PLCData_DataChanged;
-            this._start = start;
-            var bitStart = start * 8;//偏移量,按位算
-            this.Id = id;
-            this.Protocol = deviceItem;
-            var lst = this.GetType().GetInterfaces().ToList();
-
-            var ps = lst.SelectMany(v => v.GetProperties()).ToArray();
-            foreach (var p in ps)
+            try
             {
-                if (p.GetIndexParameters().Length > 0)
-                    continue;
-                if (typeof(ProtocolProxyBase).GetProperty(p.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null)
+                if (id.Contains("SRM"))
                 {
-                    continue;
+                    var a = 1;
                 }
+                var type = this.GetType();
+                if (!LockObjs.ContainsKey(type))
+                    LockObjs[type] = new object();
+
+                this.Db = db;
+                db.Ex().DataChanged += PLCData_DataChanged;
+                this.Start = start;
+                var bitStart = start * 8;//偏移量,按位算
+                this.Id = id;
+                this.Protocol = deviceItem;
+                var lst = this.GetType().GetInterfaces().ToList();
+
+                var ps = lst.SelectMany(v => v.GetProperties()).ToArray();
+                foreach (var p in ps)
+                {
+                    if (p.GetIndexParameters().Length > 0)
+                        continue;
+                    if (typeof(ProtocolProxyBase).GetProperty(p.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null)
+                    {
+                        continue;
+                    }
 
-                #region 计算偏移量
+                    #region 计算偏移量
 
-                var modeNum = 0;
+                    var modeNum = 0;
 
-                var t = p.PropertyType;
-                if (t.IsEnum)
-                    t = t.GetEnumUnderlyingType();
-                if (t == typeof(bool))//bit类型,db块中无须补齐16位
-                {
-                    modeNum = 1;
-                }
-                else if (t.IsPrimitive && Marshal.SizeOf(t) == 1)//byte char 等单字节类型,db块中无须补齐16位
-                {
-                    modeNum = 8;
-                }
-                else//其他类型,db块中必须补齐16位
-                {
-                    modeNum = 16;
-                }
-                var mod = bitStart % modeNum;
-                if (mod > 0)
-                {
-                    bitStart += modeNum - mod;
-                }
+                    var t = p.PropertyType;
+                    if (t.IsEnum)
+                        t = t.GetEnumUnderlyingType();
+                    if (t == typeof(bool))//bit类型,db块中无须补齐16位
+                    {
+                        modeNum = 1;
+                    }
+                    else if (t.IsPrimitive && Marshal.SizeOf(t) == 1)//byte char 等单字节类型,db块中无须补齐16位
+                    {
+                        modeNum = 8;
+                    }
+                    else//其他类型,db块中必须补齐16位
+                    {
+                        modeNum = 16;
+                    }
+                    var mod = bitStart % modeNum;
+                    if (mod > 0)
+                    {
+                        bitStart += modeNum - mod;
+                    }
 
-                #endregion 计算偏移量
+                    #endregion 计算偏移量
 
-                byte arrlen = 0;
-                byte strLen = 0;
-                if (t.IsArray)
-                {
-                    var attr = p.GetCustomAttributes(typeof(MaxLengthAttribute), true).FirstOrDefault() as MaxLengthAttribute;
-                    if (attr != null)
-                        arrlen = (byte)attr.Length;
-                }
-                else if (p.PropertyType == typeof(string))
-                {
-                    var attr = p.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;
-                    strLen = (byte)attr.MaximumLength;
+                    byte arrlen = 0;
+                    byte strLen = 0;
+                    if (t.IsArray)
+                    {
+                        var attr = p.GetCustomAttributes(typeof(MaxLengthAttribute), true).FirstOrDefault() as MaxLengthAttribute;
+                        if (attr != null)
+                            arrlen = (byte)attr.Length;
+                    }
+                    else if (p.PropertyType == typeof(string))
+                    {
+                        var attr = p.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;
+                        strLen = (byte)attr.MaximumLength;
+                    }
+                    var m = typeof(DataBlock).GetMethod("Regist");
+                    m = m.MakeGenericMethod(p.PropertyType);
+                    var item = m.Invoke(db.Ex(), new object[] { this.Id, p.Name, bitStart, arrlen, strLen }) as PlcItem;
+                    _items.Add(p.Name, item);
+                    bitStart += item.DataSizeOfBits;
+                    Length += item.DataSize;
                 }
-                var m = typeof(DataBlock).GetMethod("Regist");
-                m = m.MakeGenericMethod(p.PropertyType);
-                var item = m.Invoke(db.Ex(), new object[] { this.Id, p.Name, bitStart, arrlen, strLen }) as PlcItem;
-                _items.Add(p.Name, item);
-                bitStart += item.DataSizeOfBits;
-                _length += item.DataSize;
+                ProtocolType = this.Protocol.DB.GetProtocolType();
+                ProtocolDataType = ProtocolType.Assembly.GetTypes().Where(v => v.IsClass).First(v => v.GetInterface(ProtocolType.Name) != null && v != this.GetType());
+                InfoLog.INFO_SRMINFO($"{id}");
+            }
+            catch (Exception e)
+            {
+                // ignored
             }
-            ProtocolType = this.Protocol.DB.GetProtocolType();
-            ProtocolDataType = ProtocolType.Assembly.GetTypes().Where(v => v.IsClass).First(v => v.GetInterface(ProtocolType.Name) != null && v != this.GetType());
         }
 
-        private byte[] Data = null;
+        /// <summary>
+        /// 上一次从PLC中读取出的设备信息
+        /// </summary>
+        private byte[] _data;
+
         private static object _locobj = new object();
 
         private void InvokeUpdate(string user, Db db)
         {
-            //TODO:怀疑会有问题,需要再看一下
-            Task.Run(() =>
-            {
-                SaveChangs(user, db);
-            });
+            SaveChangs(user, db);
         }
 
         private WCS_PROTOCOLDATA _last = null;
@@ -159,18 +185,39 @@ namespace WCS.Core.DataTrans
 
         protected abstract WCS_PROTOCOLDATA SaveNewData(Db db, WCS_PROTOCOLDATA last, WCS_PROTOCOLDATA newobj, string user);
 
+        /// <summary>
+        /// PLC更新数据
+        /// </summary>
+        /// <param name="db">数据库上下文</param>
+        /// <param name="data">设备数据字节组</param>
         private void PLCData_DataChanged(Db db, byte[] data)
         {
-            var temp = data.Skip(_start).Take(_length).ToArray();
             try
             {
-                if (Data != null && Data.SequenceEqual(temp))
-                    return;
-                var d1 = DateTime.Now;
-                InvokeUpdate("PLC", db);
-                var d = (DateTime.Now - d1).TotalMilliseconds;
+                //按照配置信息截取对应长度的字节组
+                var temp = data.Skip(Start).Take(Length).ToArray();
+                try
+                {
+                    //如果本次数据与上次一直,结束处理流程
+                    //if (_data != null && _data.SequenceEqual(temp)) return;
+                    var sw = new Stopwatch();
+                    sw.Start();
+                    InvokeUpdate("PLC", db);
+                    sw.Stop();
+                    //if (sw.ElapsedMilliseconds <= 400) return;
+                    //Console.WriteLine($"{Id}:{Protocol.DEVICECODE}:访问耗时:{sw.ElapsedMilliseconds}");
+                    //Console.ResetColor();
+                }
+                finally
+                {
+                    _data = temp;
+                }
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.Message);
+                Console.ResetColor();
             }
-            finally { Data = temp; }
         }
 
         private static object Copy(object obj, Type type)
@@ -275,7 +322,7 @@ namespace WCS.Core.DataTrans
                    InvokeUpdate("WCS", db);
                });
 
-                Data = null;
+                _data = null;
                 WcsVersion++;
                 str += " 写入成功";
             }
@@ -299,7 +346,7 @@ namespace WCS.Core.DataTrans
                 InvokeUpdate(user, db);
             });
 
-            Data = null;
+            _data = null;
             if (user == "PLC")
                 return;
             WcsVersion++;

+ 49 - 8
WCS.Core/DbHelper/DB.cs

@@ -15,7 +15,7 @@ namespace WCS.Core.DbHelper
         /// <summary>
         /// 上下文集合
         /// </summary>
-        private static List<ContextList> _contexts = new List<ContextList>();
+        private static readonly List<ContextList> _contexts = new List<ContextList>();
 
         /// <summary>
         /// 默认上下文类类型
@@ -23,29 +23,48 @@ namespace WCS.Core.DbHelper
         public static string DefaultDbContextType { get; private set; } = null!;
 
         /// <summary>
-        ///
+        /// 指定连接连接
         /// </summary>
         /// <typeparam name="T">业务代码</typeparam>
         /// <param name="func">业务逻辑</param>
+        /// <param name="key">连接对应的Key</param>
         /// <returns></returns>
         /// <exception cref="Exception"></exception>
-        public static T Do<T>(Func<Db, T> func)
+        public static T Do<T>(Func<Db, T> func, string key)
         {
             var db = new Db();
 
-            db.Default.BeginTran();
+            db.Context(key).BeginTran();
             var res = func(db);
-            db.Default.CommitTran();
+            db.Context(key).CommitTran();
             return res;
         }
 
+        /// <summary>
+        /// 使用设置好的默认链接
+        /// </summary>
+        /// <param name="act">执行内容</param>
         public static void Do(Action<Db> act)
         {
             Do(db =>
             {
                 act(db);
                 return 1;
-            });
+            }, DefaultDbContextType);
+        }
+
+        /// <summary>
+        /// 使用指定默认链接
+        /// </summary>
+        /// <param name="act">执行内容</param>
+        /// <param name="key">连接对应的Key</param>
+        public static void Do(Action<Db> act, string key)
+        {
+            Do(db =>
+            {
+                act(db);
+                return 1;
+            }, key);
         }
 
         /// <summary>
@@ -71,9 +90,10 @@ namespace WCS.Core.DbHelper
         }
 
         /// <summary>
-        /// 创建一个上下文
+        /// 创建一个数据库连接
         /// </summary>
-        /// <param name="type"></param>
+        /// <param name="config">数据库配置信息</param>
+        /// <param name="key">数据库Key</param>
         /// <returns></returns>
         public static SqlSugarScope CreateContext(ConnectionConfig config, string key)
         {
@@ -90,6 +110,12 @@ namespace WCS.Core.DbHelper
             return ctx.Client;
         }
 
+        /// <summary>
+        /// 根据Key获取指定数据库连接
+        /// </summary>
+        /// <param name="key">目标数据库在配置中的Key</param>
+        /// <returns></returns>
+        /// <exception cref="Exception"></exception>
         public SqlSugarScope Context(string key)
         {
             var ctx = _contexts.FirstOrDefault(v => v.Key == key);
@@ -104,6 +130,12 @@ namespace WCS.Core.DbHelper
     public class ContextList
 
     {
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="client"></param>
+        /// <param name="connectionConfig"></param>
         public ContextList(string key, SqlSugarScope client, ConnectionConfig connectionConfig)
         {
             Key = key;
@@ -111,10 +143,19 @@ namespace WCS.Core.DbHelper
             ConnectionConfig = connectionConfig;
         }
 
+        /// <summary>
+        ///
+        /// </summary>
         public string Key { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public SqlSugarScope Client { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public ConnectionConfig ConnectionConfig { get; set; }
     }
 }

+ 1 - 1
WCS.Core/Redis/RedisHelper.cs

@@ -8,7 +8,7 @@ namespace WCS.Core.Redis
     /// <summary>
     /// Redis操作类
     /// </summary>
-    public class RedisHelper
+    public static class RedisHelper
     {
         /// <summary>
         /// 连接集合

+ 10 - 3
WCS.Core/WCS.Core.csproj

@@ -5,6 +5,10 @@
     <Nullable>enable</Nullable>
     <GenerateDocumentationFile>True</GenerateDocumentationFile>
     <Description>核心包</Description>
+    <Version>1.1.1</Version>
+    <PackageReleaseNotes>优化多数据库连接</PackageReleaseNotes>
+    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
+    <PackageOutputPath>D:\XM\Release\DLL</PackageOutputPath>
   </PropertyGroup>
 
   <ItemGroup>
@@ -12,11 +16,14 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="FreeRedis" Version="0.6.5" />
+    <PackageReference Include="FreeRedis" Version="1.0.3" />
     <PackageReference Include="HslCommunication" Version="6.2.2" />
     <PackageReference Include="log4net" Version="2.0.15" />
-    <PackageReference Include="SqlSugarCore" Version="5.1.2.6" />
-    <PackageReference Include="WCS.Entity" Version="1.0.4" />
+    <PackageReference Include="SqlSugarCore" Version="5.1.3.47" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\WCS.Entity\WCS.Entity.csproj" />
   </ItemGroup>
 
 </Project>

+ 32 - 6
WCS.Core/WorkInfo.cs

@@ -1,32 +1,58 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace WCS.Core
 {
+    /// <summary>
+    ///
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
     public class WorkInfo<T>
     {
+        /// <summary>
+        ///
+        /// </summary>
         public Action<T> Work { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public IEnumerable<T> Params { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public string Title { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public bool Parallel { get; set; }
     }
 
+    /// <summary>
+    ///
+    /// </summary>
     public class WorkInfo
-    { 
+    {
+        /// <summary>
+        ///
+        /// </summary>
         public virtual Action<object> Work { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public IEnumerable<object> Params { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public string Title { get; set; }
 
+        /// <summary>
+        ///
+        /// </summary>
         public bool Parallel { get; set; }
     }
-   
 }

+ 1 - 1
WCS.Entity.Protocol/WCS.Entity.Protocol.csproj

@@ -9,7 +9,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="WCS.Entity" Version="1.0.4" />
+    <ProjectReference Include="..\WCS.Entity\WCS.Entity.csproj" />
   </ItemGroup>
 
 </Project>

+ 38 - 0
WCS.Entity/PlcRawData.cs

@@ -0,0 +1,38 @@
+using SqlSugar;
+using System;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace WCS.Entity
+{
+    /// <summary>
+    /// 设备原始信息表
+    /// </summary>
+    [SugarTable(nameof(PlcRawData), "路径")]
+    public class PlcRawData
+    {
+        /// <summary>
+        /// ID
+        /// </summary>
+        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "ID")]
+        [Column(Order = 0)]
+        public virtual int ID { get; set; }
+
+        /// <summary>
+        /// 更新时间
+        /// </summary>
+        [SugarColumn(ColumnDescription = "更新时间")]
+        public DateTime UPDATETIME { get; set; } = DateTime.Now;
+
+        /// <summary>
+        /// 仓库
+        /// </summary>
+        [SugarColumn(ColumnDescription = "仓库")]
+        public string WAREHOUSE { get; set; }
+
+        /// <summary>
+        /// 内容
+        /// </summary>
+        [SugarColumn(ColumnDescription = "内容")]
+        public byte[] CONTENT { get; set; }
+    }
+}

+ 2 - 2
WCS.Service/PLCAccessors/SiemensS7PLC.cs

@@ -26,7 +26,7 @@ namespace WCS.Service.PLCAccessors
 
         public byte[] ReadBytes(ushort db, ushort address, ushort length, ushort dataLength)
         {
-            if (Configs.Any(SystemMode.虚拟PLC))
+            if (Configs.Any(SystemMode.虚拟plc))
             {
                 return PlcData.Read(new PLCData { IP = plc.IpAddress, DB = db, Length = length, DataLength = dataLength });
             }
@@ -40,7 +40,7 @@ namespace WCS.Service.PLCAccessors
 
         public void WriteBytes(ushort db, ushort address, byte[] data)
         {
-            if (Configs.Any(SystemMode.虚拟PLC))
+            if (Configs.Any(SystemMode.虚拟plc))
             {
                 PlcData.Write(new PLCData { IP = plc.IpAddress, DB = db }, address, data);
             }

+ 17 - 2
WCS.Service/Program.cs

@@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Hosting;
 using System.Runtime.InteropServices;
 using WCS.Core;
 using WCS.WebApi;
+using RedisHelper = WCS.Core.Redis.RedisHelper;
 
 namespace WCS.Service
 {
@@ -13,10 +14,24 @@ namespace WCS.Service
         /// <param name="args"></param>
         public static void Main(string[] args)
         {
-            using var mt = new Mutex(true, "WCS");
+            #region 接入Redis
+
+            RedisHelper.CreateContext(AppSettings.Config.GetConnectionString("Redis"), "default", true);
+
+            #endregion 接入Redis
+
+            //互斥锁检测
+            var mutexName = RedisHelper.Default.Get("Mutex");
+            if (string.IsNullOrEmpty(mutexName))
+            {
+                RedisHelper.Default.Set("Mutex", "   ");
+                Console.WriteLine("请在Redis中配置互斥量值");
+                return;
+            }
+            using var mt = new Mutex(true, mutexName);
             if (mt.WaitOne())
             {
-                Configs.AddSystemMode(SystemMode.虚拟PLC);
+                Configs.AddSystemMode(SystemMode.虚拟plc);
                 CreateHostBuilder(args).Build().Run(); mt.ReleaseMutex();
             }
             else

+ 65 - 7
WCS.Service/ProtocolProxy.cs

@@ -1,5 +1,6 @@
 using MessagePack;
 using MessagePack.Resolvers;
+using Newtonsoft.Json;
 using System.Collections.Concurrent;
 using System.Diagnostics;
 using System.Linq.Dynamic.Core;
@@ -13,6 +14,9 @@ using WCS.Entity.Protocol;
 
 namespace WCS.Service
 {
+    /// <summary>
+    /// 代理协议
+    /// </summary>
     public class ProtocolProxy : ProtocolProxyBase
     {
         public ProtocolProxy(string id, WCS_DATABLOCK db, ushort start, WCS_DEVICEPROTOCOL protocol) : base(id, db, start, protocol)
@@ -21,23 +25,29 @@ namespace WCS.Service
 
         private static readonly ConcurrentDictionary<Type, object[]> LastDatas = new();
 
+        /// <summary>
+        /// 获取新的数据
+        /// </summary>
+        /// <param name="db"></param>
+        /// <returns></returns>
         protected override WCS_PROTOCOLDATA GetLastData(Db db)
         {
             if (!LastDatas.ContainsKey(this.ProtocolDataType))
             {
                 LastDatas[this.ProtocolDataType] = db.Default.Queryable<dynamic>().AS($"{this.ProtocolDataType.Name}", "it").Where("ISLAST=0").OrderBy("ID").ToArray();
             }
-            dynamic datas = LastDatas[this.ProtocolDataType];
+            dynamic data = LastDatas[this.ProtocolDataType];
             var list = new List<WCS_PROTOCOLDATA>();
-            foreach (var data in datas)
+            foreach (var itemData in data)
             {
                 try
                 {
-                    if (data.DEVICECOD == Protocol.DEVICE.CODE)
-                        list.Add(data);
+                    if (itemData.DEVICECOD == Protocol.DEVICE.CODE)
+                        list.Add(itemData);
                 }
                 catch
                 {
+                    // ignored
                 }
             }
 
@@ -82,7 +92,7 @@ namespace WCS.Service
         static ProtocolProxy()
         {
             MessagePackSerializer.DefaultOptions = StandardResolver.Options.WithCompression(MessagePackCompression.Lz4Block);
-            RedisHelper.CreateContext("127.0.0.1,database=0", "default", true);
+            //RedisHelper.CreateContext("127.0.0.1,database=0", "default", true);
             RedisHelper.CreateContext("127.0.0.1,database=10", "3D");
             RedisHelper.CreateContext("127.0.0.1,database=1", "ConcurrencyControlRedis");
             RedisHelper.Default.Serialize = obj =>
@@ -142,6 +152,9 @@ namespace WCS.Service
             }
         }
 
+        /// <summary>
+        /// 所有的设备数据
+        /// </summary>
         public static ConcurrentDictionary<string, DeviceData> AllDatas = new();
 
         public static void Do()
@@ -168,22 +181,67 @@ namespace WCS.Service
                     p.SetValue(pack, coll);
                 }
 
+                #region 存入Redis
+
                 var sw = new Stopwatch();
                 sw.Start();
                 RedisHelper.Default.Set(nameof(DeviceDataPack), pack);
+                RedisHelper.Default.RPush("Packs", pack);
                 sw.Stop();
                 Console.ForegroundColor = ConsoleColor.Blue;
                 Console.WriteLine($"Redis耗时{sw.ElapsedMilliseconds}");
                 Console.ResetColor();
 
-                RedisHelper.Default.RPush("Packs", pack);
-
                 var len = RedisHelper.Default.LLen("Packs");
                 if (len > 150000)
                 {
                     RedisHelper.Default.LTrim("Packs", 20000, len);
                 }
 
+                #endregion 存入Redis
+
+                var converter = new System.Text.UnicodeEncoding();
+               
+                var plcRawData = new PlcRawData
+                {
+                    CONTENT = converter.GetBytes(JsonConvert.SerializeObject(pack)),
+                    WAREHOUSE = "1"
+                };
+
+                #region 存入PGSql
+
+                var sw1 = new Stopwatch();
+                sw1.Start();
+                Core.DbHelper.Db.Do(db =>
+                {
+                    db.Context("WCSDlog").Insertable(plcRawData).ExecuteCommand();
+                });
+                sw1.Stop();
+                Console.ForegroundColor = ConsoleColor.Blue;
+                Console.WriteLine($"PGSql耗时{sw1.ElapsedMilliseconds}");
+                Console.ResetColor();
+
+                RedisHelper.Default.RPush("Packs", pack);
+
+                #endregion 存入PGSql
+
+                #region 存入sqlServe
+
+                var sw2 = new Stopwatch();
+                sw2.Start();
+                Core.DbHelper.Db.Do(db =>
+                {
+                    db.Default.Insertable(plcRawData).ExecuteCommand();
+                });
+                sw2.Stop();
+                Console.ForegroundColor = ConsoleColor.Blue;
+                Console.WriteLine($"sqlServe耗时{sw2.ElapsedMilliseconds}");
+                Console.ResetColor();
+
+                RedisHelper.Default.RPush("Packs", pack);
+
+                #endregion 存入sqlServe
+
                 foreach (var data in AllDatas)
                 {
                     data.Value.Info = "";

+ 3 - 2
WCS.Service/WCS.Service.csproj

@@ -25,11 +25,12 @@
     <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
     <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.8" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
-    <PackageReference Include="WCS.Core" Version="1.1.0" />
-    <PackageReference Include="WCS.WebApi" Version="1.0.4" />
   </ItemGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\WCS.Core\WCS.Core.csproj" />
+    <ProjectReference Include="..\WCS.Entity\WCS.Entity.csproj" />
+    <ProjectReference Include="..\WCS.WebApi\WCS.WebApi.csproj" />
     <ProjectReference Include="..\WCS.WorkEngineering\WCS.WorkEngineering.csproj" />
   </ItemGroup>
 </Project>

+ 41 - 11
WCS.Service/Worker.cs

@@ -24,6 +24,8 @@ namespace WCS.Service
             _logger = logger;
         }
 
+        public static readonly string WcsDlog = "WCSDlog";
+
         protected override async System.Threading.Tasks.Task ExecuteAsync(CancellationToken stoppingToken)
         {
             if (stoppingToken.IsCancellationRequested)
@@ -40,11 +42,13 @@ namespace WCS.Service
 
             _logger.LogInformation("WCS开始启动");
             //InfoLog.INFO_INIT("WCS开始启动");
-            Configs.DebugRedisUrl = "127.0.0.1";
+            //Configs.DebugRedisUrl = "127.0.0.1";
             Configs.ProtocolProxyBaseType = typeof(ProtocolProxy);
             Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
             Configs.StringEncoding = Encoding.UTF8;
 
+            #region 需要改成循环遍历,以实现根据配置项完成多个数据库链接创建
+
             Db.CreateContext(new ConnectionConfig()
             {
                 ConnectionString = AppSettings.Config.GetConnectionString("WCSDB"),
@@ -72,18 +76,44 @@ namespace WCS.Service
                 db.Default.CodeFirst.InitTables(typeof(WCS_MAPPINGENTRY));
                 db.Default.CodeFirst.InitTables(typeof(WCS_USERS));
                 db.Default.CodeFirst.InitTables(typeof(WCS_StatusLog));
-                db.Default.CodeFirst.InitTables(typeof(WCS_BCR80));
-                db.Default.CodeFirst.InitTables(typeof(WCS_RGV520));
-                db.Default.CodeFirst.InitTables(typeof(WCS_RGV521));
-                db.Default.CodeFirst.InitTables(typeof(WCS_RGV523));
-                db.Default.CodeFirst.InitTables(typeof(WCS_SRM520));
-                db.Default.CodeFirst.InitTables(typeof(WCS_SRM521));
-                db.Default.CodeFirst.InitTables(typeof(WCS_SRM537));
-                db.Default.CodeFirst.InitTables(typeof(WCS_Station520));
-                db.Default.CodeFirst.InitTables(typeof(WCS_Station521));
-                db.Default.CodeFirst.InitTables(typeof(WCS_Station523));
+                db.Default.CodeFirst.InitTables(typeof(WCS.Entity.PlcRawData));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_BCR80));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_RGV520));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_RGV521));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_RGV523));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_SRM520));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_SRM521));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_SRM537));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_Station520));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_Station521));
+                //db.Default.CodeFirst.InitTables(typeof(WCS_Station523));
             });
 
+            Db.CreateContext(new ConnectionConfig()
+            {
+                ConnectionString = AppSettings.Config.GetConnectionString(WcsDlog),
+                DbType = DbType.PostgreSQL
+            }, WcsDlog);
+
+            Db.Do(db =>
+            {
+                //TODO:DbMaintenance.CreateDatabase()并没起到作用,如果没有对应的数据库的话任然需要手动新建一个
+                db.Context(WcsDlog).DbMaintenance.CreateDatabase();
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_BCR80));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV520));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV521));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_RGV523));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM520));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM521));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_SRM537));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_Station520));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_Station521));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS_Station523));
+                db.Context(WcsDlog).CodeFirst.InitTables(typeof(WCS.Entity.PlcRawData));
+            });
+
+            #endregion 需要改成循环遍历,以实现根据配置项完成多个数据库链接创建
+
             //从现有结构解析出需要的结构
             List<PLCData> list = new List<PLCData>();
             Db.Do(db =>

+ 1 - 6
WCS.Service/appsettings.json

@@ -7,11 +7,6 @@
     }
   },
   "ConnectionStrings": {
-    //"WCSDB": "Data Source=192.168.251.12;User ID=sa;Password=abc.123;Initial Catalog=WCS_MW;Integrated Security=False"
-    //"WCSDB": "Data Source=192.168.249.120;User ID=sa;Password=password@123$%^;Initial Catalog=WCS_MW;Integrated Security=False;"
-    //本地数据库
-    "WCSDB": "Data Source=LAPTOP-D9OEIS1K\\SQLEXPRESS;User ID=sa;Password=7166766;Initial Catalog=wcs;Integrated Security=False;"
-    //MySql
-    //"WCSDB": "server=localhost;Database=wcs;Uid=root;Pwd=123456;AllowLoadLocalInfile=true"
+    "Redis": "127.0.0.1,database=0,prefix=Aging:"
   }
 }

+ 6 - 2
WCS.WebApi/WCS.WebApi.csproj

@@ -10,8 +10,12 @@
     <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
     <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.8" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
-    <PackageReference Include="WCS.Core" Version="1.0.8" />
-    <PackageReference Include="WCS.Entity.Protocol" Version="1.0.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\WCS.Core\WCS.Core.csproj" />
+    <ProjectReference Include="..\WCS.Entity.Protocol\WCS.Entity.Protocol.csproj" />
+    <ProjectReference Include="..\WCS.Entity\WCS.Entity.csproj" />
   </ItemGroup>
 
 </Project>

+ 2 - 2
WCS.WebApi/WMS/WMS.cs

@@ -60,7 +60,7 @@ namespace WCS.WebApi.WMS
         /// <returns></returns>
         public static List<I_WCS_GetInTaskResponseItem> I_WCS_GetInTask(string barcode1, string devCode1, string barcode2, string devCode2, bool getTunnel1 = false, bool getTunnel2 = false)
         {
-            if (!Configs.Any(SystemMode.虚拟PLC))
+            if (!Configs.Any(SystemMode.虚拟plc))
             {
                 var data = JsonConvert.SerializeObject(new List<I_WCS_GetInTaskRequest>()
             {
@@ -141,7 +141,7 @@ namespace WCS.WebApi.WMS
 
         public static void UpdateTask(string POSIDNEXT, int wmstaskid, int status, int size = -1)
         {
-            if (Configs.Any(SystemMode.虚拟PLC)) return;
+            if (Configs.Any(SystemMode.虚拟plc)) return;
 
             var data = JsonConvert.SerializeObject(new List<I_WCS_TASKRequest>
             {

+ 1 - 1
WCS.WorkEngineering/Extensions/DeviceExtension.cs

@@ -172,7 +172,7 @@ namespace WCS.Service.Extensions
         public static WCS_DEVICE GetNext(this WCS_DEVICE source, string endAddr, Func<List<WCS_DEVICE>, bool> condition)
         {
             var path = source.GetPath(endAddr, condition);
-            if (Ltc.Do(path, v => v == null || v.Count == 0))
+            if (Ltc.Do(path, v => v == null || v.Count == 0, "判断数量", "数量异常"))
                 return null;
 
             if (source.IsConv())

+ 4 - 4
WCS.WorkEngineering/WCS.WorkEngineering.csproj

@@ -8,10 +8,10 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="WCS.Core" Version="1.1.0" />
-    <PackageReference Include="WCS.Entity" Version="1.0.4" />
-    <PackageReference Include="WCS.Entity.Protocol" Version="1.0.0" />
-    <PackageReference Include="WCS.WebApi" Version="1.0.4" />
+    <ProjectReference Include="..\WCS.Core\WCS.Core.csproj" />
+    <ProjectReference Include="..\WCS.Entity.Protocol\WCS.Entity.Protocol.csproj" />
+    <ProjectReference Include="..\WCS.Entity\WCS.Entity.csproj" />
+    <ProjectReference Include="..\WCS.WebApi\WCS.WebApi.csproj" />
   </ItemGroup>
 
 </Project>