From a1199028b3a418ee99ed3127dc6db734f1d48bc2 Mon Sep 17 00:00:00 2001 From: hehaibing-1996 Date: Thu, 25 Apr 2024 09:48:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WCS.BLL/Config/LocalFile.cs | 2 +- WCS.BLL/DbModels/InOutRecord.cs | 3 +- WCS.BLL/DbModels/OutOrder.cs | 6 + WCS.BLL/DbModels/StoreInfo.cs | 21 +- WCS.BLL/HardWare/IShelfBase.cs | 5 + WCS.BLL/HardWare/IWarningLightBase.cs | 87 ++-- WCS.BLL/HardWare/SingleLightShelf.cs | 4 + WCS.BLL/HardWare/SmartShelf.cs | 455 ++++++++++++++++-- WCS.BLL/Manager/DbInit.cs | 25 + WCS.BLL/Manager/ShelfManager.cs | 14 - WCS.BLL/Manager/TCPClientManager.cs | 108 +++++ WCS.BLL/Services/Service/InstoreService.cs | 58 ++- WCS.BLL/Services/Service/OutstoreService.cs | 32 +- WCS.BLL/Tool/TCPClient.cs | 2 +- .../ApiModel/InStore/QueryByMatSnRequest.cs | 1 - .../MatInventorySummaryModel.cs | 13 +- WCS.WebApi/Controllers/OutstoreController.cs | 14 +- WCS.WebApi/Program.cs | 6 +- .../ViewModels/InInventoryViewModel.cs | 52 +- .../ViewModels/OutInventoryAddDucumentViewModel.cs | 84 +++- .../Views/OutInventoryAddDucumentView.xaml | 17 +- .../Views/OutInventoryAddDucumentView.xaml.cs | 48 +- 22 files changed, 861 insertions(+), 196 deletions(-) create mode 100644 WCS.BLL/Manager/DbInit.cs create mode 100644 WCS.BLL/Manager/TCPClientManager.cs diff --git a/WCS.BLL/Config/LocalFile.cs b/WCS.BLL/Config/LocalFile.cs index 3a40d3d..5c07427 100644 --- a/WCS.BLL/Config/LocalFile.cs +++ b/WCS.BLL/Config/LocalFile.cs @@ -40,7 +40,7 @@ namespace WCS.BLL.Config /// /// 货架模组编码正则表达式 /// - public static readonly string ModuleCodePattern = "^[ABCD][0-9]{2}-R[0-9]{1,2}C[0-9]{1,2}$"; + public static readonly string ModuleCodePattern = "^[ABCD][0-9]{1,2}-R[0-9]{1,2}C[0-9]{1,2}$"; static object lockConfig = new object(); diff --git a/WCS.BLL/DbModels/InOutRecord.cs b/WCS.BLL/DbModels/InOutRecord.cs index 715348b..48e5e2d 100644 --- a/WCS.BLL/DbModels/InOutRecord.cs +++ b/WCS.BLL/DbModels/InOutRecord.cs @@ -11,6 +11,7 @@ namespace WCS.BLL.DbModels /// /// 出入库记录 /// + [SugarTable("in_out_record")] public class InOutRecord { /// @@ -86,7 +87,7 @@ namespace WCS.BLL.DbModels /// /// 出库单据号/盘点单据号 /// - [SugarColumn(ColumnName = "order_number", Length = 50, IsNullable = false, ColumnDescription = "出库单据号/盘点单据号")] + [SugarColumn(ColumnName = "order_number", Length = 50, IsNullable = true, ColumnDescription = "出库单据号/盘点单据号")] public string? OrderNumber { get; set; } /// diff --git a/WCS.BLL/DbModels/OutOrder.cs b/WCS.BLL/DbModels/OutOrder.cs index c3b6971..72026b9 100644 --- a/WCS.BLL/DbModels/OutOrder.cs +++ b/WCS.BLL/DbModels/OutOrder.cs @@ -38,6 +38,12 @@ namespace WCS.BLL.DbModels [SugarColumn(ColumnName = "order_type", Length = 50, IsNullable = true, ColumnDescription = "单据类型")] public string OrderType { get; set; } + /// + /// 单据同步类型 + /// + [SugarColumn(ColumnName = "sync_type", Length = 50, IsNullable = true, ColumnDescription = "单据同步类型:ByMatCode,ByMatSn")] + public string SyncType { get; set; } = string.Empty; + /// /// 创建时间 /// diff --git a/WCS.BLL/DbModels/StoreInfo.cs b/WCS.BLL/DbModels/StoreInfo.cs index 834b7c2..2d6bea9 100644 --- a/WCS.BLL/DbModels/StoreInfo.cs +++ b/WCS.BLL/DbModels/StoreInfo.cs @@ -7,76 +7,85 @@ using System.Threading.Tasks; namespace WCS.DAL.DbModels { + [SugarTable("store_info")] public partial class StoreInfo { - /// /// 库位Id /// - /// - /// 主键 自增Id - /// - //[SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsNullable = false, IsIdentity = true)] + [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsNullable = false, IsIdentity = true)] public int Id { get; set; } /// - /// 库位编码 + /// 入库的库位编码 /// + [SugarColumn(ColumnName = "store_code", Length = 50, IsNullable = false, ColumnDescription = "库位编码")] public string StoreCode { get; set; } /// /// 模组Id /// + [SugarColumn(ColumnName = "module_id", IsNullable = false, ColumnDescription = "模组Id")] public int ModuleId { get; set; } /// /// 模组编号 /// + [SugarColumn(ColumnName = "module_code", Length = 50, IsNullable = false, ColumnDescription = "模组编码")] public string ModuleCode { get; set; } /// /// 货架Id /// + [SugarColumn(ColumnName = "shelf_id", IsNullable = false, ColumnDescription = "货架Id")] public int ShelfId { get; set; } /// /// 货架号 /// + [SugarColumn(ColumnName = "shelf_code", Length = 50, IsNullable = false, ColumnDescription = "货架编码;货架一般按照报警灯来区分 一个报警灯指示的是一个货架")] public string ShelfCode { get; set; } /// /// 板子的Id /// + [SugarColumn(ColumnName = "board_id", IsNullable = false, ColumnDescription = "货架Id")] public int BoardId { get; set; } /// /// 板子上第几个灯 /// + [SugarColumn(ColumnName = "light_number", IsNullable = true, ColumnDescription = "板子上第几个灯")] public int LightNumber { get; set; } /// /// 优先级;为钢网柜推荐库位预留 /// + [SugarColumn(ColumnName = "priority", IsNullable = true, ColumnDescription = "板子上第几个灯")] public int Priority { get; set; } /// /// 当前物料;货架这种一对一且带检测的就给这个赋值,方便出入库时的查询 /// + [SugarColumn(ColumnName = "current_mat_sn", Length = 200, IsNullable = true, ColumnDescription = "当前物料")] public string CurrentMatSn { get; set; } /// /// 当前电压;当前电压,调试排查问题用 /// + [SugarColumn(ColumnName = "current_voltage", IsNullable = true, ColumnDescription = "当前电压值")] public decimal CurrentVoltage { get; set; } /// /// 标准电压;标准电压,调试排查问题用 /// + [SugarColumn(ColumnName = "standard_voltage", IsNullable = true, ColumnDescription = "标准电压值")] public decimal StandardVoltage { get; set; } /// /// 偏差电压;偏差电压,调试排查问题用 /// + [SugarColumn(ColumnName = "offset_voltage", IsNullable = true, ColumnDescription = "电压偏移值")] public decimal OffsetVoltage { get; set; } } } diff --git a/WCS.BLL/HardWare/IShelfBase.cs b/WCS.BLL/HardWare/IShelfBase.cs index 42f4a64..78a7ed0 100644 --- a/WCS.BLL/HardWare/IShelfBase.cs +++ b/WCS.BLL/HardWare/IShelfBase.cs @@ -32,6 +32,9 @@ namespace WCS.BLL.HardWare /// public int ColumnCounts { get; set; } + public int LightId { get; set; } + public List ModuleIds { get; set; } + public string ClientIp { get; set; } /// /// 货架当前模式 /// @@ -39,6 +42,8 @@ namespace WCS.BLL.HardWare public MatInfoResponse InStoreData { get; set; } + public List ExceptionMessages { get; set; } + public string OrderNumber { get; set; }//出库/盘点模式中的单据号 public string ModulesStr { get; set; } diff --git a/WCS.BLL/HardWare/IWarningLightBase.cs b/WCS.BLL/HardWare/IWarningLightBase.cs index ef6a7b7..577439b 100644 --- a/WCS.BLL/HardWare/IWarningLightBase.cs +++ b/WCS.BLL/HardWare/IWarningLightBase.cs @@ -41,6 +41,9 @@ namespace WCS.BLL.HardWare data[3] = (byte)lightMode; data[5] = (byte)lightBuzzerStatus; + //Only For Debug + data[5] = (byte)LightBuzzerStatus.关闭; + data[4] = time;//灯短亮一次的时间 data[6] = time;//蜂鸣器持续鸣叫的时间 @@ -53,49 +56,65 @@ namespace WCS.BLL.HardWare } } + /// + /// 蓝色报警灯常亮 + /// + /// public void BlueLight(TCPClient tcpClient) { LightOperation(LightColorEnum.蓝色, LightModeEnum.常亮, LightBuzzerStatus.关闭, tcpClient); } - + /// + /// 绿色报警灯常亮 + /// + /// + public void GreenLight(TCPClient tcpClient) + { + LightOperation(LightColorEnum.绿色, LightModeEnum.常亮, LightBuzzerStatus.关闭, tcpClient); + } - //public void CloseLight(string ip, int tagId) - //{ - // LightOperation(LightColorEnum.蓝色, LightModeEnum.关闭, LightBuzzerStatus.关闭, ip, "00", tagId); - //} + /// + /// 关闭报警灯 + /// + /// + public void CloseLight(TCPClient tcpClient) + { + LightOperation(LightColorEnum.蓝色, LightModeEnum.关闭, LightBuzzerStatus.关闭, tcpClient); + } - ///// - ///// 红色报警灯 响三秒 - ///// - ///// - ///// - ///// - //public void WaringLight(string ip, int tagId) - //{ - // LightOperation(LightColorEnum.红色, LightModeEnum.短亮一次, LightBuzzerStatus.鸣叫一次, ip, "22", tagId); - // Thread.Sleep(3300); - // return BlueLight(ip, tagId); - //} + /// + /// 红色报警灯 响3秒 蓝灯结束 + /// + /// + public void WaringLightBlueEnd(TCPClient tcpClient) + { + LightOperation(LightColorEnum.红色, LightModeEnum.短亮一次, LightBuzzerStatus.鸣叫一次, tcpClient, 0x22); + Thread.Sleep(3300); + BlueLight(tcpClient); + } - //public void WaringLightAlwaysRed(string ip, int tagId) - //{ - // return LightOperation(LightColorEnum.红色, LightModeEnum.常亮, LightBuzzerStatus.鸣叫一次, ip, "22", tagId); - //} + /// + /// 红色报警灯 响3秒 红灯结束 + /// + /// + public void WaringLightAlwaysRed(TCPClient tcpClient) + { + LightOperation(LightColorEnum.红色, LightModeEnum.常亮, LightBuzzerStatus.鸣叫一次, tcpClient, 0x22); + } - //public void SuccessLightBlueEnd(string ip, int tagId) - //{ - // LightOperation(LightColorEnum.绿色, LightModeEnum.短亮一次, LightBuzzerStatus.鸣叫一次, ip, "03", tagId); - // Thread.Sleep(300); - // return BlueLight(ip, tagId); - //} - - //public void SuccessLightGreenEnd(string ip, int tagId) - //{ - // LightOperation(LightColorEnum.绿色, LightModeEnum.短亮一次, LightBuzzerStatus.鸣叫一次, ip, "03", tagId); - // Thread.Sleep(300); - // return GreenLight(ip, tagId); - //} + public void SuccessLightBlueEnd(TCPClient tcpClient) + { + LightOperation(LightColorEnum.绿色, LightModeEnum.短亮一次, LightBuzzerStatus.鸣叫一次, tcpClient, 0x03); + Thread.Sleep(300); + BlueLight(tcpClient); + } + public void SuccessLightGreenEnd(TCPClient tcpClient) + { + LightOperation(LightColorEnum.绿色, LightModeEnum.短亮一次, LightBuzzerStatus.鸣叫一次, tcpClient, 0x03); + Thread.Sleep(300); + GreenLight(tcpClient); + } } } diff --git a/WCS.BLL/HardWare/SingleLightShelf.cs b/WCS.BLL/HardWare/SingleLightShelf.cs index 4d13f46..80e6feb 100644 --- a/WCS.BLL/HardWare/SingleLightShelf.cs +++ b/WCS.BLL/HardWare/SingleLightShelf.cs @@ -19,6 +19,10 @@ namespace WCS.BLL.HardWare public MatInfoResponse InStoreData { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string OrderNumber { get; set; } + public int LightId { get; set; } + public List ModuleIds { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string ClientIp { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public List ExceptionMessages { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public void GoInInstore(string IPAdress) { diff --git a/WCS.BLL/HardWare/SmartShelf.cs b/WCS.BLL/HardWare/SmartShelf.cs index 3726b0c..a8795d4 100644 --- a/WCS.BLL/HardWare/SmartShelf.cs +++ b/WCS.BLL/HardWare/SmartShelf.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Sockets; using WCS.BLL.DbModels; +using WCS.BLL.Manager; using WCS.DAL; using WCS.DAL.Db; using WCS.DAL.DbModels; @@ -26,6 +27,9 @@ namespace WCS.BLL.HardWare RowCounts = shelfInfo.Rowcounts; ColumnCounts = shelfInfo.Columncounts; CurentMode = shelfInfo.CurrentMode; + ClientIp = shelfInfo.ClientIp; + LightId = shelfInfo.LightId; + WarningLight = new WarningLight() { LightId = shelfInfo.LightId }; //初始化Module Task.Run(() => @@ -43,48 +47,52 @@ namespace WCS.BLL.HardWare }); } ModulesStr = string.Join(";", Modules.Select(t => t.ModuleCode)); + + ModuleIds = Modules.Select(t => t.ModuleId).ToList(); }); - //初始化TCPCleint - TcpCleint = new TCPClient("127.0.0.1:20002", "127.0.0.1:20003"); - TcpCleint.Connect(); - TcpCleint.tcpClient.Received += (client, e) => - { - 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 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 = (data[TcpCleint.PreFixLength + 0] << 8) + data[TcpCleint.PreFixLength + 1]; - //协议处理 判断功能位 - switch (dataTemp[TcpCleint.PreFixLength + 2]) - { - case 0x01: - ; - break; - case 0x03://正常入库信号 - InStoreReturnProcess(dataTemp); - break; - default: - ; - break; - } - } - } - return EasyTask.CompletedTask; - }; + ////初始化TCPCleint + //TcpCleint = new TCPClient("192.168.0.11:20002", "192.168.0.154:20003"); + //TcpCleint.tcpClient.Received += (client, e) => + //{ + // 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 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 = (data[TcpCleint.PreFixLength + 0] << 8) + data[TcpCleint.PreFixLength + 1]; + // var lightNumber = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]); + + // //协议处理 判断功能位 + // switch (dataTemp[TcpCleint.PreFixLength + 2]) + // { + // case 0x01://进入入库模式信号 + // GoInInstoreProcess(dataTemp, boardId, lightNumber); + // break; + // case 0x03://正常入库信号 + // InStoreReturnProcess(dataTemp); + // break; + // default: + // ; + // break; + // } + // } + // } + // return EasyTask.CompletedTask; + //}; + //TcpCleint.Connect(); } public int ShelfId { get; set; } @@ -95,8 +103,9 @@ namespace WCS.BLL.HardWare public string ModulesStr { get; set; }//当前货架所有模组的Str public string GroupName { get; set; } public List Modules { get; set; } = new List(); - public TCPClient TcpCleint { get; set; } + public TCPClient TcpCleint { get { return TCPClientManager.GetTCPClientByIPHost(ClientIp); } } + public int LightId { get; set; } public WarningLight WarningLight { get; set; } public List ExceptionMessages { get; set; } = new List(); @@ -106,6 +115,10 @@ namespace WCS.BLL.HardWare public string OrderNumber { get; set; } + + public List ModuleIds { get; set; } + public string ClientIp { get; set; } + #region 协议处理 public void GoInInstore(string? IPAddress) { @@ -118,6 +131,8 @@ namespace WCS.BLL.HardWare { this.CurentMode = Mode.入库模式; } + //清空错误 + ExceptionMessages.Clear(); //货架所有模组发送指令进入入库模式 foreach (var module in Modules.Where(t => t.IsEnable).ToList()) { @@ -137,15 +152,14 @@ namespace WCS.BLL.HardWare if (deficientTime > 0) Thread.Sleep(deficientTime); //出现异常的未进入入库模式,有红灯进行指引 - //未出现异常的需要退出入库模式 - GoOutInstore(); + this.CurentMode = Mode.待机模式; return; } //延时处理 Thread.Sleep(50); } //警示灯亮起 - //WarningLight.BlueLight(); + WarningLight.BlueLight(TcpCleint); //绑定当前进入入库PDA/WCS前端的IP InstoreIpAddress = IPAddress; //返回成功 @@ -163,13 +177,16 @@ namespace WCS.BLL.HardWare { this.CurentMode = Mode.待机模式; } + //货架所有模组发送指令退出入库模式 foreach (var module in Modules.Where(t => t.IsEnable) - .Where(t => t.CurrentMode == Mode.入库模式) + //.Where(t => t.CurrentMode == Mode.入库模式) .ToList()) { module.GoOutInstoreMode(TcpCleint); } + //报警灯熄灭 + WarningLight.CloseLight(TcpCleint); } public void GoInOutstore() @@ -217,6 +234,192 @@ namespace WCS.BLL.HardWare #endregion #region 协议返回处理 + public void ProtocolProcess(byte[] data, int boardId, int lightNumber) + { + //协议处理 判断功能位 + switch (data[TcpCleint.PreFixLength + 2]) + { + case 0x01://进入入库模式返回信号 + GoInInstoreProcess(data, boardId, lightNumber); + break; + case 0x02://退出入库模式返回信号 + GoOutInstoreProcess(data, boardId, lightNumber); + break; + case 0x03://正常入库信号 + InStoreReturnProcess(data); + break; + case 0x05://进入出库模式返回信号 + + default: + ; + break; + } + } + /// + /// 进入入库模式返回信号处理 + /// + /// + public void GoInInstoreProcess(byte[] data, int boardId, int lightNumber) + { + //库存物料与实际情况匹配 + if (data[TcpCleint.PreFixLength + 3] == 0x01) + { + var module = this.Modules.Where(t => t.BoardId == boardId) + .FirstOrDefault(); + if (module == null) + { + //TO DO 报错 + return; + } + else + { + module.CurrentMode = Mode.入库模式; + } + } + //库存物料与实际情况不匹配 + else if (data[TcpCleint.PreFixLength + 3] == 0x00) + { + var module = this.Modules.Where(t => t.BoardId == boardId).FirstOrDefault(); + if (module == null) + { + //TO DO 报错 + return; + } + else + { + module.CurrentMode = Mode.入库模式; + } + //获取当前板所有库位 + var storeInfos = DbHelp.db.Queryable() + .Where(t => t.BoardId == boardId) + .ToList(); + //当前板子的灯数量 + var boardStoreNumber = storeInfos.Count(); + + List dataTemp = new List(); + int index11 = 0; + while (boardStoreNumber > 0) + { + if (boardStoreNumber >= 4) + { + dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(8, '0').Reverse().ToList()); + boardStoreNumber = boardStoreNumber - 4; + } + else + { + dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(2 * boardStoreNumber, '0').Reverse().ToList()); + boardStoreNumber = 0; + } + index11++; + } + //当前板子的灯数量 + boardStoreNumber = storeInfos.Count(); + for (int index = 0; index <= boardStoreNumber - 1; index++) + { + //当前库位异常 + if (dataTemp[2 * index + 1] == '1') + { + if (dataTemp[2 * index] == '1') + { + var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First(); + if (storeInfo != null) + { + #region 缓存记录异常信息 + ExceptionMessages.Add($"{storeInfo.StoreCode}物料{storeInfo.CurrentMatSn}丢失,库存数据已删除,请重新扫码后入库"); + #endregion + + #region 【后台】丢失的数据处理 + Task.Run(() => + { + try + { + DbHelp.db.BeginTran(); + //库位表字段清空 + storeInfo.CurrentMatSn = string.Empty; + DbHelp.db.Updateable(storeInfo).ExecuteCommand(); + + //库存表记录删除、插入出入记录 + var inventoryDetail = DbHelp.db.Queryable().Where(t => t.StoreId == storeInfo.Id).First(); + if (inventoryDetail != null) + { + var inOutRecord = new InOutRecord() + { + StoreCode = storeInfo.StoreCode, + StoreId = storeInfo.Id, + StoreInfo = storeInfo, + + MatSN = inventoryDetail.MatSN, + MatCode = inventoryDetail.MatCode, + MatName = inventoryDetail.MatName, + MatBatch = inventoryDetail.MatBatch, + MatQty = inventoryDetail.MatQty, + MatSpec = inventoryDetail.MatSpec, + MatCustomer = inventoryDetail.MatCustomer, + MatSupplier = inventoryDetail.MatSupplier, + + Direction = DirectionEnum.丢失, + }; + DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); + } + DbHelp.db.CommitTran(); + } + catch (Exception e) + { + DbHelp.db.RollbackTran(); + } + }); + #endregion + + WarningLight.WaringLightAlwaysRed(TcpCleint); + } + //库位未配置、返回数据异常 + else + { + //Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + } + } + else if (dataTemp[2 * index] == '0') + { + var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First(); + if (storeInfo != null) + { + #region 缓存记录异常信息 + ExceptionMessages.Add($"库位{storeInfo.StoreCode}:存在物料未扫描上架"); + #endregion + WarningLight.WaringLightAlwaysRed(TcpCleint); + } + else + { + Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + } + } + } + } + } + } + + /// + /// 退出入库模式返回信号处理 + /// + /// + public void GoOutInstoreProcess(byte[] data, int boardId, int lightNumber) + { + var module = this.Modules.Where(t => t.BoardId == boardId && t.CurrentMode == Mode.入库模式).FirstOrDefault(); + if (module == null) + { + return; + } + else + { + module.CurrentMode = Mode.待机模式; + } + } + + /// + /// 正常入库信号 + /// + /// public void InStoreReturnProcess(byte[] data) { var boardId = (data[TcpCleint.PreFixLength + 0] << 8) + data[TcpCleint.PreFixLength + 1]; @@ -249,7 +452,8 @@ namespace WCS.BLL.HardWare else { module.ComfirmErrInstore(TcpCleint); - //WaringLight(shelfStatus.ClientIp, shelfStatus.LightId); + WarningLight.WaringLightBlueEnd(TcpCleint); + //WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId); //TO DO Logs.Write($"[{guid}]当前物料信息不存在,请取出后重新扫码进行入库!"); return; } @@ -257,9 +461,11 @@ namespace WCS.BLL.HardWare //该位置已放置物料 else if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn)) { + module.ComfirmErrInstore(TcpCleint); + WarningLight.WaringLightBlueEnd(TcpCleint); //ComfirmErrInstoreByIp(shelfStatus.ClientIp, boardId); - //WaringLight(shelfStatus.ClientIp, shelfStatus.LightId); - //Logs.Write($"[{guid}]该位置已放置物料!"); + //WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId); + //TO DO Logs.Write($"[{guid}]该位置已放置物料!"); return; } #endregion @@ -325,8 +531,9 @@ namespace WCS.BLL.HardWare Task.Run(() => { //确认入库(硬件入库位置亮灯1秒) - //ComfirmInstoreByIp(client.IP, boardId); + module.ComfirmInstore(TcpCleint); //报警灯亮绿灯 鸣叫一次提示 + WarningLight.SuccessLightBlueEnd(TcpCleint); //SuccessLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId); }); } @@ -335,11 +542,159 @@ namespace WCS.BLL.HardWare DbHelp.db.RollbackTran(); Logs.Write($"入库保存数据异常,异常信息为{ex.Message}"); //报警灯报警 - //WaringLight(shelfStatus.ClientIp, shelfStatus.LightId); + WarningLight.WaringLightBlueEnd(TcpCleint); + //WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId); } } #endregion } + + + /// + /// 进入出库模式协议返回 + /// + /// + /// + /// + public void GoInOutstoreProcess(byte[] data, int boardId, int lightNumber) + { + //库存物料与实际情况匹配 + if (data[TcpCleint.PreFixLength + 3] == 0x01) + { + var module = this.Modules.Where(t => t.BoardId == boardId) + .FirstOrDefault(); + if (module == null) + { + //TO DO 报错 + return; + } + else + { + module.CurrentMode = Mode.入库模式; + } + } + //库存物料与实际情况不匹配 + else if (data[TcpCleint.PreFixLength + 3] == 0x00) + { + var module = this.Modules.Where(t => t.BoardId == boardId).FirstOrDefault(); + if (module == null) + { + //TO DO 报错 + return; + } + else + { + module.CurrentMode = Mode.入库模式; + } + //获取当前板所有库位 + var storeInfos = DbHelp.db.Queryable() + .Where(t => t.BoardId == boardId) + .ToList(); + //当前板子的灯数量 + var boardStoreNumber = storeInfos.Count(); + + List dataTemp = new List(); + int index11 = 0; + while (boardStoreNumber > 0) + { + if (boardStoreNumber >= 4) + { + dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(8, '0').Reverse().ToList()); + boardStoreNumber = boardStoreNumber - 4; + } + else + { + dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(2 * boardStoreNumber, '0').Reverse().ToList()); + boardStoreNumber = 0; + } + index11++; + } + //当前板子的灯数量 + boardStoreNumber = storeInfos.Count(); + for (int index = 0; index <= boardStoreNumber - 1; index++) + { + //当前库位异常 + if (dataTemp[2 * index + 1] == '1') + { + if (dataTemp[2 * index] == '1') + { + var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First(); + if (storeInfo != null) + { + #region 缓存记录异常信息 + ExceptionMessages.Add($"{storeInfo.StoreCode}物料{storeInfo.CurrentMatSn}丢失,库存数据已删除,请重新扫码后入库"); + #endregion + + #region 【后台】丢失的数据处理 + Task.Run(() => + { + try + { + DbHelp.db.BeginTran(); + //库位表字段清空 + storeInfo.CurrentMatSn = string.Empty; + DbHelp.db.Updateable(storeInfo).ExecuteCommand(); + + //库存表记录删除、插入出入记录 + var inventoryDetail = DbHelp.db.Queryable().Where(t => t.StoreId == storeInfo.Id).First(); + if (inventoryDetail != null) + { + var inOutRecord = new InOutRecord() + { + StoreCode = storeInfo.StoreCode, + StoreId = storeInfo.Id, + StoreInfo = storeInfo, + + MatSN = inventoryDetail.MatSN, + MatCode = inventoryDetail.MatCode, + MatName = inventoryDetail.MatName, + MatBatch = inventoryDetail.MatBatch, + MatQty = inventoryDetail.MatQty, + MatSpec = inventoryDetail.MatSpec, + MatCustomer = inventoryDetail.MatCustomer, + MatSupplier = inventoryDetail.MatSupplier, + + Direction = DirectionEnum.丢失, + }; + DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); + } + DbHelp.db.CommitTran(); + } + catch (Exception e) + { + DbHelp.db.RollbackTran(); + } + }); + #endregion + + WarningLight.WaringLightAlwaysRed(TcpCleint); + } + //库位未配置、返回数据异常 + else + { + //Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + } + } + else if (dataTemp[2 * index] == '0') + { + var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First(); + if (storeInfo != null) + { + #region 缓存记录异常信息 + ExceptionMessages.Add($"库位{storeInfo.StoreCode}:存在物料未扫描上架"); + #endregion + WarningLight.WaringLightAlwaysRed(TcpCleint); + } + else + { + Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + } + } + } + } + } + } #endregion } } diff --git a/WCS.BLL/Manager/DbInit.cs b/WCS.BLL/Manager/DbInit.cs new file mode 100644 index 0000000..8d9d77b --- /dev/null +++ b/WCS.BLL/Manager/DbInit.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WCS.BLL.DbModels; +using WCS.DAL.Db; +using WCS.DAL.DbModels; + +namespace WCS.BLL.Manager +{ + public static class DbInit + { + public static void InitDb() + { + DbHelp.db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo) + , typeof(InventoryDetail), typeof(OutOrder), typeof(OutOrderDetail), typeof(OutOrderMatDetail) + , typeof(ShelfTypeInfo), typeof(MatBaseInfo), typeof(MatInfo) + , typeof(StockTakingOrder), typeof(StockTakingOrderMatDetail), typeof(InOutRecord) + ); + + DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord)); + } + } +} diff --git a/WCS.BLL/Manager/ShelfManager.cs b/WCS.BLL/Manager/ShelfManager.cs index c5e15eb..385e3f5 100644 --- a/WCS.BLL/Manager/ShelfManager.cs +++ b/WCS.BLL/Manager/ShelfManager.cs @@ -20,14 +20,6 @@ namespace WCS.BLL.Manager public static void InitShelves() { - DbHelp.db.CodeFirst.InitTables(typeof(ModuleInfo), typeof(ShelfInfo), typeof(StoreInfo) - , typeof(InventoryDetail), typeof(OutOrder), typeof(OutOrderDetail), typeof(OutOrderMatDetail) - , typeof(ShelfTypeInfo), typeof(MatBaseInfo), typeof(MatInfo) - , typeof(StockTakingOrder), typeof(StockTakingOrderMatDetail), typeof(InOutRecord) - ); - - DbHelp.dbLog.CodeFirst.InitTables(typeof(SystemApiLogRecord)); - var shelvesInDb = DbHelp.db.Queryable().ToList(); foreach (var shelfInDb in shelvesInDb) { @@ -50,11 +42,5 @@ namespace WCS.BLL.Manager return null; } } - - public static void GoInInstore() - { - - } - } } diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs new file mode 100644 index 0000000..5e5051f --- /dev/null +++ b/WCS.BLL/Manager/TCPClientManager.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using WCS.BLL.HardWare; +using WCS.DAL.Db; +using WCS.DAL.DbModels; + +namespace WCS.BLL.Manager +{ + public static class TCPClientManager + { + /// + /// 货架类型的TCP连接管理 + /// + public static List TCPClients = new List(); + public static void InitTcpClient() + { + var ips = DbHelp.db.Queryable().Select(t => t.ClientIp).ToList(); + foreach (var ip in ips) + { + var tcpCleint = new TCPClient(ip, "192.168.0.154:20003"); + tcpCleint.tcpClient.Received += (client, e) => + { + var clientIpHost = client.IP + ":" + client.Port; + + + + var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); + if (TcpCleint == null) + { + //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 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 = (data[TcpCleint.PreFixLength + 0] << 8) + data[TcpCleint.PreFixLength + 1]; + var lightNumber = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]); + + //报警灯 + 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(data, boardId, lightNumber); + } + //货架类型协议返回 + else + { + var shelf = ShelfManager.Shelves + .Where(t => t.ClientIp == clientIpHost) + .Where(t => t.ModuleIds.Contains(boardId)) + .FirstOrDefault(); + var smartShelf = shelf as SmartShelf; + smartShelf?.ProtocolProcess(data, boardId, lightNumber); + + } + + //协议处理 判断功能位 + //switch (dataTemp[TcpCleint.PreFixLength + 2]) + //{ + // case 0x20://进入入库模式信号 + // //GoInInstoreProcess(dataTemp, boardId, lightNumber); + // break; + // case 0x03://正常入库信号 + // //InStoreReturnProcess(dataTemp); + // break; + // default: + // ; + // break; + //} + } + } + return EasyTask.CompletedTask; + }; + + TCPClients.Add(tcpCleint); + tcpCleint.Connect(); + } + } + + public static TCPClient GetTCPClientByIPHost(string IpHost) + { + return TCPClients.Where(t => t.RemoteIPHost == IpHost).FirstOrDefault(); + } + } +} diff --git a/WCS.BLL/Services/Service/InstoreService.cs b/WCS.BLL/Services/Service/InstoreService.cs index 75baa7e..cd93f32 100644 --- a/WCS.BLL/Services/Service/InstoreService.cs +++ b/WCS.BLL/Services/Service/InstoreService.cs @@ -45,17 +45,25 @@ namespace WCS.BLL.Services.Service //已找到模组对应货架 shelf.GoInInstore(request.IpAdress); - //成功进入入库模式 - return new ShelfGoInInstoreResponse() - { - Code = 200, - Message = "货架进入入库模式成功!", - Data = new ShelfGoInInstoreDto() + if (shelf.CurentMode == Mode.入库模式) + //成功进入入库模式 + return new ShelfGoInInstoreResponse() { - ShelfCode = shelf.ShelfCode, - ModulesStr = shelf.ModulesStr, - } - }; + Code = 200, + Message = "货架进入入库模式成功!", + Data = new ShelfGoInInstoreDto() + { + ShelfCode = shelf.ShelfCode, + ModulesStr = shelf.ModulesStr, + } + }; + else + return new ShelfGoInInstoreResponse() + { + Code = 201, + Message = $"货架进入入库模式失败:{string.Join(",", shelf.ExceptionMessages)}", + Data = null + }; } public ResponseBase shelfGoOutInStore(ShelfGoOutInStoreRequest request) @@ -170,6 +178,7 @@ namespace WCS.BLL.Services.Service Message = $"货架[{request.ShelfCode}]不存在!", }; } + //判断当前是否是入库模式 if (shelf.CurentMode != Mode.入库模式) { @@ -191,20 +200,33 @@ namespace WCS.BLL.Services.Service if (shelf.InStoreData == null || (shelf.InStoreData as object) == null) { await Task.Delay(50); - //var inventoryDetail = DbHelp.db.Queryable().Where(t => t.MatSN == dto.matSn).First(); - //if (inventoryDetail != null) - //{ - // return Json(HttpResponseCommon.GetSuccessResponse($"{inventoryDetail.StoreCode}", null)); - //} + var inventoryDetail = DbHelp.db.Queryable() + .Where(t => t.MatSN == request.MatSn) + .First(); + if (inventoryDetail != null) + { + return new ResponseCommon() + { + Code = 200, + Message = $"入库成功!物料已放入库位{inventoryDetail.StoreCode}", + Data = new + { + StoreCode = inventoryDetail.StoreCode, + } + }; + } + else + break; } //延时处理 Thread.Sleep(50); } - + //超时未成功入库 + shelf.InStoreData = null; return new ResponseCommon() { - Code = 200, - Message = $"success", + Code = 201, + Message = $"超时未入库!请重新扫码后入库!", }; } } diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index d5a4a1b..8ecdefa 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -44,6 +44,7 @@ namespace WCS.BLL.Services.Service OrderNumber = request.OrderNumber, OrderSource = request.OrderSource, OrderType = request.OrderType, + SyncType = SyncTypeEnum.ByMatCode, CreateUser = request.UserName, }; order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); @@ -136,7 +137,7 @@ namespace WCS.BLL.Services.Service //锁库存 inventoryDetails.ForEach(t => { - t.IsLocked = false; + t.IsLocked = true; }); var lockTask = DbHelp.db.Updateable(inventoryDetails).ExecuteCommandAsync(); @@ -146,6 +147,7 @@ namespace WCS.BLL.Services.Service OrderNumber = request.OrderNumber, OrderSource = request.OrderSource, OrderType = request.OrderType, + SyncType = SyncTypeEnum.ByMatSn, CreateUser = request.UserName, }; order.Id = await DbHelp.db.Insertable(order).ExecuteReturnIdentityAsync(); @@ -291,12 +293,36 @@ namespace WCS.BLL.Services.Service public async Task GoInOutstore(GetOutOrderDetailRequest request) { + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = "不存在对应的出库单据!", + Data = null + }; + } + //获取出库单据明细 + //TO DO 如果是按物料编码出库 需要计算物料明细保存并进行锁定 + if (order.SyncType == SyncTypeEnum.ByMatCode) + { - //先找到所有物料 + } - //分组 按物料找到对应得货架编码 + //分组 按物料找到对应的货架 + { + + } //对应的货架进入出库模式 亮灯 + { + + } //返回 return new ResponseCommon() diff --git a/WCS.BLL/Tool/TCPClient.cs b/WCS.BLL/Tool/TCPClient.cs index a83354c..ccd2f0c 100644 --- a/WCS.BLL/Tool/TCPClient.cs +++ b/WCS.BLL/Tool/TCPClient.cs @@ -76,7 +76,7 @@ namespace WCS.BLL tcpClient.Received += (client, e) => { var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray(); - e.ByteBlock.Clear(); + //e.ByteBlock.Clear(); var len = data.Length; for (int index = 0; index < data.Length - PreFixLength; index++) { diff --git a/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs b/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs index 4331687..46e426a 100644 --- a/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs +++ b/WCS.Model/ApiModel/InStore/QueryByMatSnRequest.cs @@ -10,7 +10,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; } } diff --git a/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs b/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs index d71f5a9..b485d9c 100644 --- a/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs +++ b/WCS.Model/ApiModel/MatInventoryDetail/MatInventorySummaryModel.cs @@ -21,7 +21,18 @@ namespace WCS.Model.ApiModel.MatInventoryDetail public int TotalQty { get; set; } - public int NeedQty { get; set; } = 0; + + public int needQty = 0; + public int NeedQty + { + get { return needQty; } + set + { + needQty = value; + OnPropertyChanged(nameof(needQty)); + } + } + public bool IsSelected { diff --git a/WCS.WebApi/Controllers/OutstoreController.cs b/WCS.WebApi/Controllers/OutstoreController.cs index a2c5e8c..ca57c1f 100644 --- a/WCS.WebApi/Controllers/OutstoreController.cs +++ b/WCS.WebApi/Controllers/OutstoreController.cs @@ -34,7 +34,7 @@ namespace WebApi.Controllers } catch (Exception ex) { - return new ShelfGoInInstoreResponse() + return new ResponseBase() { Code = 300, Message = "ͬʧܣ" + ex.Message, @@ -58,7 +58,7 @@ namespace WebApi.Controllers } catch (Exception ex) { - return new ShelfGoInInstoreResponse() + return new ResponseBase() { Code = 300, Message = "ͬʧܣ" + ex.Message, @@ -82,7 +82,7 @@ namespace WebApi.Controllers } catch (Exception ex) { - return new ShelfGoInInstoreResponse() + return new ResponseBase() { Code = 300, Message = "ѯʧܣ" + ex.Message, @@ -105,7 +105,7 @@ namespace WebApi.Controllers } catch (Exception ex) { - return new ShelfGoInInstoreResponse() + return new ResponseBase() { Code = 300, Message = "ѯʧܣ" + ex.Message, @@ -124,11 +124,11 @@ namespace WebApi.Controllers { try { - return await _outstoreService.GetOutOrderDetail(request); + return await _outstoreService.GoInOutstore(request); } catch (Exception ex) { - return new ShelfGoInInstoreResponse() + return new ResponseBase() { Code = 300, Message = "ѯʧܣ" + ex.Message, @@ -151,7 +151,7 @@ namespace WebApi.Controllers } catch (Exception ex) { - return new ShelfGoInInstoreResponse() + return new ResponseBase() { Code = 300, Message = "ѯʧܣ" + ex.Message, diff --git a/WCS.WebApi/Program.cs b/WCS.WebApi/Program.cs index 471cc88..d312813 100644 --- a/WCS.WebApi/Program.cs +++ b/WCS.WebApi/Program.cs @@ -8,8 +8,6 @@ using System.Text; using WCS.BLL.Manager; using WCS.BLL.Services.IService; using WCS.BLL.Services.Service; -using WCS.DAL; -using WCS.DAL.Db; using WCS.WebApi; using WCS.WebApi.Controllers; @@ -24,11 +22,11 @@ namespace WebApi //LocalStatic.wCSTcpCleint = new WCS.BLL.TCPClient("127.0.0.1:20002"); //LocalStatic.wCSTcpCleint.Send(new byte[] { 0x08, 0x00, 0x00, 0x11, 0x12, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); - DbHelp.InitDb(); - AuthDbHelp.InitDb(); + DbInit.InitDb(); ShelfManager.InitShelves(); + TCPClientManager.InitTcpClient(); var builder = WebApplication.CreateBuilder(args); //// Kestrel diff --git a/货架标准上位机/ViewModels/InInventoryViewModel.cs b/货架标准上位机/ViewModels/InInventoryViewModel.cs index 9f37f84..a7821e0 100644 --- a/货架标准上位机/ViewModels/InInventoryViewModel.cs +++ b/货架标准上位机/ViewModels/InInventoryViewModel.cs @@ -164,13 +164,18 @@ namespace 货架标准上位机.ViewModel var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "instore/shelfGoInInStore", body, "POST"); if (Result != null && Result.Code == 200) { + scanner.IsInstoreMode = true; scanner.ShelfCode = Result.Data.ShelfCode; scanner.ModulesStr = Result.Data.ModulesStr; } + else if (Result != null && !string.IsNullOrEmpty(Result.Message)) + { + Growl.Warning(Result.Message); + } } catch (Exception ex) { - + Growl.Warning(ex.Message); } #endregion } @@ -196,13 +201,56 @@ namespace 货架标准上位机.ViewModel { scanner.MatSn = Result.Data.MatSN; } + else if(Result != null && !string.IsNullOrEmpty(Result.Message)) + { + Growl.Warning(Result.Message); + } } catch (Exception ex) { - + Growl.Warning(ex.Message); } #endregion } + + public ICommand BtnEndCommand { get => new DelegateCommand(BtnEnd); } + public void BtnEnd() + { + try + { + //获取当前入库的货架 + ScannerManager.Scanners.Where(t => t.IsInstoreMode).ToList().ForEach(t => + { + if (!string.IsNullOrEmpty(t.ShelfCode)) + { + var body = new ShelfGoOutInStoreRequest() + { + ShelfCode = t.ShelfCode, + DeviceType = LocalFile.Config.DeviceType, + UserName = LocalStatic.CurrentUser, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "instore/shelfGoOutInStore", body, "POST"); + if (Result != null && Result.Code == 200) + { + t.IsInstoreMode = false; + t.ShelfCode = string.Empty; + t.MatSn = string.Empty; + + t.ScannerDisplayControl.RefreshValues(t.ShelfCode, t.MatSn); + } + } + else + { + t.IsInstoreMode = false; + Logs.Write($"扫码枪{t.COM}的货架码因为某种原因丢失!"); + } + }); + } + catch (Exception ex) + { + Growl.Warning(ex.Message); + } + } #endregion } } diff --git a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs index 83d8ad2..f50aa77 100644 --- a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs @@ -1,11 +1,15 @@ using HandyControl.Controls; using Ping9719.WpfEx.Mvvm; using System; +using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using System.Windows; using System.Windows.Input; using WCS.BLL.DbModels; +using WCS.Model; using WCS.Model.ApiModel.MatInventoryDetail; +using 货架标准上位机.Api; namespace 货架标准上位机.ViewModels { @@ -21,6 +25,16 @@ namespace 货架标准上位机.ViewModels SetProperty(ref dataGridItemSource, value); } } + + private MatInventorySummaryModel selectedItemSource; + public MatInventorySummaryModel SelectedItemSource + { + get { return selectedItemSource; } + set + { + SetProperty(ref selectedItemSource, value); + } + } #endregion #region Command @@ -60,7 +74,75 @@ namespace 货架标准上位机.ViewModels } } + // 定义一个事件,当需要关闭窗口时触发 + public event Action RequestClose; - #endregion + // 一个方法,当满足某些条件时调用,以触发关闭窗口 + protected virtual void OnRequestClose() + { + RequestClose?.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; + } + //问一下此处是否要做限制 TO DO 物料分类(Group By)的规则 分到哪一类 + //else if (itemSource.NeedQty > itemSource.TotalQty) + //{ + // Growl.Warning("需求数量大于库存数量!"); + // SelectedItemSource = itemSource; + // return; + //} + #region 调用接口生成出库单据 + try + { + var body = new SysOutOrderByMatCodeRequest() + { + OrderType = "出库", + OrderSource = "WCS前端", + ItemList = DataGridItemSource.Select(t => new MatCodeItemList() + { + MatCode = t.MatCode, + 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(); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + } + catch (Exception ex) + { + Growl.Error("加载数据失败:" + ex.Message); + } + finally + { + } + #endregion + } } + #endregion +} } diff --git a/货架标准上位机/Views/OutInventoryAddDucumentView.xaml b/货架标准上位机/Views/OutInventoryAddDucumentView.xaml index 208d5d7..4d1628e 100644 --- a/货架标准上位机/Views/OutInventoryAddDucumentView.xaml +++ b/货架标准上位机/Views/OutInventoryAddDucumentView.xaml @@ -29,7 +29,7 @@ - + @@ -47,8 +47,10 @@ + RowHeight="39" + ItemsSource="{Binding DataGridItemSource}" + SelectedItem="{Binding SelectedItemSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" + AutoGenerateColumns="False" Name="dg1" FontSize="15"> @@ -58,13 +60,13 @@ - + - +