From b2f9c7cc22ffa2f27fd4c94ca99d8264c7cf5ef3 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Tue, 21 May 2024 10:32:52 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=87=BA=E5=BA=93=E5=8D=95=E6=8D=AE=E3=80=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=87=BA=E5=BA=93=E5=8D=95=E6=8D=AE=E3=80=81?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E7=89=A9=E6=96=99=E6=97=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=B4=A7=E6=9E=B6=E7=B1=BB=E5=9E=8B=E7=94=A8=E4=BA=8E=E5=8C=BA?= =?UTF-8?q?=E5=88=86=E4=BF=A1=E6=81=AF=E5=8C=96=E8=B4=A7=E6=9E=B6=E5=92=8C?= =?UTF-8?q?=E6=99=BA=E8=83=BD=E8=B4=A7=E6=9E=B6=E7=9A=84=E7=89=A9=E6=96=99?= =?UTF-8?q?=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 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 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 +