MainWorld.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using System.Collections.Concurrent;
  2. using System.ComponentModel;
  3. using System.Reflection;
  4. using Dapper;
  5. using FreeRedis;
  6. using Npgsql;
  7. using ServiceCenter.Logs;
  8. using ServiceCenter.SqlSugars;
  9. using SqlSugar;
  10. using WCS.Core;
  11. using LogInfo = ServiceCenter.Logs.LogInfo;
  12. namespace WCS.WorkEngineering.Worlds;
  13. /// <summary>
  14. /// 主世界,所有的系统(交互点)默认在该世界下执行。
  15. /// 如有系统需独立,请自行增加对应世界
  16. /// 新增世界应当继承此世界,而不是直接继承World
  17. /// </summary>
  18. [Description("主世界")]
  19. public class MainWorld : World
  20. {
  21. /// <summary>
  22. /// 数据队列
  23. /// </summary>
  24. public static ConcurrentQueue<ProtocolProxyBase> DataQueue = new();
  25. /// <summary>
  26. /// redis链接
  27. /// </summary>
  28. public static RedisClient Redis = new(Configs.DebugRedisUrl);
  29. /// <summary>
  30. /// 日志队列
  31. /// </summary>
  32. protected ConcurrentQueue<KeyLog> Logs = new();
  33. /// <summary>
  34. /// 构造函数
  35. /// </summary>
  36. public MainWorld()
  37. {
  38. }
  39. /// <summary>
  40. /// 世界执行周期间隔
  41. /// 单位:毫秒
  42. /// </summary>
  43. protected override int Interval => 500;
  44. /// <summary>
  45. /// 更新前执行,重写改方法后请自行添加执行内容
  46. /// 执行内容:清空日志队列
  47. /// </summary>
  48. protected override void BeforeUpdate(List<WorkTimes> list)
  49. {
  50. // 清空日志队列,确保日志队列中只会有当前周期日志
  51. Logs.Clear();
  52. }
  53. /// <summary>
  54. /// 更新后执行,重写改方法后请自行添加执行内容
  55. /// 执行内容:清空日志队列
  56. /// </summary>
  57. protected override void AfterUpdate(List<WorkTimes> list)
  58. {
  59. //LogHub.WorldPublish(Logs, this.GetType().Name);
  60. using (var conn = new NpgsqlConnection(Configs.QdbConnString))
  61. {
  62. var frameStr = Frame.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
  63. conn.Open();
  64. var trans = conn.BeginTransaction();
  65. try
  66. {
  67. if (DataQueue.Count > 0)
  68. {
  69. var gs = DataQueue.GroupBy(v => new { type = v.ProtocolDataType, itype = v.ProtocolType }).ToList();
  70. foreach (var g in gs)
  71. {
  72. var tableName = ((SugarTable)g.Key.type.GetCustomAttribute(typeof(SugarTable))).TableName;
  73. var cmd = $"insert into {tableName} values('{frameStr}',@Code,";
  74. cmd += string.Join(',', g.Key.itype.GetProperties().Select(v => $"@{v.Name}")) + ")";
  75. var arr = g.ToArray();
  76. conn.Execute(cmd, arr);
  77. }
  78. }
  79. if (DataQueue.Count > 0) conn.Execute($"insert into Frames(Frame) values('{frameStr}')");
  80. trans.Commit();
  81. }
  82. catch (Exception ex)
  83. {
  84. trans.Rollback();
  85. throw;
  86. }
  87. DataQueue.Clear();
  88. }
  89. LogHub.WorldPublish(Logs, GetType().Name);
  90. }
  91. /// <summary>
  92. /// 异常处理,重写改方法后请自行添加执行内容
  93. /// 执行内容:Exception as KnownException并添加至日志队列
  94. /// </summary>
  95. /// <param name="channel"></param>
  96. /// <param name="exception"></param>
  97. /// <exception cref="NotImplementedException"></exception>
  98. protected override void OnError(Channel channel, Exception exception)
  99. {
  100. if (exception is KnownException)
  101. {
  102. var ex = exception as KnownException;
  103. var log = new LogInfo
  104. { Level = ex.Level, Type = ErrorTypeEnum.Kown, LogUpLoad = ex.logUpLoad, Message = ex.Message };
  105. Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
  106. }
  107. else
  108. {
  109. var log = new LogInfo
  110. {
  111. Level = LogLevelEnum.High, Type = ErrorTypeEnum.Unkown, LogUpLoad = LogUpLoadEnum.UpLoadWMS,
  112. Message = exception.Message
  113. };
  114. Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
  115. }
  116. }
  117. /// <summary>
  118. /// 日志处理,重写改方法后请自行添加执行内容
  119. /// 执行内容:LogInfo as KeyLog并添加至日志队列
  120. /// </summary>
  121. /// <param name="channel"></param>
  122. /// <param name="logObj"></param>
  123. /// <exception cref="NotImplementedException"></exception>
  124. protected override void OnLog(Channel channel, object logObj)
  125. {
  126. if (channel == null) return;
  127. if (logObj.GetType() == typeof(string))
  128. {
  129. Logs.Enqueue(new KeyLog
  130. {
  131. Channel = channel,
  132. Log = new LogInfo
  133. {
  134. Level = LogLevelEnum.High,
  135. LogUpLoad = LogUpLoadEnum.UpLoadWMS,
  136. Message = logObj as string
  137. },
  138. Time = DateTime.Now
  139. });
  140. }
  141. else
  142. {
  143. var log = (LogInfo)logObj;
  144. Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
  145. }
  146. }
  147. /// <summary>
  148. /// 日志处理,重写改方法后请自行添加执行内容
  149. /// </summary>
  150. /// <param name="channel"></param>
  151. /// <param name="msg"></param>
  152. /// <exception cref="NotImplementedException"></exception>
  153. protected override void OnInternalLog(Channel channel, string msg)
  154. {
  155. var log = new LogInfo { Level = LogLevelEnum.Low, Message = msg };
  156. if (msg != "开始" && msg != "结束") Logs.Enqueue(new KeyLog { Channel = channel, Log = log, Time = DateTime.Now });
  157. }
  158. /// <summary>
  159. /// 获取日志,重写改方法后请自行添加执行内容
  160. /// </summary>
  161. /// <param name="channel"></param>
  162. /// <returns></returns>
  163. /// <exception cref="NotImplementedException"></exception>
  164. protected override IEnumerable<string> GetChannelMsg(Channel channel)
  165. {
  166. return Logs.Where(v => v.Channel.ToString() == channel.ToString()).Select(v => v.Log.ToString());
  167. }
  168. }