From 649e22b4ce9323f9fd6837c9d580ffe93786dd38 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Fri, 17 May 2024 15:12:07 +0800 Subject: [PATCH 01/18] =?UTF-8?q?1.WebSocket=E7=99=BB=E5=BD=95=E6=B3=A8?= =?UTF-8?q?=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2.数据重发机制 --- WCS.BLL/HardWare/IShelfBase.cs | 2 + WCS.BLL/HardWare/SingleLightShelf.cs | 1 + WCS.BLL/HardWare/SmartShelf.cs | 46 ++--- WCS.BLL/Manager/DbInit.cs | 5 + WCS.BLL/Manager/ShelfManager.cs | 4 + WCS.BLL/Manager/TCPClientManager.cs | 171 +++++++++--------- WCS.BLL/Manager/WebSoceketManager.cs | 6 +- WCS.BLL/Services/Service/UserService.cs | 13 +- WCS.BLL/Tool/Logs.cs | 23 +-- WCS.BLL/Tool/TCPClient.cs | 37 ++-- WCS.Model/ApiModel/User/UserLoginRequest.cs | 4 + WCS.WebApi/Controllers/UserController.cs | 2 + WCS.WebApi/Program.cs | 10 +- .../ViewModels/InInventoryViewModel.cs | 28 +++ .../Views/MainWindows/MainWindow1.xaml | 4 +- .../Views/Windows/UserLoginView.xaml.cs | 1 + 货架标准上位机/data/jsconfig.json | 6 +- 17 files changed, 200 insertions(+), 163 deletions(-) diff --git a/WCS.BLL/HardWare/IShelfBase.cs b/WCS.BLL/HardWare/IShelfBase.cs index c346d22..bd3b7e3 100644 --- a/WCS.BLL/HardWare/IShelfBase.cs +++ b/WCS.BLL/HardWare/IShelfBase.cs @@ -57,6 +57,8 @@ namespace WCS.BLL.HardWare /// 货架组别 /// public string GroupName { get; set; } + + public string WebSocketIpAddress { get; set; } /// /// 模组 /// diff --git a/WCS.BLL/HardWare/SingleLightShelf.cs b/WCS.BLL/HardWare/SingleLightShelf.cs index e09ab83..5a68716 100644 --- a/WCS.BLL/HardWare/SingleLightShelf.cs +++ b/WCS.BLL/HardWare/SingleLightShelf.cs @@ -25,6 +25,7 @@ namespace WCS.BLL.HardWare 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 string WebSocketIpAddress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public bool ConfirmStocktakingSingle(int BoardId, int LightNumber) { diff --git a/WCS.BLL/HardWare/SmartShelf.cs b/WCS.BLL/HardWare/SmartShelf.cs index 638efec..03ae84f 100644 --- a/WCS.BLL/HardWare/SmartShelf.cs +++ b/WCS.BLL/HardWare/SmartShelf.cs @@ -104,6 +104,9 @@ namespace WCS.BLL.HardWare public List ModuleIds { get; set; } public string ClientIp { get; set; } + //websocket通知的前端的IP地址 + public string WebSocketIpAddress { get; set; } = "127.0.0.2"; + #region 协议处理 public void GoInInstore(string? IPAddress) { @@ -186,7 +189,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); @@ -267,13 +270,13 @@ namespace WCS.BLL.HardWare var warningModel = new WebSocketMessageModel() { IsWarning = true, - WarningType = WarningTypeEnum.进入入库未响应, + WarningType = WarningTypeEnum.退出入库未响应, StoreId = 0, StoreCode = "", ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } @@ -354,7 +357,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } @@ -411,7 +414,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } @@ -503,7 +506,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } @@ -536,7 +539,7 @@ namespace WCS.BLL.HardWare var messageMode = new WebSocketMessageModel() { IsWarning = false, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, WarningType = WarningTypeEnum.通知刷新盘点 }; WarningManager.SendWarning(messageMode); @@ -590,7 +593,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); } @@ -797,7 +800,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -831,7 +834,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -916,7 +919,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!", - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); @@ -1051,7 +1054,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, SolvedGuids = warnings.Select(t => t.Guid).ToList(), }; WarningManager.SendWarning(warningModel); @@ -1079,7 +1082,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); @@ -1096,7 +1099,6 @@ namespace WCS.BLL.HardWare { Logs.Write("协议处理5.4"); var exceptionMessage = storeInfo.StoreCode + "物料被取出!"; - //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); var warningModel = new WebSocketMessageModel() { WarningType = WarningTypeEnum.入库中异常取出, @@ -1107,7 +1109,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); @@ -1213,7 +1215,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -1247,7 +1249,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); #endregion @@ -1402,7 +1404,7 @@ namespace WCS.BLL.HardWare var messageMode = new WebSocketMessageModel() { IsWarning = false, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, WarningType = WarningTypeEnum.通知刷新出库 }; WarningManager.SendWarning(messageMode); @@ -1625,7 +1627,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1", + ClientIp = WebSocketIpAddress, SolvedGuids = warnings.Select(t => t.Guid).ToList(), }; WarningManager.SendWarning(warningModel); @@ -1640,7 +1642,6 @@ namespace WCS.BLL.HardWare case 0x01: { var exceptionMessage = storeInfo.StoreCode + "出库过程中存在物料上架!"; - //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); var warningModel = new WebSocketMessageModel() { WarningType = WarningTypeEnum.出库中未扫描上架, @@ -1651,7 +1652,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress, }; WarningManager.SendWarning(warningModel); @@ -1666,7 +1667,6 @@ namespace WCS.BLL.HardWare case 0x02: { var exceptionMessage = storeInfo.StoreCode + "物料被取出!"; - //WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); var warningModel = new WebSocketMessageModel() { WarningType = WarningTypeEnum.出库中丢失, @@ -1677,7 +1677,7 @@ namespace WCS.BLL.HardWare ShelfCode = ShelfCode, ShelfId = ShelfId, WarningMessage = exceptionMessage, - ClientIp = "127.0.0.1" + ClientIp = WebSocketIpAddress }; WarningManager.SendWarning(warningModel); diff --git a/WCS.BLL/Manager/DbInit.cs b/WCS.BLL/Manager/DbInit.cs index a790d46..981e4f2 100644 --- a/WCS.BLL/Manager/DbInit.cs +++ b/WCS.BLL/Manager/DbInit.cs @@ -14,6 +14,9 @@ namespace WCS.BLL.Manager { public static void InitDb() { + Logs.Write("【初始化数据库】开始", LogsType.StartBoot); + DbHelp.db.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) @@ -43,6 +46,8 @@ namespace WCS.BLL.Manager DbHelp.db.Insertable(outDocumentSerialNumber).ExecuteCommand(); DbHelp.db.Insertable(stockTakingDocumentSerialNumber).ExecuteCommand(); } + + Logs.Write("【初始化数据库】结束", LogsType.StartBoot); } } } diff --git a/WCS.BLL/Manager/ShelfManager.cs b/WCS.BLL/Manager/ShelfManager.cs index 1126322..20a1c35 100644 --- a/WCS.BLL/Manager/ShelfManager.cs +++ b/WCS.BLL/Manager/ShelfManager.cs @@ -20,11 +20,15 @@ namespace WCS.BLL.Manager public static void InitShelves() { + Logs.Write("【InitShelves】开始", LogsType.StartBoot); + var shelvesInDb = DbHelp.db.Queryable().ToList(); foreach (var shelfInDb in shelvesInDb) { Shelves.Add(InitShelf(shelfInDb)); } + + Logs.Write("【InitShelves】结束", LogsType.StartBoot); } public static IShelfBase InitShelf(ShelfInfo shelfInDb) diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs index 1c6b76b..bb1a209 100644 --- a/WCS.BLL/Manager/TCPClientManager.cs +++ b/WCS.BLL/Manager/TCPClientManager.cs @@ -21,107 +21,97 @@ namespace WCS.BLL.Manager public static List TCPClients = new List(); public static void InitTcpClient() { + Logs.Write("【InitTcpClient】开始", LogsType.StartBoot); + var ips = DbHelp.db.Queryable() - //.Where(t => t.ShelfCode.Contains("C")) .Select(t => t.ClientIp) .Distinct() .ToList(); foreach (var ip in ips) { - var tcpCleint = new TCPClient(ip, ""); - //配置断线重连 - tcpCleint.tcpClient.Received += (client, e) => + Task.Run(() => { - var clientIpHost = client.IP + ":" + client.Port; - var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); - if (TcpCleint == null) + var tcpCleint = new TCPClient(ip, ""); + //配置断线重连 + tcpCleint.tcpClient.Received += (client, e) => { - //TO DO - return EasyTask.CompletedTask; - } - - var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); - e.ByteBlock.Clear(); - var len = data.Length; - for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++) - { - //协议拆包 通过前缀校验是否为完整数据包 - var prefixInData = data.Skip(index).Take(TcpCleint.PreFixLength); - var isEqual = prefixInData.SequenceEqual(TcpCleint.Prefix); - if (isEqual) + var clientIpHost = client.IP + ":" + client.Port; + var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); + if (TcpCleint == null) { - Logs.Write("协议处理1!"); - var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray(); - if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度 - { - continue; - } - index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1 - //获取板子ID - var boardId = (dataTemp[TcpCleint.PreFixLength + 0] << 8) + dataTemp[TcpCleint.PreFixLength + 1]; - var lightNumber = Convert.ToInt32(dataTemp[TcpCleint.PreFixLength + 3]); - - Logs.Write("协议处理2!"); - //报警灯 - if (dataTemp[TcpCleint.PreFixLength + 2] == 0x20) - { - var shelf = ShelfManager.Shelves.Where(t => t.ClientIp == clientIpHost) - .Where(t => t.LightId == boardId) - .FirstOrDefault(); - var smartShelf = shelf as SmartShelf; - smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); - } - //!= 0x20 货架类型协议返回 - else - { - Logs.Write("协议处理3!"); - var shelf = ShelfManager.Shelves - .Where(t => t.ClientIp == clientIpHost) - .Where(t => t.ModuleIds.Contains(boardId)) - .FirstOrDefault(); - var smartShelf = shelf as SmartShelf; - smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); - - } - - //协议处理 判断功能位 - //switch (dataTemp[TcpCleint.PreFixLength + 2]) - //{ - // case 0x20://进入入库模式信号 - // //GoInInstoreProcess(dataTemp, boardId, lightNumber); - // break; - // case 0x03://正常入库信号 - // //InStoreReturnProcess(dataTemp); - // break; - // default: - // ; - // break; - //} + return EasyTask.CompletedTask; } - } - Logs.Write("协议处理完毕!"); - return EasyTask.CompletedTask; - }; - //配置首次连接后复位操作 - tcpCleint.tcpClient.Connected += (client, e) => - { - var clientIpHost = client.IP + ":" + client.Port; - var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); - if (TcpCleint == null) - { - return EasyTask.CompletedTask; - } - //首次连接 - if (TcpCleint.IsFirstConnected == false) - { - InitStatus(TcpCleint); - TcpCleint.IsFirstConnected = true; - } - return EasyTask.CompletedTask; - }; - TCPClients.Add(tcpCleint); - tcpCleint.Connect(); + var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); + e.ByteBlock.Clear(); + var len = data.Length; + for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++) + { + //协议拆包 通过前缀校验是否为完整数据包 + var prefixInData = data.Skip(index).Take(TcpCleint.PreFixLength); + var isEqual = prefixInData.SequenceEqual(TcpCleint.Prefix); + if (isEqual) + { + Logs.Write("协议处理1!"); + var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray(); + if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度 + { + continue; + } + index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1 + //获取板子ID + var boardId = (dataTemp[TcpCleint.PreFixLength + 0] << 8) + dataTemp[TcpCleint.PreFixLength + 1]; + var lightNumber = Convert.ToInt32(dataTemp[TcpCleint.PreFixLength + 3]); + + Logs.Write("协议处理2!"); + //报警灯 + if (dataTemp[TcpCleint.PreFixLength + 2] == 0x20) + { + var shelf = ShelfManager.Shelves.Where(t => t.ClientIp == clientIpHost) + .Where(t => t.LightId == boardId) + .FirstOrDefault(); + var smartShelf = shelf as SmartShelf; + smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); + } + //!= 0x20 货架类型协议返回 + else + { + Logs.Write("协议处理3!"); + var shelf = ShelfManager.Shelves + .Where(t => t.ClientIp == clientIpHost) + .Where(t => t.ModuleIds.Contains(boardId)) + .FirstOrDefault(); + var smartShelf = shelf as SmartShelf; + smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); + + } + } + } + Logs.Write("协议处理完毕!"); + return EasyTask.CompletedTask; + }; + //配置首次连接后复位操作 + tcpCleint.tcpClient.Connected += (client, e) => + { + var clientIpHost = client.IP + ":" + client.Port; + var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); + if (TcpCleint == null) + { + return EasyTask.CompletedTask; + } + //首次连接 + if (TcpCleint.IsFirstConnected == false) + { + Logs.Write($"【InitTcpClient】{clientIpHost}完成首次连接", LogsType.StartBoot); + InitStatus(TcpCleint); + TcpCleint.IsFirstConnected = true; + } + return EasyTask.CompletedTask; + }; + + TCPClients.Add(tcpCleint); + tcpCleint.Connect(); + }); } //启动线程监听所有TCP是否已经完成首次连接 @@ -145,6 +135,7 @@ namespace WCS.BLL.Manager } } }); + Logs.Write("【InitTcpClient】完成后台继续连接", LogsType.StartBoot); } //后台启动时给所有板子、警示灯发送复位操作 保持状态一致 diff --git a/WCS.BLL/Manager/WebSoceketManager.cs b/WCS.BLL/Manager/WebSoceketManager.cs index 2256bd8..531dbb4 100644 --- a/WCS.BLL/Manager/WebSoceketManager.cs +++ b/WCS.BLL/Manager/WebSoceketManager.cs @@ -16,6 +16,7 @@ namespace WCS.BLL.Manager public static object flag = new object(); public static void InitWebSocket() { + Logs.Write("【启动WebSocket】开始", LogsType.StartBoot); service = new HttpService(); service.Setup(new TouchSocketConfig()//加载配置 .SetListenIPHosts(7789) @@ -32,9 +33,10 @@ namespace WCS.BLL.Manager })); service.Start(); - service.Logger.Info("服务器已启动"); + Logs.Write("【启动WebSocket】结束", LogsType.StartBoot); } - //尝试发送报警信息给前端 + + //发送报警信息给前端 public static void TrySendMessage(string IpAddress, string Message) { try diff --git a/WCS.BLL/Services/Service/UserService.cs b/WCS.BLL/Services/Service/UserService.cs index 8fa5916..8f705c8 100644 --- a/WCS.BLL/Services/Service/UserService.cs +++ b/WCS.BLL/Services/Service/UserService.cs @@ -5,6 +5,7 @@ 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; @@ -440,13 +441,23 @@ namespace WCS.BLL.Services.Service //返回字串不返回密码 user.Password = "***"; - var response = new ResponseCommon() { Code = 200, Message = "success", Data = user }; + //登录成功 + if (request.DeviceType == "WCS前端" && request.GroupNames != null) + { + var shelves = ShelfManager.Shelves.Where(t => request.GroupNames.Contains(t.GroupName)) + .ToList(); + foreach (var shelf in shelves) + { + shelf.WebSocketIpAddress = request.WebSocketIpAddress; + } + } + return response; } catch (Exception ex) diff --git a/WCS.BLL/Tool/Logs.cs b/WCS.BLL/Tool/Logs.cs index ec604ac..c450c40 100644 --- a/WCS.BLL/Tool/Logs.cs +++ b/WCS.BLL/Tool/Logs.cs @@ -22,17 +22,10 @@ namespace WCS.BLL /// Info, /// - /// 警告 + /// 启动信息 /// - Warning, - /// - /// 错误 - /// - Err, - /// - /// 数据库错误 - /// - DbErr, + StartBoot, + Api } @@ -115,16 +108,6 @@ namespace WCS.BLL Write($"{contentTitle} {JsonConvert.SerializeObject(content)}", type); } - /// - /// 写入日志 - /// - /// 错误 - /// 是否写入成功 - public static void Write(Exception ex, LogsType type = LogsType.Err) - { - Write(ex.ToString(), type); - } - /// /// 清除日志 /// diff --git a/WCS.BLL/Tool/TCPClient.cs b/WCS.BLL/Tool/TCPClient.cs index ee74e07..c5dd9aa 100644 --- a/WCS.BLL/Tool/TCPClient.cs +++ b/WCS.BLL/Tool/TCPClient.cs @@ -94,7 +94,7 @@ namespace WCS.BLL continue; } //获取返回指令的板子ID - var boardId = (data[PreFixLength + 0] << 8) + data[PreFixLength + 1]; + var boardId = (dataTemp[PreFixLength + 0] << 8) + dataTemp[PreFixLength + 1]; //查询当前板子是否有待验证的指令 var message = new MessageDto(); MessageList.TryGetValue(boardId, out message); @@ -103,7 +103,7 @@ namespace WCS.BLL { MessageList.TryRemove(boardId, out message); } - index += (PreFixLength + DataLength - 1);//每次循环index会+1 所以这里-1 + index += (PreFixLength + DataLength - 2);//每次循环index会+1 所以这里-1 } } Logs.Write($"校验发送接收处理完毕" + BitConverter.ToString(data)); @@ -131,24 +131,21 @@ namespace WCS.BLL try { //TODO如果指令已发两次 则取消重发 - Console.WriteLine(Thread.CurrentThread.ManagedThreadId); await Task.Delay(100); if (MessageList.Count > 0) { - var failedMessage = MessageList.Where(t => t.Value.SendTimes >= 2).ToList(); + var failedMessage = MessageList.Where(t => t.Value.LastSendTime < DateTime.Now.AddSeconds(-1)) + .ToList(); foreach (var message in failedMessage) { - Logs.Write(BitConverter.ToString(message.Value.Message) + - "指令未响应"); + Logs.Write(BitConverter.ToString(message.Value.Message) + "指令超时1s未响应"); } - MessageList.RemoveWhen(t => t.Value.SendTimes >= 3); - - Console.WriteLine(Thread.CurrentThread.ManagedThreadId); + MessageList.RemoveWhen(t => t.Value.SendTimes >= 2); foreach (var item in MessageList) { if (item.Value.LastSendTime < DateTime.Now.AddSeconds(-1)) { - tcpClient.Send(item.Value.Message); + Send(item.Value.Message); item.Value.SendTimes++; item.Value.LastSendTime = DateTime.Now; await Task.Delay(10); @@ -173,17 +170,25 @@ namespace WCS.BLL } - public void Send(byte[] message) + public void Send(byte[] message, bool IsReSend = false) { try { var boardId = (message[3] << 8) + message[4]; + if (boardId != 2047 && IsReSend == false) + { + MessageList.TryAdd(boardId, new MessageDto() + { + ID = boardId, + Message = message, + }); + } + lock (sendLockObject) { tcpClient.Send(message); - //TODO MessageList.AddOrUpdate(new Mes) - //发送自带10ms间隔 - Thread.Sleep(10); + //发送自带8ms间隔 + Thread.Sleep(8); } } catch (Exception ex) @@ -226,18 +231,14 @@ namespace WCS.BLL public class MessageDto { public int ID { get; set; } - /// /// 最后一次发送时间 /// public DateTime LastSendTime { get; set; } = DateTime.Now; - /// /// 发送内容 /// public byte[] Message { get; set; } - - public bool IsWating { get; set; } /// /// 发送次数 /// diff --git a/WCS.Model/ApiModel/User/UserLoginRequest.cs b/WCS.Model/ApiModel/User/UserLoginRequest.cs index f1b9c28..a3ee97f 100644 --- a/WCS.Model/ApiModel/User/UserLoginRequest.cs +++ b/WCS.Model/ApiModel/User/UserLoginRequest.cs @@ -14,5 +14,9 @@ namespace WCS.Model.ApiModel.User /// 是否配置为不登陆(如果不登陆 直接获取admin 且不验证密码了) /// public bool IsNoLogin { get; set; } = false; + + public string WebSocketIpAddress { get; set; } = string.Empty; + + public List GroupNames { get; set; } } } diff --git a/WCS.WebApi/Controllers/UserController.cs b/WCS.WebApi/Controllers/UserController.cs index bc70c55..2cc712b 100644 --- a/WCS.WebApi/Controllers/UserController.cs +++ b/WCS.WebApi/Controllers/UserController.cs @@ -52,6 +52,8 @@ namespace WCS.WebApi.Controllers [HttpPost(Name = "userLogin")] public async Task userLogin(UserLoginRequest request) { + //获取调用设备的Ip地址 + request.WebSocketIpAddress = HttpContext?.Connection?.RemoteIpAddress?.ToString(); return await _userService.UserLogin(request); } } diff --git a/WCS.WebApi/Program.cs b/WCS.WebApi/Program.cs index fefaf41..a9af159 100644 --- a/WCS.WebApi/Program.cs +++ b/WCS.WebApi/Program.cs @@ -20,19 +20,21 @@ namespace WebApi { public static void Main(string[] args) { - + //ʼwebsocket WebSoceketManager.InitWebSocket(); + //ʼݿ DbInit.InitDb(); + //ʼļ LocalFile.SaveConfig(); + //ʼTCP TCPClientManager.InitTcpClient(); + //ʼ ShelfManager.InitShelves(); - //λƺͰ - //TCPClientManager.InitStatus(); WarningManager.StartWarningMessageThread(); @@ -71,7 +73,7 @@ namespace WebApi app.UseAuthorization(); app.MapControllers(); - app.Run("http://+:8888"); + app.Run("http://0.0.0.0:8888");//0.0.0.0ʾipv4 } } } diff --git a/货架标准上位机/ViewModels/InInventoryViewModel.cs b/货架标准上位机/ViewModels/InInventoryViewModel.cs index 09ac937..c643e4c 100644 --- a/货架标准上位机/ViewModels/InInventoryViewModel.cs +++ b/货架标准上位机/ViewModels/InInventoryViewModel.cs @@ -28,6 +28,7 @@ using System.Collections.ObjectModel; using WCS.BLL.DbModels; using WCS.Model.ApiModel.MatBaseInfo; using System.Security.Cryptography; +using Ping9719.WpfEx; namespace 货架标准上位机.ViewModel { @@ -259,6 +260,33 @@ namespace 货架标准上位机.ViewModel if (Result != null && Result.Code == 200) { scanner.MatSn = Result.Data.MatSN; + #region 调用接口获取入库状态 + Task.Run(() => + { + try + { + var body = new QueryByMatSnRequest() + { + MatSn = scanner.MatSn, + ShelfCode = scanner.ShelfCode, + IpAddress = scanner.COM, + DeviceType = LocalFile.Config.DeviceType, + UserName = LocalStatic.CurrentUser, + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "instore/queryInstoreStatus", body, "POST"); + if (Result != null && !string.IsNullOrEmpty(Result.Message)) + { + TextBoxLog.AddLog(Result.Message, "InstoreLog", DateTime.Now); + scanner.MatSn = string.Empty; + scanner.ScannerDisplayControl.RefreshValues(scanner.ShelfCode, scanner.MatSn); + } + } + catch (Exception ex) + { + Growl.Warning(ex.Message); + } + }); + #endregion } else if (Result != null && !string.IsNullOrEmpty(Result.Message)) { diff --git a/货架标准上位机/Views/MainWindows/MainWindow1.xaml b/货架标准上位机/Views/MainWindows/MainWindow1.xaml index 8081593..ae08325 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow1.xaml +++ b/货架标准上位机/Views/MainWindows/MainWindow1.xaml @@ -291,10 +291,10 @@ - + diff --git a/货架标准上位机/Views/Windows/UserLoginView.xaml.cs b/货架标准上位机/Views/Windows/UserLoginView.xaml.cs index ee64eea..06cf0ba 100644 --- a/货架标准上位机/Views/Windows/UserLoginView.xaml.cs +++ b/货架标准上位机/Views/Windows/UserLoginView.xaml.cs @@ -69,6 +69,7 @@ namespace 货架标准上位机 { UserName = loginName, DeviceType = LocalFile.Config.DeviceType, + GroupNames = LocalFile.Config.GroupName, PassWord = pass, IsNoLogin = false, }; diff --git a/货架标准上位机/data/jsconfig.json b/货架标准上位机/data/jsconfig.json index 87c04ae..66c8dc1 100644 --- a/货架标准上位机/data/jsconfig.json +++ b/货架标准上位机/data/jsconfig.json @@ -4,13 +4,13 @@ //货架服务器的IP和端口号 "ApiIpHost": "http://localhost:8888/", //货架分区 - "GroupName": [ "A", "B", "C" ], + "GroupName": [ "13寸智能货架", "7寸智能货架"], //设备类型 可以配置为每个电脑不一样 - "DeviceType": "WCS前端-开发电脑", + "DeviceType": "WCS前端", //货架类型的是否开机自检 "IsBootSelfTest": false, //扫码枪COM口列表 - "ScannerComList": [ "COM1", "COM2" ], + "ScannerComList": [], //串口扫码枪延时 "ScannerTimeOut": 2000, //系统配置 From b2f9c7cc22ffa2f27fd4c94ca99d8264c7cf5ef3 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Tue, 21 May 2024 10:32:52 +0800 Subject: [PATCH 02/18] =?UTF-8?q?1.=E5=87=BA=E5=BA=93=E5=8D=95=E6=8D=AE?= =?UTF-8?q?=E3=80=81=E7=94=9F=E6=88=90=E5=87=BA=E5=BA=93=E5=8D=95=E6=8D=AE?= =?UTF-8?q?=E3=80=81=E8=AE=A1=E7=AE=97=E7=89=A9=E6=96=99=E6=97=B6=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=B4=A7=E6=9E=B6=E7=B1=BB=E5=9E=8B=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E4=BF=A1=E6=81=AF=E5=8C=96=E8=B4=A7=E6=9E=B6?= =?UTF-8?q?=E5=92=8C=E6=99=BA=E8=83=BD=E8=B4=A7=E6=9E=B6=E7=9A=84=E7=89=A9?= =?UTF-8?q?=E6=96=99=20=E5=AE=9E=E7=8E=B0=E5=88=86=E5=BC=80=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WCS.BLL/DbModels/ModuleInfo.cs | 6 + WCS.BLL/DbModels/OutOrder.cs | 16 +- WCS.BLL/DbModels/StoreInfo.cs | 8 +- WCS.BLL/Manager/TCPClientManager.cs | 9 +- WCS.BLL/Manager/WebSoceketManager.cs | 2 + WCS.BLL/Services/IService/IOutstoreService.cs | 4 +- WCS.BLL/Services/Service/InstoreService.cs | 12 +- .../Service/MatInventoryDetailService.cs | 6 +- WCS.BLL/Services/Service/OutstoreService.cs | 87 ++++++- WCS.BLL/Tool/Logs.cs | 14 +- WCS.BLL/Tool/TCPClient.cs | 59 ++--- .../ApiModel/InStore/QueryByMatSnRequest.cs | 3 +- .../GetMatInventorySummaryRequest.cs | 4 +- .../MatInventorySummaryModel.cs | 5 +- .../ApiModel/OutStore/OutImportMatModel.cs | 14 ++ .../OutStore/SysOutOrderByMatCodeRequest.cs | 9 + .../Controllers/FileDownLoadController.cs | 83 +++++++ WCS.WebApi/Controllers/OutstoreController.cs | 48 +++- WCS.WebApi/Controllers/WarningController.cs | 3 - WCS.WebApi/Files/APP.app | 0 WCS.WebApi/WCS.WebApi.csproj | 10 + 货架标准上位机/Api/ApiHelp.cs | 4 +- 货架标准上位机/Excel/出库导入模板.xlsx | Bin 0 -> 9039 bytes 货架标准上位机/Fonts/iconfont.ttf | Bin 14852 -> 16272 bytes 货架标准上位机/Models/JsConfig.cs | 4 + .../ViewModels/InInventoryViewModel.cs | 2 +- .../ViewModels/MatBaseInfoViewModel.cs | 12 - .../ViewModels/MatInventoryDetailViewModel.cs | 9 +- .../ViewModels/OutInventoryAddDucumentViewModel.cs | 81 ++++++- .../ViewModels/OutInventoryAddMatViewModel.cs | 9 + .../ViewModels/OutInventoryDocumentViewModel.cs | 11 + .../OutInventoryImportDucumentViewModel.cs | 212 ++++++++++++++++++ 货架标准上位机/ViewModels/SetViewModel.cs | 67 ++++++ .../Views/Controls/ImageDialog.xaml | 15 ++ .../Views/Controls/ImageDialog.xaml.cs | 29 +++ 货架标准上位机/Views/MatBaseInfoView.xaml | 6 +- 货架标准上位机/Views/MatInfoView.xaml | 2 +- .../Views/OutInventoryAddDucumentView.xaml | 23 +- .../Views/OutInventoryAddDucumentView.xaml.cs | 5 + .../Views/OutInventoryAddMatView.xaml.cs | 3 +- .../Views/OutInventoryDocumentView.xaml | 10 +- .../Views/OutInventoryImportDucumentView.xaml | 93 ++++++++ .../Views/OutInventoryImportDucumentView.xaml.cs | 63 ++++++ 货架标准上位机/Views/OutInventoryView.xaml | 8 - 货架标准上位机/Views/SetView.xaml | 8 + 货架标准上位机/WebSocket.cs | 6 +- 货架标准上位机/data/jsconfig.json | 4 +- 货架标准上位机/货架标准上位机.csproj | 13 ++ 48 files changed, 976 insertions(+), 125 deletions(-) create mode 100644 WCS.Model/ApiModel/OutStore/OutImportMatModel.cs create mode 100644 WCS.WebApi/Controllers/FileDownLoadController.cs create mode 100644 WCS.WebApi/Files/APP.app create mode 100644 货架标准上位机/Excel/出库导入模板.xlsx create mode 100644 货架标准上位机/ViewModels/OutInventoryImportDucumentViewModel.cs create mode 100644 货架标准上位机/Views/Controls/ImageDialog.xaml create mode 100644 货架标准上位机/Views/Controls/ImageDialog.xaml.cs create mode 100644 货架标准上位机/Views/OutInventoryImportDucumentView.xaml create mode 100644 货架标准上位机/Views/OutInventoryImportDucumentView.xaml.cs diff --git a/WCS.BLL/DbModels/ModuleInfo.cs b/WCS.BLL/DbModels/ModuleInfo.cs index 59eeedc..73a4c41 100644 --- a/WCS.BLL/DbModels/ModuleInfo.cs +++ b/WCS.BLL/DbModels/ModuleInfo.cs @@ -27,6 +27,12 @@ namespace WCS.DAL.DbModels [SugarColumn(ColumnName = "module_code", Length = 50, IsNullable = false, ColumnDescription = "模组编码")] public string ModuleCode { get; set; } + /// + /// 货架类型Id + /// + [SugarColumn(ColumnName = "shelf_type_id", IsNullable = false,DefaultValue ="0", ColumnDescription = "货架类型Id")] + public int ShelfTypeId { get; set; } + /// /// 货架Id /// diff --git a/WCS.BLL/DbModels/OutOrder.cs b/WCS.BLL/DbModels/OutOrder.cs index ae62913..dac1965 100644 --- a/WCS.BLL/DbModels/OutOrder.cs +++ b/WCS.BLL/DbModels/OutOrder.cs @@ -49,15 +49,19 @@ namespace WCS.BLL.DbModels /// /// 单据同步类型 /// - [SugarColumn(ColumnName = "sync_type",IsNullable = false, ColumnDescription = "单据同步类型:ByMatCode,ByMatSn")] + [SugarColumn(ColumnName = "sync_type", IsNullable = false, ColumnDescription = "单据同步类型:ByMatCode,ByMatSn")] public SyncTypeEnum SyncType { get; set; } - /// - /// 单据货架类型 : 单灯单据还是货架单据 - /// - [SugarColumn(ColumnName = "shelf_type", IsNullable = false, ColumnDescription = "货架类型 是信息化货架还是智能货架")] - public ShelfTypeEnum ShelfType { get; set; } + /// 货架类型名称 + /// + [SugarColumn(ColumnName = "shelf_type_name", Length = 50, IsNullable = false, ColumnDescription = "货架类型名称")] + public string ShelfTypeName { get; set; } + /// + /// 货架类型Id + /// + [SugarColumn(ColumnName = "shelf_type_id", IsNullable = false, DefaultValue = "0", ColumnDescription = "货架类型Id")] + public int ShelfTypeId { get; set; } = 0; /// /// 创建时间 diff --git a/WCS.BLL/DbModels/StoreInfo.cs b/WCS.BLL/DbModels/StoreInfo.cs index 0f84620..ff551aa 100644 --- a/WCS.BLL/DbModels/StoreInfo.cs +++ b/WCS.BLL/DbModels/StoreInfo.cs @@ -21,12 +21,16 @@ namespace WCS.DAL.DbModels /// [SugarColumn(ColumnName = "store_code", Length = 50, IsNullable = false, ColumnDescription = "库位编码")] public string StoreCode { get; set; } - + /// + /// 货架类型Id + /// + [SugarColumn(ColumnName = "shelf_type_id", IsNullable = false, DefaultValue = "0", ColumnDescription = "货架类型Id")] + public int ShelfTypeId { get; set; } /// /// 模组Id /// [SugarColumn(ColumnName = "module_id", IsNullable = false, ColumnDescription = "模组Id")] - public int ModuleId { get; set; } + public int ModuleId { get; set; } /// /// 模组编号 diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs index bb1a209..83c6690 100644 --- a/WCS.BLL/Manager/TCPClientManager.cs +++ b/WCS.BLL/Manager/TCPClientManager.cs @@ -43,6 +43,7 @@ namespace WCS.BLL.Manager } var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); + Logs.Write($"【接收】{BitConverter.ToString(data)}",LogsType.Instructions); e.ByteBlock.Clear(); var len = data.Length; for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++) @@ -52,18 +53,16 @@ namespace WCS.BLL.Manager var isEqual = prefixInData.SequenceEqual(TcpCleint.Prefix); if (isEqual) { - Logs.Write("协议处理1!"); var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray(); if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度 { continue; } + Logs.Write($"【处理单条指令 开始】{BitConverter.ToString(dataTemp)}", LogsType.Instructions); index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1 //获取板子ID var boardId = (dataTemp[TcpCleint.PreFixLength + 0] << 8) + dataTemp[TcpCleint.PreFixLength + 1]; var lightNumber = Convert.ToInt32(dataTemp[TcpCleint.PreFixLength + 3]); - - Logs.Write("协议处理2!"); //报警灯 if (dataTemp[TcpCleint.PreFixLength + 2] == 0x20) { @@ -76,18 +75,16 @@ namespace WCS.BLL.Manager //!= 0x20 货架类型协议返回 else { - Logs.Write("协议处理3!"); var shelf = ShelfManager.Shelves .Where(t => t.ClientIp == clientIpHost) .Where(t => t.ModuleIds.Contains(boardId)) .FirstOrDefault(); var smartShelf = shelf as SmartShelf; smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); - } + Logs.Write($"【处理单条指令 结束】{BitConverter.ToString(dataTemp)}", LogsType.Instructions); } } - Logs.Write("协议处理完毕!"); return EasyTask.CompletedTask; }; //配置首次连接后复位操作 diff --git a/WCS.BLL/Manager/WebSoceketManager.cs b/WCS.BLL/Manager/WebSoceketManager.cs index 531dbb4..423ee15 100644 --- a/WCS.BLL/Manager/WebSoceketManager.cs +++ b/WCS.BLL/Manager/WebSoceketManager.cs @@ -16,6 +16,7 @@ namespace WCS.BLL.Manager public static object flag = new object(); public static void InitWebSocket() { + Console.WriteLine("【启动WebSocket】开始"); Logs.Write("【启动WebSocket】开始", LogsType.StartBoot); service = new HttpService(); service.Setup(new TouchSocketConfig()//加载配置 @@ -33,6 +34,7 @@ namespace WCS.BLL.Manager })); service.Start(); + Console.WriteLine("【启动WebSocket】结束"); Logs.Write("【启动WebSocket】结束", LogsType.StartBoot); } diff --git a/WCS.BLL/Services/IService/IOutstoreService.cs b/WCS.BLL/Services/IService/IOutstoreService.cs index 8726265..b9f5c88 100644 --- a/WCS.BLL/Services/IService/IOutstoreService.cs +++ b/WCS.BLL/Services/IService/IOutstoreService.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using WCS.Model; +using WCS.Model.ApiModel.MatInventoryDetail; using WCS.Model.ApiModel.OutStore; namespace WCS.BLL.Services.IService { public interface IOutstoreService { + public Task>> importMat(List list); public Task SysOutOrderByMatCode(SysOutOrderByMatCodeRequest request); public Task SysOutOrderByMatSn(SysOutOrderByMatSnRequest request); @@ -22,7 +24,7 @@ namespace WCS.BLL.Services.IService public Task GetOutOrderMatDetail(GetOutOrderDetailRequest request); - public Task GoInOutstore(GetOutOrderDetailRequest request); + public Task GoInOutstore(GetOutOrderDetailRequest request); public Task GoOutOutstore(GetOutOrderDetailRequest request); diff --git a/WCS.BLL/Services/Service/InstoreService.cs b/WCS.BLL/Services/Service/InstoreService.cs index 991a12e..96e37ea 100644 --- a/WCS.BLL/Services/Service/InstoreService.cs +++ b/WCS.BLL/Services/Service/InstoreService.cs @@ -130,7 +130,7 @@ namespace WCS.BLL.Services.Service } IShelfBase shelf = null; - if (!request.IsSingleLightIn) + if (!request.SingleLightIn) { //获取货架 shelf = ShelfManager.Shelves.Where(t => t.ShelfCode == request.ShelfCode).FirstOrDefault(); @@ -164,13 +164,13 @@ namespace WCS.BLL.Services.Service { materialBar = request.MatSn }; - var Result = ApiHelp.GetDataFromHttp>>("http://192.168.2.23:9213/integrate/instock/queryBybar", body, "POST"); + 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.IsSingleLightIn && shelf != null) + if (!request.SingleLightIn && shelf != null) shelf.InStoreData = new MatInfoResponse() { materialBar = data.materialBar, @@ -239,7 +239,7 @@ namespace WCS.BLL.Services.Service if (matInfo != null) { //TODO 改成wcs的实体 - if (!request.IsSingleLightIn && shelf != null) + if (!request.SingleLightIn && shelf != null) shelf.InStoreData = new MatInfoResponse() { materialBar = matInfo.MatSn, @@ -468,7 +468,7 @@ namespace WCS.BLL.Services.Service data1[5] = 0x03; data1[6] = 0x02; data1[7] = 0x02; - byte[] senddata1 = Tool.Helper.Crc16(data1,data1.Length,false); + byte[] senddata1 = Tool.Helper.Crc16(data1, data1.Length, false); tCPClient.Send(senddata1); //报警灯短亮一次 byte[] data2 = new byte[8]; @@ -489,7 +489,7 @@ namespace WCS.BLL.Services.Service Message = $"入库成功!", Data = rcs.Data, }; - + } } } diff --git a/WCS.BLL/Services/Service/MatInventoryDetailService.cs b/WCS.BLL/Services/Service/MatInventoryDetailService.cs index b9881c5..c8bab98 100644 --- a/WCS.BLL/Services/Service/MatInventoryDetailService.cs +++ b/WCS.BLL/Services/Service/MatInventoryDetailService.cs @@ -128,16 +128,16 @@ namespace WCS.BLL.Services.Service var inventortyDetails = await DbHelp.db.Queryable() .WhereIF(!string.IsNullOrEmpty(request.MatName), t => t.MatName.Contains(request.MatName)) .WhereIF(!string.IsNullOrEmpty(request.MatCode), t => t.MatCode.Contains(request.MatCode)) + .WhereIF(!string.IsNullOrEmpty(request.MatBatch), t => t.MatBatch.Contains(request.MatBatch)) + .Where(t => t.StoreInfo.ShelfTypeId == request.ShelfTypeId) .GroupBy(t => t.MatCode) .GroupBy(t => t.MatBatch) .Select(t => new MatInventorySummaryModel { MatCode = t.MatCode, MatName = t.MatName, - MatBatch = t.MatBatch, MatSpec = t.MatSpec, - MatCustomer = t.MatCustomer, - MatSupplier = t.MatSupplier, + MatBatch = t.MatBatch, TotalQty = SqlFunc.AggregateSum(t.MatQty) }) .ToListAsync(); diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index e10f390..fba3311 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -1,19 +1,12 @@ using SqlSugar; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -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; using WCS.DAL.Db; -using WCS.DAL.DbModels; using WCS.Model; using WCS.Model.ApiModel.InOutRecord; +using WCS.Model.ApiModel.MatInventoryDetail; using WCS.Model.ApiModel.OutStore; namespace WCS.BLL.Services.Service @@ -23,6 +16,53 @@ namespace WCS.BLL.Services.Service 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) { @@ -35,6 +75,24 @@ namespace WCS.BLL.Services.Service 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 @@ -44,6 +102,8 @@ namespace WCS.BLL.Services.Service OrderNumber = request.OrderNumber, OrderSource = request.OrderSource, OrderType = request.OrderType, + ShelfTypeId = request.ShelfTypeId, + ShelfTypeName = request.ShelfTypeName, SyncType = SyncTypeEnum.ByMatCode, CreateUser = request.UserName, }; @@ -645,7 +705,8 @@ namespace WCS.BLL.Services.Service .Where(t => t.MatCode == outOrderDetail.MatCode) .WhereIF(!string.IsNullOrEmpty(outOrderDetail.MatBatch), t => t.MatBatch == outOrderDetail.MatBatch) .Where(t => t.IsLocked == false)//未锁定的物料 - .OrderBy(t => t.MatBatch)//先进先出 + .Where(t => t.StoreInfo.ShelfTypeId == order.ShelfTypeId) + .OrderBy(t => t.MatBatch)//按批次先进先出 //(t => t.MatQty)//零散料先出 .ToList(); @@ -873,7 +934,7 @@ namespace WCS.BLL.Services.Service } DbHelp.db.Updateable().SetColumns(it => it.OrderNumber == null).Where(it => it.OrderNumber == request.OrderNumber).ExecuteCommand(); //灭灯 - + return new ResponseCommon() { Code = 200, @@ -911,11 +972,11 @@ namespace WCS.BLL.Services.Service ior.OperateUser = request.userName; ior.OperateTime = DateTime.Now; //保存出库记录 - int count= DbHelp.db.Insertable(ior).ExecuteCommand(); + 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(); + 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(); @@ -926,5 +987,7 @@ namespace WCS.BLL.Services.Service Data = null }; } + + } } diff --git a/WCS.BLL/Tool/Logs.cs b/WCS.BLL/Tool/Logs.cs index c450c40..3872b1d 100644 --- a/WCS.BLL/Tool/Logs.cs +++ b/WCS.BLL/Tool/Logs.cs @@ -25,8 +25,18 @@ namespace WCS.BLL /// 启动信息 /// StartBoot, - - Api + /// + /// 调用外部Api的接口 + /// + Api, + /// + /// 指令发送接收 + /// + Instructions, + /// + /// 指令重发 + /// + InstructionResend } /// diff --git a/WCS.BLL/Tool/TCPClient.cs b/WCS.BLL/Tool/TCPClient.cs index c5dd9aa..10f0002 100644 --- a/WCS.BLL/Tool/TCPClient.cs +++ b/WCS.BLL/Tool/TCPClient.cs @@ -79,36 +79,38 @@ namespace WCS.BLL tcpClient.Received += (client, e) => { var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); - Logs.Write($"校验发送接收,收到数据" + BitConverter.ToString(data)); - var len = data.Length; - for (int index = 0; index < data.Length - PreFixLength; index++) + Task.Run(() => { - //协议拆包 通过前缀校验是否为完整数据包 - var prefixInData = data.Skip(index).Take(PreFixLength); - var isEqual = prefixInData.SequenceEqual(Prefix); - if (isEqual) + Logs.Write($"【校验发送接收 开始】" + BitConverter.ToString(data), LogsType.InstructionResend); + var len = data.Length; + for (int index = 0; index < data.Length - PreFixLength; index++) { - var dataTemp = data.Skip(index).Take(PreFixLength + DataLength).ToArray(); - if (dataTemp.Length < PreFixLength + DataLength)//拆包后不满足一条指令的长度 + //协议拆包 通过前缀校验是否为完整数据包 + var prefixInData = data.Skip(index).Take(PreFixLength); + var isEqual = prefixInData.SequenceEqual(Prefix); + if (isEqual) { - continue; + var dataTemp = data.Skip(index).Take(PreFixLength + DataLength).ToArray(); + if (dataTemp.Length < PreFixLength + DataLength)//拆包后不满足一条指令的长度 + { + continue; + } + //获取返回指令的板子ID + var boardId = (dataTemp[PreFixLength + 0] << 8) + dataTemp[PreFixLength + 1]; + //查询当前板子是否有待验证的指令 + var message = new MessageDto(); + MessageList.TryGetValue(boardId, out message); + //功能位校验 功能位相同视为已响应指令 删除对应的指令 + if (message?.Message[PreFixLength + 2] == dataTemp[PreFixLength + 2]) + { + MessageList.TryRemove(boardId, out message); + } + index += (PreFixLength + DataLength - 2);//每次循环index会+1 所以这里-1 } - //获取返回指令的板子ID - var boardId = (dataTemp[PreFixLength + 0] << 8) + dataTemp[PreFixLength + 1]; - //查询当前板子是否有待验证的指令 - var message = new MessageDto(); - MessageList.TryGetValue(boardId, out message); - //功能位校验 功能位相同视为已响应指令 删除对应的指令 - if (message?.Message[PreFixLength + 2] == dataTemp[PreFixLength + 2]) - { - MessageList.TryRemove(boardId, out message); - } - index += (PreFixLength + DataLength - 2);//每次循环index会+1 所以这里-1 } - } - Logs.Write($"校验发送接收处理完毕" + BitConverter.ToString(data)); + Logs.Write($"【校验发送接收 结束】" + BitConverter.ToString(data), LogsType.InstructionResend); + }); return null; - }; tcpClient.Connected += (client, e) => @@ -138,17 +140,18 @@ namespace WCS.BLL .ToList(); foreach (var message in failedMessage) { - Logs.Write(BitConverter.ToString(message.Value.Message) + "指令超时1s未响应"); + Logs.Write("【指令重发】" + BitConverter.ToString(message.Value.Message) + "指令超时1s未响应", LogsType.InstructionResend); } MessageList.RemoveWhen(t => t.Value.SendTimes >= 2); foreach (var item in MessageList) { if (item.Value.LastSendTime < DateTime.Now.AddSeconds(-1)) { + Send(item.Value.Message); item.Value.SendTimes++; item.Value.LastSendTime = DateTime.Now; - await Task.Delay(10); + Logs.Write("【指令重发】" + BitConverter.ToString(item.Value.Message) + "已进行重发", LogsType.InstructionResend); } } } @@ -175,12 +178,14 @@ namespace WCS.BLL try { var boardId = (message[3] << 8) + message[4]; + if (boardId != 2047 && IsReSend == false) { MessageList.TryAdd(boardId, new MessageDto() { ID = boardId, Message = message, + SendTimes = 1 }); } @@ -190,6 +195,8 @@ namespace WCS.BLL //发送自带8ms间隔 Thread.Sleep(8); } + + } catch (Exception ex) { diff --git a/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs b/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs index fefa30f..854b56b 100644 --- a/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs +++ b/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs @@ -11,7 +11,6 @@ namespace WCS.Model public string MatSn { get; set; } = string.Empty; public string ShelfCode { get; set; } = string.Empty; public string IpAddress { get; set; } = string.Empty; - - public bool IsSingleLightIn { get; set; } = false; + public bool SingleLightIn { get; set; } = false; } } diff --git a/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs b/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs index ccbccdb..38bfa2e 100644 --- a/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs +++ b/WCS.Model/ApiModel/MatInventoryDetail/GetMatInventorySummaryRequest.cs @@ -10,12 +10,10 @@ namespace WCS.Model.ApiModel.MatInventoryDetail public string MatName { get; set; } - public string MatSpec { get; set; } public string MatBatch { get; set; } - public string MatSupplier { get; set; } - public string MatCustomer { get; set; } + public int ShelfTypeId { get; set; } } } diff --git a/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs b/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs index b485d9c..d0e35f4 100644 --- a/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs +++ b/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs @@ -5,7 +5,7 @@ using System.Text; namespace WCS.Model.ApiModel.MatInventoryDetail { - public class MatInventorySummaryModel: INotifyPropertyChanged + public class MatInventorySummaryModel : INotifyPropertyChanged { public string MatCode { get; set; } @@ -33,6 +33,9 @@ namespace WCS.Model.ApiModel.MatInventoryDetail } } + public string Info { get; set; } + + public bool IsSelected { diff --git a/WCS.Model/ApiModel/OutStore/OutImportMatModel.cs b/WCS.Model/ApiModel/OutStore/OutImportMatModel.cs new file mode 100644 index 0000000..49f2694 --- /dev/null +++ b/WCS.Model/ApiModel/OutStore/OutImportMatModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.OutStore +{ + public class OutImportMatModel + { + public string 物料编码 { get; set; } + public string 物料名称 { get; set; } + public string 物料批次 { get; set; } + public int 需求数量 { get; set; } + } +} diff --git a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs index 645ce0c..ddd4019 100644 --- a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs +++ b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs @@ -17,6 +17,15 @@ namespace WCS.Model /// public string OrderType { get; set; } + /// + /// 货架类型Id + /// + public int ShelfTypeId { get; set; } = 0; + /// + /// 货架类型名称 + /// + public string ShelfTypeName { get; set; } = string.Empty; + public List ItemList { get; set; } } diff --git a/WCS.WebApi/Controllers/FileDownLoadController.cs b/WCS.WebApi/Controllers/FileDownLoadController.cs new file mode 100644 index 0000000..e36f103 --- /dev/null +++ b/WCS.WebApi/Controllers/FileDownLoadController.cs @@ -0,0 +1,83 @@ +using Microsoft.AspNetCore.Mvc; +using NPOI.HPSF; +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 FileDownLoadController : ControllerBase + { + + public FileDownLoadController() + { + + } + + [HttpGet("downloadApp")] + public IActionResult downloadApp(string fileName) + { + // 这里是文件的物理路径,你需要根据实际情况提供 + var filePath = Path.Combine(Directory.GetCurrentDirectory(), $"Files/{fileName}"); + + // 检查文件是否存在 + if (!System.IO.File.Exists(filePath)) + { + return NotFound(); + } + + // 获取文件流 + var stream = System.IO.File.OpenRead(filePath); + // 设置HTTP响应头,使浏览器知道这是一个附件,应该下载而不是打开 + Response.Headers.Add("Content-Disposition", "attachment; filename=\"" + fileName + "\""); + // 返回文件流作为FileResult + return File(stream, "application/octet-stream", fileName); + } + + [HttpGet("getLatestAppName")] + public ResponseCommon getLatestAppName() + { + string directoryPath = Path.Combine(Directory.GetCurrentDirectory(), $"Files"); + + // 获取目录下的所有文件信息 + FileInfo[] files = Directory.GetFiles(directoryPath, "*.app") + .Select(file => new FileInfo(file)) + .ToArray(); + + if (files == null || files.Length == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = "服务器不存在App安装包" + }; + } + //获取最后修改的一个 + FileInfo lastModifiedFile = files.OrderByDescending(f => f.LastWriteTime).First(); + if (lastModifiedFile != null) + { + return new ResponseCommon() + { + Code = 200, + Data = lastModifiedFile.Name + }; + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = "服务器不存在App安装包" + }; + + } + } + } +} diff --git a/WCS.WebApi/Controllers/OutstoreController.cs b/WCS.WebApi/Controllers/OutstoreController.cs index 217e661..7481c2d 100644 --- a/WCS.WebApi/Controllers/OutstoreController.cs +++ b/WCS.WebApi/Controllers/OutstoreController.cs @@ -1,9 +1,11 @@ using Microsoft.AspNetCore.Mvc; +using MiniExcelLibs; using WCS.BLL.HardWare; using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.BLL.Services.Service; using WCS.Model; +using WCS.Model.ApiModel.MatBaseInfo; using WCS.Model.ApiModel.OutStore; namespace WebApi.Controllers @@ -15,12 +17,54 @@ namespace WebApi.Controllers private readonly IOutstoreService _outstoreService; private readonly IGenerateService _generateService; - public OutstoreController(IOutstoreService outstoreService,IGenerateService generateService) + public OutstoreController(IOutstoreService outstoreService, IGenerateService generateService) { _outstoreService = outstoreService; _generateService = generateService; } + + /// + /// ģУͱȶ + /// + /// + /// + [Route("importMat")] + [HttpPost(Name = "importMat")] + public async Task importMat([FromForm] IFormFile excelFile, [FromForm] string userName, [FromForm] string deviceType) + { + try + { + //ļУ + if (excelFile == null || excelFile.Length == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = "ʧ:ļЧݣ" + }; + } + //ȡе + using (var stream = new MemoryStream()) + { + await excelFile.CopyToAsync(stream); + stream.Position = 0; + var list = MiniExcelLibs.MiniExcel.Query(stream, "⵼ģ", ExcelType.XLSX).ToList(); + return await _outstoreService.importMat(list); + } + } + catch (Exception ex) + { + return new ResponseBase() + { + Code = 201, + Message = "ʧܣ" + ex.Message, + }; + } + } + + + /// /// ϱͬ /// @@ -33,7 +77,7 @@ namespace WebApi.Controllers try { if (string.IsNullOrEmpty(request.OrderNumber)) - { + { request.OrderNumber = await _generateService.generateOutOrderNumber(); } return await _outstoreService.SysOutOrderByMatCode(request); diff --git a/WCS.WebApi/Controllers/WarningController.cs b/WCS.WebApi/Controllers/WarningController.cs index 5392169..b0c68e7 100644 --- a/WCS.WebApi/Controllers/WarningController.cs +++ b/WCS.WebApi/Controllers/WarningController.cs @@ -7,9 +7,6 @@ using WCS.Model.WebSocketModel; namespace WCS.WebApi.Controllers { - /// - /// 权限/用户界面的接口 - /// [ApiController] [Route("[controller]")] public class WarningController : ControllerBase diff --git a/WCS.WebApi/Files/APP.app b/WCS.WebApi/Files/APP.app new file mode 100644 index 0000000..e69de29 diff --git a/WCS.WebApi/WCS.WebApi.csproj b/WCS.WebApi/WCS.WebApi.csproj index 840dcac..4cbb681 100644 --- a/WCS.WebApi/WCS.WebApi.csproj +++ b/WCS.WebApi/WCS.WebApi.csproj @@ -18,4 +18,14 @@ + + + + + + + PreserveNewest + + + diff --git a/货架标准上位机/Api/ApiHelp.cs b/货架标准上位机/Api/ApiHelp.cs index f3559d2..99822fc 100644 --- a/货架标准上位机/Api/ApiHelp.cs +++ b/货架标准上位机/Api/ApiHelp.cs @@ -282,11 +282,11 @@ namespace 货架标准上位机.Api public static T GetDataFromHttp(string url, object dataObj, string httpMethod, bool isSaveLog = false) { Guid guid = Guid.NewGuid(); - var data = JsonConvert.SerializeObject(dataObj); + var data = dataObj == null ? string.Empty : JsonConvert.SerializeObject(dataObj); try { if (isSaveLog) - Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}",LogsType.Api); + Logs.Write($"【{guid}】开始请求调用接口 url:{url} 请求方式:{httpMethod} 数据:{data}", LogsType.Api); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = httpMethod; request.ContentType = "application/json"; diff --git a/货架标准上位机/Excel/出库导入模板.xlsx b/货架标准上位机/Excel/出库导入模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7ac38a000164760a26541a0a612b1c64e95b21a0 GIT binary patch literal 9039 zcma)CWmHw&)}})m>6Y#W0g>(lNF&`{hdz{acStu#BS@o^bR&&)OGbFMYl9M5wU0MIbcARb4s{HoC7{oex-{KMGJNWsAl=*Xe~7Q+HRK=>t= zRSUf@4haDv4g~>${#P*rAdnekW1SKERR)?3OZ>v`0lms@90!9gh0ZUG@KgAXfazk5 zZ;G*0rs%HjEkyn2t=w-JfSk9t_=T7Frlw+rJN*kDjY&7dRGzGI&*S`^`?q{t=7?p4 z0MF@Oqi%I=C6+d6w^NDA@B5Bq5RL`O|@OfFIb4R?VoW zlx>HfNoNts!4|hx91u`l(ECO>VIx>X1NWHdhF6L+k;i#$_ky+&6SaTFXS1C?XS64& z&b@e(($TzQ)$OS69Vm;1_r(29EmF?PQO(1kp8e8b?k(H|k?ssN5uI#XMvth$5!$lt z^9I8rdqIo?wXU5OkUO0%ZrXnu;t>r<*eM3jfgWxU1-$New7O_Mb9C9OY$T9vJ zaw9tjlgF5Q#f{2zu;K+Cz%J#ix5$k(vdPT(_J1ToP{TS9Ikscqwvf(UAZe34R18vY ziM%E%*jIan#d4Ar&+_AzGSkL*<+VSzTQQ~>v>(4h6IP=p)fRW!jq*DFK!Uz_F`2Ly zt9fE(W@l3vsCY#)3EMo)|A>^?5h>e3XO^6kV3-GztaNqu>K$f>Hq4C8&#}nJUOq)89tt_@!LC&};sM z)}j2~0%80`_verP?i1a>E4mgv?S&fEJ8iBnt3G3I4@0c<>n65)Zg!`C?w^?8u6?cf zuKzVcr@@595&g$pjVW_3@XqK~%c-+YC>VC7QA$yLIeR{mnYo%*Miev3ll|NxS&?AW zUaVL29;m7BGeR!WWb11TtYys!LT1P}0U7)B-6sZ}0qw$9;kSE`Zcu{&UMvn-+GGD)t)QSnB&2eI+4oBczb$5f;J& zC|c78WO#3euwY7J-<{0`zlye@`59JBI$O?4;sqQq@ccBqj@5&ONpMXVWZaU?D86J6 z#*F$`^*2PE*v(9vyMBhRU%Zpqy6a1YX>o&qB^QcR%%POfHySj8dDpE(()gT= z-2r2rL@gT&GbuTDNi>?BTfYajaQD-k&aYT0<7cGs0?RG|H4%`7Vkd=Ry1CcBpJ=PMPc1bQ#d#Yu<&@^L zu&If2$QxbEGa?M2^^`~#w3*Yl5vfr|7mqJd!>*{V$qbLU)yDBlPTwxDoWRbl^{)C{ zf}&`3Db#+19CJZc>@6|JQ~2eyjIIh-ZfIThFQ~a>(wZx1Wa=oc!m*6=;iZ*q?R3K+ z4>wpH-9e!ynmv~xFluiQE~Ges4#=QN)B>U%qosyin51_mrIMJ7m)n1}$6uX9Hg*lA zl32ZruJVL@tP%gbP9M)t@IrPnH?c8!a()I}-ymPYLO`^D*XLs?`9tiN@UPXmuQ3!& z$c5EPaU>YAx%iWEsK;f}y7p>E#C1+JzHVn!Iz57L1Z4c`%MePfBqgPouy#y?y^zoc zwN<72)If4tr3cu|{k~3lqFkJSY)g5L%q5R^q^%dXu?*^@l$<KDMDEuWS+L)1rDRab`@h;>Pxx3vFK!I z8?DI~2yZl3BuOWqMG(FS$v8WL#)rc~L?k6J$oF0uzJE_#lZ2$$C_ELnyQ9aPgcMO= z@|q?KIZT@2z2yfNg{^4_`f2+N_rj@S>}yU4l;GupPhF#pS`{^^yi-sqlF>hhZ5!vE z4-@YJR@|-wL;gj3%Ur!%6=f^Clcrx*SGjtZORX*eiVT)&M0W(nhqYXug_;(suTXXU z4Q0l*3HZYLYvs8labwu>f^|X7$~z=Aj+dCQ*0e<*3h=5`+(Q$yZz5b*N<|bYr3rf7 zf_lsmYHVJ}z@@`T8e;;u;AcB}uWf^Z3~i+3a6?|uq*w=#nj$+Qr{BSoGl#vSR4xtGaVTf%s02lQSNBpPqa|4(ZFNTtjGrT8 zq23Mx)%Nx1d}l)oBE|8u!;JnPr9J7j*jxtrb7*VbNl9vZ%%9oU>`ZlE3vhV9TkY`GG}>*nEdmc^&bY zwJ6|J_&F~8C&nO2)$Z(tuW~%}#?<7~oEXC0Fhpn_ktGxGd;r_1o=uQOiF%$no3B7z zdw~1rP=R7*mBhhN$2?u5+&D-8lD|F$dfRypM&hmni9CGBYAicjQsrG`mfm$8l7wOmTy0!bLzHxk!?vwKZzAADb{w>N&uNLfuyaj z%HVd!5=sQ5KETAkFiiORz9TUz&>V+CR43U`)C8A$oAd3IU#YHoO@&paJ%0f@LIZCA zLp$_FNGkeIG|58;I&XeO8#RyG!}_vx?KAa3!j-@#=S@|9AIF)JgM!t?nbr0q6XudL zrCKTRZ3kmrT^j83$&4@vo35aFK17OnQa3_Nbp<;a{Fq2ifE_nh^3$ zW*sKDY*xsCUr{QoX6yEQWGF3>Y8mWrc5NVM6!J@E8nK$KPKIIE)ijVq*SgN%REs~9 z>p#G@!CmAG)U5P7OMGA@7V(O&lK^m`UyZ z=s79;hp5g6{YF2u5bM>XCJ>9XMU~ZdK6J(e`3uOBrqKA>!-32-l`p|D&zh@%MN&mV zD^8d_88TNwxIF0U#M6s{kS*=m%lSelGDc%}en z&fMLSL28$IM~cO`AW5}#BA$=WGxT+<*3Vp)h^~dri5s$a?9D0DSAbEqKTg~Av5<3# z^;J>fpbO1LEQ%)jbG!zG7unWb#z{R2a3k||SVb$X}KTf30b6#C7oZ@dP&uo9%6V^QtgR2`q1Jjh5DAwvHoqb zf0791oTi0oRvx94GfsCjItKb3?+*<7B1J z#PD@2UP>Ow)HC9K4)r6SK$<5@AQyTihOc+TG(ycpZPx03e=1<>Y#vClMH!$lKFT#O zzM7Z`?IVsmAl4m`|Ln8)l`azTK!#B`q5Y{5rFgat55IX|frhVlL0|Q-0{)5a$3skC z6!e+oPa9`2%#~3y^)kDtZ(X@7AHFYJH5${o`5#n{;T3g#Elt~EN$O4ix;9w)agJY} zz=e1^UTsfSo?vaTVd>-BStu3D0@Eq0-o~0&t-83q>`dK=m__AiG!ZODzMHkzx+Who zJVOJi@9Slfm_wE}%RGwX;;O@0SdoJa`Yk)^gpx-CWh%#XD;3_Be||Tx3M|LEB+pYr zLgLrP``X)Wzu+WPYGGamtv)MUk+2rJujn;RvzgU@~Say=!2eK}-LU z?g~M|clR_Fr-PaKleDex$Hjf}M))I?o`bm_ZsZ0lkgTdH)^MqIL7D9|D>o&8YsHSE z>Z9uDlBuz?)s3mEH%Ao&{@GC9>;c|xx54~4+sA2y3zY~g-YxsOD&?2Rc{vjVkwH0D z{hJ%=!Yw&m5vk8CRi;oT-EO$h^(xc|Rl5|NO%~|L5?fzzlpecu4E8R`B;#LcA##wM zmbJc|t|Ky)xL0fc^?29nqnrI$ksa?~#BF&%N^I+U)-~zuvkTK?uO&+x({($lUoYH5 zMIqi6%~<|6L-D}X5kbnn^68um;ij^Ls*8ck{3uA<@}-Uk`d3HeEo8J&J1nA{!hW(a zef*+@y;oDLhfKJr1Bl|s;j{)^$T%&U4o(P2>V4!ww=uJdqoni@CKH^AvGGv5{*!&u z5Mea#Kk~^WnCmf+(cNfbSHF9i?S1Gj>@Z(tU+<|6mHHAIm8o+2S+{sswN}D2bGoS$ zRS{u(-F*?A9qUS@7kwT1h3Kbegxj4!T|)dYPi}S?UK?Xt-Kp+(tU<6#SkaE-OXLhm zV}o;z31a%&N~ukC%-eB>yakB6wxCQBrSGMu0E0Ix*EbGnjho>UA>&Mx2bueyrxjE0 z7RiQ|`D9jlpiPB|>gcn(lxjAkPz`d~1t_;u(`(WacagnD&J7T!P$>$7aey8`%Xro4 zwXeup#4PqKYYZBal0QQck3Ts%z|nuJM*S#sdaIcW-+bzVC+5P^uEj#HzX&J|Qy*Xn zEKyiVf-l9B@49)(9H{KvM76F|)bFI0U(-+>cj;}mM?8}gdVw<9Vrcu>k&PfP0@%oD zib>v(MlIIHEw73%usQaf0260TIpH&N(i;P)qc{s>M}s6;qvRJ`|DjNQ-O|p%*c$d zFH{f+Oce-j;W`+H0!H_5-jh;~DQp)efRt|;sT8AggaebumWihvIUgE5>>s|LPNO~N zEn-w6I39MXDyOu+Fw4r!@^U*`-s^%t$QT*R^Aq1b68NT(GVXnMwt9LeMpiZLjPS`^HJVx{`yihVxu_JUOHX-dH|% zH)|nlUT!q!@X#kNM%dxnjXqEkhQBsMYWV(kbx&BP-3W^01q|i*8{0Pzr$C1T*Z424 z1*BfFW5*2&fxhH1S$X2vQHWLad*kEYneuiIFEN5i+s#Az2-B*4viLny>wZ)R(Fb&{ zS6A1(j)qeW2@0PR^tfNQ2OAc~HZ(Zy`tjqT0U9rh{~hq?DELR~Z9+Rv#PU2@XQ1X) zs!AMA)ygL*XhLDEvkhy|t+~kUL}K*{8>}d_FE^Cq*t_E6Hb3=uu*mGqaaCW}UOmG* zwh7m0Gjx8yl#zQzt*~ab<>M5h{v@TGmB_wG~ zMQ?nR1Fi3ftUs%aGgXW1Vf38cGN}~#ewZ9+V+Fz<+}YjG`CL3ciA!pZhlke7p5G|V8!0az}}(LXC~1129cQL>dV+ZZ}+hEyV%hU zxyKn2P@=z=pjZDktM*&4gQ7kx7C;)LZ%&#M9l0{pzdb{8I9U%rH4|x@|5A(n^*#4H zZ>U_-diS|TY_ViG! zJZztitio;HV+emaUjQNP>gK-B(a{~txV`V1? z3tO{aU1jyBiryhbS^yLM@ZdVq3qoeZ_ivkz`5fgg&8Sz9vX>NsU&d%x=FsLkSH_nRHLUBaOxTH*D z!I4_jH&GUuTqCbcN1Prbo!+f!C|L*Kdl3~vT6uy>1O{HRVlKHB4%(zsQ8)t}+}*MS zz26;pu*9$F#QLL&N%g0omHQ$>8nC^gox40dqi63%mkQMIa~uvqs|XF~`Fdg&9~NGE zk*){H)RvFN@j(Xd1-@B+n?oC*{ZzVN-1ohF7hInbdU|gJy6So__Yj4Oe!qU{a;N|S zznq1vDgPo)K(U%w3=xA)%b+=(0jsoy{FIF(MA8N?v(v&CB0nMk*P9~pP_$sa4Qw|U zB81L57b0ATt=N7$+KV{xiX3J z_z-&%Jp_f|pe@aU{VC)sWiur%3~Si4m7Z_-!JFS|BNdIsyL%nvD3GHif;hs1hLNmX z*j;nqEJ(T38eSVS!$!g;@vHhL;}#M3#cyjGP0UljwF%Ts)gLQy<02sb2G45a>yP67 zdYQ@0nIU-Yfudy$kQSf0ZoUu?a%g$W7#1wW~>=1FKb6<|Bemz`t7n*je!{)Aa(%2*vwrEl!Pujt|} zMz>WIgtA_7i5Kz;8d3OjH`^-M_8&`hXOSq#@pmoKhj@H}v*!tHy0Wt?*&SYfosuUy z!ojev5}V;{9fKX=@0mB#ihd>z2gf_&;4Cn3;3^YbR&L6KBCZ{ntQ0GFPW!!c8->wk~sztGTs3g^aQ zF5W&kjGw{bBmm#RRq40bUpM8yqifm0irjtR-|Ro?Wj_|lCXu1rojqOd0b#`8ZEgq; z&`PV%>dn!}c1qGl&I)Kfpc$B3Xgrueqqa0+RWRnIMP|O{o`7pXJwRj04zW3`3x`CB zkg8-jIH)6?(MSYL)IihOBN}HLkm%M@PwU&!g+s$_tFWCViWg|2O%dBfy2t+*;k!HY zaabunUlf|Xp-~97k6C|cHd3ucUCO=r$#(c2K`v5mOOUq@MA^+f*$aoWAsZsB7wo2u z9n>SQ>sXL{T7Ef{dc^puo!2YQoiAJqxhoa9Fga?1?0C?gF4h{rhl|&IX}|FVGA=sO zbTk9kEEF(o{0JFqiQ3sZnb z+Ggj`{EE35u&k7#iNa09|5b%imOfMc)MJg(PgsrL7N@Q(H55G}kvvwp#c9V!$rce? zb(3pm%jc!B|509m%cg5v-OtF}P)%Vr9Jc0X0Pcok2O=*a`Jj?k)u@@%@!~`w0we&2 z%D1{Qq4&O&FQ`!jGarlrq$>`W%z1U!hO1EV^+_CP1c@4(vX}ipYcZI!O!5q=J=q>~ zVOnd5IIhXe^PfdT;mv2UQ*ieSLO8F5<(-Ose%Q4-LTGHl91iqc6<(YSS9a9Uo%KK4 zA71{!Br@w&vb}iL5?j~G*mUys#EAPAP5}T3h4t(B{7r^G%?vm>5RedL;A<-JKj!JT zfqy0q9!t*e@yM$~5&l_#{_gZ?33}A|?UectonKq#e>r>HlfTEKv&ZolzW?w3o-+QA z!oU5|{8jB={QuJsJteRI)J_F2=|7zQo63Hw{*-zBQ=JHWg8!-h2M_zdKKhYg{5>8& z+7(O^g6qxyQuuq6*$Wu=1PmgAQRr{0SdOGE&UD=-oHo-I*c*=hb z+y9#MBSHLoJZ3ogcZMI8|DcQiKJ%x9@uTkVtabi}?w|Cr0s!{cX2k&i9RnUL$4>gF F_kY)9lkj6l;4WTs9Hfaq@Y#s>5tm@6Kw*WeBpv~FiODCKwub=;m2GAYBj-?AXW4$dv@LeR=wfF3#tLsa! zTd)J*e&IJm|GHPcuAH$%`5$B33LNXji_L2(g~;7fhN~)lPTnbA+3f>z3HaToCcN9w z&=s(d7x3*qECK+vP>I@U74=Xbt)Vg6L3`-{JxoXF7@efkv_Q|$vvi$ar*G5ypM14F zv;FS&``aIW`oV*9JJXd4t^ki$a8sQIc30@31EmmecNOSqy7r&Br8GZOdXI=jg0`P} zTn@qrjO~_Zz$_DBmhZr`|EBQmMFZN)VE!lYVZa2H1bWy6 zH3d3ig6abOrU~i{bj$=52Rdnj+5??7!6*PNm|#4Bo;JbA06k-ZF#=j#!wP{$yq`6} zxB*=^!3YAqZi2A{`nCy173h5vj4yohl?g@~wr5N*=CJ*)2@C7?`zDwNu>GM)5mN#_ z{lEm110I|+!8C!Lya^@@?4V~1mO6M{A_vGj+$swbw%~6J?d+2aL;(AwJE)LQUARUd{e%Q{t^GR zKqT-(TpR_fe8g{Y57BTOz76x3t=?oW$!7Ma;|Y>sl@TN{Lm^t2B(vQlrEA_!BGn7& zeWZmbB#eWiq;QgG)W@-~8M$l=5nVW_tC}|zO=dHy&KIL<%Iov`Lbyzhl@$3x@CtWC zn|#74UiK73Sr$sNT5yWPmoIax;;Ik{O7hf(;t_;cGGz1_q3WFMb8Sq?QZOQ{S~$PL zuPFZEe|%h$eR?SN+>z&EA>AjJh-k6gkwjY+m2I9aPWD+OMJR4ZQ4eN@Eek3-l2<`bS|4phDnHMqKn%VCKE4q6Q)lb2YU!<)xEx4 z7B!S~O_W3&*qs?7L9(AWT8JsMsa-lAi)Nz95R+3Ou_%dUQabji?2ha|E;uaCk#sg4 zQB~dj3#ZHF+~CzZSB*$Uhn`BbIC&5GZjq2HJiks<=b_P|jD4c3r`zfNX|yfUAJ#dS zHyrks50hU<+oJe;^f{+5FPHyB8b14Md6|2lIhrPF!vbm2?8<3d$Oy|tPPVCWjh+0#(>IAsDW|2=5T0scOX!nO(gpM>z7C*xWv7CIKKj$n*`WGYvsnx@$pSH5KuQ? zv}-=i9*6}ljkBw`TaUA^d*vQ~iBI77oc)tDLl$!IBpg5w^KcYS!YhFP#e}6%eG94A zq!3|;EuGE9GYXMJ9ZzCb5MxHYD0x#!JV|jrrg@Xublec}2@hBgJGq7^{JVRPt`+g! zUXt?RErZL&4GE8K4i7gT(Ilo@HiyPyK2gGqO8T%TjbmQEFA@pX%zVQ&I{BzT$mFQ& z$z!#(JPC01V{>C8YUufezV41>?VYLir`y_|ZofShXiha(V}rZ>xU0M(TOE?MI4DXE zmD?}Z*=qdze&UgBT1_`kBH?|5ye|-_9`M9@GQ}(E@Ie1UBxE$MuUKT;_tzVZP-LNh zVAvHDJYTl$t#NnhTAiDFy@8o)e{`+7sTzOS^3=DpJ@kuK+2Qv)T%zS?y6!o&?71LY z)dcVA2!{ARKc6Y77d)N|>h)>q)mG9{qPb^Mq=_`+*K8k%r{?pk`FY`Je(47%t5)Xo kONIQ={LAx;C+3d5FmHcibm*o0;_U3n{NnY_wm*=60`kBlP5=M^ delta 1122 zcmZvaOGs2v9LB#pb92-gXLNLYH>qQplHkG�MD&iHM4ni%7^_7lB~t zG9eJcML{qq1rk)!16l}1n>HfxXQEjag$VYY`CF^*;djsDo_o*#`@XvrnIB)OigZP< z?gEY#z@8W!zBBOji#Hu`^#PT?hx)^PWh;wM0PK;PAuhNMobNf_BBetk;}h#uN523o z&iVTA=#B7?VC*{I_i%n?Bs?)@U9v)ap38aB&G1Nn`dZyH;QTe7IXE_YD{Z{HaOxv) zVVeu}54J*$6|lIMR0roXdVF<1;kLN|>{ph4{@WiN9L?Cp&U>6E!(mo=nfEG|gVye{ z<=E_)O3Y#1hBGlb$3B&ZOu@EVxU&{Tu#qpexWp}f$&msHNv$+Wv$RT^bV`r(%8bm( zszhZ&_LsfRypUf4l9$-maJ;W0v2R*t|LtpcUXED&e$#PlMoXf#LR%Y5Ye(mQ8{lJ| zh18V;FFeSGi}l+GAq7b&MIMS#h7(9bKF;DK(h5fLj$D+$k4yw` zn%*R>U9_zTb(>^h9hy6@azNM_crJt<8jMpyUk$7U;#61_gmD;HAH=1wQixkICx~BR z^^kx<9TA9GASMzqA0QM5$x|p3lCMxOq(Gr`huy;YbnzP(YHHNGz@OdavC!u%2MRl3cuz-s|9 ztI2xqm~iYkC!PEDR8m&bBUg=U()BvII(aXpIb|pHe(G0ulY7(C=2=NA@jmo!`%--i tzIb{pLo#zSTe23iB#;~UlwF public string ApiIpHost { get; set; } + /// + /// WebSocket服务器的地址 + /// + public string WebSocketUrl { get; set; } public List GroupName { get; set; } diff --git a/货架标准上位机/ViewModels/InInventoryViewModel.cs b/货架标准上位机/ViewModels/InInventoryViewModel.cs index c643e4c..cb9d04b 100644 --- a/货架标准上位机/ViewModels/InInventoryViewModel.cs +++ b/货架标准上位机/ViewModels/InInventoryViewModel.cs @@ -276,7 +276,7 @@ namespace 货架标准上位机.ViewModel var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "instore/queryInstoreStatus", body, "POST"); if (Result != null && !string.IsNullOrEmpty(Result.Message)) { - TextBoxLog.AddLog(Result.Message, "InstoreLog", DateTime.Now); + TextBoxLog.AddLog($"物料[{scanner.MatSn}]" + Result.Message, "InstoreLog", DateTime.Now); scanner.MatSn = string.Empty; scanner.ScannerDisplayControl.RefreshValues(scanner.ShelfCode, scanner.MatSn); } diff --git a/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs b/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs index ee7e65b..678b775 100644 --- a/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs +++ b/货架标准上位机/ViewModels/MatBaseInfoViewModel.cs @@ -227,18 +227,6 @@ namespace 货架标准上位机.ViewModel //已经选择文件 调用接口进行导入数据 string path = ofd.FileName; - var body = new GetMatBaseInfoRequest() - { - MatCode = MatCode, - MatName = MatName, - MatSpec = MatSpec, - IsEnable = IsEnable, - - UserName = LocalStatic.CurrentUser, - DeviceType = LocalFile.Config.DeviceType, - PageNumber = CurrentPage, - PageSize = 65535, - }; var result = await ApiHelp.PostImportFileAsync>>(path, System.Net.Http.HttpMethod.Post, LocalFile.Config.ApiIpHost + "matBaseInfo/importMatBaseInfo", LocalStatic.CurrentUser, LocalFile.Config.DeviceType); if (result.Code == 200) diff --git a/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs b/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs index f53dcd9..1cfa65e 100644 --- a/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs +++ b/货架标准上位机/ViewModels/MatInventoryDetailViewModel.cs @@ -33,14 +33,7 @@ namespace 货架标准上位机.ViewModel { public MatInventoryDetailViewModel() { - //获取物料编码列表 - //matCodes = DbHelp.db.Queryable() - // .Select(t => new DataModel() - // { - // MatCode = t.MatCode - // }) - // .Distinct() - // .ToList(); + } public void InitMatCode() diff --git a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs index 53051e8..66ad7fa 100644 --- a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs @@ -4,10 +4,12 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using WCS.BLL.DbModels; using WCS.Model; +using WCS.Model.ApiModel.Home; using WCS.Model.ApiModel.MatInventoryDetail; using 货架标准上位机.Api; @@ -35,6 +37,71 @@ namespace 货架标准上位机.ViewModels SetProperty(ref selectedItemSource, value); } } + + private List shelfTypeItems; + public List ShelfTypeItems + { + get { return shelfTypeItems; } + set + { + SetProperty(ref shelfTypeItems, value); + } + } + public void InitShelfTypeItems() + { + //调用接口更新! + Task.Run(() => + { + var body = new RequestBase() + { + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "home/getShelfTypes", body, "POST"); + if (Result != null && Result.Data != null && Result.Data.Lists.Count() > 0) + { + ShelfTypeItems = Result.Data.Lists; + SelectedShelfTypeItem = Result.Data.Lists.First(); + } + }); + } + + private ShelfTypeModel selectedShelfTypeItem; + public ShelfTypeModel SelectedShelfTypeItem + { + get { return selectedShelfTypeItem; } + set + { + SetProperty(ref selectedShelfTypeItem, value); + } + } + + private int selectedTypeCount = 0; + public int SelectedTypeCount + { + get => selectedTypeCount; + set + { + SetProperty(ref selectedTypeCount, value); + if (selectedTypeCount == 0) + { + ShelfTypeIsEnabled = true; + } + else + { + ShelfTypeIsEnabled = false; + } + } + } + + private bool shelfTypeIsEnabled = true; + public bool ShelfTypeIsEnabled + { + get => shelfTypeIsEnabled; set { SetProperty(ref shelfTypeIsEnabled, value); } + } + + #endregion #region Command @@ -44,7 +111,11 @@ namespace 货架标准上位机.ViewModels public ICommand BtnAddCommand { get => new DelegateCommand(BtnAdd); } public void BtnAdd() { - var window = new OutInventoryAddMatView(); + if (SelectedShelfTypeItem == null) + { + HandyControl.Controls.MessageBox.Show("请选择货架类型!"); + } + var window = new OutInventoryAddMatView(SelectedShelfTypeItem.Id); window.Owner = Application.Current.MainWindow; var result = window.ShowDialog(); if (result == true) @@ -52,6 +123,7 @@ namespace 货架标准上位机.ViewModels if (DataGridItemSource == null) DataGridItemSource = new ObservableCollection(); DataGridItemSource.Add(window.inventorySummary); + SelectedTypeCount = DataGridItemSource.Count; } else { @@ -66,11 +138,12 @@ namespace 货架标准上位机.ViewModels { DataGridItemSource.Remove(obj); - ; + SelectedTypeCount = DataGridItemSource.Count; } catch (Exception ex) { - + Growl.Info(ex.Message); + Logs.Write($"删除物料时发生异常", LogsType.Err); } } @@ -117,6 +190,8 @@ namespace 货架标准上位机.ViewModels { OrderType = "出库", OrderSource = "WCS前端", + ShelfTypeId = SelectedShelfTypeItem.Id, + ShelfTypeName = SelectedShelfTypeItem.ShelfTypeName, ItemList = DataGridItemSource.Select(t => new MatCodeItemList() { MatCode = t.MatCode, diff --git a/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs b/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs index 04f8520..f235045 100644 --- a/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryAddMatViewModel.cs @@ -58,6 +58,14 @@ namespace 货架标准上位机.ViewModels SetProperty(ref matName, value); } } + + private int shelfTypeId; + public int ShelfTypeId + { + get => shelfTypeId; + set { SetProperty(ref shelfTypeId, value); } + } + #endregion #region Command @@ -74,6 +82,7 @@ namespace 货架标准上位机.ViewModels { MatName = MatName, MatCode = MatCode, + ShelfTypeId = ShelfTypeId, }; var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "matInventoryDetail/getMatInventorySummary", body, "POST"); if (Result != null && Result.Data != null) diff --git a/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs index e8bf1b9..42c5d6a 100644 --- a/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs @@ -144,6 +144,17 @@ namespace 货架标准上位机.ViewModels BtnSearch(true); } + //导入出库 + public ICommand BtnImportDocumentCommand { get => new DelegateCommand(BtnImportDocument); } + public void BtnImportDocument() + { + var window = new OutInventoryImportDucumentView(); + window.Owner = Application.Current.MainWindow; + var result = window.ShowDialog(); + if (result == true) + BtnSearch(true); + } + public ICommand BtnOrderDetailCommand { get => new DelegateCommand(BtnOrderDetail); } public void BtnOrderDetail() { diff --git a/货架标准上位机/ViewModels/OutInventoryImportDucumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryImportDucumentViewModel.cs new file mode 100644 index 0000000..244a656 --- /dev/null +++ b/货架标准上位机/ViewModels/OutInventoryImportDucumentViewModel.cs @@ -0,0 +1,212 @@ +using HandyControl.Controls; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Windows; +using System.Windows.Input; +using WCS.BLL.DbModels; +using WCS.Model; +using WCS.Model.ApiModel.MatBaseInfo; +using WCS.Model.ApiModel.MatInventoryDetail; +using 货架标准上位机.Api; + +namespace 货架标准上位机.ViewModels +{ + public class OutInventoryImportDucumentViewModel : BindableBase + { + #region Property + private ObservableCollection dataGridItemSource; + public ObservableCollection DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + } + } + + private MatInventorySummaryModel selectedItemSource; + public MatInventorySummaryModel SelectedItemSource + { + get { return selectedItemSource; } + set + { + SetProperty(ref selectedItemSource, value); + } + } + #endregion + + #region Command + public ICommand BtnDownloadExcelCommand { get => new DelegateCommand(BtnDownloadExcel); } + public async void BtnDownloadExcel() + { + try + { + #region 选择文件保存路径 + Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog(); + sfd.Filter = ".xlsx文件(*.xlsx)|*.xlsx"; + sfd.FileName = "出库导入模板"; + sfd.Title = "请选择文件保存地址"; + sfd.OverwritePrompt = true; + if (sfd.ShowDialog() != true) + { + return; + } + string path = sfd.FileName; + #endregion + + #region 从本地下载复制模板 + string sourceFile = System.Environment.CurrentDirectory + "\\Excel\\出库单据导入模板.xlsx"; // 源文件路径 + string destinationFile = path; // 目标文件路径 + try + { + File.Copy(sourceFile, destinationFile, true); // true表示如果目标文件存在,则覆盖它 + Growl.Success("文件下载成功!"); + } + catch (IOException ioEx) + { + Growl.Success("文件下载失败: " + ioEx.Message); + } + catch (Exception ex) + { + Growl.Success("文件下载失败: " + ex.Message); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("导出失败:" + ex.Message); + } + } + + public ICommand BtnImportCommand { get => new DelegateCommand(BtnImport); } + public async void BtnImport() + { + try + { + #region 选择需要导入文件的路径 + Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); + ofd.Title = "选择模板"; + ofd.Filter = ".xlsx文件(*.xlsx)|*.xlsx"; + ofd.Multiselect = false; + + if (ofd.ShowDialog() != true) + { + return; + } + #endregion + //已经选择文件 调用接口进行导入数据 + string path = ofd.FileName; + #region 接口导入 返回所输入物料的状态信息 校验输入的值 + var result = await ApiHelp.PostImportFileAsync>>(path, System.Net.Http.HttpMethod.Post, + LocalFile.Config.ApiIpHost + "outstore/importMat", LocalStatic.CurrentUser, LocalFile.Config.DeviceType); + if (result.Code == 200) + { + DataGridItemSource = new ObservableCollection(result.Data); + } + else + { + if (result != null && !string.IsNullOrEmpty(result.Message)) + HandyControl.Controls.MessageBox.Show(result.Message); + else + { + HandyControl.Controls.MessageBox.Show("导入失败,请重试!"); + } + } + #endregion + } + catch (Exception ex) + { + Growl.Warning("导入失败:" + ex.Message); + } + } + + public ICommand DelCommand { get => new DelegateCommand(Del); } + public void Del(MatInventorySummaryModel obj) + { + try + { + + DataGridItemSource.Remove(obj); + ; + } + catch (Exception ex) + { + + } + } + + // 定义一个事件,当需要关闭窗口时触发 + public event Action TrueClose; + public event Action FalseClose; + // 一个方法,当满足某些条件时调用,以触发关闭窗口 + protected virtual void OnRequestClose(bool IsTrue) + { + if (IsTrue) + TrueClose?.Invoke(); + else + FalseClose?.Invoke(); + } + public ICommand GenerateOutOrderCommand { get => new DelegateCommand(GenerateOutOrder); } + public void GenerateOutOrder() + { + //数据校验 + if (DataGridItemSource == null || DataGridItemSource.Count == 0) + { + HandyControl.Controls.MessageBox.Show("选择的物料为空无法生成出库单!"); + return; + } + foreach (var itemSource in DataGridItemSource) + { + if (itemSource.NeedQty == 0) + { + Growl.Warning("需求数量未填!"); + SelectedItemSource = itemSource; + return; + } + } + #region 调用接口生成出库单据 + try + { + var body = new SysOutOrderByMatCodeRequest() + { + OrderType = "出库", + OrderSource = "WCS前端", + ItemList = DataGridItemSource.Select(t => new MatCodeItemList() + { + MatCode = t.MatCode, + MatName = t.MatName, + MatBatch = t.MatBatch, + ReqQty = t.NeedQty, + }).ToList(), + DeviceType = LocalFile.Config.DeviceType, + UserName = LocalStatic.CurrentUser + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outstore/sysOutOrderByMatCode", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success(Result.Message); + OnRequestClose(true); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + return; + } + } + catch (Exception ex) + { + Growl.Error("加载数据失败:" + ex.Message); + } + finally + { + } + #endregion + } + #endregion + } +} diff --git a/货架标准上位机/ViewModels/SetViewModel.cs b/货架标准上位机/ViewModels/SetViewModel.cs index ee16e23..1309d78 100644 --- a/货架标准上位机/ViewModels/SetViewModel.cs +++ b/货架标准上位机/ViewModels/SetViewModel.cs @@ -1,15 +1,26 @@ using HandyControl.Controls; +using HandyControl.Tools.Extension; using Microsoft.Win32; using Ping9719.WpfEx.Mvvm; +using QRCoder; using System; using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; using System.IO; using System.IO.Ports; using System.Linq; +using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using System.Windows.Documents; using System.Windows.Input; +using System.Windows.Markup; +using System.Windows.Media.Imaging; +using WCS.Model; +using 货架标准上位机.Api; +using 货架标准上位机.Views.Controls; +using static System.Net.WebRequestMethods; namespace 货架标准上位机.ViewModel { @@ -215,5 +226,61 @@ namespace 货架标准上位机.ViewModel { } } + + + public ICommand AppQRCodeCommand { get => new DelegateCommand(AppQRCode); } + public void AppQRCode() + { + try + { + #region 获取最新版App名称 + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "fileDownload/getLatestAppName", null, "GET"); + if (Result != null && Result.Code == 200) + { + //拼凑url + var downLoadUrl = LocalFile.Config.ApiIpHost + $"fileDownload/downloadApp?fileName={Result.Data}"; + //生成二维码 + var qrCodeImage = GenerateQRCode(downLoadUrl); + //展示二维码 + Dialog.Show(new ImageDialog(qrCodeImage)); + + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch + { + } + } + + public BitmapImage GenerateQRCode(string data) + { + QRCodeGenerator qrGenerator = new QRCodeGenerator(); + QRCodeData qrCodeData = qrGenerator.CreateQrCode(data, QRCodeGenerator.ECCLevel.Q); + QRCode qrCode = new QRCode(qrCodeData); + Bitmap qrCodeImage = qrCode.GetGraphic(20, Color.Black, Color.White, true); + // 将System.Drawing.Bitmap转换为System.Windows.Media.Imaging.BitmapImage + using (var memoryStream = new MemoryStream()) + { + // 假设Bitmap的Save方法支持Png格式(通常是这样) + qrCodeImage.Save(memoryStream, ImageFormat.Png); + memoryStream.Position = 0; + var bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.StreamSource = memoryStream; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + + // 返回BitmapImage + return bitmapImage; + } + } } } diff --git a/货架标准上位机/Views/Controls/ImageDialog.xaml b/货架标准上位机/Views/Controls/ImageDialog.xaml new file mode 100644 index 0000000..91740a1 --- /dev/null +++ b/货架标准上位机/Views/Controls/ImageDialog.xaml @@ -0,0 +1,15 @@ + + + + + + @@ -129,7 +129,7 @@ + + + + + + + + + + + + + + + + + + + + + + + 开机启动 diff --git a/货架标准上位机/WebSocket.cs b/货架标准上位机/WebSocket.cs index 456e697..7c7ecea 100644 --- a/货架标准上位机/WebSocket.cs +++ b/货架标准上位机/WebSocket.cs @@ -21,7 +21,7 @@ namespace 货架标准上位机 { client = new WebSocketClient(); client.Setup(new TouchSocketConfig() - .SetRemoteIPHost("ws://127.0.0.1:7789/ws") + .SetRemoteIPHost(LocalFile.Config.WebSocketUrl) .ConfigureContainer(a => { a.AddConsoleLogger(); @@ -97,7 +97,7 @@ namespace 货架标准上位机 } else { - + Application.Current.Dispatcher.Invoke(() => { WarningManager.AddWarning(warning); @@ -105,7 +105,7 @@ namespace 货架标准上位机 }); } - + } client.Send(e.DataFrame.ToText()); } diff --git a/货架标准上位机/data/jsconfig.json b/货架标准上位机/data/jsconfig.json index 66c8dc1..65236e4 100644 --- a/货架标准上位机/data/jsconfig.json +++ b/货架标准上位机/data/jsconfig.json @@ -3,8 +3,10 @@ "MySql": "server=localhost;Database=db1;Uid=root;Pwd=123456;Convert Zero Datetime=True", //货架服务器的IP和端口号 "ApiIpHost": "http://localhost:8888/", + //WebSocket的地址 + "WebSocketUrl": "ws://127.0.0.1:7789/ws", //货架分区 - "GroupName": [ "13寸智能货架", "7寸智能货架"], + "GroupName": [ "13寸智能货架", "7寸智能货架" ], //设备类型 可以配置为每个电脑不一样 "DeviceType": "WCS前端", //货架类型的是否开机自检 diff --git a/货架标准上位机/货架标准上位机.csproj b/货架标准上位机/货架标准上位机.csproj index a44de27..d26facb 100644 --- a/货架标准上位机/货架标准上位机.csproj +++ b/货架标准上位机/货架标准上位机.csproj @@ -51,6 +51,7 @@ + @@ -85,6 +86,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -102,12 +109,18 @@ + + PreserveNewest + Code Code + + Code + From 472862a978b6cd45abeb4f442044ce04063c5129 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Tue, 21 May 2024 18:46:51 +0800 Subject: [PATCH 03/18] =?UTF-8?q?1.=E5=BA=93=E4=BD=8D=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E5=92=8C=E5=90=AF=E7=94=A8=E3=80=81=E6=A8=A1=E7=BB=84=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E5=90=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2.退出出库先解锁 后发指令 --- .../Services/IService/IStoreInfoService.cs | 18 ++- WCS.BLL/Services/Service/OutstoreService.cs | 13 +- WCS.BLL/Services/Service/StoreInfoService.cs | 132 ++++++++++++++++++ .../OutStore/GetOutOrderListRequest.cs | 2 + .../StoreInfo/DisableOrEnableModuleRequest.cs | 15 ++ .../StoreInfo/DisableOrEnableStoreRequest.cs | 22 +++ .../Controllers/FileDownLoadController.cs | 2 +- WCS.WebApi/Controllers/StoreInfoController.cs | 14 ++ WCS.WebApi/Files/APP.app | 0 .../ViewModels/ModuleInfoViewModel.cs | 94 ++++++++++++- .../ViewModels/StoreInfoViewModel.cs | 90 ++++++++++++ .../Views/Controls/UserView.xaml.cs | 14 -- .../Views/MainWindows/MainWindow1.xaml | 10 +- 货架标准上位机/Views/ModuleInfoView.xaml | 13 +- 货架标准上位机/Views/StoreInfoView.xaml | 12 +- 货架标准上位机/data/jsconfig.json | 2 +- 16 files changed, 417 insertions(+), 36 deletions(-) create mode 100644 WCS.Model/ApiModel/StoreInfo/DisableOrEnableModuleRequest.cs create mode 100644 WCS.Model/ApiModel/StoreInfo/DisableOrEnableStoreRequest.cs delete mode 100644 WCS.WebApi/Files/APP.app diff --git a/WCS.BLL/Services/IService/IStoreInfoService.cs b/WCS.BLL/Services/IService/IStoreInfoService.cs index 49bff75..e4ac645 100644 --- a/WCS.BLL/Services/IService/IStoreInfoService.cs +++ b/WCS.BLL/Services/IService/IStoreInfoService.cs @@ -32,19 +32,33 @@ namespace WCS.BLL.Services.IService /// - /// 查询货架列表 + /// 查询模组列表 /// /// /// public Task> GetModules(GetModulesRequest request); + /// + /// 禁用或启用模组 + /// + /// + /// + public Task disableOrEnableModule(DisableOrEnableModuleRequest request); + /// - /// 查询货架列表 + /// 查询库位列表 /// /// /// public Task> GetStores(GetStoresRequest request); + /// + /// 禁用或启用库位 + /// + /// + /// + public Task disableOrEnableStore(DisableOrEnableStoreRequest request); + } } diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index fba3311..14cbeb6 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -261,7 +261,8 @@ namespace WCS.BLL.Services.Service 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(!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 @@ -859,6 +860,10 @@ namespace WCS.BLL.Services.Service 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.出库模式) @@ -874,15 +879,15 @@ namespace WCS.BLL.Services.Service }; } + + //退出出库模式 shelves.ForEach(t => { t.GoOutOutstore(); }); - //解锁物料 删除物料明细 - if (order.SyncType == SyncTypeEnum.ByMatCode) - CancelOutOrderMatDetails(order); + return new ResponseCommon() { diff --git a/WCS.BLL/Services/Service/StoreInfoService.cs b/WCS.BLL/Services/Service/StoreInfoService.cs index 9056619..aef3f20 100644 --- a/WCS.BLL/Services/Service/StoreInfoService.cs +++ b/WCS.BLL/Services/Service/StoreInfoService.cs @@ -12,6 +12,7 @@ using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model; using WCS.Model.ApiModel; +using WCS.Model.ApiModel.InOutRecord; using WCS.Model.ApiModel.StoreInfo; using WCS.Model.ApiModel.User; @@ -308,6 +309,58 @@ namespace WCS.BLL.Services.Service }; } } + + /// + /// 禁用或启用模组 + /// + /// + /// + public async Task disableOrEnableModule(DisableOrEnableModuleRequest request) + { + //找到库位 + var moduleInfo = await DbHelp.db.Queryable() + .Where(t => t.Id == request.ModuleId) + .FirstAsync(); + //库位不存在 + if (moduleInfo == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:模组{request.ModuleCode}不存在!" + }; + } + try + { + DbHelp.db.BeginTran(); + //禁用需要删除当前库存数据 + if (request.DisableOrEnable == DisableOrEnableEnum.Disable) + { + moduleInfo.IsEnable = false; + + } + else + { + moduleInfo.IsEnable = true; + } + DbHelp.db.Updateable(moduleInfo).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}!" + }; + } + } #endregion #region 库位管理 @@ -352,6 +405,85 @@ namespace WCS.BLL.Services.Service }; } } + + public async Task disableOrEnableStore(DisableOrEnableStoreRequest request) + { + //找到库位 + var storeInfo = await DbHelp.db.Queryable() + .Where(t => t.Id == request.StoreId) + .FirstAsync(); + //库位不存在 + if (storeInfo == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"操作失败:库位{request.SroreCode}不存在!" + }; + } + try + { + DbHelp.db.BeginTran(); + //禁用需要删除当前库存数据 + if (request.DisableOrEnable == DisableOrEnableEnum.Disable) + { + //库位 + storeInfo.CurrentMatSn = "禁用"; + //库存数据处理 + var inventorys = DbHelp.db.Queryable() + .Where(t => t.StoreId == storeInfo.Id) + .ToList(); + if (inventorys != null && inventorys.Count > 0) + { + //删除并进行出入库记录 + foreach (var inventory in inventorys) + { + var inOutRecord = new InOutRecord() + { + StoreCode = storeInfo.StoreCode, + StoreId = storeInfo.Id, + StoreInfo = storeInfo, + + MatSN = inventory.MatSN, + MatCode = inventory.MatCode, + MatName = inventory.MatName, + MatSpec = inventory.MatSpec, + MatBatch = inventory.MatBatch, + MatQty = inventory.MatQty, + MatCustomer = inventory.MatCustomer, + MatSupplier = inventory.MatSupplier, + + OperateUser = request.UserName + "(禁用库位)", + Direction = DirectionEnum.丢失, + }; + DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + DbHelp.db.Deleteable(inventory).ExecuteCommand(); + } + } + } + else + { + storeInfo.CurrentMatSn = string.Empty; + } + DbHelp.db.Updateable(storeInfo).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}!" + }; + } + } + #endregion } } diff --git a/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs b/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs index a9b18a0..76c0989 100644 --- a/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs +++ b/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs @@ -13,5 +13,7 @@ namespace WCS.Model public string OrderSource { get; set; } public string OrderType { get; set; } + + public int ShelfTypeId { get; set; } = 0; } } diff --git a/WCS.Model/ApiModel/StoreInfo/DisableOrEnableModuleRequest.cs b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableModuleRequest.cs new file mode 100644 index 0000000..60b978d --- /dev/null +++ b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableModuleRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.StoreInfo +{ + public class DisableOrEnableModuleRequest : RequestBase + { + public int ModuleId { get; set; } + + public string ModuleCode { get; set; } + + public DisableOrEnableEnum DisableOrEnable { get; set; } + } +} diff --git a/WCS.Model/ApiModel/StoreInfo/DisableOrEnableStoreRequest.cs b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableStoreRequest.cs new file mode 100644 index 0000000..1b36ec7 --- /dev/null +++ b/WCS.Model/ApiModel/StoreInfo/DisableOrEnableStoreRequest.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.StoreInfo +{ + public class DisableOrEnableStoreRequest : RequestBase + { + public int StoreId { get; set; } + + public string SroreCode { get; set; } + + public DisableOrEnableEnum DisableOrEnable { get; set; } + } + + public enum DisableOrEnableEnum + { + Disable = 0, + Enable = 1 + } + +} diff --git a/WCS.WebApi/Controllers/FileDownLoadController.cs b/WCS.WebApi/Controllers/FileDownLoadController.cs index e36f103..028b6be 100644 --- a/WCS.WebApi/Controllers/FileDownLoadController.cs +++ b/WCS.WebApi/Controllers/FileDownLoadController.cs @@ -47,7 +47,7 @@ namespace WCS.WebApi.Controllers string directoryPath = Path.Combine(Directory.GetCurrentDirectory(), $"Files"); // 获取目录下的所有文件信息 - FileInfo[] files = Directory.GetFiles(directoryPath, "*.app") + FileInfo[] files = Directory.GetFiles(directoryPath, "*.APK") .Select(file => new FileInfo(file)) .ToArray(); diff --git a/WCS.WebApi/Controllers/StoreInfoController.cs b/WCS.WebApi/Controllers/StoreInfoController.cs index 1532fb3..d0ac534 100644 --- a/WCS.WebApi/Controllers/StoreInfoController.cs +++ b/WCS.WebApi/Controllers/StoreInfoController.cs @@ -52,6 +52,13 @@ namespace WCS.WebApi.Controllers { return await _storeInfoService.GetModules(request); } + + [Route("disableOrEnableModule")] + [HttpPost(Name = "disableOrEnableModule")] + public async Task disableOrEnableModule(DisableOrEnableModuleRequest request) + { + return await _storeInfoService.disableOrEnableModule(request); + } #endregion #region 库位管理 @@ -61,6 +68,13 @@ namespace WCS.WebApi.Controllers { return await _storeInfoService.GetStores(request); } + + [Route("disableOrEnableStore")] + [HttpPost(Name = "disableOrEnableStore")] + public async Task disableOrEnableStore(DisableOrEnableStoreRequest request) + { + return await _storeInfoService.disableOrEnableStore(request); + } #endregion } } diff --git a/WCS.WebApi/Files/APP.app b/WCS.WebApi/Files/APP.app deleted file mode 100644 index e69de29..0000000 diff --git a/货架标准上位机/ViewModels/ModuleInfoViewModel.cs b/货架标准上位机/ViewModels/ModuleInfoViewModel.cs index 6476799..fa64745 100644 --- a/货架标准上位机/ViewModels/ModuleInfoViewModel.cs +++ b/货架标准上位机/ViewModels/ModuleInfoViewModel.cs @@ -19,6 +19,7 @@ using WCS.Model.ApiModel.MatBaseInfo; using WCS.Model.ApiModel.User; using WCS.Model.ApiModel; using Newtonsoft.Json.Bson; +using System.Windows; namespace 货架标准上位机.ViewModel { @@ -75,7 +76,7 @@ namespace 货架标准上位机.ViewModel public ICommand BtnResetCommand { get => new DelegateCommand(BtnReset); } public void BtnReset() { - ModuleCode = string.Empty; + ModuleCode = string.Empty; ShelfCode = string.Empty; } @@ -153,6 +154,97 @@ namespace 货架标准上位机.ViewModel } } } + + public ICommand DisableCommand { get => new DelegateCommand(Disable); } + public void Disable(ModuleInfoModel module) + { + if (module.IsEnable != true) + { + Growl.Warning("库位未被启用!"); + return; + } + var result = HandyControl.Controls.MessageBox.Show("模组禁用会影响正常流程,请确认是否屏蔽?" + , "提示", MessageBoxButton.YesNo); + if (result == MessageBoxResult.Yes) + { + #region 调用接口 禁用 + try + { + var body = new DisableOrEnableModuleRequest() + { + ModuleId = module.Id, + ModuleCode = module.ModuleCode, + DisableOrEnable = DisableOrEnableEnum.Disable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableModule", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("禁用成功"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } + else + { + return; + } + } + + public ICommand EnableCommand { get => new DelegateCommand(Enable); } + public void Enable(ModuleInfoModel module) + { + if (module.IsEnable == true) + { + Growl.Warning("库位未被禁用!"); + return; + } + #region 调用接口 临时禁用库位 删除库存数据 + try + { + var body = new DisableOrEnableModuleRequest() + { + ModuleId = module.Id, + ModuleCode = module.ModuleCode, + DisableOrEnable = DisableOrEnableEnum.Enable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableModule", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("操作成功!"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } #endregion #region PageOperation 分页操作 diff --git a/货架标准上位机/ViewModels/StoreInfoViewModel.cs b/货架标准上位机/ViewModels/StoreInfoViewModel.cs index c91026c..fc5302a 100644 --- a/货架标准上位机/ViewModels/StoreInfoViewModel.cs +++ b/货架标准上位机/ViewModels/StoreInfoViewModel.cs @@ -19,6 +19,8 @@ using WCS.Model.ApiModel.MatBaseInfo; using WCS.Model.ApiModel.User; using WCS.Model.ApiModel; using Newtonsoft.Json.Bson; +using System.Windows; +using System.Security.Cryptography; namespace 货架标准上位机.ViewModel { @@ -140,6 +142,94 @@ namespace 货架标准上位机.ViewModel } #endregion } + + public ICommand DisableCommand { get => new DelegateCommand(Disable); } + public void Disable(StoreInfoModel store) + { + var result = HandyControl.Controls.MessageBox.Show("库位屏蔽仅用于临时屏蔽硬件损坏识别的未扫描上架!\r\n" + + "操作时会删除对应库位的数据,需要保证对应库位物料已取出。\r\n" + + "请确认是否进行操作?" + , "提示", MessageBoxButton.YesNo); + if (result == MessageBoxResult.Yes) + { + #region 调用接口 临时禁用库位 删除库存数据 + try + { + var body = new DisableOrEnableStoreRequest() + { + StoreId = store.Id, + SroreCode = store.StoreCode, + DisableOrEnable = DisableOrEnableEnum.Disable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableStore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("禁用成功"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } + else + { + return; + } + } + + public ICommand EnableCommand { get => new DelegateCommand(Enable); } + public void Enable(StoreInfoModel store) + { + if (store.CurrentMatSn != "禁用") + { + Growl.Warning("库位未被禁用!"); + return; + } + #region 调用接口 临时禁用库位 删除库存数据 + try + { + var body = new DisableOrEnableStoreRequest() + { + StoreId = store.Id, + SroreCode = store.StoreCode, + DisableOrEnable = DisableOrEnableEnum.Enable, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "storeInfo/disableOrEnableStore", body, "POST"); + if (Result != null && Result.Code == 200) + { + Growl.Success("操作成功!"); + BtnSearch(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("操作失败:请重试!"); + } + } + catch (Exception ex) + { + Growl.Error("操作失败:" + ex.Message); + } + #endregion + } #endregion #region PageOperation 分页操作 diff --git a/货架标准上位机/Views/Controls/UserView.xaml.cs b/货架标准上位机/Views/Controls/UserView.xaml.cs index 0424a80..f9f989e 100644 --- a/货架标准上位机/Views/Controls/UserView.xaml.cs +++ b/货架标准上位机/Views/Controls/UserView.xaml.cs @@ -1,20 +1,6 @@ using 货架标准上位机.ViewModel; using Ping9719.WpfEx; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace 货架标准上位机 { diff --git a/货架标准上位机/Views/MainWindows/MainWindow1.xaml b/货架标准上位机/Views/MainWindows/MainWindow1.xaml index ae08325..8157270 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow1.xaml +++ b/货架标准上位机/Views/MainWindows/MainWindow1.xaml @@ -241,16 +241,16 @@ - - - - - + + + + + diff --git a/货架标准上位机/Views/ModuleInfoView.xaml b/货架标准上位机/Views/ModuleInfoView.xaml index 19b669e..bceec7c 100644 --- a/货架标准上位机/Views/ModuleInfoView.xaml +++ b/货架标准上位机/Views/ModuleInfoView.xaml @@ -84,14 +84,23 @@ - - + + + + + + - @@ -102,8 +102,8 @@ -