diff --git a/WCS.BLL/DbModels/OutOrder.cs b/WCS.BLL/DbModels/OutOrder.cs index 72026b9..7075211 100644 --- a/WCS.BLL/DbModels/OutOrder.cs +++ b/WCS.BLL/DbModels/OutOrder.cs @@ -1,4 +1,5 @@ using SqlSugar; +using WCS.Model.ApiModel.OutStore; namespace WCS.BLL.DbModels { @@ -24,7 +25,14 @@ namespace WCS.BLL.DbModels /// 单据状态 /// [SugarColumn(ColumnName = "order_status", IsNullable = false, ColumnDescription = "单据状态")] - public OutOrderStatus OrderStatus { get; set; } = OutOrderStatus.未出库; + public OutOrderStatus OrderStatus { get; set; } = OutOrderStatus.未发料; + + /// + /// 单据执行状态: 待发料, 开始发料, 暂停发料, 发料完成 + /// + [SugarColumn(ColumnName = "order_exe_status", IsNullable = true, ColumnDescription = "执行状态:\t待发料,\t开始发料,\t暂停发料,\t发料完成")] + public OutOrderExeStatus OutOrderExeStatus { get; set; } = OutOrderExeStatus.待发料; + /// /// 单据来源 @@ -41,8 +49,8 @@ namespace WCS.BLL.DbModels /// /// 单据同步类型 /// - [SugarColumn(ColumnName = "sync_type", Length = 50, IsNullable = true, ColumnDescription = "单据同步类型:ByMatCode,ByMatSn")] - public string SyncType { get; set; } = string.Empty; + [SugarColumn(ColumnName = "sync_type",IsNullable = false, ColumnDescription = "单据同步类型:ByMatCode,ByMatSn")] + public SyncTypeEnum SyncType { get; set; } /// /// 创建时间 @@ -56,13 +64,17 @@ namespace WCS.BLL.DbModels [SugarColumn(ColumnName = "create_user", Length = 100, IsNullable = true, ColumnDescription = "操作员")] public string CreateUser { get; set; } - } + /// + /// 用于绑定DataGrid中是否选择 + /// + [SugarColumn(IsIgnore = true)] + public bool IsSelected { get; set; } - public enum OutOrderStatus - { - 未出库 = 0, - 部分出库 = 1, - 全部出库 = 2 + /// + /// 用于绑定中显示序号 + /// + [SugarColumn(IsIgnore = true)] + public int RowNumber { get; set; } } } diff --git a/WCS.BLL/DbModels/OutOrderDetail.cs b/WCS.BLL/DbModels/OutOrderDetail.cs index 4bdc6c5..73550b5 100644 --- a/WCS.BLL/DbModels/OutOrderDetail.cs +++ b/WCS.BLL/DbModels/OutOrderDetail.cs @@ -32,7 +32,11 @@ namespace WCS.BLL.DbModels /// [SugarColumn(ColumnName = "mat_code", Length = 100, IsNullable = true, ColumnDescription = "物料编号")] public string MatCode { get; set; } - + /// + /// 物料名称 + /// + [SugarColumn(ColumnName = "mat_name", Length = 150, IsNullable = true, ColumnDescription = "物料名称")] + public string MatName { get; set; } /// /// 物料批次 /// @@ -45,6 +49,12 @@ namespace WCS.BLL.DbModels [SugarColumn(ColumnName = "req_qty", IsNullable = false, ColumnDescription = "物料需求数量")] public int ReqQty { get; set; } + /// + /// 物料已出库数量 + /// + [SugarColumn(ColumnName = "out_qty", IsNullable = false, DefaultValue = "0", ColumnDescription = "物料已出库数量")] + public int OutQty { get; set; } = 0; + /// /// 创建时间 /// @@ -56,5 +66,11 @@ namespace WCS.BLL.DbModels /// [SugarColumn(ColumnName = "create_user", Length = 100, IsNullable = true, ColumnDescription = "操作员")] public string CreateUser { get; set; } + + /// + /// 用于绑定中显示序号 + /// + [SugarColumn(IsIgnore = true)] + public int RowNumber { get; set; } } } diff --git a/WCS.BLL/DbModels/OutOrderMatDetail.cs b/WCS.BLL/DbModels/OutOrderMatDetail.cs index 3597411..84e1fa5 100644 --- a/WCS.BLL/DbModels/OutOrderMatDetail.cs +++ b/WCS.BLL/DbModels/OutOrderMatDetail.cs @@ -39,7 +39,7 @@ namespace WCS.BLL.DbModels public int OutOrderDetailId { get; set; } /// - /// 库存的ID + /// 库存数据的ID /// [SugarColumn(ColumnName = "inventory_detail_id", IsNullable = true)] public int InventoryDetailId { get; set; } @@ -126,5 +126,11 @@ namespace WCS.BLL.DbModels /// [SugarColumn(ColumnName = "create_user", Length = 100, IsNullable = true, ColumnDescription = "操作员")] public string CreateUser { get; set; } + + /// + /// 用于绑定中显示序号 + /// + [SugarColumn(IsIgnore = true)] + public int RowNumber { get; set; } } } diff --git a/WCS.BLL/HardWare/IShelfBase.cs b/WCS.BLL/HardWare/IShelfBase.cs index 78a7ed0..b34184e 100644 --- a/WCS.BLL/HardWare/IShelfBase.cs +++ b/WCS.BLL/HardWare/IShelfBase.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using WCS.BLL.DbModels; using WCS.Model; namespace WCS.BLL.HardWare @@ -75,7 +76,7 @@ namespace WCS.BLL.HardWare /// /// 货架进入出库模式 /// - public void GoInOutstore(); + public void GoInOutstore(List MatDetails, OutOrder outOrder); /// /// 货架退出出库模式 diff --git a/WCS.BLL/HardWare/SingleLightShelf.cs b/WCS.BLL/HardWare/SingleLightShelf.cs index 80e6feb..1978ba2 100644 --- a/WCS.BLL/HardWare/SingleLightShelf.cs +++ b/WCS.BLL/HardWare/SingleLightShelf.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using WCS.BLL.DbModels; using WCS.Model; namespace WCS.BLL.HardWare @@ -29,7 +30,7 @@ namespace WCS.BLL.HardWare throw new NotImplementedException(); } - public void GoInOutstore() + public void GoInOutstore(List MatDetails, OutOrder outOrder) { throw new NotImplementedException(); } diff --git a/WCS.BLL/HardWare/SmartShelf.cs b/WCS.BLL/HardWare/SmartShelf.cs index a8795d4..3f25da2 100644 --- a/WCS.BLL/HardWare/SmartShelf.cs +++ b/WCS.BLL/HardWare/SmartShelf.cs @@ -12,6 +12,7 @@ using WCS.DAL; using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model; +using static System.Formats.Asn1.AsnWriter; namespace WCS.BLL.HardWare { @@ -48,7 +49,7 @@ namespace WCS.BLL.HardWare } ModulesStr = string.Join(";", Modules.Select(t => t.ModuleCode)); - ModuleIds = Modules.Select(t => t.ModuleId).ToList(); + ModuleIds = Modules.Select(t => t.BoardId).ToList(); }); ////初始化TCPCleint @@ -72,14 +73,14 @@ namespace WCS.BLL.HardWare // } // index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1 // //获取板子ID - // var boardId = (data[TcpCleint.PreFixLength + 0] << 8) + data[TcpCleint.PreFixLength + 1]; + // var boardIds = (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); + // GoInInstoreProcess(dataTemp, boardIds, lightNumber); // break; // case 0x03://正常入库信号 // InStoreReturnProcess(dataTemp); @@ -107,12 +108,22 @@ namespace WCS.BLL.HardWare public int LightId { get; set; } public WarningLight WarningLight { get; set; } + /// + /// 自检异常、未响应对应模式的异常 + /// public List ExceptionMessages { get; set; } = new List(); - + /// + /// 过程中异常 入库过程中异常/出库过程中异常 + /// + public List ProcessingExceptions { get; set; } = new List(); public string? InstoreIpAddress { get; set; } = string.Empty; public MatInfoResponse InStoreData { get; set; } + public List CurrentOutStoreMatSNs { get; set; } = new List(); + + public OutOrder CurrentOutOrder { get; set; } + public string OrderNumber { get; set; } @@ -122,53 +133,92 @@ namespace WCS.BLL.HardWare #region 协议处理 public void GoInInstore(string? IPAddress) { - //判断当前模式是否为待机模式 - if (this.CurentMode != Mode.待机模式) + try { - return; - } - else - { - this.CurentMode = Mode.入库模式; - } - //清空错误 - ExceptionMessages.Clear(); - //货架所有模组发送指令进入入库模式 - foreach (var module in Modules.Where(t => t.IsEnable).ToList()) - { - module.GoInInstoreMode(TcpCleint); - } - //延时获取异常 - var timeOut = 3000; - var timeSpan = TimeSpan.FromMilliseconds(0); - var beginTime = DateTime.Now; - while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) - { - timeSpan = DateTime.Now - beginTime; - //接收到第一个异常就不继续循环了 - if (ExceptionMessages.Count() > 0) + if (this.CurentMode == Mode.入库模式) { - var deficientTime = timeOut - (int)timeSpan.TotalMilliseconds; - if (deficientTime > 0) - Thread.Sleep(deficientTime); - //出现异常的未进入入库模式,有红灯进行指引 - this.CurentMode = Mode.待机模式; + InstoreIpAddress = IPAddress; return; } - //延时处理 - Thread.Sleep(50); + //判断当前模式是否为待机模式 + else if (this.CurentMode != Mode.待机模式) + { + return; + } + else + { + this.CurentMode = Mode.入库模式; + } + //清空错误 + ExceptionMessages.Clear(); + ProcessingExceptions.Clear(); + //货架所有模组发送指令进入入库模式 + foreach (var module in Modules.Where(t => t.IsEnable).ToList()) + { + module.GoInInstoreMode(TcpCleint); + } + //延时获取异常 + var timeOut = 3000; + var timeSpan = TimeSpan.FromMilliseconds(0); + var beginTime = DateTime.Now; + while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) + { + timeSpan = DateTime.Now - beginTime; + + //所有板子成功进入入库模式 表示进入入库模式成功,跳出循环 + var isExistsNotInstore = Modules.Where(t => t.CurrentMode != Mode.入库模式) + .Where(t => t.IsEnable) + .Any(); + if (!isExistsNotInstore) + { + break; + } + + //接收到第一个异常就不继续循环了 + if (ExceptionMessages.Count() > 0) + { + var deficientTime = timeOut - (int)timeSpan.TotalMilliseconds; + if (deficientTime > 0) + Thread.Sleep(deficientTime); + //出现异常的未进入入库模式,有红灯进行指引 + this.CurentMode = Mode.待机模式; + break; + } + + //循环延时处理 + Thread.Sleep(50); + } + + //循环结束后判断当前板子状态 + var notInstoreList = Modules.Where(t => t.CurrentMode != Mode.入库模式) + .Where(t => t.IsEnable).ToList(); + + if (notInstoreList.Count > 0) + { + CurentMode = Mode.待机模式; + foreach (var item in notInstoreList) + { + ExceptionMessages.Add($"模组{item.ModuleCode}未进入入库模式!"); + } + } + + //警示灯亮起 + WarningLight.BlueLight(TcpCleint); + //绑定当前进入入库PDA/WCS前端的IP + InstoreIpAddress = IPAddress; + //返回成功 + return; + } + catch (Exception ex) + { + GoOutInstore(); + throw ex; } - //警示灯亮起 - WarningLight.BlueLight(TcpCleint); - //绑定当前进入入库PDA/WCS前端的IP - InstoreIpAddress = IPAddress; - //返回成功 - return; } public void GoOutInstore() { - //看货架是否为入库模式 + //当前货架是否为入库模式 if (CurentMode != Mode.入库模式) { return; @@ -178,20 +228,81 @@ namespace WCS.BLL.HardWare this.CurentMode = Mode.待机模式; } + //清空错误 + ExceptionMessages.Clear(); //货架所有模组发送指令退出入库模式 foreach (var module in Modules.Where(t => t.IsEnable) - //.Where(t => t.CurrentMode == Mode.入库模式) .ToList()) { - module.GoOutInstoreMode(TcpCleint); + if (module.CurrentMode == Mode.入库模式) + module.GoOutInstoreMode(TcpCleint); + } + + var timeOut = 3000; + var timeSpan = TimeSpan.FromMilliseconds(0); + var beginTime = DateTime.Now; + while (timeSpan <= TimeSpan.FromMilliseconds(timeOut)) + { + timeSpan = DateTime.Now - beginTime; + //所有板子是否成功退出入库模式 + var isExistsInstore = Modules.Where(t => t.CurrentMode != Mode.待机模式) + .Where(t => t.IsEnable) + .Any(); + if (!isExistsInstore) + { + break; + } + //循环延时处理 + Thread.Sleep(50); + } + + //循环结束后判断当前板子状态 + var list = Modules.Where(t => t.CurrentMode != Mode.待机模式) + .Where(t => t.IsEnable) + .ToList(); + if (list.Count > 0) + { + CurentMode = Mode.待机模式; + foreach (var item in list) + { + ExceptionMessages.Add($"模组{item.ModuleCode}未成功退出入库模式!"); + } } //报警灯熄灭 WarningLight.CloseLight(TcpCleint); } - public void GoInOutstore() + public void GoInOutstore(List MatDetails, OutOrder outOrder) { - throw new NotImplementedException(); + //第一步:设置货架当前模式 + if (CurentMode != Mode.待机模式) + { + Modules.ForEach(t => { t.Reset(TcpCleint); }); + } + CurentMode = Mode.出库模式; + + //第二步:货架添加需要出的SN 出库的领料单号 + //移除货架所有现有待出库的MatSN + CurrentOutStoreMatSNs.Clear(); + ////添加属于当前货架的物料 + CurrentOutStoreMatSNs.AddRange(MatDetails.Select(t => t.MatSN).ToList()); + ////记录当前出库的发料单 + CurrentOutOrder = outOrder; + + ////第三步:对应的模组进入出库模式 + var boardIds = MatDetails.Select(t => t.StoreInfo.BoardId) + .Distinct() + .ToList(); + var outModules = Modules.Where(t => boardIds.Contains(t.BoardId)).ToList(); + outModules.ForEach(t => + { + var outMatSns = MatDetails.Where(t => t.StoreInfo.ModuleId == t.Id) + .Select(t => t.MatSN) + .ToList(); + t.GoInOutStoreMode(TcpCleint, outMatSns); + }); + //所有板子亮灯后 亮警示灯 + WarningLight.GreenLight(TcpCleint); } public void GoInStocktaking() @@ -201,6 +312,15 @@ namespace WCS.BLL.HardWare public void GoOutOutstore() { + //找到在出库中的模组 + var outingModules = Modules.Where(t => t.CurrentMode == Mode.出库模式) + .ToList(); + foreach (var module in outingModules) + { + module.GoOutOutStoreMode(TcpCleint); + } + CurrentOutOrder = null; + CurrentOutStoreMatSNs.Clear(); this.CurentMode = Mode.待机模式; } @@ -236,6 +356,7 @@ namespace WCS.BLL.HardWare #region 协议返回处理 public void ProtocolProcess(byte[] data, int boardId, int lightNumber) { + Logs.Write("协议处理中的数据" + BitConverter.ToString(data) + $"板子id{boardId}"); //协议处理 判断功能位 switch (data[TcpCleint.PreFixLength + 2]) { @@ -248,8 +369,21 @@ namespace WCS.BLL.HardWare case 0x03://正常入库信号 InStoreReturnProcess(data); break; + case 0x04://入库模式中异常信号 + InStoreExceptionReturnProcess(data, boardId, lightNumber); + break; case 0x05://进入出库模式返回信号 - + GoInOutstoreProcess(data, boardId, lightNumber); + break; + case 0x06://退出出库模式返回信号 + GoOutOutstoreProcess(data, boardId, lightNumber); + break; + case 0x07://正常出库返回信号 + OutstoreReturnProcess(data, boardId, lightNumber); + break; + case 0x13://复位的返回信号 + ResetReturnProcess(data, boardId, lightNumber); + break; default: ; break; @@ -376,7 +510,7 @@ namespace WCS.BLL.HardWare //库位未配置、返回数据异常 else { - //Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + //Logs.Write($"[进入入库模式异常]板Id{boardIds},库位号{index + 1}找不到对应库位!"); } } else if (dataTemp[2 * index] == '0') @@ -451,6 +585,9 @@ namespace WCS.BLL.HardWare } else { + var exceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!"; + WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + module.ComfirmErrInstore(TcpCleint); WarningLight.WaringLightBlueEnd(TcpCleint); //WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId); @@ -463,7 +600,7 @@ namespace WCS.BLL.HardWare { module.ComfirmErrInstore(TcpCleint); WarningLight.WaringLightBlueEnd(TcpCleint); - //ComfirmErrInstoreByIp(shelfStatus.ClientIp, boardId); + //ComfirmErrInstoreByIp(shelfStatus.ClientIp, boardIds); //WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId); //TO DO Logs.Write($"[{guid}]该位置已放置物料!"); return; @@ -549,6 +686,64 @@ namespace WCS.BLL.HardWare #endregion } + /// + /// 入库模式中异常处理 + /// + /// + /// + /// + public void InStoreExceptionReturnProcess(byte[] data, int boardId, int lightNumber) + { + lightNumber = (int)data[TcpCleint.PreFixLength + 4]; + var store = DbHelp.db.Queryable() + .Where(t => t.BoardId == boardId && t.LightNumber == lightNumber) + .First(); + if (store == null) + { + //TO DO 库位未找到 + return; + } + //已放物料丢失了 物料多放了 储位恢复正常 + switch (data[TcpCleint.PreFixLength + 3]) + { + case 0x00: + { + var exceptionMessage = store.StoreCode + "恢复正常!"; + WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + + ProcessingExceptions.RemoveAll(t => t.BoardId == boardId); + } + break; + case 0x01: + { + var exceptionMessage = store.StoreCode + "入库过程中存在物料未扫描上架!"; + WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + + ProcessingExceptions.Add(new ProcessingExceptionType() + { + BoardId = boardId, + LightNumber = lightNumber, + ExceptionMessage = store.StoreCode + "入库过程中存在物料未扫描上架!" + }); + } + break; + case 0x02: + { + var exceptionMessage = store.StoreCode + "物料被取出!"; + WebSoceketManager.TrySendMessage("127.0.0.1", exceptionMessage); + + ProcessingExceptions.Add(new ProcessingExceptionType() + { + BoardId = boardId, + LightNumber = lightNumber, + ExceptionMessage = store.StoreCode + "入库过程中物料丢失!" + }); + } + break; + default: + break; + } + } /// /// 进入出库模式协议返回 @@ -570,7 +765,7 @@ namespace WCS.BLL.HardWare } else { - module.CurrentMode = Mode.入库模式; + module.CurrentMode = Mode.出库模式; } } //库存物料与实际情况不匹配 @@ -584,7 +779,7 @@ namespace WCS.BLL.HardWare } else { - module.CurrentMode = Mode.入库模式; + module.CurrentMode = Mode.出库模式; } //获取当前板所有库位 var storeInfos = DbHelp.db.Queryable() @@ -673,7 +868,7 @@ namespace WCS.BLL.HardWare //库位未配置、返回数据异常 else { - //Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!"); + //Logs.Write($"[进入入库模式异常]板Id{boardIds},库位号{index + 1}找不到对应库位!"); } } else if (dataTemp[2 * index] == '0') @@ -695,6 +890,194 @@ namespace WCS.BLL.HardWare } } } + + public void OutstoreReturnProcess(byte[] data, int boardId, int lightNumber) + { + if (CurentMode != Mode.出库模式) + { + //TO DO 未在出库模式 要报错 + //Logs.Write($"[{guid}]出库错误:该货架模式不是出库模式或盘点模式{storeInfo.ShelfCode}!"); + return; + } + lightNumber = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]); + var storeInfo = DbHelp.db.Queryable().Where(t => t.BoardId == boardId + && t.LightNumber == lightNumber) + .First(); + if (storeInfo == null) + { + //TO DO 报错 + return; + } + var module = this.Modules.Where(t => t.BoardId == boardId) + .FirstOrDefault(); + if (module == null) + { + //TO DO 报错 + return; + } + //当前库位未记录MatSn + if (string.IsNullOrEmpty(storeInfo.CurrentMatSn)) + { + //该库位是需要出库的库位,物料被多次取出or给了多个正常出库信号 + Logs.Write($"该库位是需要出库的库位,物料被反复取出or给了多个正常出库信号,库位{storeInfo.StoreCode}"); + //暂不进行处理 + return; + } + + //不是本次出库需要出的物料 + if (!CurrentOutStoreMatSNs.Contains(storeInfo.CurrentMatSn)) + { + //Logs.Write($"{storeInfo.CurrentMatSN}不是本次需要出库的物料"); + //报警灯报警 + WarningLight.WaringLightAlwaysRed(TcpCleint); + return; + } + + //获取当前的库存信息 + var inventoryDetail = DbHelp.db.Queryable().Where(t => t.MatSN == storeInfo.CurrentMatSn).First(); + if (inventoryDetail == null) + { + //Logs.Write($"{storeInfo.CurrentMatSN}库存信息不存在"); + //报警灯报警 + WarningLight.WaringLightAlwaysRed(TcpCleint); + return; + } + //获取对应的出库单明细 + var orderOrderDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == CurrentOutOrder.Id) + .Where(t => t.MatSN == inventoryDetail.MatSN) + .ToList(); + if (orderOrderDetails == null || orderOrderDetails.Count == 0) + { + //Logs.Write($"{storeInfo.CurrentMatSN},OrderDetail出库明细信息不存在"); + //报警灯报警 + WarningLight.WaringLightAlwaysRed(TcpCleint); + return; + } + + #region 校验项通过 处理出库逻辑 + //当前库位的SN + var matSN = storeInfo.CurrentMatSn; + try + { + DbHelp.db.BeginTran(); + //库存明细表 删除 + ; + //出入库记录表 新增 + 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.出库, + }; + //库位表 修改 + storeInfo.CurrentMatSn = string.Empty; + + //发料单明细表 更新为已出库 + orderOrderDetails.ForEach(x => + { + x.IsSended = true; + }); + //TO DO 发料需求表增加数量 + + //保存数据 + DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand(); + DbHelp.db.Insertable(inOutRecord).ExecuteCommand(); + DbHelp.db.Updateable(storeInfo).ExecuteCommand(); + DbHelp.db.Updateable(orderOrderDetails).ExecuteCommand(); + DbHelp.db.CommitTran(); + + //报警灯同时亮绿灯并鸣叫一次提示。 + WarningLight.SuccessLightGreenEnd(TcpCleint); + + //确认本次出库 + module.ComfirmOutstore(TcpCleint, data[TcpCleint.PreFixLength + 3]); + //shelfStatus.SetCurrentModeTime = DateTime.Now; + //LocalStatic.IsRefreshOrderDetail = true; + + //当前柜子是否还存在未出库的 + CurrentOutStoreMatSNs.RemoveAll(t => t == matSN);//删除本次已出的物料SN + + var isExsistOut = CurrentOutStoreMatSNs.Any(); + if (!isExsistOut) + { + //Logs.Write($"货架[{shelfStatus.ShelfCode}]:不存在待出物料,退出出库模式"); + //退出出库模式 + GoOutOutstore(); + WarningLight.CloseLight(TcpCleint); + + var currentPickBillNumber = CurrentOutOrder.OrderNumber; + CurrentOutOrder = null; + Task.Run(() => + { + //LocalStatic.UpdatOutOrderStatus(currentPickBillNumber); + //给信号通知出库页面更新页面的状态 + }); + } + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + //报警灯报警 + WarningLight.WaringLightAlwaysRed(TcpCleint); + } + #endregion + } + + /// + /// 退出出库模式返回信号处理 + /// + /// + public void GoOutOutstoreProcess(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 ResetReturnProcess(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.待机模式; + } + } + + #endregion } + + /// + /// 过程中异常类型 + /// + public class ProcessingExceptionType + { + public int BoardId { get; set; } + + public int LightNumber { get; set; } + + public string ExceptionMessage { get; set; } + } } diff --git a/WCS.BLL/HardWare/SmartShelfModule.cs b/WCS.BLL/HardWare/SmartShelfModule.cs index e1ccf34..db3cb20 100644 --- a/WCS.BLL/HardWare/SmartShelfModule.cs +++ b/WCS.BLL/HardWare/SmartShelfModule.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; +using TouchSocket.Core; using WCS.DAL.Db; using WCS.DAL.DbModels; @@ -32,6 +34,22 @@ namespace WCS.BLL.HardWare /// 自检模式 /// public byte[] CheckModeData = { 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + /// + /// 进入出库模式 + /// + public byte[] GoInOutstoreModeData = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 }; + + public byte[] ComfirmOutstoreData = { 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + /// + /// 退出出库模式 + /// + public byte[] GoOutOutstoreModeData = { 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + /// + /// 复位命令 + /// + public byte[] ResetData = { 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #endregion public int ModuleId { get; set; } public string ModuleCode { get; set; } @@ -90,11 +108,24 @@ namespace WCS.BLL.HardWare } else { - //退出对应的模式 回到待机状态 并记录对应的状态日志(这个分支肯定是异常了) - //记录错误日志 + //这里应该是状态异常的 正常不会是这种状态 + Reset(tcpClient); } } + /// + /// 复位 + /// + /// + public void Reset(TCPClient tcpClient) + { + tcpClient.Send(tcpClient.GenerateMessage(BoardId, ResetData)); + } + + /// + /// 自检 + /// + /// public void ShelfCheck(TCPClient tcpClient) { if (CurrentMode != Mode.待机模式) @@ -122,5 +153,68 @@ namespace WCS.BLL.HardWare tcpClient.Send(tcpClient.GenerateMessage(BoardId, CheckModeData)); } + + /// + /// 进入出库模式、亮灯 + /// + /// + public void GoInOutStoreMode(TCPClient tcpClient, List outSns) + { + var storeInfos = DbHelp.db.Queryable() + .Where(t => t.BoardId == BoardId) + .OrderBy(t => t.LightNumber) + .ToList(); + //计算物料在库的库位 + char[] data = "0000000000000000".ToCharArray(); + var storeNumber = storeInfos.Count(); + foreach (var storeInfo in storeInfos) + { + if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= storeNumber) + { + data[storeInfo.LightNumber - 1] = '1'; + } + } + var dataStr = string.Join("", data.Reverse()); + var data1 = dataStr.Substring(8, 8); + var data2 = dataStr.Substring(0, 8); + GoInOutstoreModeData[1] = Convert.ToByte(data1, 2); + GoInOutstoreModeData[2] = Convert.ToByte(data2, 2); + + //出库位置亮灯 + if (outSns != null && outSns.Count > 0) + { + var outStoreInfos = storeInfos.Where(t => outSns.Contains(t.CurrentMatSn)) + .ToList(); + char[] outData = "0000000000000000".ToCharArray(); + foreach (var storeInfo in outStoreInfos) + { + if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= storeNumber) + { + outData[storeInfo.LightNumber - 1] = '1'; + } + } + var outDataStr = string.Join("", outData.Reverse()); + var data3 = outDataStr.Substring(8, 8); + var data4 = outDataStr.Substring(0, 8); + GoInOutstoreModeData[3] = Convert.ToByte(data3, 2); + GoInOutstoreModeData[4] = Convert.ToByte(data4, 2); + } + tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoInOutstoreModeData)); + } + + public void ComfirmOutstore(TCPClient tcpClient, byte lightNumber) + { + ComfirmOutstoreData[1] = lightNumber; + tcpClient.Send(tcpClient.GenerateMessage(BoardId, ComfirmOutstoreData)); + } + + /// + /// 退出出库模式 + /// + /// + public void GoOutOutStoreMode(TCPClient tcpClient) + { + tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoOutOutstoreModeData)); + } } } diff --git a/WCS.BLL/Manager/TCPClientManager.cs b/WCS.BLL/Manager/TCPClientManager.cs index 5e5051f..5cecb13 100644 --- a/WCS.BLL/Manager/TCPClientManager.cs +++ b/WCS.BLL/Manager/TCPClientManager.cs @@ -5,6 +5,7 @@ using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using TouchSocket.Core; +using TouchSocket.Sockets; using WCS.BLL.HardWare; using WCS.DAL.Db; using WCS.DAL.DbModels; @@ -19,16 +20,18 @@ namespace WCS.BLL.Manager public static List TCPClients = new List(); public static void InitTcpClient() { - var ips = DbHelp.db.Queryable().Select(t => t.ClientIp).ToList(); + var ips = DbHelp.db.Queryable().Where(t => t.ShelfCode.Contains("A")).Select(t => t.ClientIp).ToList(); foreach (var ip in ips) { - var tcpCleint = new TCPClient(ip, "192.168.0.154:20003"); + var tcpCleint = new TCPClient(ip, "192.168.0.183:20003"); + + + //var tcpCleint = new TCPClient("192.168.0.183:20002", "192.168.0.183:20003"); + //配置断线重连 + tcpCleint.tcpClient.Received += (client, e) => { var clientIpHost = client.IP + ":" + client.Port; - - - var TcpCleint = TCPClientManager.GetTCPClientByIPHost(clientIpHost); if (TcpCleint == null) { @@ -47,14 +50,15 @@ namespace WCS.BLL.Manager if (isEqual) { var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray(); + Logs.Write($"接受到数据:{BitConverter.ToString(dataTemp)}"); 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]); + var boardId = (dataTemp[TcpCleint.PreFixLength + 0] << 8) + dataTemp[TcpCleint.PreFixLength + 1]; + var lightNumber = Convert.ToInt32(dataTemp[TcpCleint.PreFixLength + 3]); //报警灯 if (dataTemp[TcpCleint.PreFixLength + 2] == 0x20) @@ -63,7 +67,7 @@ namespace WCS.BLL.Manager .Where(t => t.LightId == boardId) .FirstOrDefault(); var smartShelf = shelf as SmartShelf; - smartShelf?.ProtocolProcess(data, boardId, lightNumber); + smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); } //货架类型协议返回 else @@ -73,7 +77,7 @@ namespace WCS.BLL.Manager .Where(t => t.ModuleIds.Contains(boardId)) .FirstOrDefault(); var smartShelf = shelf as SmartShelf; - smartShelf?.ProtocolProcess(data, boardId, lightNumber); + smartShelf?.ProtocolProcess(dataTemp, boardId, lightNumber); } diff --git a/WCS.BLL/Manager/WebSoceketManager.cs b/WCS.BLL/Manager/WebSoceketManager.cs new file mode 100644 index 0000000..b4f75d3 --- /dev/null +++ b/WCS.BLL/Manager/WebSoceketManager.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.Http; +using TouchSocket.Sockets; + +namespace WCS.BLL.Manager +{ + public static class WebSoceketManager + { + public static HttpService service; + public static void InitWebSocket() + { + service = new HttpService(); + service.Setup(new TouchSocketConfig()//加载配置 + .SetListenIPHosts(7789) + .ConfigureContainer(a => + { + a.AddConsoleLogger(); + }) + .ConfigurePlugins(a => + { + a.UseWebSocket()//添加WebSocket功能 + .SetWSUrl("/ws")//设置url直接可以连接。 + .UseAutoPong();//当收到ping报文时自动回应pong + a.Add();//自定义插件。 + })); + + service.Start(); + service.Logger.Info("服务器已启动"); + } + //尝试发送报警信息给前端 + public static void TrySendMessage(string IpAddress, string Message) + { + try + { + var clients = service.GetClients().Where(t => t.IP == IpAddress).ToList(); + foreach (var client in clients) + { + client.WebSocket.SendAsync(Message); + } + } + catch (Exception ex) + { + + } + } + } +} diff --git a/WCS.BLL/Manager/WebSocketServicePlugin.cs b/WCS.BLL/Manager/WebSocketServicePlugin.cs new file mode 100644 index 0000000..38338c8 --- /dev/null +++ b/WCS.BLL/Manager/WebSocketServicePlugin.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.Http.WebSockets; + +namespace WCS.BLL.Manager +{ + public class WebSocketServicePlugin : PluginBase, IWebSocketReceivedPlugin + { + private readonly ILog m_logger; + + public WebSocketServicePlugin(ILog logger) + { + this.m_logger = logger; + } + public async Task OnWebSocketReceived(IWebSocket client, WSDataFrameEventArgs e) + { + switch (e.DataFrame.Opcode) + { + case WSDataType.Cont: + m_logger.Info($"收到中间数据,长度为:{e.DataFrame.PayloadLength}"); + + return; + + case WSDataType.Text: + m_logger.Info(e.DataFrame.ToText()); + + if (!client.Client.IsClient) + { + var clients = WebSoceketManager.service.GetClients().ToList(); + clients.ForEach(t => + { + t.WebSocket.Send("我已收到"); + }); + client.Send("我已收到"); + } + return; + + case WSDataType.Binary: + if (e.DataFrame.FIN) + { + m_logger.Info($"收到二进制数据,长度为:{e.DataFrame.PayloadLength}"); + } + else + { + m_logger.Info($"收到未结束的二进制数据,长度为:{e.DataFrame.PayloadLength}"); + } + return; + + case WSDataType.Close: + { + m_logger.Info("远程请求断开"); + client.Close("断开"); + } + return; + + case WSDataType.Ping: + client.Pong(); + break; + + case WSDataType.Pong: + break; + + default: + break; + } + + await e.InvokeNext(); + } + } +} diff --git a/WCS.BLL/Services/IService/IOutstoreService.cs b/WCS.BLL/Services/IService/IOutstoreService.cs index 549d945..faca2dc 100644 --- a/WCS.BLL/Services/IService/IOutstoreService.cs +++ b/WCS.BLL/Services/IService/IOutstoreService.cs @@ -17,6 +17,8 @@ namespace WCS.BLL.Services.IService public Task GetOutOrderDetail(GetOutOrderDetailRequest request); + public Task GetOutOrderMatDetail(GetOutOrderDetailRequest request); + public Task GoInOutstore(GetOutOrderDetailRequest request); public Task GoOutOutstore(GetOutOrderDetailRequest request); diff --git a/WCS.BLL/Services/IService/IStoreInfoService.cs b/WCS.BLL/Services/IService/IStoreInfoService.cs index 4b81485..78f4ed3 100644 --- a/WCS.BLL/Services/IService/IStoreInfoService.cs +++ b/WCS.BLL/Services/IService/IStoreInfoService.cs @@ -27,5 +27,8 @@ namespace WCS.BLL.Services.IService /// /// public Task> addOrUpdateShelfInfo(AddShelfInfoRequest request); + + + public Task> GenerateStoreInfo(); } } diff --git a/WCS.BLL/Services/Service/InstoreService.cs b/WCS.BLL/Services/Service/InstoreService.cs index cd93f32..f7b71b0 100644 --- a/WCS.BLL/Services/Service/InstoreService.cs +++ b/WCS.BLL/Services/Service/InstoreService.cs @@ -64,6 +64,7 @@ namespace WCS.BLL.Services.Service Message = $"货架进入入库模式失败:{string.Join(",", shelf.ExceptionMessages)}", Data = null }; + } public ResponseBase shelfGoOutInStore(ShelfGoOutInStoreRequest request) @@ -78,15 +79,23 @@ namespace WCS.BLL.Services.Service Message = $"退出入库模式失败:货架[{request.ShelfCode}]不存在!", }; } - //TO DO 判断扫码枪 是否被其他扫码枪所占用 如果占用 直接退出入库模式 不发指令 - //两个扫码枪互相占用入库会有问题 + + //判断扫码枪 是否被其他扫码枪所占用 如果占用 直接退出入库模式 不发指令 shelf.GoOutInstore(); - return new ResponseCommon() - { - Code = 200, - Message = $"货架[{request.ShelfCode}]已退出入库模式!", - }; + if (shelf.ExceptionMessages == null || shelf.ExceptionMessages.Count == 0) + //已退出 + return new ResponseCommon() + { + Code = 200, + Message = $"货架[{request.ShelfCode}]已退出入库模式!", + }; + else + return new ResponseCommon() + { + Code = 200, + Message = $"货架[{request.ShelfCode}]已退出入库模式!{string.Join(",", shelf.ExceptionMessages)}", + }; } public async Task queryByMatSn(QueryByMatSnRequest request) @@ -120,8 +129,8 @@ namespace WCS.BLL.Services.Service Message = $"操作失败:物料{inventory.MatSN}已入库,库位为{inventory.StoreCode}", }; } - #region 获取物料数据 - //调用接口或者直接查询数据库 + #region 获取物料数据 //调用接口或者直接查询数据库 + //调用接口 if (1 != 1) { diff --git a/WCS.BLL/Services/Service/OutstoreService.cs b/WCS.BLL/Services/Service/OutstoreService.cs index 8ecdefa..3c37eb3 100644 --- a/WCS.BLL/Services/Service/OutstoreService.cs +++ b/WCS.BLL/Services/Service/OutstoreService.cs @@ -4,11 +4,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using TouchSocket.Sockets; 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.OutStore; namespace WCS.BLL.Services.Service { @@ -55,8 +58,10 @@ namespace WCS.BLL.Services.Service OrderId = order.Id, OrderNumber = order.OrderNumber, MatCode = item.MatCode, + MatName = item.MatName, MatBatch = item.MatBatch, ReqQty = item.ReqQty, + OutQty = 0, CreateUser = request.UserName }; await DbHelp.db.Insertable(orderDetail).ExecuteCommandAsync(); @@ -202,18 +207,31 @@ namespace WCS.BLL.Services.Service public async Task GetOutOrderList(GetOutOrderListRequest request) { //直接查询 - var outOrderList = await DbHelp.db.Queryable() - .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber.Contains(request.OrderNumber)) - .Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize) - .ToListAsync(); + 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)); + + var totalCount = await recordsQueryable.CountAsync(); + var records = await recordsQueryable + .Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize) + .ToListAsync(); + //生成序号 + for (int i = 0; i < records.Count; i++) + { + records[i].RowNumber = (request.PageNumber - 1) * 10 + i + 1; + } + return new PageQueryResponse() { Code = 200, - Message = "success", + Message = $"success", Data = new PageQueryResponseData() { - Lists = outOrderList, - Count = outOrderList.Count + TotalCount = totalCount, + MaxPage = request.PageSize == 0 ? 0 : (int)Math.Ceiling((decimal)totalCount / request.PageSize), + Count = records.Count, + Lists = records.ToList() } }; } @@ -235,7 +253,7 @@ namespace WCS.BLL.Services.Service }; } } - else if (string.IsNullOrEmpty(request.OrderNumber)) + else if (!string.IsNullOrEmpty(request.OrderNumber)) { outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) .FirstAsync(); @@ -262,29 +280,84 @@ namespace WCS.BLL.Services.Service var orderDetailTask = DbHelp.db.Queryable() .Where(t => t.OrderId == outOrder.Id) .ToListAsync(); + var orderDetail = await orderDetailTask; + //生成序号 + for (int i = 0; i < orderDetail.Count; i++) + { + orderDetail[i].RowNumber = i + 1; + } + #endregion + + + return new ResponseCommon>() + { + Code = 200, + Message = "Success", + Data = orderDetail + }; + } + + public async Task GetOutOrderMatDetail(GetOutOrderDetailRequest request) + { + OutOrder outOrder = null; + + #region 查询出库单 + if (request.OrderId != 0) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.Id == request.OrderId).FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在Id为{request.OrderId}的出库单!", + }; + } + } + else if (!string.IsNullOrEmpty(request.OrderNumber)) + { + outOrder = await DbHelp.db.Queryable().Where(t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (outOrder == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:不存在单据号为{request.OrderNumber}的出库单!", + }; + } + } + else + { + return new ResponseCommon() + { + Code = 201, + Message = $"查询失败:缺少必要参数!", + }; + } #endregion #region 出库物料明细 var orderMatDetailTask = DbHelp.db.Queryable() .Where(t => t.OrderId == outOrder.Id) .ToListAsync(); + var orderMatDetail = await orderMatDetailTask; + //生成序号 + for (int i = 0; i < orderMatDetail.Count; i++) + { + orderMatDetail[i].RowNumber = i + 1; + } #endregion - var orderDetail = await orderDetailTask; - var orderMatDetail = await orderMatDetailTask; - return new ResponseCommon() + + return new ResponseCommon> { Code = 200, Message = "Success", - Data = new - { - OrderDetailLists = orderDetail, - OrderMatDetailLists = orderMatDetail, - } + Data = orderMatDetail }; } - private string GenerateOrderNumber() { var orderNumber = "PD" + DateTime.Now.ToString("yyyyMMddHHmmss"); @@ -303,26 +376,60 @@ namespace WCS.BLL.Services.Service return new ResponseCommon() { Code = 201, - Message = "不存在对应的出库单据!", + Message = $"不存在对应的出库单据{request.OrderNumber}!", Data = null }; } - //获取出库单据明细 - //TO DO 如果是按物料编码出库 需要计算物料明细保存并进行锁定 + + //如果是按物料编码出库 需要计算物料明细、并进行物料锁定 if (order.SyncType == SyncTypeEnum.ByMatCode) { - + var result = CaculateOutOrderMatDetails(order); + if (result.Code != 200) + { + return result; + } } - //分组 按物料找到对应的货架 + //获取需要出库的物料明细 + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .Where(t => t.IsSended == false) + .Includes(t => t.StoreInfo) + .ToList(); + if (outOrderMatDetails == null || outOrderMatDetails.Count == 0) { - + return new ResponseCommon() + { + Code = 201, + Message = $"出库单据{request.OrderNumber}物料已全部出库!", + Data = null + }; } + //按货架分组 按物料找到对应的货架 + var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId) + .Distinct() + .ToList(); + var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList(); ; - //对应的货架进入出库模式 亮灯 + var outherModeShelfs = shelfs.Where(t => t.CurentMode != HardWare.Mode.待机模式).Select(t => t.ShelfCode).ToList(); + if (outherModeShelfs != null && outherModeShelfs.Count > 0) { - + return new ResponseCommon() + { + Code = 201, + Message = $"进入出库模式失败:货架{string.Join("", outherModeShelfs)}不在待机模式", + Data = null + }; } + //对应的货架对应位置 进入出库模式 亮灯 + shelfs.ForEach(shelf => + { + var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode) + .Distinct() + .ToList(); + shelf.GoInOutstore(matDetails,order); + }); //返回 return new ResponseCommon() @@ -333,17 +440,188 @@ namespace WCS.BLL.Services.Service }; } + private ResponseBase CaculateOutOrderMatDetails(OutOrder order) + { + try + { + DbHelp.db.BeginTran(); + + ////第一步 删除、解锁 放在上一次结束入库时操作 + //var outOrderMatDetails = DbHelp.db.Queryable() + // .Where(t => t.OrderId == order.Id) + // .ToList(); + //var inventoryIds = outOrderMatDetails.Select(t => t.Id).ToList(); + //var inventoryDetails = DbHelp.db.Queryable() + // .Where(t => inventoryIds.Contains(t.Id)) + // .ToList(); + //inventoryDetails.ForEach(t => { t.IsLocked = false; }); + //DbHelp.db.Deleteable(outOrderMatDetails).ExecuteCommand(); + //DbHelp.db.Updateable(inventoryDetails).ExecuteCommand(); + + //第一步 找到需求物料 + var outOrderDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .ToList(); + if (outOrderDetails == null || outOrderDetails.Count == 0) + { + return new ResponseCommon() + { + Code = 201, + Message = $"计算物料失败,{order.OrderNumber}没有单据明细!" + }; + } + //第二步 开始计算物料 + List outOrderMatDetails = new List(); + foreach (var outOrderDetail in outOrderDetails) + { + //2.1筛选 满足 图号 批次的库存 + var matInventoryDetails = DbHelp.db.Queryable() + .Where(t => t.MatCode == outOrderDetail.MatCode) + .WhereIF(!string.IsNullOrEmpty(outOrderDetail.MatBatch), t => t.MatBatch == outOrderDetail.MatBatch) + .OrderBy(t => t.MatBatch)//先进先出 + .OrderBy(t => t.MatQty)//零散料先出 + .ToList(); + + //2.2按照搜索出来的库存和当前未出的数量 计算需要出的SN + for (int i = 0; i < matInventoryDetails.Count && outOrderDetail.ReqQty - outOrderDetail.OutQty > 0; i++) + { + if (outOrderDetail.ReqQty - outOrderDetail.OutQty <= matInventoryDetails[i].MatQty) + { + outOrderMatDetails.Add(new OutOrderMatDetail() + { + OrderId = outOrderDetail.Id, + OrderNumber = outOrderDetail.OrderNumber, + OutOrderDetailId = outOrderDetail.Id, + InventoryDetailId = matInventoryDetails[i].Id, + StoreId = matInventoryDetails[i].StoreId, + StoreCode = matInventoryDetails[i].StoreCode, + MatSN = matInventoryDetails[i].MatSN, + MatCode = matInventoryDetails[i].MatCode, + MatName = matInventoryDetails[i].MatName, + MatSpec = matInventoryDetails[i].MatSpec, + MatBatch = matInventoryDetails[i].MatBatch, + MatQty = matInventoryDetails[i].MatQty, + MatSupplier = matInventoryDetails[i].MatSupplier, + MatCustomer = matInventoryDetails[i].MatCustomer, + IsSended = false, + CreateUser = "待定", + }); + outOrderDetail.ReqQty = 0; + + matInventoryDetails[i].IsLocked = true; + DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand(); + } + else + { + outOrderDetail.ReqQty = outOrderDetail.ReqQty - matInventoryDetails[i].MatQty; + + outOrderMatDetails.Add(new OutOrderMatDetail() + { + OrderId = outOrderDetail.Id, + OrderNumber = outOrderDetail.OrderNumber, + OutOrderDetailId = outOrderDetail.Id, + InventoryDetailId = matInventoryDetails[i].Id, + StoreId = matInventoryDetails[i].StoreId, + StoreCode = matInventoryDetails[i].StoreCode, + MatSN = matInventoryDetails[i].MatSN, + MatCode = matInventoryDetails[i].MatCode, + MatName = matInventoryDetails[i].MatName, + MatSpec = matInventoryDetails[i].MatSpec, + MatBatch = matInventoryDetails[i].MatBatch, + MatQty = matInventoryDetails[i].MatQty, + MatSupplier = matInventoryDetails[i].MatSupplier, + MatCustomer = matInventoryDetails[i].MatCustomer, + IsSended = false, + CreateUser = "待定", + }); + + matInventoryDetails[i].IsLocked = true; + DbHelp.db.Updateable(matInventoryDetails[i]).ExecuteCommand(); + } + } + } + DbHelp.db.Insertable(outOrderMatDetails).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}" + }; + } + } + + private ResponseBase CancelOutOrderMatDetails(OutOrder order) + { + try + { + DbHelp.db.BeginTran(); + var outOrderMatDetails = DbHelp.db.Queryable() + .Where(t => t.OrderId == order.Id) + .ToList(); + var inventoryIds = outOrderMatDetails.Select(t => t.Id).ToList(); + var inventoryDetails = DbHelp.db.Queryable() + .Where(t => inventoryIds.Contains(t.Id)) + .ToList(); + inventoryDetails.ForEach(t => { t.IsLocked = false; }); + DbHelp.db.Deleteable(outOrderMatDetails).ExecuteCommand(); + DbHelp.db.Updateable(inventoryDetails).ExecuteCommand(); + DbHelp.db.CommitTran(); + return new ResponseCommon() + { + Code = 200, + Message = $"Success" + }; + } + catch (Exception ex) + { + DbHelp.db.RollbackTran(); + return new ResponseCommon() + { + Code = 300, + Message = $"发生异常:{ex.Message}" + }; + } + } + public async Task GoOutOutstore(GetOutOrderDetailRequest request) { + //获取出库单 + var order = await DbHelp.db.Queryable() + .WhereIF(request.OrderId != 0, t => t.Id == request.OrderId) + .WhereIF(!string.IsNullOrEmpty(request.OrderNumber), t => t.OrderNumber == request.OrderNumber) + .FirstAsync(); + if (order == null) + { + return new ResponseCommon() + { + Code = 201, + Message = $"不存在对应的出库单据{request.OrderNumber}!", + Data = null + }; + } + //找到正在出对应出库单的货架 var shelves = ShelfManager.Shelves.Where(t => t.OrderNumber == request.OrderNumber) .ToList(); + //退出出库模式 shelves.ForEach(t => { t.GoOutOutstore(); }); + //解锁物料 删除物料明细 + CancelOutOrderMatDetails(order); + return new ResponseCommon() { Code = 200, diff --git a/WCS.BLL/Services/Service/StoreInfoService.cs b/WCS.BLL/Services/Service/StoreInfoService.cs index 4b02af6..dc6b8d6 100644 --- a/WCS.BLL/Services/Service/StoreInfoService.cs +++ b/WCS.BLL/Services/Service/StoreInfoService.cs @@ -236,5 +236,43 @@ namespace WCS.BLL.Services.Service return response; } } + + Task> IStoreInfoService.GetShelves(GetShelvesRequest request) + { + throw new NotImplementedException(); + } + + Task> IStoreInfoService.addOrUpdateShelfInfo(AddShelfInfoRequest request) + { + throw new NotImplementedException(); + } + + async Task> IStoreInfoService.GenerateStoreInfo() + { + var shelfInfo = await DbHelp.db.Queryable().Where(t => t.ShelfCode == "C04-1").FirstAsync(); + var ModuleInfos = await DbHelp.db.Queryable().Where(t => t.ShelfId == shelfInfo.Id).ToListAsync(); + ModuleInfos.ForEach(moduleInfo => + { + for (int i = 1; i <= moduleInfo.LightCount; i++) + { + var storeInfo = new StoreInfo() + { + StoreCode = moduleInfo.ModuleCode + "-" + i.ToString(), + ModuleId = moduleInfo.Id, + ModuleCode = moduleInfo.ModuleCode, + ShelfId = shelfInfo.Id, + ShelfCode = shelfInfo.ShelfCode, + BoardId = moduleInfo.BoardId, + LightNumber = i, + Priority = 1, + CurrentMatSn = string.Empty, + }; + DbHelp.db.Insertable(storeInfo).ExecuteCommand(); + + } + }); + + return new ResponseCommon() { Message = "111"}; + } } } diff --git a/WCS.BLL/Tool/TCPClient.cs b/WCS.BLL/Tool/TCPClient.cs index ccd2f0c..86064ee 100644 --- a/WCS.BLL/Tool/TCPClient.cs +++ b/WCS.BLL/Tool/TCPClient.cs @@ -60,7 +60,7 @@ namespace WCS.BLL //载入配置 tcpClient.Setup(new TouchSocketConfig() .SetRemoteIPHost(RemoteIPHost) - .SetBindIPHost(BindIPHost) + //.SetBindIPHost(BindIPHost) .ConfigurePlugins(a => { //配置断线重连 @@ -156,24 +156,35 @@ namespace WCS.BLL } } + public void ReConnectAsync() + { + tcpClient.TryConnectAsync(); + } + + public void Send(byte[] message) { - var boardId = (message[3] << 8) + message[4]; - //记录发送指令 用于通信校验 同Id只校验最后一个指令 - ////MessageList.AddOrUpdate(boardId, new MessageDto() - ////{ - //// ID = boardId, - //// Message = message, - ////}, (key, oldValue) => oldValue = new MessageDto() - ////{ - //// ID = boardId, - //// Message = message, - ////}); - lock (sendLockObject) + try { - tcpClient.Send(message); - //发送自带10ms间隔 - Thread.Sleep(10); + var boardId = (message[3] << 8) + message[4]; + lock (sendLockObject) + { + tcpClient.Send(message); + //发送自带10ms间隔 + Thread.Sleep(10); + } + } + catch (Exception ex) + { + //因异常断连时(网线已经被断了) 尝试重连一次 + if (ex is NotConnectedException) + { + Task.Run(() => + { + ReConnectAsync(); + }); + } + throw ex; } } diff --git a/WCS.BLL/WCS.BLL.csproj b/WCS.BLL/WCS.BLL.csproj index efc647d..013ebfa 100644 --- a/WCS.BLL/WCS.BLL.csproj +++ b/WCS.BLL/WCS.BLL.csproj @@ -7,7 +7,8 @@ - + + diff --git a/WCS.Model/ApiModel/OutStore/GetOutOrderDetailRequest.cs b/WCS.Model/ApiModel/OutStore/GetOutOrderDetailRequest.cs index 0087be3..3ed25e2 100644 --- a/WCS.Model/ApiModel/OutStore/GetOutOrderDetailRequest.cs +++ b/WCS.Model/ApiModel/OutStore/GetOutOrderDetailRequest.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace WCS.Model { - public class GetOutOrderDetailRequest : ResponseBase + public class GetOutOrderDetailRequest : RequestBase { public int OrderId { get; set; } public string OrderNumber { get; set; } diff --git a/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs b/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs index c55e967..a9b18a0 100644 --- a/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs +++ b/WCS.Model/ApiModel/OutStore/GetOutOrderListRequest.cs @@ -10,10 +10,8 @@ namespace WCS.Model { public string OrderNumber { get; set; } - public int OrderStatus { get; set; } + public string OrderSource { get; set; } - //public int PageNumber { get; set; } - - //public int PageSize { get; set; } + public string OrderType { get; set; } } } diff --git a/WCS.Model/ApiModel/OutStore/OutOrderDetailModel.cs b/WCS.Model/ApiModel/OutStore/OutOrderDetailModel.cs new file mode 100644 index 0000000..918a8b1 --- /dev/null +++ b/WCS.Model/ApiModel/OutStore/OutOrderDetailModel.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.OutStore +{ + public class OutOrderDetailModel + { + public int Id { get; set; } + + public int OrderId { get; set; } + + public string OrderNumber { get; set; } + + public string MatCode { get; set; } + + public string MatName { get; set; } + + public string MatBatch { get; set; } + + public int ReqQty { get; set; } + + public int OutQty { get; set; } + + public DateTime CreateTime { get; set; } + + public string CreateUser { get; set; } + + public int RowNumber { get; set; } + } +} diff --git a/WCS.Model/ApiModel/OutStore/OutOrderMatDetailModel.cs b/WCS.Model/ApiModel/OutStore/OutOrderMatDetailModel.cs new file mode 100644 index 0000000..0d2ab85 --- /dev/null +++ b/WCS.Model/ApiModel/OutStore/OutOrderMatDetailModel.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WCS.Model.ApiModel.OutStore +{ + public class OutOrderMatDetailModel + { + public int Id { get; set; } + + public int OrderId { get; set; } + + public string OrderNumber { get; set; } + + public int OutOrderDetailId { get; set; } + + public int InventoryDetailId { get; set; } + + #region 库位属性 + public int StoreId { get; set; } + + public string StoreCode { get; set; } + + + #endregion + + #region 物料属性 + public string MatSN { get; set; } + public string MatCode { get; set; } + public string MatName { get; set; } + + public string MatSpec { get; set; } + + public string MatBatch { get; set; } + + public int MatQty { get; set; } + + public string? MatSupplier { get; set; } + + public string? MatCustomer { get; set; } + #endregion + + public bool IsSended { get; set; } = false; + + public DateTime CreateTime { get; set; } + + public string CreateUser { get; set; } + + public int RowNumber { get; set; } + } +} diff --git a/WCS.Model/ApiModel/OutStore/OutOrderModel.cs b/WCS.Model/ApiModel/OutStore/OutOrderModel.cs new file mode 100644 index 0000000..f46bbfc --- /dev/null +++ b/WCS.Model/ApiModel/OutStore/OutOrderModel.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace WCS.Model.ApiModel.OutStore +{ + public class OutOrderModel : INotifyPropertyChanged + { + public int Id { get; set; } + + public string OrderNumber { get; set; } + public OutOrderStatus OrderStatus { get; set; } + + public OutOrderExeStatus OutOrderExeStatus { get; set; } + + public string OrderSource { get; set; } + + public string OrderType { get; set; } + + public SyncTypeEnum SyncType { get; set; } + + public DateTime CreateTime { get; set; } + + public string CreateUser { get; set; } + public bool IsSelected + { + get { return isSelected; } + set + { + isSelected = value; + OnPropertyChanged(nameof(IsSelected)); + } + } + public bool isSelected; + public int RowNumber { get; set; } + + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public enum OutOrderStatus + { + 未发料 = 0, + 部分发料 = 1, + 全部发料 = 2 + } + + public enum OutOrderExeStatus + { + 待发料 = 0, + 开始发料 = 1, + 暂停发料 = 2, + 发料完成 = 3 + } + + public enum SyncTypeEnum + { + ByMatCode = 0, + ByMatSn = 1 + } +} diff --git a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs index d729437..645ce0c 100644 --- a/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs +++ b/WCS.Model/ApiModel/OutStore/SysOutOrderByMatCodeRequest.cs @@ -23,6 +23,7 @@ namespace WCS.Model public class MatCodeItemList { public string MatCode { get; set; } + public string MatName { get; set; } public string MatBatch { get; set; } public int ReqQty { get; set; } } diff --git a/WCS.WebApi/Controllers/OutstoreController.cs b/WCS.WebApi/Controllers/OutstoreController.cs index ca57c1f..3e752a5 100644 --- a/WCS.WebApi/Controllers/OutstoreController.cs +++ b/WCS.WebApi/Controllers/OutstoreController.cs @@ -113,6 +113,30 @@ namespace WebApi.Controllers } } + /// + /// ȡⵥϸ + /// + /// + /// + [Route("getOutOrderMatDetail")] + [HttpPost(Name = "getOutOrderMatDetail")] + public async Task getOutOrderMatDetail(GetOutOrderDetailRequest request) + { + try + { + return await _outstoreService.GetOutOrderMatDetail(request); + } + catch (Exception ex) + { + return new ResponseBase() + { + Code = 300, + Message = "ѯʧܣ" + ex.Message, + }; + } + } + + /// /// ͨⵥݺſʼ /// @@ -147,7 +171,7 @@ namespace WebApi.Controllers { try { - return await _outstoreService.GetOutOrderDetail(request); + return await _outstoreService.GoOutOutstore(request); } catch (Exception ex) { diff --git a/WCS.WebApi/Controllers/StoreInfoController.cs b/WCS.WebApi/Controllers/StoreInfoController.cs index d70b609..0357891 100644 --- a/WCS.WebApi/Controllers/StoreInfoController.cs +++ b/WCS.WebApi/Controllers/StoreInfoController.cs @@ -35,5 +35,11 @@ namespace WCS.WebApi.Controllers { return await _storeInfoService.addOrUpdateShelfInfo(request); } + + [HttpPost("GenerateStoreInfo")] + public async Task> GenerateStoreInfo() + { + return await _storeInfoService.GenerateStoreInfo(); + } } } diff --git a/WCS.WebApi/Program.cs b/WCS.WebApi/Program.cs index d312813..b387403 100644 --- a/WCS.WebApi/Program.cs +++ b/WCS.WebApi/Program.cs @@ -18,7 +18,7 @@ namespace WebApi public static void Main(string[] args) { - + WebSoceketManager.InitWebSocket(); //LocalStatic.wCSTcpCleint = new WCS.BLL.TCPClient("127.0.0.1:20002"); //LocalStatic.wCSTcpCleint.Send(new byte[] { 0x08, 0x00, 0x00, 0x11, 0x12, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); @@ -28,7 +28,9 @@ namespace WebApi TCPClientManager.InitTcpClient(); - var builder = WebApplication.CreateBuilder(args); + + + var builder = WebApplication.CreateBuilder(args); //// Kestrel //builder.WebHost.ConfigureKestrel((context, options) => //{ diff --git a/WCS.WebApi/WCS.WebApi.csproj b/WCS.WebApi/WCS.WebApi.csproj index adda62f..840dcac 100644 --- a/WCS.WebApi/WCS.WebApi.csproj +++ b/WCS.WebApi/WCS.WebApi.csproj @@ -11,7 +11,6 @@ - diff --git a/WCS.WebApi/WCS后端.sln b/WCS.WebApi/WCS后端.sln index 3f36bb4..3faa1d1 100644 --- a/WCS.WebApi/WCS后端.sln +++ b/WCS.WebApi/WCS后端.sln @@ -10,6 +10,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WCS.BLL", "..\WCS.BLL\WCS.BLL.csproj", "{A6B0DB70-BE92-487C-BA6B-56441B676C85}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "货架标准上位机", "..\货架标准上位机\货架标准上位机.csproj", "{A24FAA0F-8483-4741-BFE7-EC2C56C811A6}" + ProjectSection(ProjectDependencies) = postProject + {118D453B-1693-4C00-8378-20ECBFCF2700} = {118D453B-1693-4C00-8378-20ECBFCF2700} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WCS.Model", "..\WCS.Model\WCS.Model.csproj", "{7CE9AF07-3538-46C3-BBF0-A039BDE15AAF}" EndProject diff --git a/货架标准上位机/ViewModels/InInventoryViewModel.cs b/货架标准上位机/ViewModels/InInventoryViewModel.cs index a7821e0..30ebb7a 100644 --- a/货架标准上位机/ViewModels/InInventoryViewModel.cs +++ b/货架标准上位机/ViewModels/InInventoryViewModel.cs @@ -140,6 +140,7 @@ namespace 货架标准上位机.ViewModel { scanner.ShelfCode = string.Empty; scanner.ModulesStr = string.Empty; + } } catch (Exception ex) @@ -201,7 +202,7 @@ namespace 货架标准上位机.ViewModel { scanner.MatSn = Result.Data.MatSN; } - else if(Result != null && !string.IsNullOrEmpty(Result.Message)) + else if (Result != null && !string.IsNullOrEmpty(Result.Message)) { Growl.Warning(Result.Message); } @@ -237,6 +238,7 @@ namespace 货架标准上位机.ViewModel t.MatSn = string.Empty; t.ScannerDisplayControl.RefreshValues(t.ShelfCode, t.MatSn); + Growl.Success(Result.Message); } } else diff --git a/货架标准上位机/ViewModels/MainViewModel.cs b/货架标准上位机/ViewModels/MainViewModel.cs index 93eaa5d..dae0781 100644 --- a/货架标准上位机/ViewModels/MainViewModel.cs +++ b/货架标准上位机/ViewModels/MainViewModel.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Markup; @@ -25,6 +26,18 @@ namespace 货架标准上位机.ViewModel /// public string Title { get => title; set { SetProperty(ref title, value); } } + + private bool goToOutVentoryView; + public bool GoToOutVentoryView + { + get { return goToOutVentoryView; } + set + { + SetProperty(ref goToOutVentoryView, value); + } + } + + #region 专用_MainWindow2 //隐藏式选项卡的高度 public double TabItemHeight { get; set; } = 0; @@ -72,6 +85,10 @@ namespace 货架标准上位机.ViewModel { ScannerManager.InitScanners(); }), + new Tuple("初始化WebSocket连接..", "初始化WebSocket连接失败,请联系管理员", () => + { + WebSocket.InitWebSocket(); + }), }; MainLoadWindow.TaskSleepTime = 200; @@ -88,7 +105,7 @@ namespace 货架标准上位机.ViewModel }); - ////不登录,直接使用最高权限 + //不登录,直接使用最高权限 //{ // UserLoginView.NotLogin(); // return true; diff --git a/货架标准上位机/ViewModels/MatInfoViewModel.cs b/货架标准上位机/ViewModels/MatInfoViewModel.cs index 08d4152..02a31c2 100644 --- a/货架标准上位机/ViewModels/MatInfoViewModel.cs +++ b/货架标准上位机/ViewModels/MatInfoViewModel.cs @@ -124,7 +124,6 @@ namespace 货架标准上位机.ViewModel CurrentPage = 1; return; } - #region 调用接口获取数据 //var dia = Dialog.Show(new TextDialog()); try @@ -159,8 +158,6 @@ namespace 货架标准上位机.ViewModel //dia.Close(); } #endregion - - } /// diff --git a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs index f50aa77..47d2ac0 100644 --- a/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs +++ b/货架标准上位机/ViewModels/OutInventoryAddDucumentViewModel.cs @@ -116,8 +116,9 @@ namespace 货架标准上位机.ViewModels ItemList = DataGridItemSource.Select(t => new MatCodeItemList() { MatCode = t.MatCode, + MatName = t.MatName, MatBatch = t.MatBatch, - ReqQty = t.NeedQty + ReqQty = t.NeedQty, }).ToList(), DeviceType = LocalFile.Config.DeviceType, UserName = LocalStatic.CurrentUser diff --git a/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs new file mode 100644 index 0000000..ba27c69 --- /dev/null +++ b/货架标准上位机/ViewModels/OutInventoryDocumentViewModel.cs @@ -0,0 +1,378 @@ +using HandyControl.Controls; +using Ping9719.WpfEx.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; +using WCS.Model; +using WCS.Model.ApiModel.MatBaseInfo; +using WCS.Model.ApiModel.OutStore; +using 货架标准上位机.Api; + +namespace 货架标准上位机.ViewModels +{ + public class OutInventoryDocumentViewModel : BindableBase + { + public OutInventoryDocumentViewModel() + { + BtnSearch(); + } + + #region Properties界面绑定的实体 + private ObservableCollection dataGridItemSource; + public ObservableCollection DataGridItemSource + { + get { return dataGridItemSource; } + set + { + SetProperty(ref dataGridItemSource, value); + } + } + + public OutOrderModel selectedataGridItem; + public OutOrderModel SelectedataGridItem + { + get { return selectedataGridItem; } + set + { + SetProperty(ref selectedataGridItem, value); + } + } + + private string orderNumber; + public string OrderNumber + { + get { return orderNumber; } + set + { + SetProperty(ref orderNumber, value); + } + } + + private string orderType; + public string OrderType + { + get { return orderType; } + set + { + SetProperty(ref orderType, value); + } + } + + private string orderSource; + public string OrderSource + { + get { return orderSource; } + set + { + SetProperty(ref orderSource, value); + } + } + + #endregion + + #region Command + public ICommand BtnSearchCommand { get => new DelegateCommand(BtnSearchReset); } + public void BtnSearchReset() + { + BtnSearch(true); + } + public void BtnSearch(bool IsPageReset = true) + { + if (CurrentPage == 0 || IsPageReset) + { + CurrentPage = 1; + return; + } + + #region 调用接口获取数据 + try + { + var body = new GetOutOrderListRequest() + { + OrderNumber = OrderNumber, + OrderType = OrderType, + OrderSource = OrderSource, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + PageNumber = CurrentPage, + PageSize = 10, + }; + var Result = ApiHelp.GetDataFromHttp>(LocalFile.Config.ApiIpHost + "outStore/GetOutOrderList", body, "POST"); + if (Result != null && Result.Data != null && Result.Data.Lists != null) + { + DataGridItemSource = new ObservableCollection(Result.Data.Lists); + MaxPage = Result.Data.MaxPage; + TotalCount = Result.Data.TotalCount; + } + } + catch (Exception ex) + { + Growl.Error("加载数据失败:" + ex.Message); + } + finally + { + } + #endregion + } + + public ICommand BtnResetCommand { get => new DelegateCommand(BtnReset); } + public void BtnReset() + { + + } + + public ICommand BtnDeleteCommand { get => new DelegateCommand(BtnDelete); } + public void BtnDelete() + { + + } + + public ICommand BtnOrderDetailCommand { get => new DelegateCommand(BtnOrderDetail); } + public void BtnOrderDetail() + { + try + { + if (DataGridItemSource == null) + { + Growl.Warning("未勾选数据!"); + } + + //判断是否勾选数据 + var selectedOutOrder = DataGridItemSource.Where(t => t.IsSelected) + .FirstOrDefault(); + if (selectedOutOrder == null) + { + Growl.Warning("未勾选数据!"); + } + + #region 调用接口获取数据 + + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + + }; + var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "outStore/getOutOrderDetail", body, "POST"); + if (Result != null && Result.Code == 200) + { + if (Result.Data.Count > 0) + { + //打开窗体 + var window = new OutInventoryDocumentDetailView(Result.Data); + window.Owner = Application.Current.MainWindow; + window.ShowDialog(); + } + else + { + Growl.Warning("该单据没有单据明细!"); + } + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + + } + + public ICommand BtnOrderMatDetailCommand { get => new DelegateCommand(BtnOrderMatDetail); } + public void BtnOrderMatDetail() + { + try + { + if (DataGridItemSource == null) + { + Growl.Warning("未勾选数据!"); + } + + //判断是否勾选数据 + var selectedOutOrder = DataGridItemSource.Where(t => t.IsSelected) + .FirstOrDefault(); + if (selectedOutOrder == null) + { + Growl.Warning("未勾选数据!"); + } + #region 调用接口获取数据 + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + + }; + var Result = ApiHelp.GetDataFromHttp>>(LocalFile.Config.ApiIpHost + "outStore/getOutOrderMatDetail", body, "POST"); + if (Result != null && Result.Code == 200) + { + if (Result.Data.Count > 0) + { + //打开窗体 + var window = new OutInventoryDocumentMatDetailView(Result.Data); + window.Owner = Application.Current.MainWindow; + window.ShowDialog(); + } + else + { + Growl.Warning("该单据没有发料明细!"); + } + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + } + + //开始入库 如果成功就直接跳转出库界面 + public ICommand BtnStartCommand { get => new DelegateCommand(BtnStart); } + public void BtnStart() + { + try + { + if (DataGridItemSource == null) + { + Growl.Warning("未勾选数据!"); + } + //判断是否勾选数据 + var selectedOutOrder = DataGridItemSource.Where(t => t.IsSelected) + .FirstOrDefault(); + if (selectedOutOrder == null) + { + Growl.Warning("未勾选数据!"); + } + + #region 调用接口开始出库 + var body = new GetOutOrderDetailRequest() + { + OrderId = selectedOutOrder.Id, + OrderNumber = selectedOutOrder.OrderNumber, + UserName = LocalStatic.CurrentUser, + DeviceType = LocalFile.Config.DeviceType, + }; + var Result = ApiHelp.GetDataFromHttp(LocalFile.Config.ApiIpHost + "outStore/goInOutstore", body, "POST"); + if (Result != null && Result.Code == 200) + { + //成功后直接跳转 + MainWindow1.viewModel.GoToOutVentoryView = true; + Growl.Success("已跳转到物料出库页面!"); + } + else if (Result != null) + { + Growl.Warning(Result.Message); + } + else + { + Growl.Warning("调用接口失败!"); + } + #endregion + } + catch (Exception ex) + { + Growl.Error("出现异常:" + ex.Message); + } + finally + { + } + } + + public ICommand BtnPauseCommand { get => new DelegateCommand(BtnPause); } + public void BtnPause() + { + + } + #endregion + + #region PageOperation 分页操作 + private int currentPage; + public int CurrentPage + { + get { return currentPage; } + set + { + SetProperty(ref currentPage, value); + BtnSearch(false); + } + } + + private int maxPage; + public int MaxPage + { + get { return maxPage; } + set { SetProperty(ref maxPage, value); } + } + + //总数量 + private int totalCount; + public int TotalCount + { + get { return totalCount; } + set { SetProperty(ref totalCount, value); } + } + + public ICommand BtnFirstPageCommand { get => new DelegateCommand(BtnFirstPage); } + public void BtnFirstPage() + { + CurrentPage = 1; + } + + public ICommand BtnPrePageCommand { get => new DelegateCommand(BtnPrePage); } + public void BtnPrePage() + { + if (CurrentPage > 1) + { + CurrentPage--; + } + } + + public ICommand BtnNextPageCommand { get => new DelegateCommand(BtnNextPage); } + public void BtnNextPage() + { + if (CurrentPage < MaxPage) + { + CurrentPage++; + } + } + + public ICommand BtnLastPageCommand { get => new DelegateCommand(BtnLastPage); } + public void BtnLastPage() + { + if (CurrentPage != MaxPage) + { + CurrentPage = MaxPage; + } + } + #endregion + } +} diff --git a/货架标准上位机/Views/HomeView.xaml b/货架标准上位机/Views/HomeView.xaml index f3ddfc4..94c724d 100644 --- a/货架标准上位机/Views/HomeView.xaml +++ b/货架标准上位机/Views/HomeView.xaml @@ -39,7 +39,7 @@ 报警 - + @@ -49,10 +49,10 @@ 日志 - + - + diff --git a/货架标准上位机/Views/InInventoryView.xaml b/货架标准上位机/Views/InInventoryView.xaml index 789aec7..0f89dcd 100644 --- a/货架标准上位机/Views/InInventoryView.xaml +++ b/货架标准上位机/Views/InInventoryView.xaml @@ -13,7 +13,8 @@ - + + @@ -26,113 +27,51 @@ - - - - + + - + + + + + + + + + + 入库报警信息 + + + + + + + + + 入库日志信息 + + + + + + diff --git a/货架标准上位机/Views/InInventoryView.xaml.cs b/货架标准上位机/Views/InInventoryView.xaml.cs index 988aba8..c8793cd 100644 --- a/货架标准上位机/Views/InInventoryView.xaml.cs +++ b/货架标准上位机/Views/InInventoryView.xaml.cs @@ -65,5 +65,13 @@ namespace 货架标准上位机 { } + + private void Button_PreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Space) + { + e.Handled = true; // 阻止空格键触发按钮点击事件 + } + } } } diff --git a/货架标准上位机/Views/MainWindows/MainWindow1.xaml b/货架标准上位机/Views/MainWindows/MainWindow1.xaml index 77c6bf4..4fcc4e9 100644 --- a/货架标准上位机/Views/MainWindows/MainWindow1.xaml +++ b/货架标准上位机/Views/MainWindows/MainWindow1.xaml @@ -74,7 +74,7 @@ - + @@ -86,9 +86,6 @@ - - - @@ -103,6 +100,17 @@ + + + + 出库单据 + + + + + + + @@ -113,7 +121,7 @@ - + @@ -251,7 +259,7 @@ - + diff --git a/货架标准上位机/Views/OutInventoryDocumentDetailView.xaml b/货架标准上位机/Views/OutInventoryDocumentDetailView.xaml new file mode 100644 index 0000000..e5649b7 --- /dev/null +++ b/货架标准上位机/Views/OutInventoryDocumentDetailView.xaml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +