using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data.OscarClient; using System.Linq; using System.Text; using System.Threading.Tasks; using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.HardWare; using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model.ApiModel.InOutRecord; using WCS.Model.WebSocketModel; namespace WCS.BLL.Manager { /// /// 报警信息 /// public static class WarningManager { public static object flag = new object(); public static void StartWarningMessageThread() { Task.Run(() => { while (true) { try { var noReceivedWarningMessage = Warnings.Where(t => t.ClientIsReceived == false && t.LastSendTime < DateTime.Now.AddSeconds(-5)) .ToList(); foreach (var warning in noReceivedWarningMessage) { WebSoceketManager.TrySendMessage(warning.ClientIp, JsonConvert.SerializeObject(warning)); warning.LastSendTime = DateTime.Now; } } catch (Exception ex) { } Thread.Sleep(5000); } }); } public static List Warnings { get; set; } = new List(); public static void SendWarning(WebSocketMessageModel warning) { lock (flag) { Warnings.Add(warning); //发送WebSocket记录 Logs.Write(JsonConvert.SerializeObject(warning), LogsType.WebSocket); WebSoceketManager.TrySendMessage(warning.ClientIp, JsonConvert.SerializeObject(warning)); warning.LastSendTime = DateTime.Now; } } public static void ClearWarning(WebSocketMessageModel warning, SolveTypeEnum solveType) { try { var shelfIsWarning = true; var warningInManager = Warnings.Where(t => t.Guid == warning.Guid).FirstOrDefault(); if (warningInManager != null) { if (solveType == SolveTypeEnum.处理) { switch (warningInManager.WarningType) { case WarningTypeEnum.入库自检丢失: SolveLoss(warningInManager); break; case WarningTypeEnum.出库自检丢失: SolveLoss(warningInManager); break; case WarningTypeEnum.自检丢失: SolveLoss(warningInManager); break; } } else if (solveType == SolveTypeEnum.屏蔽库位) { switch (warningInManager.WarningType) { case WarningTypeEnum.出库自检未扫描上架: DisableNoScan(warningInManager); break; case WarningTypeEnum.入库自检未扫描上架: DisableNoScan(warningInManager); break; case WarningTypeEnum.自检未扫描上架: DisableNoScan(warningInManager); break; } } else if (solveType == SolveTypeEnum.忽略) { //不发指令了 } //消除报警缓存信息 lock (flag) { Warnings.Remove(warningInManager); } } //货架是否还存在报警信息 shelfIsWarning = Warnings.Where(t => t.ShelfId == warning.ShelfId) .Where(t => t.IsWarning) .Any(); //对应货架如果不存在报警信息了 指示灯回到对应的状态 Logs.Write($"shelfIsWarning{shelfIsWarning}", LogsType.WebSocket); if (!shelfIsWarning) { Logs.Write("货架不存在报警信息", LogsType.WebSocket); var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == warning.ShelfId) .FirstOrDefault(); if (shelf != null) { try { Logs.Write("smartShelf?.ClearWarning();", LogsType.WebSocket); var smartShelf = shelf as SmartShelf; smartShelf?.ClearWarning(); smartShelf.IsWarning = false; } catch (Exception ex) { } } } if (warning.WarningType == WarningTypeEnum.入库中未扫描上架 || warning.WarningType == WarningTypeEnum.入库中异常取出 || warning.WarningType == WarningTypeEnum.出库中丢失 || warning.WarningType == WarningTypeEnum.出库中未扫描上架) { return; } #region 重新发指令进入对应模式 Logs.Write($"GoInRightMode", LogsType.WebSocket); GoInRightMode(warning); #endregion } catch (Exception e) { Logs.Write($"消除报警信息失败:发生异常" + e.Message); } } public static void RemoveMessage(WebSocketMessageModel warning) { var warningInManager = Warnings.Where(t => t.Guid == warning.Guid).FirstOrDefault(); lock (flag) { Warnings.Remove(warningInManager); } } #region 报警消除的处理 /// /// 未扫描上架禁用库位 /// /// public static void DisableNoScan(WebSocketMessageModel warning) { #region 【后台】未扫描上架库位的处理 try { //获取库位 var storeInfo = DbHelp.db.Queryable() .Where(t => t.ShelfId == warning.ShelfId) .Where(t => t.Id == warning.StoreId) .First(); if (storeInfo != null) { storeInfo.CurrentMatSn = "禁用"; DbHelp.db.Updateable(storeInfo).ExecuteCommand(); if (LocalFile.Config.IsMx) { var DingDing = string.Empty; MXBackgroundThread.SendDingDingMsg($"【智能货架】库位{storeInfo.StoreCode}被 {warning.SolvedUser} “未扫描上架弹窗”屏蔽,请及时调查或维保硬件!", new List { "104379", "103595" }, ref DingDing); Logs.Write($"【智能货架】库位{storeInfo.StoreCode}被 {warning.SolvedUser} “未扫描上架弹窗”屏蔽,请及时调查或维保硬件!"); #region 计算库位禁用率并发送 Task.Run(() => { var disabledStore = DbHelp.db.Queryable() .Where(t => t.CurrentMatSn == "禁用") .ToList(); var allStore = DbHelp.db.Queryable() .ToList(); var disabledCount = disabledStore.Count(); var allCount = allStore.Count(); var disabledACount = disabledStore.Where(t => t.ShelfCode.Contains("A")).ToList().Count(); var allACount = allStore.Where(t => t.ShelfCode.Contains("A")).ToList().Count(); var disabledCCount = disabledStore.Where(t => t.ShelfCode.Contains("C")).ToList().Count(); var allCCount = allStore.Where(t => t.ShelfCode.Contains("C")).ToList().Count(); var disabledModule = DbHelp.db.Queryable() .Where(t => t.IsEnable == false) .ToList(); var allModule = DbHelp.db.Queryable() .ToList(); var disabledModuleCount = disabledModule.Count(); var allModuleCount = allModule.Count(); var disabledAModuleCount = disabledModule.Where(t => t.ShelfCode.Contains("A")).ToList().Count(); var allAModuleCount = allModule.Where(t => t.ShelfCode.Contains("A")).ToList().Count(); var disabledCModuleCount = disabledModule.Where(t => t.ShelfCode.Contains("C")).ToList().Count(); var allCModuleCount = allModule.Where(t => t.ShelfCode.Contains("C")).ToList().Count(); var message = $"【智能货架】当前库位总数{allCount},禁用总数{disabledCount},禁用率{((double)disabledCount / allCount).ToString("P")}," + $"其中A区库位总数{allACount},禁用数{disabledACount},禁用率{((double)disabledACount / allACount).ToString("P")}," + $"C区库位总数{allCCount},禁用数{disabledCCount},禁用率{((double)disabledCCount / allCCount).ToString("P")}。\r\n" + $"当前模组总数{allModuleCount},禁用总数{disabledModuleCount},禁用率{((double)disabledModuleCount / allModuleCount).ToString("P")}," + $"其中A区模组总数{allAModuleCount},禁用数{disabledAModuleCount},禁用率{((double)disabledAModuleCount / allAModuleCount).ToString("P")}," + $"C区模组总数{allCModuleCount},禁用数{disabledCModuleCount},禁用率{((double)disabledCModuleCount / allCModuleCount).ToString("P")}。"; Logs.Write(message); var dd = string.Empty; MXBackgroundThread.SendDingDingMsg(message, new List { "104379", "103595" }, ref dd); }); #endregion } } } catch (Exception e) { DbHelp.db.RollbackTran(); } #endregion } public static void SolveLoss(WebSocketMessageModel warning) { #region 【后台】丢失的数据处理 try { //获取库位 var storeInfo = DbHelp.db.Queryable() .Where(t => t.ShelfId == warning.ShelfId) .Where(t => t.Id == warning.StoreId) .First(); if (storeInfo != null) { DbHelp.db.BeginTran(); //库位表字段清空 storeInfo.CurrentMatSn = string.Empty; DbHelp.db.Updateable(storeInfo).ExecuteCommand(); //库存表记录删除、插入出入记录 var inventoryDetail = DbHelp.db.Queryable().Where(t => t.StoreId == storeInfo.Id).First(); if (inventoryDetail != null) { var inOutRecord = new InOutRecord() { StoreCode = storeInfo.StoreCode, StoreId = storeInfo.Id, StoreInfo = storeInfo, R = storeInfo.R, C = storeInfo.C, Wei = storeInfo.Wei, BigShelfCode = storeInfo.BigShelfCode, GroupName = storeInfo.GroupName, MatSN = inventoryDetail.MatSN, MatCode = inventoryDetail.MatCode, MatName = inventoryDetail.MatName, MatBatch = inventoryDetail.MatBatch, MatQty = inventoryDetail.MatQty, MatSpec = inventoryDetail.MatSpec, MatCustomer = inventoryDetail.MatCustomer, MatSupplier = inventoryDetail.MatSupplier, Direction = DirectionEnum.丢失, OperateUser = warning.SolvedUser, }; DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); #region 如果是出库 删除正在出库缓存的数据 if (warning.WarningType == WarningTypeEnum.出库自检丢失) { Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,用户点击【处理】,删除数据", LogsType.Outstore); //清掉需要出库的缓存 var shelf = ShelfManager.Shelves .Where(t => t.ShelfId == warning.ShelfId) .FirstOrDefault(); if (shelf != null) { var smartShelf = shelf as SmartShelf; if (smartShelf != null) { //删除货架上缓存的那一条数据 smartShelf.CurrentOutStoreMatSNs.RemoveAll(t => t == inventoryDetail.MatSN); Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,已删除货架缓存,剩余物料为{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore); //删除模组上缓存的那一条数据 var module = smartShelf.Modules.Where(t => t.ModuleId == warning.ModuleId).FirstOrDefault(); if (module != null) { module.CurrentOutSns.RemoveAll(t => t == inventoryDetail.MatSN); Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,已删除模组缓存,剩余物料为{string.Join(",", module.CurrentOutSns)}", LogsType.Outstore); } //删除已丢失的出库明细数据 var outOrderMatDetail = DbHelp.db.Queryable() .Where(t => t.OrderId == smartShelf.CurrentOutOrder.Id) .Where(t => t.MatSN == inventoryDetail.MatSN && t.IsSended == false) .ToList(); Logs.Write($"【出库自检】发现物料{inventoryDetail.MatSN}丢失,删除出库物料明细数据{outOrderMatDetail.Count}条!"); DbHelp.db.Deleteable(outOrderMatDetail).ExecuteCommand(); } } } #endregion } DbHelp.db.CommitTran(); } } catch (Exception e) { DbHelp.db.RollbackTran(); } #endregion } public static void GoInRightMode(WebSocketMessageModel warning) { try { //模组还存在其他异常 暂时不进入对应模式 var moduleOtherError = WarningManager.Warnings.Where(t => t.ShelfId == warning.ShelfId && t.ModuleId == warning.ModuleId).Any(); if (moduleOtherError) { var guids = WarningManager.Warnings.Where(t => t.ShelfId == warning.ShelfId && t.ModuleId == warning.ModuleId).Select(t => t.Guid.ToString()).ToList(); Logs.Write($"模组还存在其他异常 暂时不进入对应模式.{string.Join("''", guids)}", LogsType.WebSocket); return; } var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == warning.ShelfId) .FirstOrDefault(); if (shelf != null) { Logs.Write($"shelf != null", LogsType.WebSocket); var smartShelf = shelf as SmartShelf; if (smartShelf != null) { var module = smartShelf.Modules.Where(t => t.ModuleId == warning.ModuleId).FirstOrDefault(); if (module != null) { switch (smartShelf.CurrentMode) { case Mode.入库模式: module.GoInInstoreMode(smartShelf.TcpCleint); smartShelf.WarningLight.BlueLight(smartShelf.TcpCleint); break; case Mode.出库模式: Logs.Write("smartShelf.GoInOutstoreByWebSocket", LogsType.WebSocket); smartShelf.GoInOutstoreByWebSocket(module.ModuleId); break; case Mode.待机模式: module.Reset(smartShelf.TcpCleint); smartShelf.WarningLight.CloseLight(smartShelf.TcpCleint); break; default: break; } } } else { Logs.Write($"smartShelf != null", LogsType.WebSocket); } } else { Logs.Write($"shelf == null", LogsType.WebSocket); } } catch (Exception e) { Logs.Write("重置模组状态异常" + e.Message); } } #endregion } }