Parcourir la source

重构代码并优化注释格式

在多个文件中进行了以下更改:
1. 调整了属性和注释的顺序,使代码更加整洁。
2. 移除了不必要的 `using` 语句,简化了代码结构。
3. 添加了新的属性和方法,扩展了类和接口的功能。
4. 修正了注释格式,使其更加一致和规范。
5. 优化了日志记录和错误处理机制,提高了代码的健壮性和可维护性。
林豪 左 il y a 11 mois
Parent
commit
3739955d67

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

@@ -18,9 +18,11 @@
     <None Remove="Logs\**" />
   </ItemGroup>
   <ItemGroup>
+    <PackageReference Include="Dapper" Version="2.1.35" />
     <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
     <PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="8.0.0" />
     <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
+    <PackageReference Include="Npgsql" Version="8.0.4" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\WCS.WorkEngineering\WCS.WorkEngineering.csproj" />

+ 35 - 227
WCS.WorkEngineering/ProtocolProxy.cs

@@ -1,239 +1,47 @@
-using ServiceCenter.SqlSugars;
-using WCS.Core;
-using WCS.Entity.Protocol;
-using WCS.Entity.Protocol.BCR;
+using WCS.Core;
 using WCS.Entity.Protocol.DataStructure;
-using WCS.Entity.Protocol.Protocol.DataStructure;
-using WCS.Entity.Protocol.RGV;
-using WCS.Entity.Protocol.Robot;
-using WCS.Entity.Protocol.SRM;
-using WCS.Entity.Protocol.Station;
-using WCS.Entity.Protocol.Truss;
-using WCS.WorkEngineering.Systems;
+using WCS.WorkEngineering.Worlds;
 
-namespace WCS.WorkEngineering
+namespace WCS.WorkEngineering;
+
+public class ProtocolProxy : ProtocolProxyBase
 {
-    public class ProtocolProxy : ProtocolProxyBase
+    public ProtocolProxy(Device dev, ProtocolInfo info, Type protocolType, World world) : base(dev, info, protocolType,world)
     {
-        public static DeviceDataPack DataPack { get; set; } = new DeviceDataPack();
-
-        public ProtocolProxy(Device dev, ProtocolInfo info, Type protocolType, World world) : base(dev, info, protocolType, world)
-        {
-        }
+    }
 
-        protected override void DataChanged()
-        {
-            //if (Device.Code == "RGV1" && Info.DBInfo.No == 520)
-            //{
-            //    var a = Items;
-            //    //var dev=Device.Protocol(ProtocolType)
-            //    var b = a;
-            //}
+    public static DeviceDataPack DataPack { get; set; } = new();
 
-            //try
-            //{
-            //    var datas = DataCollectionSysyem.AllDatas;
-            //    if (Device.Code.All(char.IsNumber))
-            //    {
-            //        if (!datas.ContainsKey(Device.Code)) datas[Device.Code] = new StationData { Code = Device.Code };
-            //    }
-            //    else if (Device.Code.Contains("SRM"))
-            //    {
-            //        if (!datas.ContainsKey(Device.Code)) datas[Device.Code] = new SRMData { Code = Device.Code };
-            //    }
-            //    else if (Device.Code.Contains("Truss"))
-            //    {
-            //        if (!datas.ContainsKey(Device.Code)) datas[Device.Code] = new TrussData() { Code = Device.Code };
-            //    }
-            //    else if (Device.Code.Contains("Robot"))
-            //    {
-            //        if (!datas.ContainsKey(Device.Code)) datas[Device.Code] = new RobotData() { Code = Device.Code };
-            //    }
-            //    else if (Device.Code.Contains("RGV"))
-            //    {
-            //        if (!datas.ContainsKey(Device.Code)) datas[Device.Code] = new RGVData { Code = Device.Code };
-            //    }
+    protected override void DataChanged()
+    {
+        MainWorld.DataQueue.Enqueue(this);
+    }
 
-            //    if (!datas.TryGetValue(Device.Code, out var data)) return;
-            //    data.Frame = DateTime.Now;
-            //    var p = data.GetType().GetProperties().FirstOrDefault(v => v.PropertyType == ProtocolDataType);
-            //    //var ty90 = WCS_Station90;
-            //    //if (p.getty is ty90 or)
-            //    //{
-            //    //}
-            //    if (p == null) return;
-            //    p.SetValue(data, DictionaryToEntity(ProtocolDataType, Items, data));
-            //}
-            //catch (Exception ex)
-            //{
-            //    Console.WriteLine(ex.Message);
-            //}
-        }
+    private Type GetProtocolType(Type source)
+    {
+        var t = source.GetInterfaces().FirstOrDefault(v => v.GetInterfaces().Any(d => d.Name == "IProtocol"));
+        return t;
+    }
 
-        public void DictionaryToEntity(Type type, Dictionary<string, PlcItem> plcItems, DeviceData data)
+    public object DictionaryToEntity(Type type, Dictionary<string, PlcItem> items)
+    {
+        var a = Activator.CreateInstance(type);
+        foreach (var ty in type.GetProperties())
+        foreach (var item in items.Where(item => ty.Name == item.Key))
         {
-            //var entity = Activator.CreateInstance(type);
-            ////采集量
-            //Parallel.ForEach(type.GetProperties(), ty =>
-            //{
-            //    if (plcItems.Any(x => x.Key == ty.Name))
-            //    {
-            //        var item = plcItems.First(x => ty.Name == x.Key);
-            //        ty.SetValue(entity, item.Value.Value);
-            //    }
-            //});
-
-            //Parallel.ForEach(type.GetProperties(), ty =>
-            //{
-            //    var items = data.GetType().GetProperties();
-            //    if (items.Any(x => x.Name == ty.Name))
-            //    {
-            //        var item = items.First(x => ty.Name == x.Name);
-            //        ty.SetValue(entity, item.GetValue(data));
-            //    }
-            //});
-
-            //foreach (var ty in type.GetProperties().Where(x => x.Name == nameof(TDengineBaseEntity.CreateSql)))
-            //{
-            //    var db = new SqlSugarHelper().PLC;
-            //    switch (type.Name)
-            //    {
-            //        case nameof(WCS_SRM520):
-            //            var item = entity as WCS_SRM520;
-            //            ty.SetValue(entity, GetString(db.Insertable(item).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_SRM521):
-            //            var item1 = entity as WCS_SRM521;
-            //            ty.SetValue(entity, GetString(db.Insertable(item1).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_SRM537):
-            //            var item2 = entity as WCS_SRM537;
-            //            ty.SetValue(entity, GetString(db.Insertable(item2).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_RGV520):
-            //            var item3 = entity as WCS_RGV520;
-            //            ty.SetValue(entity, GetString(db.Insertable(item3).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_RGV521):
-            //            var item4 = entity as WCS_RGV521;
-            //            ty.SetValue(entity, GetString(db.Insertable(item4).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_BCR80):
-            //            var item5 = entity as WCS_BCR80;
-            //            ty.SetValue(entity, GetString(db.Insertable(item5).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_BCR81):
-            //            var item6 = entity as WCS_BCR81;
-            //            ty.SetValue(entity, GetString(db.Insertable(item6).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_BCR83):
-            //            var item7 = entity as WCS_BCR83;
-            //            ty.SetValue(entity, GetString(db.Insertable(item7).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Station520):
-            //            var item8 = entity as WCS_Station520;
-            //            ty.SetValue(entity, GetString(db.Insertable(item8).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Station521):
-            //            var item9 = entity as WCS_Station521;
-            //            ty.SetValue(entity, GetString(db.Insertable(item9).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Station523):
-            //            var item10 = entity as WCS_Station523;
-            //            ty.SetValue(entity, GetString(db.Insertable(item10).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Station524):
-            //            var item11 = entity as WCS_Station524;
-            //            ty.SetValue(entity, GetString(db.Insertable(item11).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Station525):
-            //            var item12 = entity as WCS_Station525;
-            //            ty.SetValue(entity, GetString(db.Insertable(item12).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Station90):
-            //            var item13 = entity as WCS_Station90;
-            //            ty.SetValue(entity, GetString(db.Insertable(item13).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Station91):
-            //            var item14 = entity as WCS_Station91;
-            //            ty.SetValue(entity, GetString(db.Insertable(item14).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Truss520):
-            //            var item15 = entity as WCS_Truss520;
-            //            ty.SetValue(entity, GetString(db.Insertable(item15).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Truss521):
-            //            var item16 = entity as WCS_Truss521;
-            //            ty.SetValue(entity, GetString(db.Insertable(item16).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Truss523):
-            //            var item17 = entity as WCS_Truss523;
-            //            ty.SetValue(entity, GetString(db.Insertable(item17).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Truss530):
-            //            var item18 = entity as WCS_Truss530;
-            //            ty.SetValue(entity, GetString(db.Insertable(item18).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Truss531):
-            //            var item19 = entity as WCS_Truss531;
-            //            ty.SetValue(entity, GetString(db.Insertable(item19).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Robot520):
-            //            var item20 = entity as WCS_Robot520;
-            //            ty.SetValue(entity, GetString(db.Insertable(item20).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Robot521):
-            //            var item21 = entity as WCS_Robot521;
-            //            ty.SetValue(entity, GetString(db.Insertable(item21).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Robot522):
-            //            var item22 = entity as WCS_Robot522;
-            //            ty.SetValue(entity, GetString(db.Insertable(item22).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Robot530):
-            //            var item23 = entity as WCS_Robot530;
-            //            ty.SetValue(entity, GetString(db.Insertable(item23).ToSqlString()));
-            //            break;
-
-            //        case nameof(WCS_Robot531):
-            //            var item24 = entity as WCS_Robot531;
-            //            ty.SetValue(entity, GetString(db.Insertable(item24).ToSqlString()));
-            //            break;
-            //    }
-            //}
-            //return entity;
+            ty.SetValue(a, item.Value.Value);
+            break;
         }
 
-        public string GetString(string value)
-        {
-            return value.Replace("INSERT INTO ", "")
-                .Replace(",N'", ",'")
-                .Replace("\0", "")
-                .Replace("wcs_", "")
-                .Replace("(N'", "('") + "\r";
-        }
+        return a;
+    }
+
+    public string GetString(string value)
+    {
+        return value.Replace("INSERT INTO ", "")
+            .Replace(",N'", ",'")
+            .Replace("\0", "")
+            .Replace("wcs_", "")
+            .Replace("(N'", "('") + "\r";
     }
-}
+}

+ 1 - 1
WCS.WorkEngineering/Systems/DataCollectionSysyem.cs

@@ -25,7 +25,7 @@ namespace WCS.WorkEngineering.Systems
     /// <summary>
     ///  数据采集
     /// </summary>
-    [BelongTo(typeof(DataWorld))]
+    [BelongTo(typeof(MainWorld))]
     [Description("数据采集系统")]
     public class DataCollectionSysyem : SystemBase
     {

+ 1 - 1
WCS.WorkEngineering/Systems/MainSysyem.cs

@@ -22,7 +22,7 @@ namespace WCS.WorkEngineering.Systems
     /// <summary>
     ///  数据处理
     /// </summary>
-    [BelongTo(typeof(MainWorld))]
+    //[BelongTo(typeof(MainWorld))]
     [Description("数据处理")]
     public class MainSysyem : SystemBase
     {

+ 1 - 0
WCS.WorkEngineering/WCS.WorkEngineering.csproj

@@ -15,6 +15,7 @@
     <None Remove="Systems\puiaxxwa.5zv~" />
   </ItemGroup>
   <ItemGroup>
+    <PackageReference Include="Dapper" Version="2.1.35" />
     <PackageReference Include="DuckDB.NET.Data.Full" Version="1.1.0.1" />
     <PackageReference Include="MessagePack" Version="2.5.172" />
     <PackageReference Include="RestSharp" Version="112.0.0" />

+ 172 - 107
WCS.WorkEngineering/Worlds/MainWorld.cs

@@ -1,135 +1,200 @@
-using ServiceCenter.Logs;
-using System.Collections.Concurrent;
+using System.Collections.Concurrent;
 using System.ComponentModel;
-using System.Diagnostics;
+using Dapper;
+using FreeRedis;
+using Npgsql;
+using ServiceCenter.Logs;
+using ServiceCenter.SqlSugars;
 using WCS.Core;
 using LogInfo = ServiceCenter.Logs.LogInfo;
 
-namespace WCS.WorkEngineering.Worlds
+namespace WCS.WorkEngineering.Worlds;
+
+/// <summary>
+///     主世界,所有的系统(交互点)默认在该世界下执行。
+///     如有系统需独立,请自行增加对应世界
+///     新增世界应当继承此世界,而不是直接继承World
+/// </summary>
+[Description("主世界")]
+public class MainWorld : World
 {
     /// <summary>
-    /// 主世界,所有的系统(交互点)默认在该世界下执行。
-    /// 如有系统需独立,请自行增加对应世界
-    /// 新增世界应当继承此世界,而不是直接继承World
+    ///     数据队列
+    /// </summary>
+    public static ConcurrentQueue<ProtocolProxyBase> DataQueue = new();
+
+    /// <summary>
+    ///     redis链接
+    /// </summary>
+    public static RedisClient Redis = new(Configs.DebugRedisUrl);
+
+    /// <summary>
+    ///     日志队列
+    /// </summary>
+    protected ConcurrentQueue<KeyLog> Logs = new();
+
+    /// <summary>
+    ///     构造函数
     /// </summary>
-    [Description("主世界")]
-    public class MainWorld : World
+    public MainWorld()
     {
-        /// <summary>
-        /// 构造函数
-        /// </summary>
-        public MainWorld()
-        {
-        }
+    }
 
-        /// <summary>
-        ///  日志队列
-        /// </summary>
-        protected ConcurrentQueue<KeyLog> Logs = new ConcurrentQueue<KeyLog>();
-
-        /// <summary>
-        ///  世界执行周期间隔
-        ///  单位:毫秒
-        /// </summary>
-        protected override int Interval => 300;
-
-        /// <summary>
-        ///  更新前执行,重写改方法后请自行添加执行内容
-        ///  执行内容:清空日志队列
-        /// </summary>
-        protected override void BeforeUpdate(List<WorkTimes> list)
-        {
-            // 清空日志队列,确保日志队列中只会有当前周期日志
-            Logs.Clear();
-        }
+    /// <summary>
+    ///     世界执行周期间隔
+    ///     单位:毫秒
+    /// </summary>
+    protected override int Interval => 300;
 
-        /// <summary>
-        /// 更新后执行,重写改方法后请自行添加执行内容
-        /// 执行内容:清空日志队列
-        /// </summary>
-        protected override void AfterUpdate(List<WorkTimes> list)
-        {
-            //LogHub.WorldPublish(Logs, this.GetType().Name);
-            LogHub.WorldPublish(Logs, this.GetType().Name);
-        }
+    /// <summary>
+    ///     更新前执行,重写改方法后请自行添加执行内容
+    ///     执行内容:清空日志队列
+    /// </summary>
+    protected override void BeforeUpdate(List<WorkTimes> list)
+    {
+        // 清空日志队列,确保日志队列中只会有当前周期日志
+        Logs.Clear();
+    }
 
-        /// <summary>
-        ///  异常处理,重写改方法后请自行添加执行内容
-        ///  执行内容:Exception as KnownException并添加至日志队列
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="exception"></param>
-        /// <exception cref="NotImplementedException"></exception>
-        protected override void OnError(Channel channel, Exception exception)
+    /// <summary>
+    ///     更新后执行,重写改方法后请自行添加执行内容
+    ///     执行内容:清空日志队列
+    /// </summary>
+    protected override void AfterUpdate(List<WorkTimes> list)
+    {
+        //LogHub.WorldPublish(Logs, this.GetType().Name);
+        using (var conn = new NpgsqlConnection(SqlSugarHelper._PLC))
         {
-            if (exception is KnownException)
-            {
-                var ex = exception as KnownException;
-                var log = new LogInfo { Level = ex.Level, Type = ErrorTypeEnum.Kown, LogUpLoad = ex.logUpLoad, Message = ex.Message };
-                Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
-            }
-            else
+            var frameStr = Frame.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
+            conn.Open();
+            var trans = conn.BeginTransaction();
+            try
             {
-                var log = new LogInfo { Level = LogLevelEnum.High, Type = ErrorTypeEnum.Unkown, LogUpLoad = LogUpLoadEnum.UpLoadWMS, Message = exception.Message };
-                Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
-            }
-        }
+//                    var sSql = "SELECT coalesce(max(Ver),0) FROM LocationData";
+//                    var ver = conn.Query<long>(sSql).First();
 
-        /// <summary>
-        ///  日志处理,重写改方法后请自行添加执行内容
-        ///  执行内容:LogInfo as KeyLog并添加至日志队列
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="logObj"></param>
-        /// <exception cref="NotImplementedException"></exception>
-        protected override void OnLog(Channel channel, object logObj)
-        {
-            if (channel == null) return;
-            if (logObj.GetType() == typeof(string))
-            {
-                Logs.Enqueue(new KeyLog
+//                    LocationData[] ldarr = null;
+//                    using (var wms = new SqlConnection(Configs.wmsConnString))
+//                    {
+//                        sSql = @"select '" + frameStr + @"' Frame,F_No Code,F_line Line,F_cell Col,F_layer Layer,F_depth Depth,F_roadway Tunnel, F_status Status,F_isStop IsStop,cast(F_Version as bigint)Ver
+//from dbo.BASE_LOCATION with(nolock) where F_Version>" + ver;
+//                        ldarr = wms.Query<LocationData>(sSql).ToArray();
+//                    }
+
+//                    if (ldarr.Length > 0)
+//                    {
+//                        var ps = typeof(LocationData).GetProperties();
+//                        var cols = string.Join(',', ps.Select(v => v.Name));
+//                        var pCols = string.Join(',', ps.Select(v => $"@{v.Name}"));
+//                        sSql = $"insert into {nameof(LocationData)}({cols}) values({pCols})";
+//                        var rc = conn.Execute(sSql, ldarr);
+//                        //fi.Ver = ldarr.Max(v => v.Ver);
+//                    }
+                if (DataQueue.Count > 0)
                 {
-                    Channel = channel,
-                    Log = new LogInfo()
+                    var gs = DataQueue.GroupBy(v => new { type = v.ProtocolDataType, itype = v.ProtocolType }).ToList();
+                    foreach (var g in gs)
                     {
-                        Level = LogLevelEnum.High,
-                        LogUpLoad = LogUpLoadEnum.UpLoadWMS,
-                        Message = logObj as string,
-                    },
-                    Time = DateTime.Now
-                });
+                        var cmd = $"insert into {g.Key.type.Name} values('{frameStr}',@Code,";
+                        cmd += string.Join(',', g.Key.itype.GetProperties().Select(v => $"@{v.Name}")) + ")";
+                        var arr = g.ToArray();
+                        conn.Execute(cmd, arr);
+                    }
+                }
+
+                if (DataQueue.Count > 0) conn.Execute($"insert into Frames(Frame) values('{frameStr}')");
+                trans.Commit();
             }
-            else
+            catch (Exception ex)
             {
-                var log = (LogInfo)logObj;
-                Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
+                trans.Rollback();
+                throw;
             }
+
+            DataQueue.Clear();
         }
 
-        /// <summary>
-        ///  日志处理,重写改方法后请自行添加执行内容
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <param name="msg"></param>
-        /// <exception cref="NotImplementedException"></exception>
-        protected override void OnInternalLog(Channel channel, string msg)
+        LogHub.WorldPublish(Logs, GetType().Name);
+    }
+
+    /// <summary>
+    ///     异常处理,重写改方法后请自行添加执行内容
+    ///     执行内容:Exception as KnownException并添加至日志队列
+    /// </summary>
+    /// <param name="channel"></param>
+    /// <param name="exception"></param>
+    /// <exception cref="NotImplementedException"></exception>
+    protected override void OnError(Channel channel, Exception exception)
+    {
+        if (exception is KnownException)
+        {
+            var ex = exception as KnownException;
+            var log = new LogInfo
+                { Level = ex.Level, Type = ErrorTypeEnum.Kown, LogUpLoad = ex.logUpLoad, Message = ex.Message };
+            Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
+        }
+        else
         {
-            var log = new LogInfo { Level = LogLevelEnum.Low, Message = msg };
-            if (msg != "开始" && msg != "结束")
+            var log = new LogInfo
             {
-                Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
-            }
+                Level = LogLevelEnum.High, Type = ErrorTypeEnum.Unkown, LogUpLoad = LogUpLoadEnum.UpLoadWMS,
+                Message = exception.Message
+            };
+            Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
         }
+    }
 
-        /// <summary>
-        ///  获取日志,重写改方法后请自行添加执行内容
-        /// </summary>
-        /// <param name="channel"></param>
-        /// <returns></returns>
-        /// <exception cref="NotImplementedException"></exception>
-        protected override IEnumerable<string> GetChannelMsg(Channel channel)
+    /// <summary>
+    ///     日志处理,重写改方法后请自行添加执行内容
+    ///     执行内容:LogInfo as KeyLog并添加至日志队列
+    /// </summary>
+    /// <param name="channel"></param>
+    /// <param name="logObj"></param>
+    /// <exception cref="NotImplementedException"></exception>
+    protected override void OnLog(Channel channel, object logObj)
+    {
+        if (channel == null) return;
+        if (logObj.GetType() == typeof(string))
+        {
+            Logs.Enqueue(new KeyLog
+            {
+                Channel = channel,
+                Log = new LogInfo
+                {
+                    Level = LogLevelEnum.High,
+                    LogUpLoad = LogUpLoadEnum.UpLoadWMS,
+                    Message = logObj as string
+                },
+                Time = DateTime.Now
+            });
+        }
+        else
         {
-            return Logs.Where(v => v.Channel.ToString() == channel.ToString()).Select(v => v.Log.ToString());
+            var log = (LogInfo)logObj;
+            Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
         }
     }
-}
+
+    /// <summary>
+    ///     日志处理,重写改方法后请自行添加执行内容
+    /// </summary>
+    /// <param name="channel"></param>
+    /// <param name="msg"></param>
+    /// <exception cref="NotImplementedException"></exception>
+    protected override void OnInternalLog(Channel channel, string msg)
+    {
+        var log = new LogInfo { Level = LogLevelEnum.Low, Message = msg };
+        if (msg != "开始" && msg != "结束") Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
+    }
+
+    /// <summary>
+    ///     获取日志,重写改方法后请自行添加执行内容
+    /// </summary>
+    /// <param name="channel"></param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    protected override IEnumerable<string> GetChannelMsg(Channel channel)
+    {
+        return Logs.Where(v => v.Channel.ToString() == channel.ToString()).Select(v => v.Log.ToString());
+    }
+}