From 311a695498e84e6b4deb769d01bef584cb9932c3 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Sun, 5 May 2024 16:57:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8A=A5=E8=AD=A6=E7=AA=97?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 出库流程调试、优化 --- WCS.BLL/Config/JsConfig.cs | 2 + WCS.BLL/DbModels/StockTakingOrder.cs | 9 +- WCS.BLL/HardWare/IShelfBase.cs | 6 +- WCS.BLL/HardWare/IWarningLightBase.cs | 2 +- WCS.BLL/HardWare/SingleLightShelf.cs | 3 +- WCS.BLL/HardWare/SmartShelf.cs | 449 ++++++++++++++---- WCS.BLL/HardWare/SmartShelfModule.cs | 3 + WCS.BLL/Manager/TCPClientManager.cs | 31 +- WCS.BLL/Manager/WarningManager.cs | 239 ++++++++++ WCS.BLL/Manager/WebSoceketManager.cs | 7 +- WCS.BLL/Manager/WebSocketServicePlugin.cs | 33 +- WCS.BLL/Services/IService/IWarningService.cs | 18 + WCS.BLL/Services/Service/InstoreService.cs | 99 +++- WCS.BLL/Services/Service/OutstoreService.cs | 152 +++--- .../Services/Service/StockTakingService.cs | 17 +- WCS.BLL/Services/Service/WarningService.cs | 51 ++ WCS.BLL/Tool/Api/ApiHelp.cs | 224 +++++++-- .../Tool/Api/ApiModel/queryByBarResponse.cs | 29 ++ WCS.BLL/Tool/Api/Models/ApiResult.cs | 19 - WCS.BLL/Tool/Logs.cs | 1 + .../GetStockTakingOrdersRequest.cs | 10 +- .../Stocktaking/StockTakingOrderModel.cs | 50 ++ .../WebSocketModel/SolveWarningRequesr.cs | 18 + .../WebSocketModel/WebSocketMessageModel.cs | 47 ++ WCS.WebApi/Controllers/HomeController.cs | 2 +- WCS.WebApi/Controllers/OutstoreController.cs | 2 +- WCS.WebApi/Controllers/WarningController.cs | 31 ++ WCS.WebApi/Program.cs | 23 +- 货架标准上位机/ViewModels/MainViewModel.cs | 10 + .../ViewModels/MatInventoryDetailViewModel.cs | 2 +- .../ViewModels/OutInventoryDocumentViewModel.cs | 5 + .../ViewModels/OutInventoryViewModel.cs | 27 +- .../ViewModels/StocktakingDocumentViewModel.cs | 384 +++++++++++++++ 货架标准上位机/Views/InInventoryView.xaml | 6 +- .../Views/MainWindows/MainWindow1.xaml | 12 + .../Views/OutInventoryDocumentView.xaml | 4 +- 货架标准上位机/Views/OutInventoryView.xaml | 2 +- 货架标准上位机/Views/OutInventoryView.xaml.cs | 5 + .../Views/StocktakingDocumentView.xaml | 175 +++++++ .../Views/StocktakingDocumentView.xaml.cs | 66 +++ .../Views/Windows/WarningWindow.xaml | 42 ++ .../Views/Windows/WarningWindow.xaml.cs | 154 ++++++ 货架标准上位机/WarningManager.cs | 58 +++ 货架标准上位机/WebSocket.cs | 50 +- 44 files changed, 2272 insertions(+), 307 deletions(-) create mode 100644 WCS.BLL/Manager/WarningManager.cs create mode 100644 WCS.BLL/Services/IService/IWarningService.cs create mode 100644 WCS.BLL/Services/Service/WarningService.cs create mode 100644 WCS.BLL/Tool/Api/ApiModel/queryByBarResponse.cs delete mode 100644 WCS.BLL/Tool/Api/Models/ApiResult.cs create mode 100644 WCS.Model/ApiModel/Stocktaking/StockTakingOrderModel.cs create mode 100644 WCS.Model/WebSocketModel/SolveWarningRequesr.cs create mode 100644 WCS.Model/WebSocketModel/WebSocketMessageModel.cs create mode 100644 WCS.WebApi/Controllers/WarningController.cs create mode 100644 货架标准上位机/ViewModels/StocktakingDocumentViewModel.cs create mode 100644 货架标准上位机/Views/StocktakingDocumentView.xaml create mode 100644 货架标准上位机/Views/StocktakingDocumentView.xaml.cs create mode 100644 货架标准上位机/Views/Windows/WarningWindow.xaml create mode 100644 货架标准上位机/Views/Windows/WarningWindow.xaml.cs create mode 100644 货架标准上位机/WarningManager.cs diff --git a/WCS.BLL/Config/JsConfig.cs b/WCS.BLL/Config/JsConfig.cs index 4b475a2..f3f2eb5 100644 --- a/WCS.BLL/Config/JsConfig.cs +++ b/WCS.BLL/Config/JsConfig.cs @@ -12,5 +12,7 @@ namespace WCS.BLL.Config public class JsConfig { public List ModuleCodePatterns { get; set; } + + public bool IsSameMatCodeOut { get; set; } } } diff --git a/WCS.BLL/DbModels/StockTakingOrder.cs b/WCS.BLL/DbModels/StockTakingOrder.cs index cd36466..1b31581 100644 --- a/WCS.BLL/DbModels/StockTakingOrder.cs +++ b/WCS.BLL/DbModels/StockTakingOrder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using WCS.Model.ApiModel.Stocktaking; namespace WCS.BLL.DbModels { @@ -61,12 +62,4 @@ namespace WCS.BLL.DbModels public bool IsSelected { get; set; } } - - public enum StocktakingOrderStatus - { - 未盘点 = 0, - 部分盘点 = 1, - 盘点完成 = 2, - 已提交 = 3 - } } diff --git a/WCS.BLL/HardWare/IShelfBase.cs b/WCS.BLL/HardWare/IShelfBase.cs index b34184e..b24d048 100644 --- a/WCS.BLL/HardWare/IShelfBase.cs +++ b/WCS.BLL/HardWare/IShelfBase.cs @@ -13,6 +13,10 @@ namespace WCS.BLL.HardWare /// public interface IShelfBase { + /// + /// 货架是否处于报警中 + /// + public bool IsWarning { get; set; } /// /// 货架ID 数据库中那个 /// @@ -39,7 +43,7 @@ namespace WCS.BLL.HardWare /// /// 货架当前模式 /// - public Mode CurentMode { get; set; } + public Mode CurrentMode { get; set; } public MatInfoResponse InStoreData { get; set; } diff --git a/WCS.BLL/HardWare/IWarningLightBase.cs b/WCS.BLL/HardWare/IWarningLightBase.cs index 577439b..0c3a291 100644 --- a/WCS.BLL/HardWare/IWarningLightBase.cs +++ b/WCS.BLL/HardWare/IWarningLightBase.cs @@ -42,7 +42,7 @@ namespace WCS.BLL.HardWare data[5] = (byte)lightBuzzerStatus; //Only For Debug - data[5] = (byte)LightBuzzerStatus.关闭; + //data[5] = (byte)LightBuzzerStatus.关闭; data[4] = time;//灯短亮一次的时间 data[6] = time;//蜂鸣器持续鸣叫的时间 diff --git a/WCS.BLL/HardWare/SingleLightShelf.cs b/WCS.BLL/HardWare/SingleLightShelf.cs index 1978ba2..bc3ddf8 100644 --- a/WCS.BLL/HardWare/SingleLightShelf.cs +++ b/WCS.BLL/HardWare/SingleLightShelf.cs @@ -14,7 +14,7 @@ namespace WCS.BLL.HardWare public string ShelfCode { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public int RowCounts { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public int ColumnCounts { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public Mode CurentMode { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public Mode CurrentMode { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string ModulesStr { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string GroupName { get; set; } public MatInfoResponse InStoreData { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -24,6 +24,7 @@ namespace WCS.BLL.HardWare public List ModuleIds { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string ClientIp { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public List ExceptionMessages { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public bool IsWarning { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public void GoInInstore(string IPAdress) { diff --git a/WCS.BLL/HardWare/SmartShelf.cs b/WCS.BLL/HardWare/SmartShelf.cs index 2d4de35..7a69ff3 100644 --- a/WCS.BLL/HardWare/SmartShelf.cs +++ b/WCS.BLL/HardWare/SmartShelf.cs @@ -6,12 +6,14 @@ using System.Text; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Sockets; +using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.Manager; using WCS.DAL; using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model; +using WCS.Model.WebSocketModel; using static System.Formats.Asn1.AsnWriter; namespace WCS.BLL.HardWare @@ -27,7 +29,7 @@ namespace WCS.BLL.HardWare ShelfCode = shelfInfo.ShelfCode; RowCounts = shelfInfo.Rowcounts; ColumnCounts = shelfInfo.Columncounts; - CurentMode = shelfInfo.CurrentMode; + CurrentMode = shelfInfo.CurrentMode; ClientIp = shelfInfo.ClientIp; LightId = shelfInfo.LightId; WarningLight = new WarningLight() { LightId = shelfInfo.LightId }; @@ -96,18 +98,39 @@ namespace WCS.BLL.HardWare //TcpCleint.Connect(); } + public int ShelfId { get; set; } public string ShelfCode { get; set; } public int RowCounts { get; set; } public int ColumnCounts { get; set; } - public Mode CurentMode { get; set; } + public Mode CurrentMode { get; set; } public string ModulesStr { get; set; }//当前货架所有模组的Str public string GroupName { get; set; } public List Modules { get; set; } = new List(); public TCPClient TcpCleint { get { return TCPClientManager.GetTCPClientByIPHost(ClientIp); } } public int LightId { get; set; } + public bool IsWarning { get; set; } = false; public WarningLight WarningLight { get; set; } + public void ClearWarning() + { + if (this.CurrentMode == Mode.入库模式) + { + WarningLight.BlueLight(TcpCleint); + } + else if (this.CurrentMode == Mode.出库模式) + { + WarningLight.GreenLight(TcpCleint); + } + else if (this.CurrentMode == Mode.盘点模式) + { + WarningLight.GreenLight(TcpCleint); + } + else + { + WarningLight.CloseLight(TcpCleint); + } + } /// /// 自检异常、未响应对应模式的异常 /// @@ -136,19 +159,19 @@ namespace WCS.BLL.HardWare { try { - if (this.CurentMode == Mode.入库模式) + if (this.CurrentMode == Mode.入库模式) { CurrentCom = IPAddress; return; } //判断当前模式是否为待机模式 - else if (this.CurentMode != Mode.待机模式) + else if (this.CurrentMode != Mode.待机模式) { return; } else { - this.CurentMode = Mode.入库模式; + this.CurrentMode = Mode.入库模式; } //清空错误 ExceptionMessages.Clear(); @@ -195,15 +218,20 @@ namespace WCS.BLL.HardWare if (notInstoreList.Count > 0) { - + foreach (var item in notInstoreList) { ExceptionMessages.Add($"模组{item.ModuleCode}未进入入库模式!"); } + //通信校验 + + IsWarning = true; + WarningLight.WaringLightAlwaysRed(TcpCleint); } - //警示灯亮起 - WarningLight.BlueLight(TcpCleint); + //没有报警才亮蓝灯 + if(!IsWarning) + WarningLight.BlueLight(TcpCleint); //绑定当前进入入库PDA/WCS前端的IP CurrentCom = IPAddress; //返回成功 @@ -219,13 +247,13 @@ namespace WCS.BLL.HardWare public void GoOutInstore() { //当前货架是否为入库模式 - if (CurentMode != Mode.入库模式) + if (CurrentMode != Mode.入库模式) { return; } else { - this.CurentMode = Mode.待机模式; + this.CurrentMode = Mode.待机模式; } //清空错误 @@ -262,7 +290,7 @@ namespace WCS.BLL.HardWare .ToList(); if (list.Count > 0) { - CurentMode = Mode.待机模式; + CurrentMode = Mode.待机模式; foreach (var item in list) { ExceptionMessages.Add($"模组{item.ModuleCode}未成功退出入库模式!"); @@ -275,11 +303,11 @@ namespace WCS.BLL.HardWare public void GoInOutstore(List MatDetails, OutOrder outOrder) { //第一步:设置货架当前模式 - if (CurentMode != Mode.待机模式) + if (CurrentMode != Mode.待机模式) { Modules.ForEach(t => { t.Reset(TcpCleint); }); } - CurentMode = Mode.出库模式; + CurrentMode = Mode.出库模式; //第二步:货架添加需要出的SN 出库的领料单号 //移除货架所有现有待出库的MatSN @@ -292,12 +320,13 @@ namespace WCS.BLL.HardWare ////第三步:对应的模组进入出库模式 var boardIds = MatDetails.Select(t => t.StoreInfo.BoardId) .Distinct() + .OrderBy(t => t) .ToList(); var outModules = Modules.Where(t => boardIds.Contains(t.BoardId)).ToList(); outModules.ForEach(t => { - var outMatSns = MatDetails.Where(t => t.StoreInfo.ModuleId == t.Id) - .Select(t => t.MatSN) + var outMatSns = MatDetails.Where(mat => mat.StoreInfo.BoardId == t.BoardId) + .Select(mat => mat.MatSN) .ToList(); t.GoInOutStoreMode(TcpCleint, outMatSns); }); @@ -307,7 +336,7 @@ namespace WCS.BLL.HardWare public void GoInStocktaking() { - this.CurentMode = Mode.盘点模式; + this.CurrentMode = Mode.盘点模式; } public void GoOutOutstore() @@ -319,14 +348,14 @@ namespace WCS.BLL.HardWare { module.GoOutOutStoreMode(TcpCleint); } - CurrentOutOrder = null; CurrentOutStoreMatSNs.Clear(); - this.CurentMode = Mode.待机模式; + WarningLight.CloseLight(TcpCleint); + this.CurrentMode = Mode.待机模式; } public void GoOutStocktaking() { - this.CurentMode = Mode.待机模式; + this.CurrentMode = Mode.待机模式; } void IShelfBase.Reset() @@ -390,7 +419,7 @@ namespace WCS.BLL.HardWare default: ; break; - + } Logs.Write("协议处理5"); } @@ -407,7 +436,6 @@ namespace WCS.BLL.HardWare .FirstOrDefault(); if (module == null) { - //TO DO 报错 return; } else @@ -421,7 +449,6 @@ namespace WCS.BLL.HardWare var module = this.Modules.Where(t => t.BoardId == boardId).FirstOrDefault(); if (module == null) { - //TO DO 报错 return; } else @@ -467,47 +494,63 @@ namespace WCS.BLL.HardWare ExceptionMessages.Add($"{storeInfo.StoreCode}物料{storeInfo.CurrentMatSn}丢失,库存数据已删除,请重新扫码后入库"); #endregion - #region 【后台】丢失的数据处理 - Task.Run(() => + //#region 【后台】丢失的数据处理 + //Task.Run(() => + //{ + // try + // { + // DbHelp.db.BeginTran(); + // //库位表字段清空 + // storeInfo.CurrentMatSn = string.Empty; + // DbHelp.db.Updateable(storeInfo).ExecuteCommand(); + + // //库存表记录删除、插入出入记录 + // var inventoryDetail = DbHelp.db.Queryable().Where(t => t.StoreId == storeInfo.Id).First(); + // if (inventoryDetail != null) + // { + // var inOutRecord = new InOutRecord() + // { + // StoreCode = storeInfo.StoreCode, + // StoreId = storeInfo.Id, + // StoreInfo = storeInfo, + + // MatSN = inventoryDetail.MatSN, + // MatCode = inventoryDetail.MatCode, + // MatName = inventoryDetail.MatName, + // MatBatch = inventoryDetail.MatBatch, + // MatQty = inventoryDetail.MatQty, + // MatSpec = inventoryDetail.MatSpec, + // MatCustomer = inventoryDetail.MatCustomer, + // MatSupplier = inventoryDetail.MatSupplier, + + // Direction = DirectionEnum.丢失, + // }; + // DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + // DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); + // } + // DbHelp.db.CommitTran(); + // } + // catch (Exception e) + // { + // DbHelp.db.RollbackTran(); + // } + //}); + //#endregion + #region 不处理、WebSocket通知前台 + var exceptionMessage = storeInfo.StoreCode + $"进入入库自检发现物料{storeInfo.CurrentMatSn}丢失,请确认是否删除?"; + var warningModel = new WebSocketMessageModel() { - try - { - DbHelp.db.BeginTran(); - //库位表字段清空 - storeInfo.CurrentMatSn = string.Empty; - DbHelp.db.Updateable(storeInfo).ExecuteCommand(); - - //库存表记录删除、插入出入记录 - var inventoryDetail = DbHelp.db.Queryable().Where(t => t.StoreId == storeInfo.Id).First(); - if (inventoryDetail != null) - { - var inOutRecord = new InOutRecord() - { - StoreCode = storeInfo.StoreCode, - StoreId = storeInfo.Id, - StoreInfo = storeInfo, - - MatSN = inventoryDetail.MatSN, - MatCode = inventoryDetail.MatCode, - MatName = inventoryDetail.MatName, - MatBatch = inventoryDetail.MatBatch, - MatQty = inventoryDetail.MatQty, - MatSpec = inventoryDetail.MatSpec, - MatCustomer = inventoryDetail.MatCustomer, - MatSupplier = inventoryDetail.MatSupplier, - - Direction = DirectionEnum.丢失, - }; - DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); - DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); - } - DbHelp.db.CommitTran(); - } - catch (Exception e) - { - DbHelp.db.RollbackTran(); - } - }); + WarningType = WarningTypeEnum.入库自检丢失, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + ModuleId = module.ModuleId, + ModuleCode = module.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1" + }; + WarningManager.SendWarning(warningModel); #endregion WarningLight.WaringLightAlwaysRed(TcpCleint); @@ -526,6 +569,24 @@ namespace WCS.BLL.HardWare #region 缓存记录异常信息 ExceptionMessages.Add($"库位{storeInfo.StoreCode}:存在物料未扫描上架"); #endregion + + #region 不处理、WebSocket通知前台 + var exceptionMessage = $"进入入库自检发现库位{storeInfo.StoreCode}存在物料未扫描上架,请拿下后点击【确认】消除报警"; + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.入库自检未扫描上架, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + ModuleId = module.ModuleId, + ModuleCode = module.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1" + }; + WarningManager.SendWarning(warningModel); + #endregion + WarningLight.WaringLightAlwaysRed(TcpCleint); } else @@ -596,7 +657,20 @@ namespace WCS.BLL.HardWare { Logs.Write("协议处理5.5"); var exceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!"; - WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.入库中未扫描上架, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + ModuleId = module.ModuleId, + ModuleCode = module.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!", + ClientIp = "127.0.0.1" + }; + WarningManager.SendWarning(warningModel); + Logs.Write("协议处理5.4"); module.ComfirmErrInstore(TcpCleint); WarningLight.WaringLightAlwaysRed(TcpCleint); @@ -608,8 +682,6 @@ namespace WCS.BLL.HardWare { module.ComfirmErrInstore(TcpCleint); WarningLight.WaringLightBlueEnd(TcpCleint); - //ComfirmErrInstoreByIp(shelfStatus.ClientIp, boardIds); - //WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId); //TO DO Logs.Write($"[{guid}]该位置已放置物料!"); return; } @@ -703,11 +775,11 @@ namespace WCS.BLL.HardWare { Logs.Write("协议处理5.1"); lightNumber = (int)data[TcpCleint.PreFixLength + 4]; - var store = DbHelp.db.Queryable() + var storeInfo = DbHelp.db.Queryable() .Where(t => t.BoardId == boardId && t.LightNumber == lightNumber) .First(); Logs.Write("协议处理5.2"); - if (store == null) + if (storeInfo == null) { //TO DO 库位未找到 return; @@ -718,9 +790,30 @@ namespace WCS.BLL.HardWare { case 0x00: { - Logs.Write("协议处理5.4"); - var exceptionMessage = store.StoreCode + "恢复正常!"; - WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var warnings = WarningManager.Warnings.Where(t => t.IsWarning = true) + .Where(t => t.ShelfId == ShelfId && t.StoreId == storeInfo.Id) + .ToList(); + + var exceptionMessage = storeInfo.StoreCode + "恢复正常!"; + var warningModel = new WebSocketMessageModel() + { + IsWarning = false, + WarningType = WarningTypeEnum.恢复正常, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1", + SolvedGuids = warnings.Select(t => t.Guid).ToList(), + }; + WarningManager.SendWarning(warningModel); + //自动消除本地缓存的报警 + warnings.ForEach(warning => + { + WarningManager.ClearWarning(warning, SolveTypeEnum.忽略); + }); + ProcessingExceptions.RemoveAll(t => t.BoardId == boardId); Logs.Write("协议处理5.5"); } @@ -728,13 +821,27 @@ namespace WCS.BLL.HardWare case 0x01: { Logs.Write("协议处理5.4"); - var exceptionMessage = store.StoreCode + "入库过程中存在物料未扫描上架!"; - WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var exceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!"; + //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.入库中未扫描上架, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + //ModuleId = module.ModuleId, + //ModuleCode = module.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1" + }; + WarningManager.SendWarning(warningModel); + ProcessingExceptions.Add(new ProcessingExceptionType() { BoardId = boardId, LightNumber = lightNumber, - ExceptionMessage = store.StoreCode + "入库过程中存在物料未扫描上架!" + ExceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!" }); Logs.Write("协议处理5.5"); } @@ -742,13 +849,27 @@ namespace WCS.BLL.HardWare case 0x02: { Logs.Write("协议处理5.4"); - var exceptionMessage = store.StoreCode + "物料被取出!"; - WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var exceptionMessage = storeInfo.StoreCode + "物料被取出!"; + //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.入库中异常取出, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + //ModuleId = module.ModuleId, + //ModuleCode = module.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1" + }; + WarningManager.SendWarning(warningModel); + ProcessingExceptions.Add(new ProcessingExceptionType() { BoardId = boardId, LightNumber = lightNumber, - ExceptionMessage = store.StoreCode + "入库过程中物料丢失!" + ExceptionMessage = storeInfo.StoreCode + "入库过程中物料丢失!" }); Logs.Write("协议处理5.5"); } @@ -906,7 +1027,7 @@ namespace WCS.BLL.HardWare public void OutstoreReturnProcess(byte[] data, int boardId, int lightNumber) { - if (CurentMode != Mode.出库模式) + if (CurrentMode != Mode.出库模式) { //TO DO 未在出库模式 要报错 Logs.Write($"出库错误:{ShelfCode}该货架模式不是出库模式或盘点模式!"); @@ -1003,7 +1124,7 @@ namespace WCS.BLL.HardWare x.IsSended = true; }); //TO DO 发料需求表增加数量 - + //保存数据 DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); @@ -1016,16 +1137,23 @@ namespace WCS.BLL.HardWare //确认本次出库 module.ComfirmOutstore(TcpCleint, data[TcpCleint.PreFixLength + 3]); + + //通知前台刷新 Task.Run(() => { - //给信号通知出库页面更新页面的状态 + var messageMode = new WebSocketMessageModel() + { + IsWarning = false, + ClientIp = "127.0.0.1", + WarningType = WarningTypeEnum.通知刷新出库 + }; + WarningManager.SendWarning(messageMode); }); //当前柜子是否还存在未出库的 CurrentOutStoreMatSNs.RemoveAll(t => t == matSN);//删除本次已出的物料SN - - var isExsistOut = CurrentOutStoreMatSNs.Any(); + //本批次出库已完成 if (!isExsistOut) { @@ -1033,8 +1161,97 @@ namespace WCS.BLL.HardWare GoOutOutstore(); WarningLight.CloseLight(TcpCleint); var currentPickBillNumber = CurrentOutOrder.OrderNumber; + //OrderNumber = string.Empty; CurrentOutOrder = null; } + + //看是否是分批次出库的情况 分批次亮灯 + if (LocalFile.Config.IsSameMatCodeOut) + { + #region 触发下一批次的精准发料 + //查一下是否是当前发料单最后一个货架(在出库模式 同一个发料单下) + var isLastShelf = ShelfManager.Shelves + .Where(t => t.OrderNumber == OrderNumber) + .Where(t => t.CurrentMode == Mode.出库模式) + .Any(); + if (!isLastShelf) + { + Logs.Write($"发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料"); + var outOrder = DbHelp.db.Queryable() + .Where(t => t.OrderNumber == OrderNumber) + .First(); + if (outOrder != null) + { + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == outOrder.Id) + .Where(t => t.IsSended == false) + .Includes(t => t.StoreInfo) + .ToList(); + + if (outOrderMatDetails != null && outOrderMatDetails.Count > 0) + { + //存在待出库 然后之前又没亮灯的情况 => 精准发料分批次亮灯 + Logs.Write($"发料单{OrderNumber},还有物料未出!"); + 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($"发料单{OrderNumber},本次亮灯物料{matCode}!"); + } + //相同物料不存在盘数超过n的情况,剩余物料全部亮灯 + else + { + //剩余物料全出 + Logs.Write($"发料单{OrderNumber},剩余物料灯全亮!"); + } + + var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) + .Distinct() + .ToList(); + var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList(); ; + + var otherModeShelfs = shelfs.Where(t => t.CurrentMode != HardWare.Mode.待机模式).ToList(); + if (otherModeShelfs != null && otherModeShelfs.Count > 0) + { + otherModeShelfs.ForEach(t => + { + t.Reset(); + }); + Thread.Sleep(1000); + } + //对应的货架对应位置 进入出库模式 亮灯 + shelfs.ForEach(shelf => + { + var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode) + + .Distinct() + .ToList(); + shelf.GoInOutstore(matDetails, outOrder); + shelf.OrderNumber = outOrder.OrderNumber; + }); + + } + else + { + Logs.Write($"发料单{OrderNumber},当前物料已发完!"); + } + } + else + { + Logs.Write($"发料单{OrderNumber},OutOrder为null,肯定是有问题"); + } + + } + #endregion + } + } catch (Exception ex) { @@ -1071,10 +1288,10 @@ namespace WCS.BLL.HardWare public void OutstoreExceptionReturnProcess(byte[] data, int boardId, int lightNumber) { lightNumber = (int)data[TcpCleint.PreFixLength + 4]; - var store = DbHelp.db.Queryable() + var storeInfo = DbHelp.db.Queryable() .Where(t => t.BoardId == boardId && t.LightNumber == lightNumber) .First(); - if (store == null) + if (storeInfo == null) { //TO DO 库位未找到 return; @@ -1084,32 +1301,82 @@ namespace WCS.BLL.HardWare { case 0x00: { - var exceptionMessage = store.StoreCode + "恢复正常!"; - WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + //对应的异常 + var warnings = WarningManager.Warnings.Where(t => t.IsWarning = true) + .Where(t => t.ShelfId == ShelfId && t.StoreId == storeInfo.Id) + .ToList(); + + var exceptionMessage = storeInfo.StoreCode + "恢复正常!"; + var warningModel = new WebSocketMessageModel() + { + IsWarning = false, + WarningType = WarningTypeEnum.恢复正常, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1", + SolvedGuids = warnings.Select(t => t.Guid).ToList(), + }; + WarningManager.SendWarning(warningModel); + //自动消除本地缓存的报警 + warnings.ForEach(warning => + { + WarningManager.ClearWarning(warning, SolveTypeEnum.忽略); + }); ProcessingExceptions.RemoveAll(t => t.BoardId == boardId); } break; case 0x01: { - var exceptionMessage = store.StoreCode + "出库过程中存在物料上架!"; - WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var exceptionMessage = storeInfo.StoreCode + "出库过程中存在物料上架!"; + //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.出库中未扫描上架, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + //ModuleId = module.ModuleId, + //ModuleCode = module.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1" + }; + WarningManager.SendWarning(warningModel); + ProcessingExceptions.Add(new ProcessingExceptionType() { BoardId = boardId, LightNumber = lightNumber, - ExceptionMessage = store.StoreCode + "出库过程中存在物料上架!" + ExceptionMessage = storeInfo.StoreCode + "出库过程中存在物料上架!" }); } break; case 0x02: { - var exceptionMessage = store.StoreCode + "物料被取出!"; - WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var exceptionMessage = storeInfo.StoreCode + "物料被取出!"; + //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + var warningModel = new WebSocketMessageModel() + { + WarningType = WarningTypeEnum.出库中丢失, + StoreId = storeInfo.Id, + StoreCode = storeInfo.StoreCode, + //ModuleId = module.ModuleId, + //ModuleCode = module.ModuleCode, + ShelfCode = ShelfCode, + ShelfId = ShelfId, + WarningMessage = exceptionMessage, + ClientIp = "127.0.0.1" + }; + WarningManager.SendWarning(warningModel); + ProcessingExceptions.Add(new ProcessingExceptionType() { BoardId = boardId, LightNumber = lightNumber, - ExceptionMessage = store.StoreCode + "出库过程中物料被异常取出!" + ExceptionMessage = storeInfo.StoreCode + "出库过程中物料被异常取出!" }); } break; diff --git a/WCS.BLL/HardWare/SmartShelfModule.cs b/WCS.BLL/HardWare/SmartShelfModule.cs index db3cb20..b864abd 100644 --- a/WCS.BLL/HardWare/SmartShelfModule.cs +++ b/WCS.BLL/HardWare/SmartShelfModule.cs @@ -57,6 +57,8 @@ namespace WCS.BLL.HardWare public bool IsEnable { get; set; } public Mode CurrentMode { get; set; } + public List CurrentOutSns { get; set; } + public void SetCurrentMode() { @@ -160,6 +162,7 @@ namespace WCS.BLL.HardWare /// public void GoInOutStoreMode(TCPClient tcpClient, List outSns) { + CurrentOutSns = outSns; var storeInfos = DbHelp.db.Queryable() .Where(t => t.BoardId == BoardId) .OrderBy(t => t.LightNumber) diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs index 9e4ac1d..3ed4036 100644 --- a/WCS.BLL/Manager/TCPClientManager.cs +++ b/WCS.BLL/Manager/TCPClientManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Sockets; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; @@ -24,14 +25,10 @@ namespace WCS.BLL.Manager foreach (var ip in ips) { var tcpCleint = new TCPClient(ip, "192.168.9.183:20003"); - - - //var tcpCleint = new TCPClient("192.168.0.183:20002", "192.168.0.183:20003"); //配置断线重连 - tcpCleint.tcpClient.Received += (client, e) => { - + var clientIpHost = client.IP + ":" + client.Port; var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); if (TcpCleint == null) @@ -108,6 +105,30 @@ namespace WCS.BLL.Manager } } + public static void InitStatus() + { + Task.Run(() => + { + try + { + + + Thread.Sleep(1000); + //给所有板子发复位 + TCPClients.ForEach(tcpClient => + { + //板子复位 + new SmartShelfModule() { BoardId = 2047 }.Reset(tcpClient); + //报警灯复位 + new WarningLight().CloseLight(tcpClient); + }); + } + catch (Exception ex) + { + Logs.Write($"启动时复位异常,{ex.Message}"); + } + }); + } public static TCPClient GetTCPClientByIPHost(string IpHost) { return TCPClients.Where(t => t.RemoteIPHost == IpHost).FirstOrDefault(); diff --git a/WCS.BLL/Manager/WarningManager.cs b/WCS.BLL/Manager/WarningManager.cs new file mode 100644 index 0000000..4ce40a6 --- /dev/null +++ b/WCS.BLL/Manager/WarningManager.cs @@ -0,0 +1,239 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Data.OscarClient; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WCS.BLL.DbModels; +using WCS.BLL.HardWare; +using WCS.DAL.Db; +using WCS.DAL.DbModels; +using WCS.Model.WebSocketModel; + +namespace WCS.BLL.Manager +{ + /// + /// 报警信息 + /// + public static class WarningManager + { + public static object flag = new object(); + public static void StartWarningMessageThread() + { + Task.Run(() => + { + while (true) + { + try + { + var noReceivedWarningMessage = Warnings.Where(t => t.ClientIsReceived == false && t.LastSendTime < DateTime.Now.AddSeconds(-5)) + .ToList(); + foreach (var warning in noReceivedWarningMessage) + { + WebSoceketManager.TrySendMessage(warning.ClientIp, JsonConvert.SerializeObject(warning)); + warning.LastSendTime = DateTime.Now; + } + } + catch (Exception ex) + { + + } + Thread.Sleep(5000); + } + }); + } + public static List Warnings { get; set; } = new List(); + public static void SendWarning(WebSocketMessageModel warning) + { + lock (flag) + { + Warnings.Add(warning); + WebSoceketManager.TrySendMessage(warning.ClientIp, JsonConvert.SerializeObject(warning)); + warning.LastSendTime = DateTime.Now; + } + + } + + public static void ClearWarning(WebSocketMessageModel warning, SolveTypeEnum solveType) + { + try + { + var shelfIsWarning = true; + var warningInManager = Warnings.Where(t => t.Guid == warning.Guid).FirstOrDefault(); + if (warningInManager != null) + { + if (solveType == SolveTypeEnum.处理) + { + //TODO 对应报警处理对应的数据 + switch (warningInManager.WarningType) + { + case WarningTypeEnum.入库自检丢失: + SolveLoss(warningInManager); + break; + case WarningTypeEnum.入库自检未扫描上架: + SolveNoScan(warningInManager); + break; + } + } + + //消除报警缓存信息 + lock (flag) + { + Warnings.Remove(warningInManager); + } + } + + //货架是否还存在报警信息 + shelfIsWarning = Warnings.Where(t => t.ShelfId == warning.ShelfId) + .Any(); + + //对应货架如果不存在报警信息了 指示灯回到对应的状态 + if (!shelfIsWarning) + { + var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == warning.ShelfId) + .FirstOrDefault(); + if (shelf != null) + { + try + { + var smartShelf = shelf as SmartShelf; + smartShelf?.ClearWarning(); + smartShelf.IsWarning = false; + } + catch (Exception ex) + { + + } + } + } + + #region 重新发指令进入对应模式 + GoInRightMode(warning); + #endregion + + } + catch (Exception e) + { + Logs.Write($"消除报警信息失败:发生异常" + e.Message); + } + } + + public static void RemoveMessage(WebSocketMessageModel warning) + { + var warningInManager = Warnings.Where(t => t.Guid == warning.Guid).FirstOrDefault(); + lock (flag) + { + Warnings.Remove(warningInManager); + } + } + + + #region 报警消除的处理 + public static void SolveNoScan(WebSocketMessageModel warning) + { + + } + + public static void SolveLoss(WebSocketMessageModel warning) + { + #region 【后台】丢失的数据处理 + + try + { + //获取库位 + var storeInfo = DbHelp.db.Queryable() + .Where(t => t.Id == warning.StoreId) + .First(); + if (storeInfo != null) + { + DbHelp.db.BeginTran(); + //库位表字段清空 + storeInfo.CurrentMatSn = string.Empty; + DbHelp.db.Updateable(storeInfo).ExecuteCommand(); + + //库存表记录删除、插入出入记录 + var inventoryDetail = DbHelp.db.Queryable().Where(t => t.StoreId == storeInfo.Id).First(); + if (inventoryDetail != null) + { + var inOutRecord = new InOutRecord() + { + StoreCode = storeInfo.StoreCode, + StoreId = storeInfo.Id, + StoreInfo = storeInfo, + + MatSN = inventoryDetail.MatSN, + MatCode = inventoryDetail.MatCode, + MatName = inventoryDetail.MatName, + MatBatch = inventoryDetail.MatBatch, + MatQty = inventoryDetail.MatQty, + MatSpec = inventoryDetail.MatSpec, + MatCustomer = inventoryDetail.MatCustomer, + MatSupplier = inventoryDetail.MatSupplier, + + Direction = DirectionEnum.丢失, + }; + DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); + } + DbHelp.db.CommitTran(); + } + } + catch (Exception e) + { + DbHelp.db.RollbackTran(); + } + + #endregion + } + + public static void GoInRightMode(WebSocketMessageModel warning) + { + try + { + //模组还存在其他异常 暂时不进入对应模式 + var moduleOtherError = WarningManager.Warnings.Where(t => t.ShelfId == warning.ShelfId && t.ModuleId == warning.ModuleId).Any(); + if (moduleOtherError) + { + return; + } + + var shelf = ShelfManager.Shelves.Where(t => t.ShelfId == warning.ShelfId) + .FirstOrDefault(); + if (shelf != null) + { + var smartShelf = shelf as SmartShelf; + if (smartShelf != null) + { + var module = smartShelf.Modules.Where(t => t.ModuleId == warning.ModuleId).FirstOrDefault(); + if (module != null) + { + switch (smartShelf.CurrentMode) + { + case Mode.入库模式: + module.GoInInstoreMode(smartShelf.TcpCleint); + smartShelf.WarningLight.BlueLight(smartShelf.TcpCleint); + break; + case Mode.出库模式: + module.GoInOutStoreMode(smartShelf.TcpCleint, module.CurrentOutSns); + smartShelf.WarningLight.GreenLight(smartShelf.TcpCleint); + break; + case Mode.待机模式: + module.Reset(smartShelf.TcpCleint); + smartShelf.WarningLight.CloseLight(smartShelf.TcpCleint); + break; + default: break; + } + } + } + } + } + catch (Exception e) + { + Logs.Write("重置模组状态异常" + e.Message); + } + } + #endregion + + } +} diff --git a/WCS.BLL/Manager/WebSoceketManager.cs b/WCS.BLL/Manager/WebSoceketManager.cs index b4f75d3..2256bd8 100644 --- a/WCS.BLL/Manager/WebSoceketManager.cs +++ b/WCS.BLL/Manager/WebSoceketManager.cs @@ -12,6 +12,8 @@ namespace WCS.BLL.Manager public static class WebSoceketManager { public static HttpService service; + + public static object flag = new object(); public static void InitWebSocket() { service = new HttpService(); @@ -40,7 +42,10 @@ namespace WCS.BLL.Manager var clients = service.GetClients().Where(t => t.IP == IpAddress).ToList(); foreach (var client in clients) { - client.WebSocket.SendAsync(Message); + lock (client) + { + client.WebSocket.Send(Message); + } } } catch (Exception ex) diff --git a/WCS.BLL/Manager/WebSocketServicePlugin.cs b/WCS.BLL/Manager/WebSocketServicePlugin.cs index 38338c8..4560201 100644 --- a/WCS.BLL/Manager/WebSocketServicePlugin.cs +++ b/WCS.BLL/Manager/WebSocketServicePlugin.cs @@ -1,10 +1,13 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Http.WebSockets; +using static System.Net.Mime.MediaTypeNames; +using WCS.Model.WebSocketModel; namespace WCS.BLL.Manager { @@ -30,12 +33,30 @@ namespace WCS.BLL.Manager if (!client.Client.IsClient) { - var clients = WebSoceketManager.service.GetClients().ToList(); - clients.ForEach(t => + try { - t.WebSocket.Send("我已收到"); - }); - client.Send("我已收到"); + var message = e.DataFrame.ToText(); + var warning = JsonConvert.DeserializeObject(message); + if (warning.IsWarning == false) + { + WarningManager.RemoveMessage(warning); + return; + } + if (warning != null) + { + //收到这个表示客户端已成功收到消息并提示给前端 避免一直发 + var warningInManager = WarningManager.Warnings.Where(t => t.Guid == warning.Guid).FirstOrDefault(); + if (warningInManager != null) + { + + warningInManager.ClientIsReceived = true; + } + } + } + catch + { + } + } return; diff --git a/WCS.BLL/Services/IService/IWarningService.cs b/WCS.BLL/Services/IService/IWarningService.cs new file mode 100644 index 0000000..7f0733f --- /dev/null +++ b/WCS.BLL/Services/IService/IWarningService.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WCS.Model; +using WCS.Model.WebSocketModel; + +namespace WCS.BLL.Services.IService +{ + /// + /// 处理、查询报警使用的服务 + /// + public interface IWarningService + { + public Task> SolveWarning(SolveWarningRequest request); + } +} diff --git a/WCS.BLL/Services/Service/InstoreService.cs b/WCS.BLL/Services/Service/InstoreService.cs index f6ba428..5e87a5c 100644 --- a/WCS.BLL/Services/Service/InstoreService.cs +++ b/WCS.BLL/Services/Service/InstoreService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Runtime; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -10,9 +11,12 @@ 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.Model; using WCS.Model.ApiModel.MatBaseInfo; +using static Dm.net.buffer.ByteArrayBuffer; namespace WCS.BLL.Services.Service { @@ -63,7 +67,7 @@ namespace WCS.BLL.Services.Service //已找到模组对应货架 shelf.GoInInstore(request.IpAdress); - if (shelf.CurentMode == Mode.入库模式) + if (shelf.CurrentMode == Mode.入库模式) //成功进入入库模式 return new ShelfGoInInstoreResponse() { @@ -129,12 +133,12 @@ namespace WCS.BLL.Services.Service }; } //判断当前是否是入库模式 - if (shelf.CurentMode != Mode.入库模式) + if (shelf.CurrentMode != Mode.入库模式) { return new ResponseCommon() { Code = 201, - Message = $"操作失败:货架[{request.ShelfCode}]不在入库模式!\r\n当前为{shelf.CurentMode}", + Message = $"操作失败:货架[{request.ShelfCode}]不在入库模式!\r\n当前为{shelf.CurrentMode}", }; } //判断物料是否已入库 @@ -149,9 +153,92 @@ namespace WCS.BLL.Services.Service } #region 获取物料数据 //调用接口或者直接查询数据库 //TODO做成配置 调用接口 - if (1 != 1) + if (1 == 1) { + #region 调用Mes接口获取物料信息 + try + { + var body = new + { + materialBar = request.MatSn + }; + //var Result = ApiHelp.GetDataFromHttp>>("http://192.168.2.23:9213/integrate/instock/queryBybar", body, "POST"); + var Result = new ResponseCommon>() + { + Code = 200, + Data = new List() {new queryByBarResponse() + { + materialBar = request.MatSn, + materialCode = "111222", + materialName = "电阻", + materialQty = 1000, + } + } + }; + //查询到物料信息 + if (Result != null && Result.Code == 200 && Result.Data != null && Result.Data.Count > 0) + { + var data = Result.Data.First(); + shelf.InStoreData = new MatInfoResponse() + { + materialBar = data.materialBar, + materialCode = data.materialCode, + materialName = data.materialName, + materialQty = data.materialQty, + materialSpec = data.materialSpec, + batchNo = data.batchNo, + supplier = "", + customer = data.materialBar, + 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系统中未获取到物料信息 + 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 @@ -207,12 +294,12 @@ namespace WCS.BLL.Services.Service } //判断当前是否是入库模式 - if (shelf.CurentMode != Mode.入库模式) + if (shelf.CurrentMode != Mode.入库模式) { return new ResponseCommon() { Code = 201, - Message = $"货架[{request.ShelfCode}]已退出入库模式!\r\n当前为{shelf.CurentMode}", + Message = $"货架[{request.ShelfCode}]已退出入库模式!\r\n当前为{shelf.CurrentMode}", }; } diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index 087638b..3e0902b 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using TouchSocket.Sockets; +using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.Manager; using WCS.BLL.Services.IService; @@ -403,78 +404,112 @@ namespace WCS.BLL.Services.Service public async Task GoInOutstore(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) + try { - return new ResponseCommon() + //获取出库单 + 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) { - Code = 201, - Message = $"不存在对应的出库单据{request.OrderNumber}!", - Data = null - }; - } - - //如果是按物料编码出库 需要计算物料明细、并进行物料锁定 - if (order.SyncType == SyncTypeEnum.ByMatCode) - { - var result = CaculateOutOrderMatDetails(order); - if (result.Code != 200) - { - return result; + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; } - } - //获取需要出库的物料明细 - 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() + //如果是按物料编码出库 需要计算物料明细、并进行物料锁定 + if (order.SyncType == SyncTypeEnum.ByMatCode) { - Code = 201, - Message = $"出库单据{request.OrderNumber}物料已全部出库!", - Data = null - }; - } - //按货架分组 按物料找到对应的货架 - var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) - .Distinct() + var result = CaculateOutOrderMatDetails(order); + 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 + }; + } + //按货架分组 按物料找到对应的货架 + 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(); - var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).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},剩余物料灯全亮!"); + } + } - var outherModeShelfs = shelfs.Where(t => t.CurentMode != HardWare.Mode.待机模式).Select(t => t.ShelfCode).ToList(); - if (outherModeShelfs != null && outherModeShelfs.Count > 0) - { - return new ResponseCommon() - { - Code = 201, - Message = $"进入出库模式失败:货架{string.Join("", outherModeShelfs)}不在待机模式", - Data = null - }; - } - //对应的货架对应位置 进入出库模式 亮灯 - shelfs.ForEach(shelf => + //对应的货架对应位置 进入出库模式 亮灯 + 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() + //返回 + return new ResponseCommon() + { + Code = 200, + Message = "Success", + Data = null + }; + } + catch (Exception ex) { - Code = 200, - Message = "Success", - Data = null - }; + await GoInOutstore(request); + throw ex; + } } private ResponseBase CaculateOutOrderMatDetails(OutOrder order) @@ -657,7 +692,8 @@ namespace WCS.BLL.Services.Service }); //解锁物料 删除物料明细 - CancelOutOrderMatDetails(order); + if (order.SyncType == SyncTypeEnum.ByMatCode) + CancelOutOrderMatDetails(order); return new ResponseCommon() { diff --git a/WCS.BLL/Services/Service/StockTakingService.cs b/WCS.BLL/Services/Service/StockTakingService.cs index 8253385..69163eb 100644 --- a/WCS.BLL/Services/Service/StockTakingService.cs +++ b/WCS.BLL/Services/Service/StockTakingService.cs @@ -312,21 +312,22 @@ namespace WCS.BLL.Services.Service { var recordsQueryable = DbHelp.db.Queryable() - .WhereIF(!string.IsNullOrEmpty(request.StocktakingOrderNumber), t => t.StocktakingOrderNumber.Contains(request.StocktakingOrderNumber)); + .WhereIF(!string.IsNullOrEmpty(request.StocktakingOrderNumber), t => t.StocktakingOrderNumber.Contains(request.StocktakingOrderNumber)) + .WhereIF(!string.IsNullOrEmpty(request.StocktakingOrderSource), t => t.StocktakingOrderSource!=null && t.StocktakingOrderSource.Contains(request.StocktakingOrderSource)); switch (request.StocktakingOrderStatus) { case Model.ApiModel.Stocktaking.StocktakingOrderStatus.未盘点: - recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.未盘点); + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == StocktakingOrderStatus.未盘点); break; case Model.ApiModel.Stocktaking.StocktakingOrderStatus.部分盘点: - recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.部分盘点); + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == StocktakingOrderStatus.部分盘点); break; case Model.ApiModel.Stocktaking.StocktakingOrderStatus.已提交: - recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.已提交); + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == StocktakingOrderStatus.已提交); break; case Model.ApiModel.Stocktaking.StocktakingOrderStatus.盘点完成: - recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == DbModels.StocktakingOrderStatus.盘点完成); + recordsQueryable = recordsQueryable.Where(t => t.StocktakingOrderStatus == StocktakingOrderStatus.盘点完成); break; default: break; @@ -530,7 +531,7 @@ namespace WCS.BLL.Services.Service #endregion #region 查询当前盘点盘已启动的货架 - var shelfs = ShelfManager.Shelves.Where(t => t.CurentMode == HardWare.Mode.盘点模式 && t.OrderNumber == order.StocktakingOrderNumber).ToList(); + var shelfs = ShelfManager.Shelves.Where(t => t.CurrentMode == HardWare.Mode.盘点模式 && t.OrderNumber == order.StocktakingOrderNumber).ToList(); shelfs.ForEach(t => { t.GoOutStocktaking(); @@ -674,7 +675,7 @@ namespace WCS.BLL.Services.Service #endregion #region 判断单据状态 - if (order.StocktakingOrderStatus != DbModels.StocktakingOrderStatus.已提交) + if (order.StocktakingOrderStatus != StocktakingOrderStatus.已提交) { return new ResponseCommon() { @@ -682,7 +683,7 @@ namespace WCS.BLL.Services.Service Message = $"单据已提交,请勿重复提交!", }; } - else if (order.StocktakingOrderStatus != DbModels.StocktakingOrderStatus.盘点完成) + else if (order.StocktakingOrderStatus != StocktakingOrderStatus.盘点完成) { return new ResponseCommon() { diff --git a/WCS.BLL/Services/Service/WarningService.cs b/WCS.BLL/Services/Service/WarningService.cs new file mode 100644 index 0000000..4fcd5ce --- /dev/null +++ b/WCS.BLL/Services/Service/WarningService.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using TouchSocket.Core; +using WCS.BLL.Manager; +using WCS.BLL.Services.IService; +using WCS.DAL; +using WCS.DAL.Db.AuthDb; +using WCS.Model; +using WCS.Model.ApiModel; +using WCS.Model.ApiModel.User; +using WCS.Model.WebSocketModel; + +namespace WCS.BLL.Services.Service +{ + public class WarningService : IWarningService + { + public async Task> SolveWarning(SolveWarningRequest request) + { + //获取对应的报警 + var warning = WarningManager.Warnings + .Where(t => t.Guid == request.Guid) + .FirstOrDefault(); + if (warning != null) + { + WarningManager.ClearWarning(warning, request.SolveType); + } + //判断一下是否还存在对应报警 + warning = WarningManager.Warnings + .Where(t => t.Guid == request.Guid) + .FirstOrDefault(); + if (warning == null) + return new ResponseCommon() + { + Code = 200, + Message = "报警解除成功!" + }; + else + { + return new ResponseCommon() + { + Code = 201, + Message = "报警解除失败!请重试!" + }; + } + } + } +} diff --git a/WCS.BLL/Tool/Api/ApiHelp.cs b/WCS.BLL/Tool/Api/ApiHelp.cs index c8dfa92..98fffcf 100644 --- a/WCS.BLL/Tool/Api/ApiHelp.cs +++ b/WCS.BLL/Tool/Api/ApiHelp.cs @@ -3,15 +3,18 @@ using Newtonsoft.Json.Linq; using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Windows.Input; -using WCS.BLL.Tool.Api.Models; +using WCS.BLL; +using WCS.Model; -namespace WCS.BLL.Tool.Api +namespace WCS.BLL.Tool { public static class ApiHelp { @@ -19,57 +22,57 @@ namespace WCS.BLL.Tool.Api static ApiHelp() { httpClient = new HttpClient(); - httpClient.Timeout = TimeSpan.FromSeconds(5); - httpClient.DefaultRequestHeaders.Add("User-Agent", "Chrome/95.0.4638.69 Safari/537.36"); - //ServicePointManager.Expect100Continue = false; + httpClient.Timeout = TimeSpan.FromSeconds(10); + httpClient.DefaultRequestHeaders.Add("UserModel-Agent", "Chrome/95.0.4638.69 Safari/537.36"); + ServicePointManager.Expect100Continue = false; } - public static ApiResult Get(string uri, object? query = null, object? body = null) + public static async Task Get(string uri, object? query = null, object? body = null) { - return Send(HttpMethod.Get, uri, query, body); + return await Send(HttpMethod.Get, uri, query, body); } - public static ApiResult Get(IEnumerable uri, object? query = null, object? body = null) + public static async Task Get(IEnumerable uri, object? query = null, object? body = null) { - return Send(HttpMethod.Get, uri, query, body); + return await Send(HttpMethod.Get, uri, query, body); } - public static ApiResult Get(string uri, object? query = null, object? body = null) + public static async Task Get(string uri, object? query = null, object? body = null) { - return Send(HttpMethod.Get, uri, query, body); + return await Send(HttpMethod.Get, uri, query, body); } - public static ApiResult Get(IEnumerable uri, object? query = null, object? body = null) + public static async Task Get(IEnumerable uri, object? query = null, object? body = null) { - return Send(HttpMethod.Get, uri, query, body); + return await Send(HttpMethod.Get, uri, query, body); } - public static ApiResult Post(string uri, object? body = null, object? query = null) + public static async Task Post(string uri, object? body = null, object? query = null) { - return Send(HttpMethod.Post, uri, query, body); + return await Send(HttpMethod.Post, uri, query, body); } - public static ApiResult Post(IEnumerable uri, object? body = null, object? query = null) + public static async Task Post(IEnumerable uri, object? body = null, object? query = null) { - return Send(HttpMethod.Post, uri, query, body); + return await Send(HttpMethod.Post, uri, query, body); } - public static ApiResult Post(string uri, object? body = null, object? query = null) + public static async Task Post(string uri, object? body = null, object? query = null) { - return Send(HttpMethod.Post, uri, query, body); + return await Send(HttpMethod.Post, uri, query, body); } - public static ApiResult Post(IEnumerable uri, object? body = null, object? query = null) + public static async Task Post(IEnumerable uri, object? body = null, object? query = null) { - return Send(HttpMethod.Post, uri, query, body); + return await Send(HttpMethod.Post, uri, query, body); } - public static ApiResult Send(HttpMethod method, string uri, object? query = null, object? body = null) + public static async Task Send(HttpMethod method, string uri, object? query = null, object? body = null) { - return Send(method, new string[] { uri }, query, body); + return await Send(method, new string[] { uri }, query, body); } - public static ApiResult Send(HttpMethod method, IEnumerable uri, object? query = null, object? body = null) + public static async Task Send(HttpMethod method, IEnumerable uri, object? query = null, object? body = null) { HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, "".AppendPathSegments(uri).SetQueryParams(query)); @@ -79,35 +82,44 @@ namespace WCS.BLL.Tool.Api httpRequestMessage.Content = content; } - var re = httpClient.SendAsync(httpRequestMessage).Result; + var re = await httpClient.SendAsync(httpRequestMessage); if (!re.IsSuccessStatusCode) - return new ApiResult() { Code = ((int)re.StatusCode).ToString() }; + return new ResponseBase() { Code = (int)re.StatusCode }; - var con = re.Content.ReadAsStringAsync().Result; - return JsonConvert.DeserializeObject(con) ?? new ApiResult(); + var con = await re.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(con) ?? new ResponseBase(); } - public static ApiResult Send(HttpMethod method, string uri, object? query = null, object? body = null) + public static async Task Send(HttpMethod method, string uri, object? query = null, object? body = null) { - return Send(method, new string[] { uri }, query, body); + return await Send(method, new string[] { uri }, query, body); } - public static ApiResult Send(HttpMethod method, IEnumerable uri, object? query = null, object? body = null) + public static async Task Send(HttpMethod method, IEnumerable uri, object? query = null, object? body = null) { - HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, "".AppendPathSegments(uri).SetQueryParams(query)); - - if (body != null) + try { - var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); - httpRequestMessage.Content = content; + var url = "".AppendPathSegments(uri).SetQueryParams(query); + HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, url); + + if (body != null) + { + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + httpRequestMessage.Content = content; + } + + var re = await httpClient.SendAsync(httpRequestMessage); + if (!re.IsSuccessStatusCode) + return default(T); + + var con = await re.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(con) ?? default(T); ; + } + catch (Exception ex) + { + return default(T); } - var re = httpClient.SendAsync(httpRequestMessage).Result; - if (!re.IsSuccessStatusCode) - return new ApiResult() { Code = ((int)re.StatusCode).ToString() }; - - var con = re.Content.ReadAsStringAsync().Result; - return JsonConvert.DeserializeObject>(con) ?? new ApiResult(); } /// @@ -118,17 +130,18 @@ namespace WCS.BLL.Tool.Api /// 地址 public static string AppendPathSegments(this string url, IEnumerable segments) { - string urlStr = url; + string urlStr = url.Trim(); foreach (var segment in segments) { - var val = segment?.ToString(); + var val = segment?.ToString()?.Trim() ?? ""; if (string.IsNullOrWhiteSpace(val)) continue; if (urlStr.EndsWith("/")) urlStr = urlStr.Substring(0, urlStr.Length - 1); - urlStr += val!.StartsWith("/") ? val : $"/{val}"; + if (val.Length > 0) + urlStr += string.IsNullOrEmpty(urlStr) || val.StartsWith("/") ? val : $"/{val}"; } return urlStr; } @@ -178,5 +191,126 @@ namespace WCS.BLL.Tool.Api return urlStr; } + + /// + /// Post方式下载Excel文件 + /// + /// 文件保存的路径 + /// + /// + /// + /// + public static async Task PostDownloadFileAsync(string localFilePath, HttpMethod method, string requestUrl, object? body = null) + { + HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, requestUrl); + if (body != null) + { + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + httpRequestMessage.Content = content; + } + using (var response = await httpClient.SendAsync(httpRequestMessage)) + { + response.EnsureSuccessStatusCode(); // 确保请求成功 + + // 获取内容头中的文件名(如果需要的话) + //var contentDisposition = ContentDispositionHeaderValue.Parse(response.Content.Headers.ContentDisposition.ToString()); + //string filename = contentDisposition.FileName.Trim('"'); // 去除引号 + var filename = string.Empty; + // 如果提供的本地文件路径没有文件名,则使用从响应头中获取的文件名 + if (Path.GetFileName(localFilePath) == string.Empty) + { + localFilePath = Path.Combine(Path.GetDirectoryName(localFilePath), filename); + } + // 写入文件 + using (var fileStream = new FileStream(localFilePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true)) + { + await response.Content.CopyToAsync(fileStream); + } + } + } + + /// + /// Post方式导入Excel文件 + /// + /// 文件保存的路径 + /// + /// + /// + /// + public static async Task PostImportFileAsync(string localFilePath, HttpMethod method, string requestUrl, string userName, string deviceType) + { + HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, requestUrl); + + using (var content = new MultipartFormDataContent()) + { + var fileContent = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read)); + fileContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/form-data"); + content.Add(fileContent, "excelFile", Path.GetFileName(localFilePath)); + + var userNameContent = new StringContent(userName); + userNameContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/form-data"); + content.Add(userNameContent, "userName"); + + var deviceTypeContent = new StringContent(deviceType); + deviceTypeContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/form-data"); + content.Add(deviceTypeContent, "deviceType"); + + httpRequestMessage.Content = content; + using (var response = await httpClient.SendAsync(httpRequestMessage)) + { + response.EnsureSuccessStatusCode(); // 确保请求成功 + var filename = string.Empty; + + if (!response.IsSuccessStatusCode) + return default(T); + + var con = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(con) ?? default(T); ; + } + } + } + + + public static T GetDataFromHttp(string url, object dataObj, string httpMethod, bool isSaveLog = false) + { + Guid guid = Guid.NewGuid(); + var data = JsonConvert.SerializeObject(dataObj); + try + { + if (isSaveLog) + Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}", LogsType.Api); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + request.Method = httpMethod; + request.ContentType = "application/json"; + request.Timeout = 10000; + + if (!string.IsNullOrEmpty(data)) + { + string strContent = data; //参数data + using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream())) + { + dataStream.Write(strContent); + dataStream.Close(); + } + } + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + string encoding = response.ContentEncoding; + if (encoding == null || encoding.Length < 1) + { + encoding = "UTF-8"; //默认编码 + } + StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding)); + string retString = reader.ReadToEnd(); + if (isSaveLog) + Logs.Write($"【{guid}】请求调用接口结束 返回数据为{retString}", LogsType.Api); + return JsonConvert.DeserializeObject(retString); + } + catch (Exception ex) + { + Logs.Write($"【{guid}】请求调用遇到异常 异常信息为{ex.Message}"); + return default(T); + } + } } } diff --git a/WCS.BLL/Tool/Api/ApiModel/queryByBarResponse.cs b/WCS.BLL/Tool/Api/ApiModel/queryByBarResponse.cs new file mode 100644 index 0000000..8cc4316 --- /dev/null +++ b/WCS.BLL/Tool/Api/ApiModel/queryByBarResponse.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WCS.BLL.Tool.Api.ApiModel +{ + public class queryByBarResponse + { + public string materialBar { get; set; } + /// + /// + /// + public string materialCode { get; set; } + /// + /// 有源蜂鸣器 + /// + public string materialName { get; set; } + /// + /// TMB09A03/5X9电压3V + /// + public string materialSpec { get; set; } + + public double materialQty { get; set; } + + public string batchNo { get; set; } + } +} diff --git a/WCS.BLL/Tool/Api/Models/ApiResult.cs b/WCS.BLL/Tool/Api/Models/ApiResult.cs deleted file mode 100644 index 4d2bf95..0000000 --- a/WCS.BLL/Tool/Api/Models/ApiResult.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace WCS.BLL.Tool.Api.Models -{ - public class ApiResult - { - public string Code { get; set; } - public string Message { get; set; } - } - - public class ApiResult : ApiResult - { - public T Data { get; set; } - } -} diff --git a/WCS.BLL/Tool/Logs.cs b/WCS.BLL/Tool/Logs.cs index ce9b424..ec604ac 100644 --- a/WCS.BLL/Tool/Logs.cs +++ b/WCS.BLL/Tool/Logs.cs @@ -33,6 +33,7 @@ namespace WCS.BLL /// 数据库错误 /// DbErr, + Api } /// diff --git a/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs b/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs index 498ec26..fa61891 100644 --- a/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs +++ b/WCS.Model/ApiModel/Stocktaking/GetStockTakingOrdersRequest.cs @@ -7,15 +7,9 @@ namespace WCS.Model.ApiModel.Stocktaking public class GetStockTakingOrdersRequest : PageQueryRequestBase { public string StocktakingOrderNumber { get; set; } + public string StocktakingOrderSource { get; set; } + public string StocktakingOrderType { get; set; } public StocktakingOrderStatus? StocktakingOrderStatus { get; set; } } - - public enum StocktakingOrderStatus - { - 未盘点 = 0, - 部分盘点 = 1, - 盘点完成 = 2, - 已提交 = 3 - } } diff --git a/WCS.Model/ApiModel/Stocktaking/StockTakingOrderModel.cs b/WCS.Model/ApiModel/Stocktaking/StockTakingOrderModel.cs new file mode 100644 index 0000000..a2388c7 --- /dev/null +++ b/WCS.Model/ApiModel/Stocktaking/StockTakingOrderModel.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace WCS.Model.ApiModel.Stocktaking +{ + public class StockTakingOrderModel : INotifyPropertyChanged + { + public int Id { get; set; } + + public string StocktakingOrderNumber { get; set; } + + public StocktakingOrderStatus StocktakingOrderStatus { get; set; } = StocktakingOrderStatus.未盘点; + + public string? StocktakingOrderSource { get; set; } + + public DateTime CreateTime { get; set; } = DateTime.Now; + + public string CreateUser { get; set; } + + public int RowNumber { get; set; } + + public bool IsSelected + { + get { return isSelected; } + set + { + isSelected = value; + OnPropertyChanged(nameof(IsSelected)); + } + } + public bool isSelected; + + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public enum StocktakingOrderStatus + { + 未盘点 = 0, + 部分盘点 = 1, + 盘点完成 = 2, + 已提交 = 3 + } + +} diff --git a/WCS.Model/WebSocketModel/SolveWarningRequesr.cs b/WCS.Model/WebSocketModel/SolveWarningRequesr.cs new file mode 100644 index 0000000..94a718d --- /dev/null +++ b/WCS.Model/WebSocketModel/SolveWarningRequesr.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.WebSocketModel +{ + public class SolveWarningRequest + { + public Guid Guid { get; set; } + public SolveTypeEnum SolveType { get; set; } + } + + public enum SolveTypeEnum + { + 处理 = 0, + 忽略 = 1, + } +} diff --git a/WCS.Model/WebSocketModel/WebSocketMessageModel.cs b/WCS.Model/WebSocketModel/WebSocketMessageModel.cs new file mode 100644 index 0000000..3c88dd6 --- /dev/null +++ b/WCS.Model/WebSocketModel/WebSocketMessageModel.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.WebSocketModel +{ + public class WebSocketMessageModel + { + public bool IsWarning { get; set; } = true; + public Guid Guid { get; set; } = Guid.NewGuid(); + public WarningTypeEnum WarningType { get; set; } + public int StoreId { get; set; } + public string StoreCode { get; set; } + public int ModuleId { get; set; } + public string ModuleCode { get; set; } + public int ShelfId { get; set; } + public string ShelfCode { get; set; } + public string WarningMessage { get; set; } + /// + /// 发送到前端的地址 + /// + public string ClientIp { get; set; } + public DateTime LastSendTime { get; set; } + public bool ClientIsReceived { get; set; } + + //恢复正常需要消除的报警guid + public List SolvedGuids { get; set; } + } + + public enum WarningTypeEnum + { + 进入入库未响应 = 0, + 入库自检丢失 = 1, + 入库自检未扫描上架 = 2, + 入库中异常取出 = 3, + 入库中未扫描上架 = 4, + 退出入库未响应 = 5, + 进入出库未响应 = 6, + 出库自检丢失 = 7, + 出库自检未扫描上架 = 8, + 出库中丢失 = 9, + 出库中未扫描上架 = 10, + 退出出库未响应 = 11, + 恢复正常 = 50, + 通知刷新出库 = 51, + } +} diff --git a/WCS.WebApi/Controllers/HomeController.cs b/WCS.WebApi/Controllers/HomeController.cs index ff9b24a..8a15a64 100644 --- a/WCS.WebApi/Controllers/HomeController.cs +++ b/WCS.WebApi/Controllers/HomeController.cs @@ -77,7 +77,7 @@ namespace WCS.WebApi.Controllers { ShelfId = t.ShelfId, ShelfCode = t.ShelfCode, - CurentMode = (int)t.CurentMode, + CurentMode = (int)t.CurrentMode, ModulesStr = t.ModulesStr, GroupName = t.GroupName }).ToList(), diff --git a/WCS.WebApi/Controllers/OutstoreController.cs b/WCS.WebApi/Controllers/OutstoreController.cs index d99a880..3b7064d 100644 --- a/WCS.WebApi/Controllers/OutstoreController.cs +++ b/WCS.WebApi/Controllers/OutstoreController.cs @@ -178,7 +178,7 @@ namespace WebApi.Controllers return new ResponseBase() { Code = 300, - Message = "ѯʧܣ" + ex.Message, + Message = "ģʽʧܣ" + ex.Message, }; } } diff --git a/WCS.WebApi/Controllers/WarningController.cs b/WCS.WebApi/Controllers/WarningController.cs new file mode 100644 index 0000000..5392169 --- /dev/null +++ b/WCS.WebApi/Controllers/WarningController.cs @@ -0,0 +1,31 @@ +using Microsoft.AspNetCore.Mvc; +using WCS.BLL.Services.IService; +using WCS.Model; +using WCS.Model.ApiModel; +using WCS.Model.ApiModel.User; +using WCS.Model.WebSocketModel; + +namespace WCS.WebApi.Controllers +{ + /// + /// 权限/用户界面的接口 + /// + [ApiController] + [Route("[controller]")] + public class WarningController : ControllerBase + { + public IWarningService _warningService { get; set; } + + public WarningController(IWarningService warningService) + { + _warningService = warningService; + } + + [Route("solveWarning")] + [HttpPost(Name = "solveWarning")] + public async Task SolveWarning(SolveWarningRequest request) + { + return await _warningService.SolveWarning(request); + } + } +} diff --git a/WCS.WebApi/Program.cs b/WCS.WebApi/Program.cs index d892f1e..284c239 100644 --- a/WCS.WebApi/Program.cs +++ b/WCS.WebApi/Program.cs @@ -21,34 +21,22 @@ namespace WebApi { WebSoceketManager.InitWebSocket(); - //LocalStatic.wCSTcpCleint = new WCS.BLL.TCPClient("127.0.0.1:20002"); - //LocalStatic.wCSTcpCleint.Send(new byte[] { 0x08, 0x00, 0x00, 0x11, 0x12, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); DbInit.InitDb(); LocalFile.SaveConfig(); - ShelfManager.InitShelves(); - TCPClientManager.InitTcpClient(); + ShelfManager.InitShelves(); + //λƺͰ + TCPClientManager.InitStatus(); - var builder = WebApplication.CreateBuilder(args); - //// Kestrel - //builder.WebHost.ConfigureKestrel((context, options) => - //{ - // // ü˿ - // options.Listen(IPAddress.Any, 8888); // IPַ5001˿ + WarningManager.StartWarningMessageThread(); - // // - // options.Limits.MaxRequestBodySize = 10 * 1024 * 1024; // СΪ10MB - // options.Limits.MaxConcurrentConnections = 1000; // 󲢷 - // options.Limits.MinRequestBodyDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10)); // Сݴ + var builder = WebApplication.CreateBuilder(args); - // // ҪSSL/TLSӴ - // // : options.Listen(IPAddress.Any, 5000, listenOptions => { listenOptions.UseHttps("path_to_certificate.pfx", "certificate_password"); }); - //}); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle @@ -65,6 +53,7 @@ namespace WebApi builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); //롢ɵõģʽ builder.Services.AddSingleton(); diff --git a/货架标准上位机/ViewModels/MainViewModel.cs b/货架标准上位机/ViewModels/MainViewModel.cs index dae0781..934852c 100644 --- a/货架标准上位机/ViewModels/MainViewModel.cs +++ b/货架标准上位机/ViewModels/MainViewModel.cs @@ -37,6 +37,16 @@ namespace 货架标准上位机.ViewModel } } + private bool goToStockTakingView; + public bool GoToStockTakingView + { + get { return goToStockTakingView; } + set + { + SetProperty(ref goToStockTakingView, value); + } + } + #region 专用_MainWindow2 //隐藏式选项卡的高度 diff --git a/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs b/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs index b9c6c8a..8d133b6 100644 --- a/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs +++ b/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs @@ -290,7 +290,7 @@ namespace 货架标准上位机.ViewModel UserName = LocalStatic.CurrentUser, DeviceType = LocalFile.Config.DeviceType, - PageNumber = CurrentPage, + PageNumber = 1, PageSize = 10000, }; var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "matInventoryDetail/getMatInventoryDetail", body, "POST"); diff --git a/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs index 905694e..2a904f6 100644 --- a/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs @@ -266,6 +266,7 @@ namespace 货架标准上位机.ViewModels if (DataGridItemSource == null) { Growl.Warning("未勾选数据!"); + return; } //判断是否勾选数据 var selectedOutOrder = DataGridItemSource.Where(t => t.IsSelected) @@ -273,6 +274,7 @@ namespace 货架标准上位机.ViewModels if (selectedOutOrder == null) { Growl.Warning("未勾选数据!"); + return; } #region 调用接口开始出库 @@ -288,6 +290,9 @@ namespace 货架标准上位机.ViewModels { //成功后直接跳转 MainWindow1.viewModel.GoToOutVentoryView = true; + //刷新出库单列表 + OutVentoryView.viewModel.RefreshOutOrderList(selectedOutOrder.OrderNumber); + Growl.Success("已跳转到物料出库页面!"); } else if (Result != null) diff --git a/货架标准上位机/ViewModels/OutInventoryViewModel.cs b/货架标准上位机/ViewModels/OutInventoryViewModel.cs index d34d490..be92593 100644 --- a/货架标准上位机/ViewModels/OutInventoryViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryViewModel.cs @@ -31,27 +31,6 @@ namespace 货架标准上位机.ViewModel { public OutInventoryViewModel() { - //线程 更新当前选择的订单的状态 - //Task.Run(() => - //{ - // while (true) - // { - // try - // { - // Thread.Sleep(1000); - // //if (LocalStatic.IsRefreshOrderDetail) - // //{ - // // LocalStatic.IsRefreshOrderDetail = false; - // // SelectedPickBillNumberChanged(); - // //} - // } - // catch - // { - // //Logs.Write("更新订单状态异常!!"); - // } - // } - //}); - RefreshOutOrderList(); } @@ -242,7 +221,7 @@ namespace 货架标准上位机.ViewModel } } - public void RefreshOutOrderList() + public void RefreshOutOrderList(string OrderNumber = "") { #region 调用接口获取发料单 try @@ -255,6 +234,10 @@ namespace 货架标准上位机.ViewModel if (Result != null && Result.Code == 200) { OutOrderList = new ObservableCollection(Result.Data.Lists); + if (!string.IsNullOrEmpty(OrderNumber)) + { + SelectedOutOrder = OutOrderList.Where(t => t.OrderNumber == OrderNumber).FirstOrDefault(); + } } else if (Result != null && !string.IsNullOrEmpty(Result.Message)) { diff --git a/货架标准上位机/ViewModels/StocktakingDocumentViewModel.cs b/货架标准上位机/ViewModels/StocktakingDocumentViewModel.cs new file mode 100644 index 0000000..e79dbeb --- /dev/null +++ b/货架标准上位机/ViewModels/StocktakingDocumentViewModel.cs @@ -0,0 +1,384 @@ +using HandyControl.Controls; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using WCS.Model; +using WCS.Model.ApiModel.MatBaseInfo; +using WCS.Model.ApiModel.OutStore; +using WCS.Model.ApiModel.Stocktaking; +using 货架标准上位机.Api; + +namespace 货架标准上位机.ViewModels +{ + public class StocktakingDocumentViewModel : BindableBase + { + public StocktakingDocumentViewModel() + { + BtnSearch(); + } + + #region Properties界面绑定的实体 + private ObservableCollection dataGridItemSource; + public ObservableCollection DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + } + } + + public StockTakingOrderModel selectedataGridItem; + public StockTakingOrderModel SelectedataGridItem + { + get { return selectedataGridItem; } + set + { + SetProperty(ref selectedataGridItem, value); + } + } + + private string orderNumber; + public string OrderNumber + { + get { return orderNumber; } + set + { + SetProperty(ref orderNumber, value); + } + } + + private string orderType; + public string OrderType + { + get { return orderType; } + set + { + SetProperty(ref orderType, value); + } + } + + private string orderSource; + public string OrderSource + { + get { return orderSource; } + set + { + SetProperty(ref orderSource, value); + } + } + + #endregion + + #region Command + public ICommand BtnSearchCommand { get => new DelegateCommand(BtnSearchReset); } + public void BtnSearchReset() + { + BtnSearch(true); + } + public void BtnSearch(bool IsPageReset = true) + { + if (CurrentPage == 0 || IsPageReset) + { + CurrentPage = 1; + return; + } + + #region 调用接口获取数据 + try + { + var body = new GetStockTakingOrdersRequest() + { + StocktakingOrderNumber = OrderNumber, + StocktakingOrderType = OrderType, + StocktakingOrderSource = OrderSource, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + PageNumber = CurrentPage, + PageSize = 10, + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "stockTaking/getStockTakingOrders", body, "POST"); + if (Result != null && Result.Data != null && Result.Data.Lists != null) + { + DataGridItemSource = new ObservableCollection(Result.Data.Lists); + MaxPage = Result.Data.MaxPage; + TotalCount = Result.Data.TotalCount; + } + } + catch (Exception ex) + { + Growl.Error("加载数据失败:" + ex.Message); + } + finally + { + } + #endregion + } + + public ICommand BtnResetCommand { get => new DelegateCommand(BtnReset); } + public void BtnReset() + { + OrderNumber = string.Empty; + OrderType = string.Empty; + OrderSource = string.Empty; + } + + //public ICommand BtnDeleteCommand { get => new DelegateCommand(BtnDelete); } + //public void BtnDelete() + //{ + + //} + + public ICommand BtnOrderDetailCommand { get => new DelegateCommand(BtnOrderDetail); } + public void BtnOrderDetail() + { + try + { + if (DataGridItemSource == null) + { + Growl.Warning("未勾选数据!"); + } + + //判断是否勾选数据 + var selectedOutOrder = DataGridItemSource.Where(t => t.IsSelected) + .FirstOrDefault(); + if (selectedOutOrder == null) + { + Growl.Warning("未勾选数据!"); + } + + #region 调用接口获取数据 + + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.StocktakingOrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + + }; + var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "outStore/getOutOrderDetail", body, "POST"); + if (Result != null && Result.Code == 200) + { + if (Result.Data.Count > 0) + { + //打开窗体 + var window = new OutInventoryDocumentDetailView(Result.Data); + window.Owner = Application.Current.MainWindow; + window.ShowDialog(); + } + else + { + Growl.Warning("该单据没有单据明细!"); + } + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + + } + + public ICommand BtnOrderMatDetailCommand { get => new DelegateCommand(BtnOrderMatDetail); } + public void BtnOrderMatDetail() + { + try + { + if (DataGridItemSource == null) + { + Growl.Warning("未勾选数据!"); + } + + //判断是否勾选数据 + var selectedOutOrder = DataGridItemSource.Where(t => t.IsSelected) + .FirstOrDefault(); + if (selectedOutOrder == null) + { + Growl.Warning("未勾选数据!"); + } + #region 调用接口获取数据 + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.StocktakingOrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + + }; + var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "outStore/getOutOrderMatDetail", body, "POST"); + if (Result != null && Result.Code == 200) + { + if (Result.Data.Count > 0) + { + //打开窗体 + var window = new OutInventoryDocumentMatDetailView(Result.Data); + window.Owner = Application.Current.MainWindow; + window.ShowDialog(); + } + else + { + Growl.Warning("该单据没有发料明细!"); + } + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + } + + //开始入库 如果成功就直接跳转出库界面 + public ICommand BtnStartCommand { get => new DelegateCommand(BtnStart); } + public void BtnStart() + { + WarningManager.AddWarning(new WCS.Model.WebSocketModel.WebSocketMessageModel()); + //try + //{ + // if (DataGridItemSource == null) + // { + // Growl.Warning("未勾选数据!"); + // return; + // } + // //判断是否勾选数据 + // var selectedOutOrder = DataGridItemSource.Where(t => t.IsSelected) + // .FirstOrDefault(); + // if (selectedOutOrder == null) + // { + // Growl.Warning("未勾选数据!"); + // return; + // } + + // #region 调用接口开始盘点 + // var body = new GetOutOrderDetailRequest() + // { + // OrderId = selectedOutOrder.Id, + // OrderNumber = selectedOutOrder.StocktakingOrderNumber, + // UserName = LocalStatic.CurrentUser, + // DeviceType = LocalFile.Config.DeviceType, + // }; + // var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outStore/goInOutstore", body, "POST"); + // if (Result != null && Result.Code == 200) + // { + // //成功后直接跳转 + // MainWindow1.viewModel.GoToOutVentoryView = true; + // Growl.Success("已跳转到物料出库页面!"); + // } + // else if (Result != null) + // { + // Growl.Warning(Result.Message); + // } + // else + // { + // Growl.Warning("调用接口失败!"); + // } + // #endregion + //} + //catch (Exception ex) + //{ + // Growl.Error("出现异常:" + ex.Message); + //} + //finally + //{ + //} + } + + public ICommand BtnPauseCommand { get => new DelegateCommand(BtnPause); } + public void BtnPause() + { + WarningManager.RemoveWarning(Guid.NewGuid()); + } + #endregion + + #region PageOperation 分页操作 + private int currentPage; + public int CurrentPage + { + get { return currentPage; } + set + { + SetProperty(ref currentPage, value); + BtnSearch(false); + } + } + + private int maxPage; + public int MaxPage + { + get { return maxPage; } + set { SetProperty(ref maxPage, value); } + } + + //总数量 + private int totalCount; + public int TotalCount + { + get { return totalCount; } + set { SetProperty(ref totalCount, value); } + } + + public ICommand BtnFirstPageCommand { get => new DelegateCommand(BtnFirstPage); } + public void BtnFirstPage() + { + CurrentPage = 1; + } + + public ICommand BtnPrePageCommand { get => new DelegateCommand(BtnPrePage); } + public void BtnPrePage() + { + if (CurrentPage > 1) + { + CurrentPage--; + } + } + + public ICommand BtnNextPageCommand { get => new DelegateCommand(BtnNextPage); } + public void BtnNextPage() + { + if (CurrentPage < MaxPage) + { + CurrentPage++; + } + } + + public ICommand BtnLastPageCommand { get => new DelegateCommand(BtnLastPage); } + public void BtnLastPage() + { + if (CurrentPage != MaxPage) + { + CurrentPage = MaxPage; + } + } + #endregion + } +} diff --git a/货架标准上位机/Views/InInventoryView.xaml b/货架标准上位机/Views/InInventoryView.xaml index 0f89dcd..6f5e9c6 100644 --- a/货架标准上位机/Views/InInventoryView.xaml +++ b/货架标准上位机/Views/InInventoryView.xaml @@ -50,10 +50,10 @@ - + - + diff --git a/货架标准上位机/Views/MainWindows/MainWindow1.xaml b/货架标准上位机/Views/MainWindows/MainWindow1.xaml index 4fcc4e9..3c8db79 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow1.xaml +++ b/货架标准上位机/Views/MainWindows/MainWindow1.xaml @@ -123,6 +123,18 @@ + + + + 盘点单据 + + + + + + + + diff --git a/货架标准上位机/Views/OutInventoryDocumentView.xaml b/货架标准上位机/Views/OutInventoryDocumentView.xaml index 3f87a9c..a865303 100644 --- a/货架标准上位机/Views/OutInventoryDocumentView.xaml +++ b/货架标准上位机/Views/OutInventoryDocumentView.xaml @@ -14,7 +14,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/货架标准上位机/Views/OutInventoryView.xaml b/货架标准上位机/Views/OutInventoryView.xaml index 44a8ea6..842afad 100644 --- a/货架标准上位机/Views/OutInventoryView.xaml +++ b/货架标准上位机/Views/OutInventoryView.xaml @@ -88,7 +88,7 @@ - + diff --git a/货架标准上位机/Views/OutInventoryView.xaml.cs b/货架标准上位机/Views/OutInventoryView.xaml.cs index 14c57c3..8a85ba9 100644 --- a/货架标准上位机/Views/OutInventoryView.xaml.cs +++ b/货架标准上位机/Views/OutInventoryView.xaml.cs @@ -60,5 +60,10 @@ namespace 货架标准上位机 parent.RaiseEvent(eventArg); } } + + private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) + { + viewModel.RefreshOutOrderList(viewModel.SelectedOutOrderNumber); + } } } diff --git a/货架标准上位机/Views/StocktakingDocumentView.xaml b/货架标准上位机/Views/StocktakingDocumentView.xaml new file mode 100644 index 0000000..789a28b --- /dev/null +++ b/货架标准上位机/Views/StocktakingDocumentView.xaml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +