399 lines
19 KiB
C#
399 lines
19 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 报警信息
|
||
/// </summary>
|
||
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<WebSocketMessageModel> Warnings { get; set; } = new List<WebSocketMessageModel>();
|
||
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)
|
||
{
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
#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 报警消除的处理
|
||
/// <summary>
|
||
/// 未扫描上架禁用库位
|
||
/// </summary>
|
||
/// <param name="warning"></param>
|
||
public static void DisableNoScan(WebSocketMessageModel warning)
|
||
{
|
||
#region 【后台】未扫描上架库位的处理
|
||
try
|
||
{
|
||
//获取库位
|
||
var storeInfo = DbHelp.db.Queryable<StoreInfo>()
|
||
.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<string> { "104379", "103595" }, ref DingDing);
|
||
#region 计算库位禁用率并发送
|
||
Task.Run(() =>
|
||
{
|
||
var disabledStore = DbHelp.db.Queryable<StoreInfo>()
|
||
.Where(t => t.CurrentMatSn == "禁用")
|
||
.ToList();
|
||
var allStore = DbHelp.db.Queryable<StoreInfo>()
|
||
.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<ModuleInfo>()
|
||
.Where(t => t.IsEnable == false)
|
||
.ToList();
|
||
var allModule = DbHelp.db.Queryable<ModuleInfo>()
|
||
.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")}。";
|
||
|
||
var dd = string.Empty;
|
||
MXBackgroundThread.SendDingDingMsg(message, new List<string> { "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<StoreInfo>()
|
||
.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<InventoryDetail>().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<OutOrderMatDetail>()
|
||
.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
|
||
|
||
}
|
||
}
|