From ac14b225072eee90f55adc38d9f2134843de1be1 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Tue, 28 May 2024 17:48:48 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=89=8D=E5=90=8E=E7=AB=AF=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=A4=8D=E4=BD=8D=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2.tcpclient心跳设置 3.优化后端启动速度 4.增加后端出库日志 --- WCS.BLL/Config/JsConfig.cs | 1 + WCS.BLL/HardWare/SingleLightShelf.cs | 2 +- WCS.BLL/HardWare/SmartShelf.cs | 172 ++- WCS.BLL/Manager/DbInit.cs | 111 +- WCS.BLL/Manager/TCPClientManager.cs | 40 +- .../Services/Service/InstoreService.cs.orig | 552 +++++++ WCS.BLL/Services/Service/OutstoreService.cs | 12 +- .../Services/Service/OutstoreService.cs.orig | 1311 +++++++++++++++++ WCS.BLL/Tool/DependencyExtensions.cs | 53 + WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs | 67 + WCS.BLL/Tool/Logs.cs | 6 +- .../Tool/MyFixedHeaderDataHandlingAdapter .cs | 85 ++ WCS.BLL/Tool/TCPClient.cs | 2 + .../ApiModel/Home/ResetShelfStatusRequest.cs | 15 + WCS.WebApi/Controllers/HomeController.cs | 65 +- WCS.WebApi/Controllers/WarningController.cs | 2 + 货架标准上位机/ViewModels/DeviceViewModel.cs | 530 +------ 货架标准上位机/Views/Controls/DeviceView.xaml | 118 +- .../Views/Controls/DeviceView.xaml.cs | 343 ----- .../Views/MXWindows/MXMainWindow.xaml | 5 - 货架标准上位机/Views/ModuleInfoView.xaml | 34 +- 货架标准上位机/Views/ModuleInfoView.xaml.cs | 9 + 货架标准上位机/Views/SetView.xaml | 4 +- 货架标准上位机/data/jsconfig.json | 4 +- 24 files changed, 2403 insertions(+), 1140 deletions(-) create mode 100644 WCS.BLL/Services/Service/InstoreService.cs.orig create mode 100644 WCS.BLL/Services/Service/OutstoreService.cs.orig create mode 100644 WCS.BLL/Tool/DependencyExtensions.cs create mode 100644 WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs create mode 100644 WCS.BLL/Tool/MyFixedHeaderDataHandlingAdapter .cs create mode 100644 WCS.Model/ApiModel/Home/ResetShelfStatusRequest.cs diff --git a/WCS.BLL/Config/JsConfig.cs b/WCS.BLL/Config/JsConfig.cs index d5ef580..83b67ab 100644 --- a/WCS.BLL/Config/JsConfig.cs +++ b/WCS.BLL/Config/JsConfig.cs @@ -38,6 +38,7 @@ namespace WCS.BLL.Config /// public string? WMSUrl { get; set; } + public bool IsResetDBOrTable { get; set; } #region 盟讯公司后台配置 public bool IsMx { get; set; } /// diff --git a/WCS.BLL/HardWare/SingleLightShelf.cs b/WCS.BLL/HardWare/SingleLightShelf.cs index f5fc4ca..6a2ee8f 100644 --- a/WCS.BLL/HardWare/SingleLightShelf.cs +++ b/WCS.BLL/HardWare/SingleLightShelf.cs @@ -72,7 +72,7 @@ namespace WCS.BLL.HardWare public void Reset() { - throw new NotImplementedException(); + return; } public void SetCurrentMode() diff --git a/WCS.BLL/HardWare/SmartShelf.cs b/WCS.BLL/HardWare/SmartShelf.cs index 2d5a694..a0c519a 100644 --- a/WCS.BLL/HardWare/SmartShelf.cs +++ b/WCS.BLL/HardWare/SmartShelf.cs @@ -302,6 +302,7 @@ namespace WCS.BLL.HardWare CurrentOutStoreMatSNs.Clear(); ////添加属于当前货架的物料 CurrentOutStoreMatSNs.AddRange(MatDetails.Select(t => t.MatSN).ToList()); + Logs.Write($"货架【{ShelfCode}】本次发料物料为{string.Join(",", CurrentOutStoreMatSNs)}!", LogsType.Outstore); ////记录当前出库的发料单 CurrentOutOrder = outOrder; @@ -365,63 +366,71 @@ namespace WCS.BLL.HardWare } catch (Exception e) { + Logs.Write($"货架【{ShelfCode}】进入出库模式发生异常!", LogsType.Outstore); GoOutOutstore(); throw e; } } public void GoOutOutstore() { - //找到在出库中的模组 - var outingModules = Modules.Where(t => t.CurrentMode == Mode.出库模式) - .ToList(); - foreach (var module in outingModules) + try { - module.GoOutOutStoreMode(TcpCleint); - } - //Task.Run(() => - //{ - //通信校验 - var timeOut = 3000; - var timeSpan = TimeSpan.FromMilliseconds(0); - var beginTime = DateTime.Now; - while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) - { - timeSpan = DateTime.Now - beginTime; - - //所有板子成功退出出库模式 表示退出出库模式成功,跳出循环 - var isExistsOutstore = outingModules.Where(t => t.CurrentMode == Mode.出库模式) - .Where(t => t.IsEnable) - .Any(); - if (!isExistsOutstore) + Logs.Write($"货架【{ShelfCode}】,开始退出出库", LogsType.Outstore); + //找到在出库中的模组 + var outingModules = Modules.Where(t => t.CurrentMode == Mode.出库模式) + .ToList(); + foreach (var module in outingModules) { - break; + module.GoOutOutStoreMode(TcpCleint); } - //循环延时处理 - Thread.Sleep(50); - } - var list = outingModules.Where(t => t.IsEnable && t.CurrentMode == Mode.出库模式).ToList(); - if (list != null && list.Count > 0) - { - var messages = list.Select(t => $"模组{t.ModuleCode}未退出出库模式!").ToList(); - messages.Add("请及时联系技术人员处理!"); - var exceptionMessage = string.Join("\r\n", messages); - var warningModel = new WebSocketMessageModel() + //通信校验 + var timeOut = 3000; + var timeSpan = TimeSpan.FromMilliseconds(0); + var beginTime = DateTime.Now; + while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) { - IsWarning = true, - WarningType = WarningTypeEnum.退出入库未响应, - StoreId = 0, - StoreCode = "", - ShelfCode = ShelfCode, - ShelfId = ShelfId, - WarningMessage = exceptionMessage, - ClientIp = WebSocketIpAddress, - }; - WarningManager.SendWarning(warningModel); + timeSpan = DateTime.Now - beginTime; + + //所有板子成功退出出库模式 表示退出出库模式成功,跳出循环 + var isExistsOutstore = outingModules.Where(t => t.CurrentMode == Mode.出库模式) + .Where(t => t.IsEnable) + .Any(); + if (!isExistsOutstore) + { + break; + } + //循环延时处理 + Thread.Sleep(50); + } + var list = outingModules.Where(t => t.IsEnable && t.CurrentMode == Mode.出库模式).ToList(); + if (list != null && list.Count > 0) + { + var messages = list.Select(t => $"模组{t.ModuleCode}未退出出库模式!").ToList(); + messages.Add("请及时联系技术人员处理!"); + var exceptionMessage = string.Join("\r\n", messages); + var warningModel = new WebSocketMessageModel() + { + IsWarning = true, + WarningType = WarningTypeEnum.退出出库未响应, + StoreId = 0, + StoreCode = "", + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = WebSocketIpAddress, + }; + WarningManager.SendWarning(warningModel); + } + + CurrentOutStoreMatSNs.Clear(); + WarningLight.CloseLight(TcpCleint); + this.CurrentMode = Mode.待机模式; + Logs.Write($"货架【{ShelfCode}】,结束退出出库", LogsType.Outstore); + } + catch (Exception ex) + { + Logs.Write($"货架【{ShelfCode}】,退出出库时发生异常{ex.Message}", LogsType.Outstore); } - //}); - CurrentOutStoreMatSNs.Clear(); - WarningLight.CloseLight(TcpCleint); - this.CurrentMode = Mode.待机模式; } public void GoInStocktaking(List MatDetails, StockTakingOrder stockTakingOrder) @@ -603,9 +612,18 @@ namespace WCS.BLL.HardWare this.CurrentMode = Mode.待机模式; } - void IShelfBase.Reset() + public void Reset() { - throw new NotImplementedException(); + var modules = Modules.Where(t => t.IsEnable).ToList(); + if (modules != null && modules.Count > 0) + { + modules.ForEach(t => + { + t.Reset(TcpCleint); + }); + } + WarningLight.CloseLight(TcpCleint); + this.CurrentMode = Mode.待机模式; } void IShelfBase.SetCurrentMode() @@ -630,7 +648,6 @@ namespace WCS.BLL.HardWare #region 协议返回处理 public void ProtocolProcess(byte[] data, int boardId, int lightNumber) { - Logs.Write("协议处理4"); //协议处理 判断功能位 switch (data[TcpCleint.PreFixLength + 2]) { @@ -672,7 +689,6 @@ namespace WCS.BLL.HardWare break; } - Logs.Write("协议处理5"); } /// /// 进入入库模式返回信号处理 @@ -1034,19 +1050,16 @@ namespace WCS.BLL.HardWare /// public void InStoreExceptionReturnProcess(byte[] data, int boardId, int lightNumber) { - Logs.Write("协议处理5.1"); lightNumber = (int)data[TcpCleint.PreFixLength + 4]; var storeInfo = DbHelp.db.Queryable() .Where(t => t.ShelfId == ShelfId) .Where(t => t.BoardId == boardId && t.LightNumber == lightNumber) .First(); - Logs.Write("协议处理5.2"); if (storeInfo == null) { //TO DO 库位未找到 return; } - Logs.Write("协议处理5.3"); //已放物料丢失了 物料多放了 储位恢复正常 switch (data[TcpCleint.PreFixLength + 3]) { @@ -1077,12 +1090,10 @@ namespace WCS.BLL.HardWare }); ProcessingExceptions.RemoveAll(t => t.BoardId == boardId); - Logs.Write("协议处理5.5"); } break; case 0x01: { - Logs.Write("协议处理5.4"); var exceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!"; var warningModel = new WebSocketMessageModel() { @@ -1104,12 +1115,10 @@ namespace WCS.BLL.HardWare LightNumber = lightNumber, ExceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!" }); - Logs.Write("协议处理5.5"); } break; case 0x02: { - Logs.Write("协议处理5.4"); var exceptionMessage = storeInfo.StoreCode + "物料被取出!"; var warningModel = new WebSocketMessageModel() { @@ -1131,7 +1140,6 @@ namespace WCS.BLL.HardWare LightNumber = lightNumber, ExceptionMessage = storeInfo.StoreCode + "入库过程中物料丢失!" }); - Logs.Write("协议处理5.5"); } break; default: @@ -1281,7 +1289,7 @@ namespace WCS.BLL.HardWare { if (CurrentMode != Mode.出库模式) { - Logs.Write($"出库错误:{ShelfCode}该货架模式不是出库模式或盘点模式!"); + Logs.Write($"出库错误:{ShelfCode}该货架模式不是出库模式或盘点模式!", LogsType.Outstore); return; } lightNumber = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]); @@ -1303,7 +1311,7 @@ namespace WCS.BLL.HardWare if (string.IsNullOrEmpty(storeInfo.CurrentMatSn)) { //该库位是需要出库的库位,物料被多次取出or给了多个正常出库信号 - Logs.Write($"该库位是需要出库的库位,物料被反复取出or给了多个正常出库信号,库位{storeInfo.StoreCode}"); + Logs.Write($"该库位是需要出库的库位,物料被反复取出or给了多个正常出库信号,库位{storeInfo.StoreCode}", LogsType.Outstore); //暂不进行处理 return; } @@ -1311,7 +1319,7 @@ namespace WCS.BLL.HardWare //不是本次出库需要出的物料 if (!CurrentOutStoreMatSNs.Contains(storeInfo.CurrentMatSn)) { - Logs.Write($"{storeInfo.CurrentMatSn}不是本次需要出库的物料"); + Logs.Write($"{storeInfo.CurrentMatSn}不是本次需要出库的物料", LogsType.Outstore); //报警灯报警 WarningLight.WaringLightAlwaysRed(TcpCleint); return; @@ -1321,7 +1329,7 @@ namespace WCS.BLL.HardWare var inventoryDetail = DbHelp.db.Queryable().Where(t => t.MatSN == storeInfo.CurrentMatSn).First(); if (inventoryDetail == null) { - Logs.Write($"{storeInfo.CurrentMatSn}库存信息不存在"); + Logs.Write($"{storeInfo.CurrentMatSn}库存信息不存在", LogsType.Outstore); //报警灯报警 WarningLight.WaringLightAlwaysRed(TcpCleint); return; @@ -1335,7 +1343,7 @@ namespace WCS.BLL.HardWare if (orderMatDetails == null) { - Logs.Write($"{storeInfo.CurrentMatSn},OrderDetail出库明细信息不存在"); + Logs.Write($"{storeInfo.CurrentMatSn},OrderDetail出库明细信息不存在", LogsType.Outstore); //报警灯报警 WarningLight.WaringLightAlwaysRed(TcpCleint); return; @@ -1408,9 +1416,11 @@ namespace WCS.BLL.HardWare module.ComfirmOutstore(TcpCleint, data[TcpCleint.PreFixLength + 3]); - //当前柜子是否还存在未出库的 + Logs.Write($"货架【{ShelfCode}】,用户取出物料{matSN}", LogsType.Outstore); CurrentOutStoreMatSNs.RemoveAll(t => t == matSN);//删除本次已出的物料SN + Logs.Write($"货架【{ShelfCode}】,当前货架剩余物料{string.Join(",", CurrentOutStoreMatSNs)}", LogsType.Outstore); + var isExsistOut = CurrentOutStoreMatSNs.Any(); var tempOrder = CurrentOutOrder; @@ -1432,6 +1442,7 @@ namespace WCS.BLL.HardWare //本次亮灯的物料已全部取出 if (!isExsistOut) { + Logs.Write($"货架【{ShelfCode}】,本次亮灯的物料已全部取出", LogsType.Outstore); CurrentOutOrder = null; //退出出库模式 @@ -1453,7 +1464,7 @@ namespace WCS.BLL.HardWare .Any(); if (!isLastShelf) { - Logs.Write($"发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料"); + Logs.Write($"发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料", LogsType.Outstore); var outOrder = DbHelp.db.Queryable() .Where(t => t.OrderNumber == OrderNumber) .First(); @@ -1468,7 +1479,7 @@ namespace WCS.BLL.HardWare if (outOrderMatDetails != null && outOrderMatDetails.Count > 0) { //存在待出库 然后之前又没亮灯的情况 => 继续分批次亮灯 - Logs.Write($"发料单{OrderNumber},还有物料未出!"); + Logs.Write($"发料单{OrderNumber},还有物料未出!", LogsType.Outstore); var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode) .Select(o => new { count = o.Count(), bb = o }) .Where(o => o.count >= 2) @@ -1480,13 +1491,13 @@ namespace WCS.BLL.HardWare var matCode = outOrderDetailCount.First().bb.Key; outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode) .ToList(); - Logs.Write($"发料单{OrderNumber},本次亮灯物料{matCode}!"); + Logs.Write($"发料单{OrderNumber},本次亮灯物料{matCode}!", LogsType.Outstore); } //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 else { //剩余物料全出 - Logs.Write($"发料单{OrderNumber},剩余物料灯全亮!"); + Logs.Write($"发料单{OrderNumber},剩余物料灯全亮!", LogsType.Outstore); } var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) @@ -1517,14 +1528,35 @@ namespace WCS.BLL.HardWare } else { - Logs.Write($"发料单{OrderNumber},当前物料已发完!"); + Logs.Write($"发料单{OrderNumber},当前物料已发完!", LogsType.Outstore); } } else { - Logs.Write($"发料单{OrderNumber},OutOrder为null,肯定是有问题"); + Logs.Write($"发料单{OrderNumber},OutOrder为null,肯定是有问题", LogsType.Outstore); } + } + else + { + Logs.Write($"发料单{OrderNumber},非最后一个出库货架!", LogsType.Outstore); + var otherShelfs = ShelfManager.Shelves + .Where(t => t.OrderNumber == OrderNumber) + .Where(t => t.CurrentMode == Mode.出库模式) + .ToList(); + otherShelfs.ForEach(shelf => + { + try + { + if (shelf is SmartShelf) + { + var smartShelf = (SmartShelf)shelf; + Logs.Write($"货架【{smartShelf.ShelfCode}】待取物料{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore); + } + } + catch + { } + }); } #endregion } diff --git a/WCS.BLL/Manager/DbInit.cs b/WCS.BLL/Manager/DbInit.cs index e7d6f36..3a25c02 100644 --- a/WCS.BLL/Manager/DbInit.cs +++ b/WCS.BLL/Manager/DbInit.cs @@ -21,7 +21,7 @@ namespace WCS.BLL.Manager Logs.Write("【初始化数据库】开始", LogsType.StartBoot); //初始化数据库对象 if (LocalFile.Config.IsMx) - { + { DbHelp.db = new SqlSugarScope(new ConnectionConfig() { ConnectionString = LocalFile.Config.DataDbPath, @@ -57,60 +57,73 @@ namespace WCS.BLL.Manager { }; }); + Logs.Write("【初始化数据库】MX", LogsType.StartBoot); } - - - DbHelp.db.DbMaintenance.CreateDatabase(); - DbHelp.dbLog.DbMaintenance.CreateDatabase(); - - DbHelp.db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo) - , typeof(InventoryDetail), typeof(OutOrder), typeof(OutOrderDetail), typeof(OutOrderMatDetail) - , typeof(ShelfTypeInfo), typeof(MatBaseInfo), typeof(MatInfo) - , typeof(StockTakingOrder), typeof(StockTakingOrderMatDetail), typeof(InOutRecord) - , typeof(DocumentSerialNumber) - ); - - DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord)); - - //初始化单据序列号数据 - if (!DbHelp.db.Queryable().Any()) + //手动修改后台配置后再进行CodeFirst 数据库的生成、表的生成 + if (LocalFile.Config.IsResetDBOrTable) { - var outDocumentSerialNumber = new DocumentSerialNumber() - { - DocumentType = DocumentTypeEnum.出库单据, - UpdateDate = DateTime.Now, - CurrentSerialNumber = 0 - }; + #region 建库建表 只在表有变动时运行 + DbHelp.db.DbMaintenance.CreateDatabase(); + DbHelp.dbLog.DbMaintenance.CreateDatabase(); + Logs.Write("【初始化数据库】创建数据库", LogsType.StartBoot); - var stockTakingDocumentSerialNumber = new DocumentSerialNumber() - { - DocumentType = DocumentTypeEnum.盘点单据, - UpdateDate = DateTime.Now, - CurrentSerialNumber = 0 - }; + DbHelp.db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo) + , typeof(InventoryDetail), typeof(OutOrder), typeof(OutOrderDetail), typeof(OutOrderMatDetail) + , typeof(ShelfTypeInfo), typeof(MatBaseInfo), typeof(MatInfo) + , typeof(StockTakingOrder), typeof(StockTakingOrderMatDetail), typeof(InOutRecord) + , typeof(DocumentSerialNumber) + ); + Logs.Write("【初始化数据库】db建表", LogsType.StartBoot); - DbHelp.db.Insertable(outDocumentSerialNumber).ExecuteCommand(); - DbHelp.db.Insertable(stockTakingDocumentSerialNumber).ExecuteCommand(); + DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord)); + Logs.Write("【初始化数据库】logdb建表", LogsType.StartBoot); + + //初始化单据序列号数据 + if (!DbHelp.db.Queryable().Any()) + { + var outDocumentSerialNumber = new DocumentSerialNumber() + { + DocumentType = DocumentTypeEnum.出库单据, + UpdateDate = DateTime.Now, + CurrentSerialNumber = 0 + }; + + var stockTakingDocumentSerialNumber = new DocumentSerialNumber() + { + DocumentType = DocumentTypeEnum.盘点单据, + UpdateDate = DateTime.Now, + CurrentSerialNumber = 0 + }; + + DbHelp.db.Insertable(outDocumentSerialNumber).ExecuteCommand(); + DbHelp.db.Insertable(stockTakingDocumentSerialNumber).ExecuteCommand(); + } + Logs.Write("【初始化数据库】DocumentSerialNumber", LogsType.StartBoot); + + //初始化货架类型 + if (!DbHelp.db.Queryable().Any()) + { + var smartShelf = new ShelfTypeInfo() + { + ShelfTypeName = "智能货架" + }; + var singleLight = new ShelfTypeInfo() + { + ShelfTypeName = "信息化货架" + }; + DbHelp.db.Insertable(smartShelf).ExecuteCommand(); + DbHelp.db.Insertable(singleLight).ExecuteCommand(); + } + Logs.Write("【初始化数据库】初始化货架类型", LogsType.StartBoot); + + //初始化权限数据库 + AuthDbHelp.InitDb(); + #endregion + + LocalFile.Config.IsResetDBOrTable = false; + LocalFile.SaveConfig(); } - //初始化货架类型 - if (!DbHelp.db.Queryable().Any()) - { - var smartShelf = new ShelfTypeInfo() - { - ShelfTypeName = "智能货架" - }; - var singleLight = new ShelfTypeInfo() - { - ShelfTypeName = "信息化货架" - }; - DbHelp.db.Insertable(smartShelf).ExecuteCommand(); - DbHelp.db.Insertable(singleLight).ExecuteCommand(); - } - Logs.Write("【初始化数据库】结束", LogsType.StartBoot); - - //初始化权限数据库 - AuthDbHelp.InitDb(); } } } diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs index a01f9e0..4c016f1 100644 --- a/WCS.BLL/Manager/TCPClientManager.cs +++ b/WCS.BLL/Manager/TCPClientManager.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Sockets; +using WCS.BLL.Config; using WCS.BLL.HardWare; using WCS.DAL.Db; using WCS.DAL.DbModels; @@ -25,6 +26,7 @@ namespace WCS.BLL.Manager Logs.Write("【InitTcpClient】开始", LogsType.StartBoot); var ips = DbHelp.db.Queryable() + .WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName),t => t.GroupName == LocalFile.Config.GroupName) .Select(t => t.ClientIp) .Distinct() .ToList(); @@ -33,7 +35,6 @@ namespace WCS.BLL.Manager Task.Run(() => { var tcpCleint = new TCPClient(ip, ""); - //配置断线重连 tcpCleint.tcpClient.Received += (client, e) => { var clientIpHost = client.IP + ":" + client.Port; @@ -44,7 +45,7 @@ namespace WCS.BLL.Manager } var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); - Logs.Write($"【接收】{BitConverter.ToString(data)}",LogsType.Instructions); + Logs.Write($"【接收】{BitConverter.ToString(data)}", LogsType.Instructions); e.ByteBlock.Clear(); var len = data.Length; for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++) @@ -78,7 +79,7 @@ namespace WCS.BLL.Manager { var shelf = ShelfManager.Shelves .Where(t => t.ClientIp == clientIpHost) - .Where(t => t.ModuleIds.Contains(boardId)) + .Where(t => t.ModuleIds != null && t.ModuleIds.Contains(boardId)) .FirstOrDefault(); var smartShelf = shelf as SmartShelf; smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); @@ -101,6 +102,7 @@ namespace WCS.BLL.Manager if (TcpCleint.IsFirstConnected == false) { Logs.Write($"【InitTcpClient】{clientIpHost}完成首次连接", LogsType.StartBoot); + Console.WriteLine($"【InitTcpClient】{clientIpHost}完成首次连接"); InitStatus(TcpCleint); TcpCleint.IsFirstConnected = true; } @@ -117,23 +119,31 @@ namespace WCS.BLL.Manager { while (true) { - Thread.Sleep(1000); - var noFirstConnectedClients = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false) - .ToList(); - if (noFirstConnectedClients.Count == 0) + try { - break; - } - else - { - noFirstConnectedClients.ForEach(t => + Thread.Sleep(1000); + var noFirstConnectedClients = TCPClientManager.TCPClients.Where(t => t.IsFirstConnected == false) + .ToList(); + if (noFirstConnectedClients.Count == 0) { - t.ReConnectAsync(); - }); + break; + } + else + { + Console.WriteLine($"存在tcp未完成首次连接,继续重连!"); + noFirstConnectedClients.ForEach(t => + { + t.ReConnectAsync(); + }); + } + } + catch (Exception ex) + { + } } }); - Logs.Write("【InitTcpClient】完成后台继续连接", LogsType.StartBoot); + Logs.Write("【InitTcpClient】完成 后台继续连接", LogsType.StartBoot); } //后台启动时给所有板子、警示灯发送复位操作 保持状态一致 diff --git a/WCS.BLL/Services/Service/InstoreService.cs.orig b/WCS.BLL/Services/Service/InstoreService.cs.orig new file mode 100644 index 0000000..b0977c8 --- /dev/null +++ b/WCS.BLL/Services/Service/InstoreService.cs.orig @@ -0,0 +1,552 @@ +using OracleInternal.SqlAndPlsqlParser.LocalParsing; +using System.ComponentModel.DataAnnotations.Schema; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using WCS.BLL.Config; +using WCS.BLL.DbModels; +using WCS.BLL.HardWare; +using WCS.BLL.Manager; +using WCS.BLL.Services.IService; +using WCS.BLL.Tool; +using WCS.BLL.Tool.Api.ApiModel; +using WCS.DAL.Db; +using WCS.DAL.DbModels; +using WCS.Model; +using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MXBackgroundThread; + +namespace WCS.BLL.Services.Service +{ + public class InstoreService : IInstoreService + { + public InstoreService() { } + + public ResponseBase shelfGoInInStore(ShelfGoInInstoreRequest request) + { + //校验货架编码规则 + //取配置文件中得货架编码规则 + bool isValid = false; + var patterns = LocalFile.Config.ModuleCodePatterns; + if (patterns != null && patterns.Count > 0) + { + foreach (var pattern in patterns) + { + isValid = Regex.IsMatch(request.ModuleCode, pattern); + //匹配到第一个符合条件的货架码 就直接退出循环 认为匹配成功 + if (isValid) + break; + } + } + //如果配置文件缺失 使用默认正则进行匹配 + else + { + isValid = Regex.IsMatch(request.ModuleCode, LocalFile.DefaultModuleCodePattern); + } + + if (!isValid) + { + return new ResponseBase() + { + Code = 202, + Message = $"模组编码{request.ModuleCode}不满足模组编码规则!", + }; + } + //找到模组对应的货架 + var shelf = ShelfManager.Shelves.Where(t => t.ModulesStr.Contains(request.ModuleCode)).FirstOrDefault(); + if (shelf == null)//未找到 + { + return new ResponseBase() + { + Code = 201, + Message = "未找到模组对应的货架", + }; + } + //已找到模组对应货架 + shelf.GoInInstore(request.IpAdress); + + if (shelf.CurrentMode == Mode.入库模式) + //成功进入入库模式 + return new ShelfGoInInstoreResponse() + { + Code = 200, + Message = $"货架进入入库模式成功!{string.Join(",", shelf.ExceptionMessages)}", + Data = new ShelfGoInInstoreDto() + { + ShelfCode = shelf.ShelfCode, + ModulesStr = shelf.ModulesStr, + } + }; + else + return new ShelfGoInInstoreResponse() + { + Code = 201, + Message = $"货架进入入库模式失败:{string.Join(",", shelf.ExceptionMessages)}", + Data = null + }; + + } + + public ResponseBase shelfGoOutInStore(ShelfGoOutInStoreRequest request) + { + //获取货架 + var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + if (shelf == null)//货架不存在 + { + return new ResponseCommon() + { + Code = 201, + Message = $"退出入库模式失败:货架[{request.ShelfCode}]不存在!", + }; + } + + //判断扫码枪 是否被其他扫码枪所占用 如果占用 直接退出入库模式 不发指令 + shelf.GoOutInstore(); + + if (shelf.ExceptionMessages == null || shelf.ExceptionMessages.Count == 0) + //已退出 + return new ResponseCommon() + { + Code = 200, + Message = $"货架[{request.ShelfCode}]已退出入库模式!", + }; + else + return new ResponseCommon() + { + Code = 200, + Message = $"货架[{request.ShelfCode}]已退出入库模式!{string.Join(",", shelf.ExceptionMessages)}", + }; + } + + public async Task queryByMatSn(QueryByMatSnRequest request) + { + //判断物料是否已入库 + var inventory = await DbHelp.db.Queryable().Where(t => t.MatSN == request.MatSn).FirstAsync(); + if (inventory != null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:物料{inventory.MatSN}已入库!库位为{inventory.StoreCode}", + }; + } + + IShelfBase shelf = null; + if (!request.SingleLightIn) + { + //获取货架 + shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + if (shelf == null)//货架不存在 + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:货架[{request.ShelfCode}]不存在!", + }; + } + //判断当前是否是入库模式 + if (shelf.CurrentMode != Mode.入库模式) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:货架[{request.ShelfCode}]不在入库模式!\r\n当前为{shelf.CurrentMode}", + }; + } + } + + #region 获取物料数据 //调用接口或者直接查询数据库 + // 调用接口 + if (LocalFile.Config.IsAccessWMS) + { + #region 调用WMS接口获取物料信息 + try + { + var body = new + { + materialBar = request.MatSn + }; + var Result = ApiHelp.GetDataFromHttp>>("http://192.168.2.23:9213/integrate/instock/queryBybar", body, "POST", true); + + //查询到物料信息 + if (Result != null && Result.Code == 200 && Result.Data != null && Result.Data.Count > 0) + { + var data = Result.Data.First(); + if (!request.SingleLightIn && shelf != null) + shelf.InStoreData = new MatInfoResponse() + { + materialBar = data.materialBar, + materialCode = data.materialCode, + materialName = data.materialName, + materialQty = data.materialQty, + materialSpec = data.materialSpec, + batchNo = data.batchNo, + supplier = "", + customer = "", + + InstoreUser = request.UserName + }; + + var matInfo = new MatInfo() + { + MatSn = data.materialBar, + MatCode = data.materialCode, + MatName = data.materialName, + MatBatch = data.batchNo, + MatQty = (int)data.materialQty, + MatSpec = data.materialSpec, + MatSupplier = "", + MatCustomer = "", + }; + + return new ResponseCommon() + { + Code = 200, + Data = matInfo, + Message = "success" + }; + } + else if (Result != null && Result.Code == 200 && Result.Data == null) + { + //Mes系统中未获取到物料信息 + + //简单校验看是否满足海康物料 + //海康物料 只扫了外箱码 未扫条码 + if ((request.MatSn.Length == 54 || request.MatSn.Length == 56) && !request.MatSn.Contains("\\") && !request.MatSn.Contains("/")) + { + + if (!request.SingleLightIn && shelf != null) + shelf.InStoreData = new MatInfoResponse() + { + materialBar = request.MatSn, + materialCode = "暂时未知", + materialName = "暂时未知", + materialQty = 0, + materialSpec = "暂时未知", + batchNo = "暂时未知", + supplier = "", + customer = "", + + InstoreUser = request.UserName + }; + + var matInfo = new MatInfo() + { + MatSn = request.MatSn, + MatCode = "暂时未知", + MatName = "暂时未知", + MatBatch = "暂时未知", + MatQty = 0, + MatSpec = "暂时未知", + MatSupplier = "", + MatCustomer = "", + }; + + return new ResponseCommon() + { + Code = 200, + Data = matInfo, + Message = "success" + }; + } + + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:调用Mes接口未获取到物料信息!", + }; + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:调用Mes接口失败!", + }; + } + } + catch (Exception e) + { + return new ResponseCommon() + { + Code = 300, + Message = $"操作失败:调用Mes接口发生异常{e.Message}", + }; + } + #endregion + } + //查询数据库是否存在这个物料 + else + { + var matInfo = await DbHelp.db.Queryable().Where(t => t.MatSn == request.MatSn).FirstAsync(); + if (matInfo != null) + { + //TODO 改成wcs的实体 + if (!request.SingleLightIn && shelf != null) + shelf.InStoreData = new MatInfoResponse() + { + materialBar = matInfo.MatSn, + materialCode = matInfo.MatCode, + materialName = matInfo.MatName, + materialQty = matInfo.MatQty, + materialSpec = matInfo.MatSpec, + batchNo = matInfo.MatBatch, + supplier = matInfo.MatSupplier, + customer = matInfo.MatCustomer, + + InstoreUser = request.UserName + }; + + return new ResponseCommon() + { + Code = 200, + Data = matInfo, + Message = "success" + }; + } + else + return new ResponseCommon() + { + Code = 201, + Data = null, + Message = $"不存在物料{request.MatSn}" + }; + } + #endregion + } + + /// + /// 单灯出库时查询物料信息 这里返回库存的数据 + /// + /// + /// + public async Task queryByMatSnOut(QueryByMatSnRequest request) + { + //判断物料是否已入库 + var inventory = await DbHelp.db.Queryable().Where(t => t.MatSN == request.MatSn).FirstAsync(); + if (inventory == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:物料不在库存内,无法进行出库!", + }; + } + else + { + return new ResponseCommon() + { + Code = 200, + Message = $"Success", + Data = new MatInfo() + { + MatSn = inventory.MatSN, + MatCode = inventory.MatCode, + MatName = inventory.MatName, + MatBatch = inventory.MatBatch, + MatQty = inventory.MatQty, + MatSpec = inventory.MatSpec, + MatSupplier = inventory.MatSupplier, + MatCustomer = inventory.MatCustomer, + } + }; + } + } + + public async Task queryInstoreStatus(QueryByMatSnRequest request) + { + //获取货架 + var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + if (shelf == null)//货架不存在 + { + return new ResponseCommon() + { + Code = 201, + Message = $"货架[{request.ShelfCode}]不存在!", + }; + } + + //判断当前是否是入库模式 + if (shelf.CurrentMode != Mode.入库模式) + { + return new ResponseCommon() + { + Code = 201, + Message = $"货架[{request.ShelfCode}]已退出入库模式!\r\n当前为{shelf.CurrentMode}", + }; + } + + //TODO 配置这个时间相当于需要入库扫码后需要等待的时间 + var timeOut = 5000; + var timeSpan = TimeSpan.FromMilliseconds(0); + var beginTime = DateTime.Now; + while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) + { + timeSpan = DateTime.Now - beginTime; + //已入库当前扫码的物料时 查询数据库 + if (shelf.InStoreData == null || (shelf.InStoreData as object) == null) + { + await Task.Delay(50); + var inventoryDetail = DbHelp.db.Queryable() + .Where(t => t.MatSN == request.MatSn) + .First(); + if (inventoryDetail != null) + { + return new ResponseCommon() + { + Code = 200, + Message = $"入库成功!物料已放入库位{inventoryDetail.StoreCode}", + Data = new + { + StoreCode = inventoryDetail.StoreCode, + } + }; + } + else + break; + } + //延时处理 + Thread.Sleep(50); + } + //超时未成功入库 + shelf.InStoreData = null; + return new ResponseCommon() + { + Code = 201, + Message = $"超时未入库!请重新扫码后入库!", + Data = new + { + StoreCode = string.Empty, + } + }; + } + + public async Task queryInstoreStatusSingle(QueryByMatSnRequestSingle request) + { + //获取货架 + //var shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); + //if (shelf == null)//货架不存在 + //{ + // return new ResponseCommon() + // { + // Code = 201, + // Message = $"货架[{request.ShelfCode}]不存在!", + // }; + //} + List MI = DbHelp.db.Queryable().Where(it => it.ModuleCode == request.ShelfCode).ToList(); + if (MI.Count == 0) + { + return new ResponseCommonSingle() + { + Code = 201, + Message = $"货架[{request.ShelfCode}]不存在!", + }; + } + ResponseCommonSingle rcs = new ResponseCommonSingle(); + rcs.Data = new List(); + + string sendIP = MI[0].CleintIp; //单灯IP + int PCBId = MI[0].BoardId; //单灯PCB板ID + + List SI = DbHelp.db.Queryable().Where(it => it.ModuleCode == request.ShelfCode).ToList(); + + List si = DbHelp.db.Queryable().Where(it => it.ShelfCode == MI[0].ShelfCode).ToList(); + int warnLightID = si[0].LightId; + + foreach (QueryByMatSnRequestSingle.MatSnListDetail matSnListDetail in request.MatSnList) + { + Detail detail = new Detail(); + try + { + InventoryDetail inventoryDetail = new InventoryDetail(); + inventoryDetail.MatSN = matSnListDetail.MatSn; + inventoryDetail.MatCode = matSnListDetail.MatCode; + inventoryDetail.MatName = matSnListDetail.MatName; + inventoryDetail.MatSpec = matSnListDetail.MatSpec; + inventoryDetail.MatBatch = matSnListDetail.MatBatch; + inventoryDetail.MatQty = matSnListDetail.MatQty; + inventoryDetail.MatCustomer = matSnListDetail.MatCustomer; + inventoryDetail.MatSupplier = matSnListDetail.MatSupplier; + inventoryDetail.StoreCode = request.ShelfCode; + inventoryDetail.StoreId = SI[0].Id; + + int count = DbHelp.db.Insertable(inventoryDetail).ExecuteCommand(); + + InOutRecord ior = new InOutRecord(); + ior.MatSN = matSnListDetail.MatSn; + ior.MatCode = matSnListDetail.MatCode; + ior.MatName = matSnListDetail.MatName; + ior.MatSpec = matSnListDetail.MatSpec; + ior.MatBatch = matSnListDetail.MatBatch; + ior.MatQty = matSnListDetail.MatQty; + ior.MatCustomer = matSnListDetail.MatCustomer; + ior.MatSupplier = matSnListDetail.MatSupplier; + ior.StoreCode = request.ShelfCode; + ior.StoreId = SI[0].Id; + ior.Direction = DirectionEnum.入库; + ior.OperateTime = DateTime.Now; + ior.OperateUser = request.UserName; + int count1 = DbHelp.db.Insertable(ior).ExecuteCommand(); + + detail.matsn = matSnListDetail.MatSn; + detail.result = "入库成功"; + rcs.Data.Add(detail); + } + catch (Exception ee) + { + detail.matsn = matSnListDetail.MatSn; + detail.result = "入库失败"; + detail.reason = ee.Message; + rcs.Data.Add(detail); + } + } + //亮灯 + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); +<<<<<<< HEAD + //byte[] data1 = new byte[8]; + //data1[0] = 0xff; + //data1[1] = 0x02; + //data1[2] = 0x00; + //data1[3] = 0x0a; + //data1[4] = (byte)warnLightID; + //data1[5] = 0x03; + //data1[6] = 0x02; + //data1[7] = 0x02; + //byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, true); + byte[] senddata1 = Tool.Helper.InstoreWarnLight(warnLightID); +======= + byte[] data1 = new byte[8]; + data1[0] = 0xff; + data1[1] = 0x02; + data1[2] = 0x00; + data1[3] = 0x0a; + data1[4] = (byte)warnLightID; + data1[5] = 0x03; + data1[6] = 0x02; + data1[7] = 0x02; + byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, false); +>>>>>>> 11 + tCPClient.Send(senddata1); //报警灯短亮一次 + + //byte[] data2 = new byte[8]; + //data2[0] = 0xff; + //data2[1] = 0x01; + //data2[2] = 0x00; + //data2[3] = 0x0a; + //data2[4] = 0x01; + //data2[5] = (byte)PCBId; + //data2[6] = 0x03; + //data2[7] = 0x02; + //byte[] senddata2 = Tool.Helper.Crc16(data2, data2.Length, true); + byte[] senddata2 = Tool.Helper.InstoreLight(PCBId); + tCPClient.Send(senddata2); //库位灯短亮一次 + + return new ResponseCommonSingle() + { + Code = 200, + Message = $"入库成功!", + Data = rcs.Data, + }; + + } + } +} diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index 6195d59..e57e316 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -654,7 +654,7 @@ namespace WCS.BLL.Services.Service }; } - if (request.IsStart)//&& order.OutOrderExeStatus != OutOrderExeStatus.发料完成 + if (request.IsStart) { order.OutOrderExeStatus = OutOrderExeStatus.开始发料; DbHelp.db.Updateable(order).ExecuteCommand(); @@ -690,13 +690,13 @@ namespace WCS.BLL.Services.Service var matCode = outOrderDetailCount.First().bb.Key; outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode) .ToList(); - Logs.Write($"出库单{order.OrderNumber},本次亮灯物料{matCode}!"); + Logs.Write($"出库单{order.OrderNumber},本次亮灯物料{matCode}!",LogsType.Outstore); } //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 else { //剩余物料全出 - Logs.Write($"出库单{order.OrderNumber},剩余物料灯全亮!"); + Logs.Write($"出库单{order.OrderNumber},剩余物料灯全亮!", LogsType.Outstore); } } @@ -708,6 +708,7 @@ namespace WCS.BLL.Services.Service .ToList(); shelf.GoInOutstore(matDetails, order); shelf.OrderNumber = order.OrderNumber; + Logs.Write($"出库单{order.OrderNumber},货架{shelf.ShelfCode}进入入库模式!", LogsType.Outstore); }); //返回 @@ -720,6 +721,7 @@ namespace WCS.BLL.Services.Service } catch (Exception ex) { + Logs.Write($"本次发料发生异常!{ex.Message}", LogsType.Outstore); await GoOutOutstore(request); throw ex; } @@ -1108,16 +1110,12 @@ namespace WCS.BLL.Services.Service }; } - - //退出出库模式 shelves.ForEach(t => { t.GoOutOutstore(); }); - - return new ResponseCommon() { Code = 200, diff --git a/WCS.BLL/Services/Service/OutstoreService.cs.orig b/WCS.BLL/Services/Service/OutstoreService.cs.orig new file mode 100644 index 0000000..3ec8826 --- /dev/null +++ b/WCS.BLL/Services/Service/OutstoreService.cs.orig @@ -0,0 +1,1311 @@ +using Microsoft.Data.SqlClient; +using SqlSugar; +using WCS.BLL.Config; +using WCS.BLL.DbModels; +using WCS.BLL.Manager; +using WCS.BLL.Services.IService; +using WCS.BLL.Tool; +using WCS.DAL.Db; +using WCS.Model; +using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MatInventoryDetail; +using WCS.Model.ApiModel.OutStore; + +namespace WCS.BLL.Services.Service +{ + public class OutstoreService : IOutstoreService + { + public OutstoreService() + { + + } + public async Task>> importMat(List list) + { + //数据校验 + if (list == null || list.Count == 0) + { + return new ResponseCommon>() + { + Code = 201, + Message = "导入失败:导入文件中没有内容!" + }; + } + //需求数量 + var errorCount = list.Where(t => t.需求数量 <= 0).ToList(); + if (errorCount != null && errorCount.Count > 0) + { + return new ResponseCommon>() + { + Code = 201, + Message = "导入失败:需求数量需要大于0!" + }; + } + //每一个物料进行搜索库存 + var returnList = new List(); + foreach (var item in list) + { + var inventoryCount = await DbHelp.db.Queryable() + .Where(t => t.MatCode == item.物料编码) + .Where(t => t.MatBatch == item.物料批次) + .Where(t => t.IsLocked == false) + .SumAsync(t => t.MatQty); + var info = inventoryCount < item.需求数量 ? "库存数量小于需求数量" : string.Empty; + returnList.Add(new MatInventorySummaryModel() + { + MatCode = item.物料编码, + MatName = item.物料名称, + MatBatch = item.物料批次, + NeedQty = item.需求数量, + TotalQty = inventoryCount, + Info = info + }); + } + return new ResponseCommon>() + { + Code = 200, + Data = returnList + }; + } + public async Task SysOutOrderByMatCode(SysOutOrderByMatCodeRequest request) + { + //参数合法性校验 + if (request.ItemList == null || request.ItemList.Count == 0) + { + return new ResponseBase() + { + Code = 201, + Message = "出库单据同步失败:缺少需要出库的物料类型!" + }; + } + //补齐货架类型名称 + if (string.IsNullOrEmpty(request.ShelfTypeName)) + { + var shelfType = await DbHelp.db.Queryable() + .Where(t => t.Id == request.ShelfTypeId) + .FirstAsync(); + if (shelfType == null) + { + return new ResponseBase() + { + Code = 201, + Message = $"出库单据同步失败:缺少必要参数!ShelfTypeId" + }; + } + else + request.ShelfTypeName = shelfType.ShelfTypeName; + } + + //保存数据 + await DbHelp.db.BeginTranAsync(); + try + { + var order = new OutOrder() + { + OrderNumber = request.OrderNumber, + OrderSource = request.OrderSource, + OrderType = request.OrderType, + ShelfTypeId = request.ShelfTypeId, + ShelfTypeName = request.ShelfTypeName, + SyncType = SyncTypeEnum.ByMatCode, + CreateUser = request.UserName, + }; + order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); + request.ItemList.ForEach(async item => + { + var orderDetail = new OutOrderDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + MatCode = item.MatCode, + MatName = item.MatName, + MatBatch = item.MatBatch, + ReqQty = item.ReqQty, + OutQty = 0, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderDetail).ExecuteCommandAsync(); + }); + await DbHelp.db.CommitTranAsync(); + return new ResponseCommon() + { + Code = 200, + Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}", + }; ; + } + catch (Exception ex) + { + await DbHelp.db.RollbackTranAsync(); + Console.WriteLine(ex.Message); + return new ResponseBase() + { + Code = 200, + Message = $"出库单据同步失败:{ex.Message}" + }; + } + } + + public async Task SysOutOrderByMatSn(SysOutOrderByMatSnRequest request) + { + + //参数合法性校验 + if (request.SnList == null || request.SnList.Count == 0) + { + return new ResponseBase() + { + Code = 201, + Message = "出库单据同步失败:缺少物料明细!" + }; + } + //标准版逻辑-库存有无校验 & 库存已锁校验 + if (!LocalFile.Config.IsMx) + { + try + { + await DbHelp.db.BeginTranAsync(); + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.SnList.Contains(t.MatSN)) + .TranLock(DbLockType.Wait) + .ToListAsync(); + if (inventoryDetails.Count < request.SnList.Count)//库存的物料少于需求的物料数量 + { + var existsSns = inventoryDetails.Select(t => t.MatSN).ToList(); + request.SnList.RemoveAll(t => existsSns.Contains(t)); + await DbHelp.db.RollbackTranAsync(); + //返回提示哪些物料库存不存在 + return new ResponseCommon() + { + Code = 201, + Message = "出库单据同步失败:存在物料不在库存中!", + Data = request.SnList + + }; + } + else if (inventoryDetails.Where(t => t.IsLocked).Any()) + { + await DbHelp.db.RollbackTranAsync(); + //返回提示哪些物料库存已被锁定 + return new ResponseCommon() + { + Code = 201, + Message = "出库单据同步失败:存在物料被锁定!", + Data = inventoryDetails.Where(t => t.IsLocked).Select(t => t.MatSN).ToList() + }; + } + + #region 保存数据 + + //锁库存 + inventoryDetails.ForEach(t => + { + t.IsLocked = true; + }); + var lockTask = DbHelp.db.Updateable(inventoryDetails).ExecuteCommandAsync(); + + //保存数据 + var order = new OutOrder() + { + OrderNumber = request.OrderNumber, + OrderSource = request.OrderSource, + OrderType = request.OrderType, + SyncType = SyncTypeEnum.ByMatSn, + CreateUser = request.UserName, + }; + order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); + + //通过库存数据保存出库物料明细表 + var matDetailTasks = inventoryDetails.Select(async t => + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + InventoryDetailId = t.Id, + StoreId = t.StoreId, + StoreCode = t.StoreCode, + MatSN = t.MatSN, + MatCode = t.MatCode, + MatName = t.MatName, + MatSpec = t.MatSpec, + MatBatch = t.MatBatch, + MatQty = t.MatQty, + MatSupplier = t.MatSupplier, + MatCustomer = t.MatCustomer, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + }).ToList(); + + await lockTask; + await Task.WhenAll(matDetailTasks); + + await DbHelp.db.CommitTranAsync(); + return new ResponseCommon() + { + Code = 200, + Message = $"出库单据同步成功!\r\n出库单据号为{request.OrderNumber}", + Data = order.Id + }; + #endregion + } + catch (Exception ex) + { + await DbHelp.db.RollbackTranAsync(); + return new ResponseBase() + { + Code = 201, + Message = $"出库单据同步失败:{ex.Message}" + }; + } + } + //盟讯公司逻辑 不锁库存 直接保存数据/清除未发送的 + else + { + try + { + DbHelp.db.BeginTran(); + //1. 获取库存物料明细 + var inventoryDetails = await DbHelp.db.Queryable() + .Where(t => request.SnList.Contains(t.MatSN)) + .ToListAsync(); + if (inventoryDetails == null || inventoryDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = "保存出库单失败!请重试!", + Data = request.SnList + }; + } + //2. 先获取对应单号是否已经保存 + var outOrder = DbHelp.db.Queryable() + .Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.GroupName == LocalFile.Config.GroupName) + .First(); + //数据库中没有才添加 + if (outOrder == null) + { + //OutOrder + outOrder = new OutOrder() + { + OrderNumber = request.OrderNumber, + OutOrderExeStatus = OutOrderExeStatus.开始发料, + OrderSource = "WCS前端", + SyncType = SyncTypeEnum.ByMatSn, + ShelfTypeName = "智能货架", + ShelfTypeId = 0, + GroupName = LocalFile.Config.GroupName, + }; + outOrder.Id = await DbHelp.db.Insertable(outOrder).ExecuteReturnIdentityAsync(); + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.Id == outOrder.Id) + .FirstAsync(); + //保存单据失败了 + if (outOrder == null) + return new ResponseCommon() + { + Code = 201, + Message = "保存出库单失败!保存Order失败!", + Data = request.SnList + }; + + //出库物料明细 + foreach (var item in inventoryDetails) + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = outOrder.Id, + OrderNumber = outOrder.OrderNumber, + InventoryDetailId = item.Id, + StoreId = item.StoreId, + StoreCode = item.StoreCode, + MatSN = item.MatSN, + MatCode = item.MatCode, + MatName = item.MatName, + MatSpec = item.MatSpec, + MatBatch = item.MatBatch, + MatQty = item.MatQty, + MatSupplier = item.MatSupplier, + MatCustomer = item.MatCustomer, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + } + DbHelp.db.CommitTran(); + } + //数据库已有该Order + else + { + outOrder.CreateTime = DateTime.Now; + DbHelp.db.Updateable(outOrder).ExecuteCommand(); + //删除未出库的 + var outOrderDetails = DbHelp.db.Deleteable() + .Where(t => t.OrderId == outOrder.Id) + .Where(t => t.IsSended == false) + .ExecuteCommand(); + //当前已出库的 //已出库的也不在库存中了 应该查询不到了 + //避免影响效率 就不查重了 + foreach (var item in inventoryDetails) + { + var orderMatDetail = new OutOrderMatDetail() + { + OrderId = outOrder.Id, + OrderNumber = outOrder.OrderNumber, + InventoryDetailId = item.Id, + StoreId = item.StoreId, + StoreCode = item.StoreCode, + MatSN = item.MatSN, + MatCode = item.MatCode, + MatName = item.MatName, + MatSpec = item.MatSpec, + MatBatch = item.MatBatch, + MatQty = item.MatQty, + MatSupplier = item.MatSupplier, + MatCustomer = item.MatCustomer, + CreateUser = request.UserName + }; + await DbHelp.db.Insertable(orderMatDetail).ExecuteCommandAsync(); + } + DbHelp.db.CommitTran(); + + //更新订单状态 + Task.Run(() => + { + if (outOrder != null) + { + #region 物料明细表是否已发完 + var orderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToList(); + var isExistNoSendMat = orderMatDetails.Where(t => t.IsSended == false) + .Any(); + if (isExistNoSendMat) + { + outOrder.OrderStatus = OutOrderStatus.部分发料; + } + else + { + outOrder.OrderStatus = OutOrderStatus.全部发料; + outOrder.OutOrderExeStatus = OutOrderExeStatus.发料完成; + } + #endregion + DbHelp.db.Updateable(outOrder).ExecuteCommand(); + } + }); + } + return new ResponseCommon() + { + Code = 200, + Message = $"Success", + Data = request.SnList + }; + + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + Logs.Write($"同步出库单据发生异常{ex.Message}", LogsType.Info); + return new ResponseCommon() + { + Code = 201, + Message = $"保存出库单失败!{ex.Message}!", + Data = request.SnList + }; + } + + } + + } + + public async Task GetOutOrderList(GetOutOrderListRequest request) + { + //直接查询 + var recordsQueryable = DbHelp.db.Queryable() + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber.Contains(request.OrderNumber)) + .WhereIF(!string.IsNullOrEmpty(request.OrderSource), t => t.OrderSource.Contains(request.OrderSource)) + .WhereIF(!string.IsNullOrEmpty(request.OrderType), t => t.OrderType.Contains(request.OrderType)) + .WhereIF(request.ShelfTypeId != 0, t => t.ShelfTypeId == request.ShelfTypeId); + + var totalCount = await recordsQueryable.CountAsync(); + var records = await recordsQueryable + .Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize) + .ToListAsync(); + //生成序号 + for (int i = 0; i < records.Count; i++) + { + records[i].RowNumber = (request.PageNumber - 1) * request.PageSize + i + 1; + } + + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + TotalCount = totalCount, + MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize), + Count = records.Count, + Lists = records.ToList() + } + }; + } + + public async Task GetOutOrderListByStatus(GetOutOrderListByStatusRequest request) + { + if (request.OrderExeStatus == null || request.OrderExeStatus.Count == 0) + { + //不传入状态不显示 + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + Lists = new List() + } + }; + } + //直接查询 + var recordsQueryable = DbHelp.db.Queryable().Where(t => request.OrderExeStatus.Contains(t.OutOrderExeStatus)); + + var totalCount = await recordsQueryable.CountAsync(); + var records = await recordsQueryable + .OrderByDescending(t => t.CreateTime) + //.Take(request.PageSize) + .ToListAsync(); + + return new PageQueryResponse() + { + Code = 200, + Message = $"success", + Data = new PageQueryResponseData() + { + //TotalCount = totalCount, + //MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize), + //Count = records.Count, + Lists = records.ToList() + } + }; + } + public async Task GetOutOrderDetail(GetOutOrderDetailRequest request) + { + OutOrder outOrder = null; + + #region 查询出库单 + if (request.OrderId != 0) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.Id == request.OrderId).FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在Id为{request.OrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.OrderNumber)) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:缺少必要参数!", + }; + } + #endregion + + #region 查询出库单明细 + var orderDetailTask = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToListAsync(); + var orderDetail = await orderDetailTask; + //生成序号 + for (int i = 0; i < orderDetail.Count; i++) + { + orderDetail[i].RowNumber = i + 1; + } + #endregion + + return new ResponseCommon>() + { + Code = 200, + Message = "Success", + Data = orderDetail + }; + } + + public async Task GetOutOrderMatDetail(GetOutOrderDetailRequest request) + { + OutOrder outOrder = null; + + #region 查询出库单 + if (request.OrderId != 0) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.Id == request.OrderId).FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在Id为{request.OrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.OrderNumber)) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在出库单据号为{request.OrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:缺少必要参数!", + }; + } + #endregion + + #region 出库物料明细 + var orderMatDetailTask = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .ToListAsync(); + var orderMatDetail = await orderMatDetailTask; + //生成序号 + for (int i = 0; i < orderMatDetail.Count; i++) + { + orderMatDetail[i].RowNumber = i + 1; + } + #endregion + + + return new ResponseCommon> + { + Code = 200, + Message = outOrder.OrderStatus.ToString(), + Data = orderMatDetail + }; + } + + public async Task GoInOutstore(GetOutOrderDetailRequest request) + { + try + { + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + + //如果是按物料编码出库 需要计算物料明细、并进行物料锁定 + if (order.SyncType == SyncTypeEnum.ByMatCode) + { + var result = CaculateOutOrderMatDetails(order, request.UserName); + if (result.Code != 200) + { + return result; + } + } + + //获取需要出库的物料明细 + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .Where(t => t.IsSended == false) + .Includes(t => t.StoreInfo) + .ToList(); + if (outOrderMatDetails == null || outOrderMatDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"出库单据{request.OrderNumber}物料已全部完成出库!", + Data = null + }; + } + + if (request.IsStart)//&& order.OutOrderExeStatus != OutOrderExeStatus.发料完成 + { + order.OutOrderExeStatus = OutOrderExeStatus.开始发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + + //按货架分组 按物料找到对应的货架 + var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) + .Distinct() + .ToList(); + var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList(); ; + + var outherModeShelfs = shelfs.Where(t => t.CurrentMode != HardWare.Mode.待机模式).Select(t => t.ShelfCode).ToList(); + if (outherModeShelfs != null && outherModeShelfs.Count > 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"进入出库模式失败:货架{string.Join("", outherModeShelfs)}不在待机模式", + Data = null + }; + } + //看是否是分批次出库的情况 分批次亮灯 + if (LocalFile.Config.IsSameMatCodeOut) + { + var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode) + .Select(o => new { count = o.Count(), bb = o }) + .Where(o => o.count >= 2) + .OrderByDescending(o => o.count) + .ToList(); + //相同物料存在盘数超过2的情况,亮下一个盘数多的物料 + if (outOrderDetailCount.Count > 0) + { + var matCode = outOrderDetailCount.First().bb.Key; + outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode) + .ToList(); + Logs.Write($"出库单{order.OrderNumber},本次亮灯物料{matCode}!"); + } + //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 + else + { + //剩余物料全出 + Logs.Write($"出库单{order.OrderNumber},剩余物料灯全亮!"); + } + } + + //对应的货架对应位置 进入出库模式 亮灯 + shelfs.ForEach(shelf => + { + var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode) + .Distinct() + .ToList(); + shelf.GoInOutstore(matDetails, order); + shelf.OrderNumber = order.OrderNumber; + }); + + //返回 + return new ResponseCommon() + { + Code = 200, + Message = "Success", + Data = null + }; + } + catch (Exception ex) + { + await GoOutOutstore(request); + throw ex; + } + } + + public async Task GoInOutstoreSingle(GetOutOrderDetailRequest request) + { + try + { + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + + //如果是按物料编码出库 需要计算物料明细、并进行物料锁定 + if (order.SyncType == SyncTypeEnum.ByMatCode) + { + var result = CaculateOutOrderMatDetails(order, request.UserName); + if (result.Code != 200) + { + return result; + } + } + + //获取需要出库的物料明细 + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .Where(t => t.IsSended == false) + .Includes(t => t.StoreInfo) + .ToList(); + if (outOrderMatDetails == null || outOrderMatDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"出库单据{request.OrderNumber}物料已全部完成出库!", + Data = null + }; + } + + if (request.IsStart)//&& order.OutOrderExeStatus != OutOrderExeStatus.发料完成 + { + order.OutOrderExeStatus = OutOrderExeStatus.开始发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + //获取亮灯颜色 + List UsedColor = new List(); + string LightColor = ""; + List ol = DbHelp.db.Queryable().OrderBy(it => it.Id, OrderByType.Asc).ToList(); + foreach (OrderLight orderLight in ol) + { + UsedColor.Add(orderLight.LightColor); + if (orderLight.OrderNumber == request.OrderNumber) + { + LightColor = orderLight.LightColor; + break; + } + } + if (LightColor == "") + { + foreach (OrderLight orderLight in ol) + { + if (orderLight.OrderNumber == null) + { + LightColor = orderLight.LightColor; + DbHelp.db.Updateable().SetColumns(it => it.OrderNumber, request.OrderNumber).Where(it => it.LightColor == LightColor).ExecuteCommand(); + break; + } + } + } + //获取出库需求 + List outorderdetal = DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.OrderId == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .ToList(); + + OutResponseCommonSingle orcs = new OutResponseCommonSingle(); + orcs.Data = new List(); + foreach (OutOrderDetail outdetail in outorderdetal) + { + OutDetail od = new OutDetail(); + od.OrderId = outdetail.OrderId; + od.OrderNumber = outdetail.OrderNumber; + od.MatCode = outdetail.MatCode; + od.MatBatch = outdetail.MatBatch; + od.ReqQty = outdetail.ReqQty; + od.CreateTime = outdetail.CreateTime; + od.CreateUser = outdetail.CreateUser; + od.MatName = outdetail.MatName; + od.OutQty = outdetail.OutQty; + od.LightColor = LightColor; + orcs.Data.Add(od); + } + //需要出库的货架名 + List StoreCode = new List(); + //库位灯亮灯 + Dictionary> dict = new Dictionary>(); + foreach (OutOrderMatDetail oomd in outOrderMatDetails) + { + List mi= DbHelp.db.Queryable().Where(it => it.ModuleCode == oomd.StoreCode).ToList(); + if (mi.Count != 0) + { + if (!StoreCode.Contains(oomd.StoreCode)) + { + StoreCode.Add(oomd.StoreCode); + } + if (!dict.Keys.Contains(mi[0].CleintIp)) + { + List board_id = new List(); + board_id.Add(mi[0].BoardId); + dict.Add(mi[0].CleintIp, board_id); + } + else + { + foreach (var v in dict) + { + if (v.Key == mi[0].CleintIp) + { + if (!v.Value.Contains(mi[0].BoardId)) + { + v.Value.Add(mi[0].BoardId); + } + } + } + } + } + } + foreach (var v in dict) + { + string sendIP = v.Key; + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); + byte[] lightOn = Helper.OutstoreLight(v.Value, LightColor,1); + tCPClient.Send(lightOn); + Thread.Sleep(100); + } + //报警灯亮 + List WarnLightShelfCode = new List(); + foreach (string storecode in StoreCode) + { + List mi = DbHelp.db.Queryable().Where(it => it.ModuleCode == storecode).ToList(); + if (mi.Count != 0) + { + if (!WarnLightShelfCode.Contains(mi[0].ShelfCode)) + { + WarnLightShelfCode.Add(mi[0].ShelfCode); + } + } + } + foreach (string shelfcode in WarnLightShelfCode) + { + List si = DbHelp.db.Queryable().Where(it => it.ShelfCode == shelfcode).ToList(); + if (si.Count != 0) + { + for (int i = 0; i < si.Count; i++) + { + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(si[i].ClientIp); + byte[] warnlightOn = Helper.OutstoreWarnLight(si[i].LightId,"无",1,0); + tCPClient.Send(warnlightOn); + Thread.Sleep(100); + } + } + } + //返回 + return new OutResponseCommonSingle() + { + Code = 200, + Message = "Success", + Data = orcs.Data + }; + } + catch (Exception ex) + { + await GoOutOutstore(request); + throw ex; + } + } + + //计算、加锁 + private ResponseBase CaculateOutOrderMatDetails(OutOrder order, string createUser = "") + { + try + { + DbHelp.db.BeginTran(); + //第一步 物料需求表 + var outOrderDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .ToList(); + if (outOrderDetails == null || outOrderDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"计算物料失败,{order.OrderNumber}没有出库单据明细!" + }; + } + //第二步 开始计算物料 + List outOrderMatDetails = new List(); + foreach (var outOrderDetail in outOrderDetails) + { + //2.1筛选 满足 物料编码、批次的库存 + var matInventoryDetails = DbHelp.db.Queryable() + .Where(t => t.MatCode == outOrderDetail.MatCode) + .WhereIF(!string.IsNullOrEmpty(outOrderDetail.MatBatch), t => t.MatBatch == outOrderDetail.MatBatch) + .Where(t => t.IsLocked == false)//未锁定的物料 + .Where(t => t.StoreInfo.ShelfTypeId == order.ShelfTypeId) + .OrderBy(t => t.MatBatch)//按批次先进先出 + //(t => t.MatQty)//零散料先出 + .ToList(); + + //2.2按照搜索出来的库存和当前未出的数量 计算需要出的SN + for (int i = 0; i < matInventoryDetails.Count && outOrderDetail.ReqQty - outOrderDetail.OutQty > 0; i++) + { + if (outOrderDetail.ReqQty - outOrderDetail.OutQty <= matInventoryDetails[i].MatQty) + { + outOrderMatDetails.Add(new OutOrderMatDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + OutOrderDetailId = outOrderDetail.Id, + InventoryDetailId = matInventoryDetails[i].Id, + StoreId = matInventoryDetails[i].StoreId, + StoreCode = matInventoryDetails[i].StoreCode, + MatSN = matInventoryDetails[i].MatSN, + MatCode = matInventoryDetails[i].MatCode, + MatName = matInventoryDetails[i].MatName, + MatSpec = matInventoryDetails[i].MatSpec, + MatBatch = matInventoryDetails[i].MatBatch, + MatQty = matInventoryDetails[i].MatQty, + MatSupplier = matInventoryDetails[i].MatSupplier, + MatCustomer = matInventoryDetails[i].MatCustomer, + IsSended = false, + CreateUser = createUser, + }); + outOrderDetail.ReqQty = 0; + + matInventoryDetails[i].IsLocked = true; + DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand(); + } + else + { + outOrderDetail.ReqQty = outOrderDetail.ReqQty - matInventoryDetails[i].MatQty; + + outOrderMatDetails.Add(new OutOrderMatDetail() + { + OrderId = order.Id, + OrderNumber = order.OrderNumber, + OutOrderDetailId = outOrderDetail.Id, + InventoryDetailId = matInventoryDetails[i].Id, + StoreId = matInventoryDetails[i].StoreId, + StoreCode = matInventoryDetails[i].StoreCode, + MatSN = matInventoryDetails[i].MatSN, + MatCode = matInventoryDetails[i].MatCode, + MatName = matInventoryDetails[i].MatName, + MatSpec = matInventoryDetails[i].MatSpec, + MatBatch = matInventoryDetails[i].MatBatch, + MatQty = matInventoryDetails[i].MatQty, + MatSupplier = matInventoryDetails[i].MatSupplier, + MatCustomer = matInventoryDetails[i].MatCustomer, + IsSended = false, + CreateUser = createUser, + }); + + matInventoryDetails[i].IsLocked = true; + DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand(); + } + } + } + DbHelp.db.Insertable(outOrderMatDetails).ExecuteCommand(); + DbHelp.db.CommitTran(); + if (outOrderMatDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"计算物料失败,没有满足条件的物料进行出库!(请检查对应物料是否已被锁定)" + }; + } + else + + return new ResponseCommon() + { + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon() + { + Code = 300, + Message = $"发生异常:{ex.Message}" + }; + } + } + + //删除 解锁 + private ResponseBase CancelOutOrderMatDetails(OutOrder order) + { + try + { + DbHelp.db.BeginTran(); + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .Where(t => t.IsSended == false) + .ToList(); + + var inventoryIds = outOrderMatDetails.Select(t => t.InventoryDetailId).ToList(); + var inventoryDetails = DbHelp.db.Queryable() + .Where(t => inventoryIds.Contains(t.Id)) + .ToList(); + inventoryDetails.ForEach(t => { t.IsLocked = false; }); + DbHelp.db.Deleteable(outOrderMatDetails).ExecuteCommand(); + DbHelp.db.Updateable(inventoryDetails).ExecuteCommand(); + + DbHelp.db.CommitTran(); + return new ResponseCommon() + { + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon() + { + Code = 300, + Message = $"解锁物料时发生异常:{ex.Message}" + }; + } + } + + public async Task GoOutOutstore(GetOutOrderDetailRequest request) + { + + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + //执行状态改为暂停 + if (request.IsPause && order.OutOrderExeStatus != OutOrderExeStatus.发料完成) + { + order.OutOrderExeStatus = OutOrderExeStatus.暂停发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + + //解锁物料 删除物料明细 + if (order.SyncType == SyncTypeEnum.ByMatCode) + CancelOutOrderMatDetails(order); + + //找到正在出对应出库单的货架 + var shelves = ShelfManager.Shelves.Where(t => t.OrderNumber == request.OrderNumber) + .Where(t => t.CurrentMode == HardWare.Mode.出库模式) + .ToList(); + + if (shelves == null || shelves.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"出库单据【{request.OrderNumber}】不在出库中!", + Data = null + }; + } + + + + //退出出库模式 + shelves.ForEach(t => + { + t.GoOutOutstore(); + }); + + + + return new ResponseCommon() + { + Code = 200, + Message = "Success", + Data = null + }; + + } + + public async Task GoOutOutstoreSingle(GetOutOrderDetailRequest request) + { + + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + + //判断出库状态 + bool isComplete = true; + List ood = DbHelp.db.Queryable().Where(it => it.OrderNumber == request.OrderNumber).ToList(); + foreach (OutOrderDetail detail in ood) + { + if (detail.ReqQty > detail.OutQty) + { + isComplete = false; + break; + } + } + if (isComplete == false) + { + order.OutOrderExeStatus = OutOrderExeStatus.暂停发料; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + else + { + order.OutOrderExeStatus = OutOrderExeStatus.发料完成; + DbHelp.db.Updateable(order).ExecuteCommand(); + } + //解锁物料 + List List = DbHelp.db.Queryable().Where(it => it.OrderNumber == request.OrderNumber).ToList(); + foreach (OutOrderMatDetail listdetail in List) + { + DbHelp.db.Updateable().SetColumns(it => it.IsLocked == false).Where(it => it.MatSN == listdetail.MatSN).ExecuteCommand(); + } + + DbHelp.db.Updateable().SetColumns(it => it.OrderNumber == null).Where(it => it.OrderNumber == request.OrderNumber).ExecuteCommand(); + //灭灯 +<<<<<<< HEAD + //获取需要出库的物料明细 + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderNumber == request.OrderNumber) + .ToList(); + //需要出库的货架名 + List StoreCode = new List(); + //库位灯灭灯 + Dictionary> dict = new Dictionary>(); + foreach (OutOrderMatDetail oomd in outOrderMatDetails) + { + List mi = DbHelp.db.Queryable().Where(it => it.ModuleCode == oomd.StoreCode).ToList(); + if (mi.Count != 0) + { + if (!StoreCode.Contains(oomd.StoreCode)) + { + StoreCode.Add(oomd.StoreCode); + } + if (!dict.Keys.Contains(mi[0].CleintIp)) + { + List board_id = new List(); + board_id.Add(mi[0].BoardId); + dict.Add(mi[0].CleintIp, board_id); + } + else + { + foreach (var v in dict) + { + if (v.Key == mi[0].CleintIp) + { + if (!v.Value.Contains(mi[0].BoardId)) + { + v.Value.Add(mi[0].BoardId); + } + } + } + } + } + } + foreach (var v in dict) + { + string sendIP = v.Key; + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(sendIP); + byte[] lightOn = Helper.OutstoreLight(v.Value, "无",0); + tCPClient.Send(lightOn); + Thread.Sleep(100); + } + //报警灯灭 + List WarnLightShelfCode = new List(); + foreach (string storecode in StoreCode) + { + List mi = DbHelp.db.Queryable().Where(it => it.ModuleCode == storecode).ToList(); + if (mi.Count != 0) + { + if (!WarnLightShelfCode.Contains(mi[0].ShelfCode)) + { + WarnLightShelfCode.Add(mi[0].ShelfCode); + } + } + } + foreach (string shelfcode in WarnLightShelfCode) + { + List si = DbHelp.db.Queryable().Where(it => it.ShelfCode == shelfcode).ToList(); + if (si.Count != 0) + { + for (int i = 0; i < si.Count; i++) + { + TCPClient tCPClient = TCPClientManager.GetTCPClientByIPHost(si[i].ClientIp); + byte[] warnlightOn = Helper.OutstoreWarnLight(si[i].LightId, "无", 0, 0); + tCPClient.Send(warnlightOn); + Thread.Sleep(100); + } + } + } + + +======= +>>>>>>> 11 + + return new ResponseCommon() + { + Code = 200, + Message = "Success", + Data = null + }; + + } + + public async Task SingleLightConfirmOutstore(OutOrderMatDetailModelSingle request) + { + InOutRecord ior = new InOutRecord(); + List id = DbHelp.db.Queryable().Where(it => it.MatSN == request.MatSn).ToList(); + if (id.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"此SN不在库存中{request.MatSn}!", + Data = null + }; + } + ior.StoreId = id[0].StoreId; + ior.StoreCode = id[0].StoreCode; + ior.MatSN = request.MatSn; + ior.MatCode = request.MatCode; + ior.MatName = request.MatName; + ior.MatSpec = request.MatSpec; + ior.MatBatch = request.MatBatch; + ior.MatQty = request.Qty; + ior.MatSupplier = request.MatSupplier; + ior.MatCustomer = request.MatCustomer; + ior.OrderNumber = request.orderNumber; + ior.Direction = DirectionEnum.出库; + ior.OperateUser = request.userName; + ior.OperateTime = DateTime.Now; + //保存出库记录 + int count = DbHelp.db.Insertable(ior).ExecuteCommand(); + //删除库存 + DbHelp.db.Deleteable().Where(it => it.MatSN == request.MatSn).ExecuteCommand(); + //更新需求表 + List odd = DbHelp.db.Queryable().Where(it => it.OrderNumber == request.orderNumber).Where(it => it.MatCode == request.MatCode).ToList(); + odd[0].OutQty += request.Qty; + DbHelp.db.Updateable(odd[0]).ExecuteCommand(); + + return new ResponseCommon() + { + Code = 200, + Message = $"出库成功", + Data = null + }; + } + + + } +} diff --git a/WCS.BLL/Tool/DependencyExtensions.cs b/WCS.BLL/Tool/DependencyExtensions.cs new file mode 100644 index 0000000..75142f7 --- /dev/null +++ b/WCS.BLL/Tool/DependencyExtensions.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.Sockets; + +namespace WCS.BLL.Tool +{ + /// + /// 一个心跳计数器扩展。 + /// + internal static class DependencyExtensions + { + public static readonly DependencyProperty HeartbeatTimerProperty = + DependencyProperty.Register("HeartbeatTimer", null); + + public static bool Ping(this TClient client) where TClient : ITcpClientBase + { + try + { + var data = new byte[] { 0x05, 0x00, 0x00, 0x06, 0x78, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00 }; + client.Send(data); + return true; + } + catch (Exception ex) + { + Logs.Write($"【{client.IP}:{client.Port}】发送心跳中发现异常:" + ex.Message, LogsType.Info); + if (ex is NotConnectedException) + { + + } + } + return false; + } + + public static bool Pong(this TClient client) where TClient : ITcpClientBase + { + try + { + client.Send(new MyRequestInfo() { DataType = DataType.Pong }.PackageAsBytes()); + return true; + } + catch (Exception ex) + { + client.Logger.Exception(ex); + } + + return false; + } + } +} diff --git a/WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs b/WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs new file mode 100644 index 0000000..3f97479 --- /dev/null +++ b/WCS.BLL/Tool/HeartbeatAndReceivePlugin.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.Sockets; + +namespace WCS.BLL.Tool +{ + internal class HeartbeatAndReceivePlugin : PluginBase, ITcpConnectedPlugin, ITcpDisconnectedPlugin, ITcpReceivedPlugin + { + private readonly int m_timeTick; + private readonly ILog logger; + + [DependencyInject("20000")] + public HeartbeatAndReceivePlugin(int timeTick, ILog logger) + { + this.m_timeTick = 20000; + this.logger = logger; + } + + + public async Task OnTcpConnected(ITcpClientBase client, ConnectedEventArgs e) + { + if (client is ISocketClient) + { + return;//此处可判断,如果为服务器,则不用使用心跳。 + } + + if (client.GetValue(DependencyExtensions.HeartbeatTimerProperty) is Timer timer) + { + timer.Dispose(); + } + + client.SetValue(DependencyExtensions.HeartbeatTimerProperty, new Timer((o) => + { + client.Ping(); + }, null, 0, this.m_timeTick)); + await e.InvokeNext(); + } + + public async Task OnTcpDisconnected(ITcpClientBase client, DisconnectEventArgs e) + { + if (client.GetValue(DependencyExtensions.HeartbeatTimerProperty) is Timer timer) + { + timer.Dispose(); + client.SetValue(DependencyExtensions.HeartbeatTimerProperty, null); + } + + await e.InvokeNext(); + } + + public async Task OnTcpReceived(ITcpClientBase client, ReceivedDataEventArgs e) + { + if (e.RequestInfo is MyRequestInfo myRequest) + { + this.logger.Info(myRequest.ToString()); + if (myRequest.DataType == DataType.Ping) + { + client.Pong(); + } + } + await e.InvokeNext(); + } + } +} diff --git a/WCS.BLL/Tool/Logs.cs b/WCS.BLL/Tool/Logs.cs index 3872b1d..ad80dc1 100644 --- a/WCS.BLL/Tool/Logs.cs +++ b/WCS.BLL/Tool/Logs.cs @@ -36,7 +36,11 @@ namespace WCS.BLL /// /// 指令重发 /// - InstructionResend + InstructionResend, + /// + /// 出库流程日志 + /// + Outstore, } /// diff --git a/WCS.BLL/Tool/MyFixedHeaderDataHandlingAdapter .cs b/WCS.BLL/Tool/MyFixedHeaderDataHandlingAdapter .cs new file mode 100644 index 0000000..9714c97 --- /dev/null +++ b/WCS.BLL/Tool/MyFixedHeaderDataHandlingAdapter .cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; + +namespace WCS.BLL.Tool +{ + + internal class MyFixedHeaderDataHandlingAdapter : CustomFixedHeaderDataHandlingAdapter + { + public override int HeaderLength => 3; + + public override bool CanSendRequestInfo => false; + + protected override MyRequestInfo GetInstance() + { + return new MyRequestInfo(); + } + + protected override void PreviewSend(IRequestInfo requestInfo) + { + throw new NotImplementedException(); + } + } + + internal class MyRequestInfo : IFixedHeaderRequestInfo + { + public DataType DataType { get; set; } + public byte[] Data { get; set; } + + public int BodyLength { get; private set; } + + public bool OnParsingBody(byte[] body) + { + if (body.Length == this.BodyLength) + { + this.Data = body; + return true; + } + return false; + } + + public bool OnParsingHeader(byte[] header) + { + if (header.Length == 3) + { + this.BodyLength = TouchSocketBitConverter.Default.ToUInt16(header, 0) - 1; + this.DataType = (DataType)header[2]; + return true; + } + return false; + } + + public void Package(ByteBlock byteBlock) + { + byteBlock.Write((ushort)((this.Data == null ? 0 : this.Data.Length) + 1)); + byteBlock.Write((byte)this.DataType); + if (this.Data != null) + { + byteBlock.Write(this.Data); + } + } + + public byte[] PackageAsBytes() + { + using var byteBlock = new ByteBlock(); + this.Package(byteBlock); + return byteBlock.ToArray(); + } + + public override string ToString() + { + return $"数据类型={this.DataType},数据={(this.Data == null ? "null" : Encoding.UTF8.GetString(this.Data))}"; + } + } + + internal enum DataType : byte + { + Ping, + Pong, + Data + } +} diff --git a/WCS.BLL/Tool/TCPClient.cs b/WCS.BLL/Tool/TCPClient.cs index 10f0002..ac7a314 100644 --- a/WCS.BLL/Tool/TCPClient.cs +++ b/WCS.BLL/Tool/TCPClient.cs @@ -2,6 +2,7 @@ using System.Text; using TouchSocket.Core; using TouchSocket.Sockets; +using WCS.BLL.Tool; namespace WCS.BLL @@ -68,6 +69,7 @@ namespace WCS.BLL { //配置断线重连 a.UseReconnection(-1, true, 1000); + a.Add(); }) .ConfigureContainer(a => { diff --git a/WCS.Model/ApiModel/Home/ResetShelfStatusRequest.cs b/WCS.Model/ApiModel/Home/ResetShelfStatusRequest.cs new file mode 100644 index 0000000..e96603b --- /dev/null +++ b/WCS.Model/ApiModel/Home/ResetShelfStatusRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.Home +{ + public class ResetShelfStatusRequest : RequestBase + { + public List SelfIds { get; set; } + + public bool IsResetAll { get; set; } + + public List GroupNames { get; set; } + } +} diff --git a/WCS.WebApi/Controllers/HomeController.cs b/WCS.WebApi/Controllers/HomeController.cs index 8a15a64..47dfd25 100644 --- a/WCS.WebApi/Controllers/HomeController.cs +++ b/WCS.WebApi/Controllers/HomeController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using SqlSugar; using WCS.BLL.DbModels; +using WCS.BLL.HardWare; using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.BLL.Services.Service; @@ -85,9 +86,71 @@ namespace WCS.WebApi.Controllers } catch (Exception ex) { - return null; + return new ResponseBase() + { + Code = 300, + Message = "获取失败:" + ex.Message, + }; } } + /// + /// 重置货架的状态 使其回到待机模式 + /// + /// + /// + [Route("resetShelfStatus")] + [HttpPost(Name = "resetShelfStatus")] + public async Task resetShelfStatus(ResetShelfStatusRequest request) + { + try + { + if (request.IsResetAll == false && (request.SelfIds == null || request.SelfIds.Count == 0)) + { + return new ResponseBase() + { + Code = 201, + Message = "复位失败:请选择需要复位的货架!", + }; + } + if (request.IsResetAll == true && (request.GroupNames == null || request.GroupNames.Count == 0)) + { + return new ResponseBase() + { + Code = 201, + Message = "复位失败:请选择需要复位的货架区域!", + }; + } + var shelfs = new List(); + if (request.IsResetAll == false) + shelfs = ShelfManager.Shelves + .Where(t => request.SelfIds.Contains(t.ShelfId)) + .Where(t => t.CurrentMode != Mode.待机模式) + .ToList(); + else + shelfs = ShelfManager.Shelves + .Where(t => request.GroupNames.Contains(t.GroupName)) + .Where(t => t.CurrentMode != Mode.待机模式) + .ToList(); + foreach (var shelf in shelfs) + { + shelf.Reset(); + } + return new ResponseBase() + { + Code = 200, + Message = "success", + }; + + } + catch (Exception ex) + { + return new ResponseBase() + { + Code = 300, + Message = ex.Message, + }; + } + } } } diff --git a/WCS.WebApi/Controllers/WarningController.cs b/WCS.WebApi/Controllers/WarningController.cs index b0c68e7..410c066 100644 --- a/WCS.WebApi/Controllers/WarningController.cs +++ b/WCS.WebApi/Controllers/WarningController.cs @@ -24,5 +24,7 @@ namespace WCS.WebApi.Controllers { return await _warningService.SolveWarning(request); } + + } } diff --git a/货架标准上位机/ViewModels/DeviceViewModel.cs b/货架标准上位机/ViewModels/DeviceViewModel.cs index aa10160..f393f5c 100644 --- a/货架标准上位机/ViewModels/DeviceViewModel.cs +++ b/货架标准上位机/ViewModels/DeviceViewModel.cs @@ -9,531 +9,43 @@ using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using WCS.Model; +using WCS.Model.ApiModel.Home; +using 货架标准上位机.Api; namespace 货架标准上位机.ViewModel { public class DeviceViewModel : BindableBase { - //循环间隙时间 - int whileSleep = 1500; + public ICommand ResetAllShelfCommand { get => new DelegateCommand(ResetAllShelf); } /// - /// 是否繁忙。繁忙状态下不在进行定时刷新操作。 + /// 打开用户 /// - public bool IsBusy { get; set; } = false; - //public IIoTBase plc; - - #region 属性 - /// - /// 监听 - /// - public IEnumerable DataReads { get; set; } - /// - /// 控制 - /// - public IEnumerable DataWrites { get; set; } - /// - /// 气缸 - /// - public IEnumerable DataUrns { get; set; } - /// - /// 伺服 - /// - public IEnumerable DataServos { get; set; } - - private bool IsVis_ = false; - /// - /// 当前页面是否显示 - /// - public bool IsVis { get => IsVis_; set { SetProperty(ref IsVis_, value); } } - - #region 是否展示 - private bool IsVisRead_ = true; - public bool IsVisRead { get => IsVisRead_; set { SetProperty(ref IsVisRead_, value); } } - - private bool IsVisWrite_ = true; - public bool IsVisWrite { get => IsVisWrite_; set { SetProperty(ref IsVisWrite_, value); } } - - private bool IsVisUrn_ = true; - public bool IsVisUrn { get => IsVisUrn_; set { SetProperty(ref IsVisUrn_, value); } } - - private bool IsVisServo_ = true; - public bool IsVisServo { get => IsVisServo_; set { SetProperty(ref IsVisServo_, value); } } - #endregion - - #region 是否折叠 - private bool IsVisExpRead_ = true; - public bool IsVisExpRead { get => IsVisExpRead_; set { SetProperty(ref IsVisExpRead_, value); } } - - private bool IsVisExpWrite_ = true; - public bool IsVisExpWrite { get => IsVisExpWrite_; set { SetProperty(ref IsVisExpWrite_, value); } } - - private bool IsVisExpUrn_ = false; - public bool IsVisExpUrn { get => IsVisExpUrn_; set { SetProperty(ref IsVisExpUrn_, value); } } - - private bool IsVisExpServo_ = false; - public bool IsVisExpServo { get => IsVisExpServo_; set { SetProperty(ref IsVisExpServo_, value); } } - #endregion - - #endregion - - /// - /// 循环读取数据 - /// - public async void WhileRead() + public void ResetAllShelf() { - while (true) + #region 调用接口 请求重置所有货架的状态 + var body = new ResetShelfStatusRequest() { - try - { - if (!IsVis || IsBusy) - { - await Task.Delay(whileSleep); - continue; - } - - ////监控 - if (DataReads != null && IsVisExpRead) - { - foreach (var item in DataReads) - { - if (!item.IsExpanded) - continue; - - var plcAdd = item.ExcelTag; - if (string.IsNullOrWhiteSpace(plcAdd.地址)) - continue; - - var ts = plcAdd.类型.Trim().ToLower(); - switch (ts) - { - case "bool": - //var datab = plc?.Read(plcAdd.地址); - //item.Value = datab?.IsSucceed == true ? datab.Value : false; - break; - case "byte": - //var datay = plc?.Read(plcAdd.地址); - //item.Value = datay?.IsSucceed == true ? datay.Value : "-"; - break; - case "int16": - //var datai16 = plc?.Read(plcAdd.地址); - //item.Value = datai16?.IsSucceed == true ? datai16.Value : "-"; - break; - case "int32": - //var datai32 = plc?.Read(plcAdd.地址); - //item.Value = datai32?.IsSucceed == true ? datai32.Value : "-"; - break; - case "uint16": - //var dataui16 = plc?.Read(plcAdd.地址); - //item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-"; - break; - case "uint32": - //var dataui32 = plc?.Read(plcAdd.地址); - //item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-"; - break; - case "float": - case "single": - //var datas = plc?.Read(plcAdd.地址); - //item.Value = datas?.IsSucceed == true ? datas.Value : "-"; - break; - case "double": - //var datad = plc?.Read(plcAdd.地址); - //item.Value = datad?.IsSucceed == true ? datad.Value : "-"; - break; - default: - break; - } - } - } - - ////控制 - if (DataWrites != null && IsVisExpWrite) - { - foreach (var item in DataWrites) - { - if (!item.IsExpanded) - continue; - - var plcAdd = item.ExcelTag; - if (string.IsNullOrWhiteSpace(plcAdd.读地址)) - continue; - - var ts = plcAdd.类型.Trim().ToLower(); - switch (ts) - { - case "bool": - //var datab = plc?.Read(plcAdd.读地址); - //item.Value = datab?.IsSucceed == true ? datab.Value : false; - break; - case "byte": - //var datay = plc?.Read(plcAdd.读地址); - //item.Value = datay?.IsSucceed == true ? datay.Value : "-"; - break; - case "int16": - //var datai16 = plc?.Read(plcAdd.读地址); - //item.Value = datai16?.IsSucceed == true ? datai16.Value : "-"; - break; - case "int32": - //var datai32 = plc?.Read(plcAdd.读地址); - //item.Value = datai32?.IsSucceed == true ? datai32.Value : "-"; - break; - case "uint16": - //var dataui16 = plc?.Read(plcAdd.读地址); - //item.Value = dataui16?.IsSucceed == true ? dataui16.Value : "-"; - break; - case "uint32": - //var dataui32 = plc?.Read(plcAdd.读地址); - //item.Value = dataui32?.IsSucceed == true ? dataui32.Value : "-"; - break; - case "float": - case "single": - //var datas = plc?.Read(plcAdd.读地址); - //item.Value = datas?.IsSucceed == true ? datas.Value : "-"; - break; - case "double": - //var datad = plc?.Read(plcAdd.读地址); - //item.Value = datad?.IsSucceed == true ? datad.Value : "-"; - break; - default: - break; - } - } - } - - ////气缸 - if (DataUrns != null && IsVisExpUrn) - { - foreach (var item in DataUrns) - { - if (!item.IsExpanded) - continue; - - var plcAdd = item.ExcelTag; - if (!string.IsNullOrWhiteSpace(plcAdd.推到位地址)) - { - //var data1 = plc?.Read(plcAdd.推到位地址); - //item.IsGoTo = data1?.IsSucceed == true ? data1.Value : false; - } - if (!string.IsNullOrWhiteSpace(plcAdd.回到位地址)) - { - //var data2 = plc?.Read(plcAdd.回到位地址); - //item.IsRetTo = data2?.IsSucceed == true ? data2.Value : false; - } - } - } - - ////伺服 - if (DataServos != null && IsVisExpServo) - { - foreach (var item in DataServos) - { - if (!item.IsExpanded) - continue; - - ////读取地址信息 - var plcAdd = item.ExcelTag; - if (!string.IsNullOrWhiteSpace(plcAdd.当前位置获取)) - { - //var data1 = plc?.Read(plcAdd.当前位置获取); - //item.Location = data1?.IsSucceed == true ? data1.Value : 0; - } - if (!string.IsNullOrWhiteSpace(plcAdd.手动速度获取) && (item.IsJog || !item.IsFold)) - { - //var data2 = plc?.Read(plcAdd.手动速度获取); - //item.JogSpeed = data2?.IsSucceed == true ? data2.Value : 0; - } - if (!string.IsNullOrWhiteSpace(plcAdd.自动速度设置) && (!item.IsJog || !item.IsFold)) - { - //var data3 = plc?.Read(plcAdd.自动速度设置); - //item.AutoSpeed = data3?.IsSucceed == true ? data3.Value : 0; - } - } - } - - await Task.Delay(whileSleep); - } - catch (Exception) - { - - } + IsResetAll = true, + GroupNames = LocalFile.Config.GroupName, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "home/resetShelfStatus", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Warning("复位成功!"); } - } - - /*一起选中【操作控制】【操作气缸】【操作伺服】可以快速解开全部注释*/ - - #region 操作控制 - ////单击 - public void WriteClick(object sender, RoutedEventArgs e) - { - var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("切换")) + else if (Result != null) { - Task.Run(() => - { - var boolval = data.Value is true; - //plc?.Write(dataExcel.写地址, !boolval); - data.Value = !boolval; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); - }); + Growl.Warning(Result.Message); } else { - var ts = dataExcel.类型.Trim().ToLower(); - switch (ts) - { - case "byte": - WriteClickDialog(data); - break; - case "int16": - WriteClickDialog(data); - break; - case "int32": - WriteClickDialog(data); - break; - case "uint16": - WriteClickDialog(data); - break; - case "uint32": - WriteClickDialog(data); - break; - case "float": - case "single": - WriteClickDialog(data); - break; - case "double": - WriteClickDialog(data); - break; - default: - break; - } + Growl.Warning("调用接口失败!"); } + #endregion } - - ////单击弹框 - void WriteClickDialog(DeviceWriteModel data) where T : struct - { - var dataExcel = data.ExcelTag; - var val = TipInputView.Show($"请输入新的[{dataExcel.名称}]值:", "修改值", "请输入值"); - if (!val.HasValue) - return; - - //plc?.Write(dataExcel.写地址, val.Value); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = val.Value, Mode = "" }); - } - - ////按下左键 - public void LeftDown(object sender, MouseButtonEventArgs e) - { - var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.写地址, true); - data.Value = true; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); - }); - } - } - - ////放开左键 - public void LeftUp(object sender, MouseButtonEventArgs e) - { - var data = (DeviceWriteModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (dataExcel.类型.Trim().ToLower() == "bool" && mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.写地址, false); - data.Value = false; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "控制", Funct = string.Empty, Val = data.Value, Mode = mode }); - }); - } - } - #endregion - - #region 操作气缸 - ////按钮1单击 - public void Button1_Click(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("切换")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, true); - //plc?.Write(dataExcel.回地址, false); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = true, Mode = mode }); - }); - } - } - - ////按钮1按下 - public void But1ClickDown(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, true); - data.IsGoTo = true; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = true, Mode = mode }); - }); - } - } - - ////按钮1松开 - public void But1ClickUp(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, false); - data.IsGoTo = false; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "推", Val = false, Mode = mode }); - }); - } - } - - ////按钮2单击 - public void Button2_Click(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("切换")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.推地址, false); - //plc?.Write(dataExcel.回地址, true); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = true, Mode = mode }); - }); - } - } - - ////按钮2按下 - public void But2ClickDown(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.回地址, true); - data.IsRetTo = true; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = true, Mode = mode }); - }); - } - } - - ////按钮2松开 - public void But2ClickUp(object sender, RoutedEventArgs e) - { - var data = (DeviceUrnModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = dataExcel.点动切换?.Trim() ?? ""; - - if (mode.StartsWith("点动")) - { - Task.Run(() => - { - //plc?.Write(dataExcel.回地址, false); - data.IsRetTo = false; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "气缸", Funct = "回", Val = false, Mode = mode }); - }); - } - } - #endregion - - #region 操作伺服 - ////尝试改变伺服的位置时 - public void LocationChange(object sender, RoutedEventArgs e) - { - var data = (DeviceServoModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = string.Empty; - - ////运动方式 - if (e.OriginalSource is ServoClickType servoClickType) - { - if (servoClickType == ServoClickType.StartDotAdd) - { - //plc?.Write(dataExcel.位置点动加, true); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "开始点动加", Val = true, Mode = mode }); - } - else if (servoClickType == ServoClickType.EndDotAdd) - { - //plc?.Write(dataExcel.位置点动加, false); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "结束点动加", Val = false, Mode = mode }); - } - else if (servoClickType == ServoClickType.StartDotSub) - { - //plc?.Write(dataExcel.位置点动减, true); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "开始点动减", Val = true, Mode = mode }); - } - else if (servoClickType == ServoClickType.EndDotSub) - { - //plc?.Write(dataExcel.位置点动减, false); - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "结束点动减", Val = false, Mode = mode }); - } - } - ////运动到指定位置 - else if (e.OriginalSource is double val) - { - //plc?.Write(dataExcel.位置移动, Convert.ToSingle(val)); - data.Location = val; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "位置移动", Val = val, Mode = mode }); - } - } - - ////尝试改变伺服的速度时 - public void SpeedChange(object sender, RoutedEventArgs e) - { - var data = (DeviceServoModel)((FrameworkElement)sender).DataContext; - var dataExcel = data.ExcelTag; - var mode = string.Empty; - - var data2 = (ServoSpeed)e.OriginalSource; - if (data2.Name.StartsWith("手动")) - { - //plc?.Write(dataExcel.手动速度设置, Convert.ToSingle(data2.Speed)); - data.JogSpeed = data2.Speed; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "手动速度设置", Val = data2.Speed, Mode = mode }); - } - else - { - //plc?.Write(dataExcel.自动速度设置, Convert.ToSingle(data2.Speed)); - data.AutoSpeed = data2.Speed; - IotDevice.UserChange?.Invoke(new IotDevice() { Name = data.Name, Type = "伺服", Funct = "自动速度设置", Val = data2.Speed, Mode = mode }); - - } - } - #endregion } public class DeviceReadModel : BindableBase diff --git a/货架标准上位机/Views/Controls/DeviceView.xaml b/货架标准上位机/Views/Controls/DeviceView.xaml index 157de56..821ac3a 100644 --- a/货架标准上位机/Views/Controls/DeviceView.xaml +++ b/货架标准上位机/Views/Controls/DeviceView.xaml @@ -13,126 +13,14 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/货架标准上位机/Views/Controls/DeviceView.xaml.cs b/货架标准上位机/Views/Controls/DeviceView.xaml.cs index 9bbf943..5cd3797 100644 --- a/货架标准上位机/Views/Controls/DeviceView.xaml.cs +++ b/货架标准上位机/Views/Controls/DeviceView.xaml.cs @@ -29,362 +29,19 @@ namespace 货架标准上位机 public DeviceView() { InitializeComponent(); - //viewModel.plc = LocalStatic.Plc; this.DataContext = viewModel; } //第一次显示,渲染Ui private void visfir(object sender, EventArgs e) { - if (IsInDesignMode) - return; - - if (!System.IO.File.Exists(LocalFile.PlcDotPath)) - { - Growl.Info($"没有找到文档[{LocalFile.PlcDotPath}],请联系管理员。"); - return; - } - - //读Excel - viewModel.DataReads = ExcelDeviceReadModel.GetDatas(); - viewModel.DataWrites = ExcelDeviceWriteModel.GetDatas(); - viewModel.DataUrns = ExcelDeviceUrnModel.GetDatas(); - viewModel.DataServos = ExcelDeviceServoModel.GetDatas(); - - //加载页面 - ReadUi(viewModel.DataReads); - WriteUi(viewModel.DataWrites); - UrnUi(viewModel.DataUrns); - ServoUi(viewModel.DataServos); - - //展示限制 - viewModel.IsVisRead = viewModel.DataReads.Any(); - viewModel.IsVisWrite = viewModel.DataWrites.Any(); - viewModel.IsVisUrn = viewModel.DataUrns.Any(); - viewModel.IsVisServo = viewModel.DataServos.Any(); - - Task.Run(viewModel.WhileRead); } private void vis(object sender, DependencyPropertyChangedEventArgs e) { if (IsInDesignMode) return; - - viewModel.IsVis = (bool)e.NewValue; } - #region 渲染页面 - void ReadUi(IEnumerable data) - { - stackPanel1.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.Value = item.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - item.IsExpanded = true; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item.ExcelTag)}.{nameof(item.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - stackPanel1.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - item2.Value = item2.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item2; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item2.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item2.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item2.ExcelTag)}.{nameof(item2.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - expander.Content = wrapPanel; - stackPanel1.Children.Add(expander); - } - } - } - - void WriteUi(IEnumerable data) - { - if (true) - { - stackPanel2.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.Value = item.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - item.IsExpanded = true; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item; - iotState.Click += viewModel.WriteClick; - iotState.PreviewMouseLeftButtonDown += viewModel.LeftDown; - iotState.PreviewMouseLeftButtonUp += viewModel.LeftUp; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item.ExcelTag)}.{nameof(item.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - stackPanel2.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - item2.Value = item2.ExcelTag.类型.Trim().ToLower() == "bool" ? false : "-"; - - IotStateInfo iotState = new IotStateInfo(); - iotState.DataContext = item2; - iotState.Click += viewModel.WriteClick; - iotState.PreviewMouseLeftButtonDown += viewModel.LeftDown; - iotState.PreviewMouseLeftButtonUp += viewModel.LeftUp; - iotState.SetBinding(IotStateInfo.HeaderProperty, nameof(item2.Name)); - iotState.SetBinding(IotStateInfo.ValueProperty, nameof(item2.Value)); - iotState.SetBinding(IotStateInfo.PostfixProperty, $"{nameof(item2.ExcelTag)}.{nameof(item2.ExcelTag.单位)}"); - - wrapPanel.Children.Add(iotState); - } - expander.Content = wrapPanel; - stackPanel2.Children.Add(expander); - } - } - } - } - - void UrnUi(IEnumerable data) - { - if (true) - { - stackPanel3.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.IsExpanded = true; - - IotUrnMode iotUrn = new IotUrnMode(); - iotUrn.DataContext = item; - iotUrn.SetBinding(IotUrnMode.TextProperty, nameof(item.Name)); - iotUrn.SetBinding(IotUrnMode.IsButBadge1Property, nameof(item.IsGoTo)); - iotUrn.SetBinding(IotUrnMode.IsButBadge2Property, nameof(item.IsRetTo)); - iotUrn.Button1.Click += viewModel.Button1_Click; - iotUrn.Button1.PreviewMouseLeftButtonDown += viewModel.But1ClickDown; - iotUrn.Button1.PreviewMouseLeftButtonUp += viewModel.But1ClickUp; - iotUrn.Button2.Click += viewModel.Button2_Click; - iotUrn.Button2.PreviewMouseLeftButtonDown += viewModel.But2ClickDown; - iotUrn.Button2.PreviewMouseLeftButtonUp += viewModel.But2ClickUp; - - wrapPanel.Children.Add(iotUrn); - } - stackPanel3.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - IotUrnMode iotUrn = new IotUrnMode(); - iotUrn.DataContext = item2; - iotUrn.SetBinding(IotUrnMode.TextProperty, nameof(item2.Name)); - iotUrn.SetBinding(IotUrnMode.IsButBadge1Property, nameof(item2.IsGoTo)); - iotUrn.SetBinding(IotUrnMode.IsButBadge2Property, nameof(item2.IsRetTo)); - iotUrn.Button1.Click += viewModel.Button1_Click; - iotUrn.Button1.PreviewMouseLeftButtonDown += viewModel.But1ClickDown; - iotUrn.Button1.PreviewMouseLeftButtonUp += viewModel.But1ClickUp; - iotUrn.Button2.Click += viewModel.Button2_Click; - iotUrn.Button2.PreviewMouseLeftButtonDown += viewModel.But2ClickDown; - iotUrn.Button2.PreviewMouseLeftButtonUp += viewModel.But2ClickUp; - - wrapPanel.Children.Add(iotUrn); - } - expander.Content = wrapPanel; - stackPanel3.Children.Add(expander); - } - } - } - } - - void ServoUi(IEnumerable data) - { - if (true) - { - stackPanel4.Children.Clear(); - if (data == null || !data.Any()) - return; - - var moren = data.Where(o => string.IsNullOrWhiteSpace(o.ExcelTag.组名)); - var group = data.Where(o => !string.IsNullOrWhiteSpace(o.ExcelTag.组名)).GroupBy(o => o.ExcelTag.组名); - - if (moren.Any()) - { - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item in moren) - { - item.IsExpanded = true; - - IotServoMode iotServo = new IotServoMode(); - iotServo.DataContext = item; - iotServo.SetBinding(IotServoMode.TextProperty, nameof(item.Name)); - iotServo.SetBinding(IotServoMode.Speed1Property, nameof(item.JogSpeed)); - iotServo.SetBinding(IotServoMode.Speed2Property, nameof(item.AutoSpeed)); - iotServo.SetBinding(IotServoMode.LocationProperty, nameof(item.Location)); - iotServo.SetBinding(IotServoMode.IsVis1Property, new Binding(nameof(item.IsJog)) { Mode = BindingMode.TwoWay }); - iotServo.SetBinding(IotServoMode.IsFoldProperty, new Binding(nameof(item.IsFold)) { Mode = BindingMode.TwoWay }); - iotServo.LocationChange += viewModel.LocationChange; - iotServo.SpeedChange += viewModel.SpeedChange; - - wrapPanel.Children.Add(iotServo); - } - stackPanel4.Children.Add(wrapPanel); - } - if (group.Any()) - { - foreach (var item in group) - { - Expander expander = new Expander(); - expander.Header = item.Key; - expander.Tag = item; - expander.Expanded += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = true; - } - }; - expander.Collapsed += (s, e) => - { - var c = (IGrouping)((Expander)s).Tag; - foreach (var item in c) - { - item.IsExpanded = false; - } - }; - - WrapPanel wrapPanel = new WrapPanel(); - foreach (var item2 in item) - { - IotServoMode iotServo = new IotServoMode(); - iotServo.DataContext = item2; - iotServo.SetBinding(IotServoMode.TextProperty, nameof(item2.Name)); - iotServo.SetBinding(IotServoMode.Speed1Property, nameof(item2.JogSpeed)); - iotServo.SetBinding(IotServoMode.Speed2Property, nameof(item2.AutoSpeed)); - iotServo.SetBinding(IotServoMode.LocationProperty, nameof(item2.Location)); - iotServo.SetBinding(IotServoMode.IsVis1Property, new Binding(nameof(item2.IsJog)) { Mode = BindingMode.TwoWay }); - iotServo.SetBinding(IotServoMode.IsFoldProperty, new Binding(nameof(item2.IsFold)) { Mode = BindingMode.TwoWay }); - iotServo.LocationChange += viewModel.LocationChange; - iotServo.SpeedChange += viewModel.SpeedChange; - - wrapPanel.Children.Add(iotServo); - } - expander.Content = wrapPanel; - stackPanel4.Children.Add(expander); - } - } - } - } - #endregion } } diff --git a/货架标准上位机/Views/MXWindows/MXMainWindow.xaml b/货架标准上位机/Views/MXWindows/MXMainWindow.xaml index a9afc94..55b1e73 100644 --- a/货架标准上位机/Views/MXWindows/MXMainWindow.xaml +++ b/货架标准上位机/Views/MXWindows/MXMainWindow.xaml @@ -267,11 +267,6 @@ - - - - - diff --git a/货架标准上位机/Views/ModuleInfoView.xaml b/货架标准上位机/Views/ModuleInfoView.xaml index 24287e0..cd3f376 100644 --- a/货架标准上位机/Views/ModuleInfoView.xaml +++ b/货架标准上位机/Views/ModuleInfoView.xaml @@ -41,7 +41,7 @@ - +