From 104462c3520e962719cb349ef582ba53628f13e9 Mon Sep 17 00:00:00 2001 From: "yang.lee" Date: Wed, 6 Dec 2023 11:48:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=97=A5=E5=BF=97=E5=88=86?= =?UTF-8?q?=E5=89=B2=E7=BA=BF=EF=BC=8C=E7=9C=8B=E7=9D=80=E7=9C=BC=E8=8A=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dto/Inputs/CTUUnloadConfirmInput.cs | 12 ++ .../Tnb.WarehouseMgr/DeviceProviderService.cs | 31 +++-- .../Tnb.WarehouseMgr/WareHouseService.cs | 112 ++++++++++-------- .../WmsEmptyInstockService.cs | 31 +++-- .../WmsEmptyOutstockService .cs | 11 +- 5 files changed, 128 insertions(+), 69 deletions(-) create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CTUUnloadConfirmInput.cs diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CTUUnloadConfirmInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CTUUnloadConfirmInput.cs new file mode 100644 index 00000000..d1e8795b --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/CTUUnloadConfirmInput.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tnb.WarehouseMgr.Entities.Dto.Inputs +{ + public class CTUUnloadConfirmInput + { + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs b/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs index e9086acc..6e036949 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs @@ -149,7 +149,6 @@ namespace Tnb.WarehouseMgr [HttpPost, NonUnify, AllowAnonymous] public async Task UnloadConfirm(ConfirmInput input)// { - Logger.Information("--------------------------------------------------------"); Logger.Information("放货确认.................."); Logger.Information($"输入参数:{JsonConvert.SerializeObject(input)}"); try @@ -215,7 +214,7 @@ namespace Tnb.WarehouseMgr } return await ToApiResult(HttpStatusCode.InternalServerError, "电梯还未开门,请重试!"); - + } catch (Exception ex) { @@ -223,7 +222,6 @@ namespace Tnb.WarehouseMgr return await ToApiResult(HttpStatusCode.InternalServerError, "电梯还未开门,请重试!"); throw; } - Logger.Information("--------------------------------------------------------"); } /// @@ -233,7 +231,6 @@ namespace Tnb.WarehouseMgr [HttpPost, NonUnify, AllowAnonymous] public async Task TaskChainCallBack(TaskChainCallBackInput input) { - Logger.Information("--------------------------------------------------------"); try { @@ -298,10 +295,9 @@ namespace Tnb.WarehouseMgr return await ToApiResult(HttpStatusCode.InternalServerError, "请重试!"); throw; } - Logger.Information("--------------------------------------------------------"); return await ToApiResult(HttpStatusCode.OK, "成功"); - + } /// @@ -312,7 +308,6 @@ namespace Tnb.WarehouseMgr [HttpPost, NonUnify, AllowAnonymous] public async Task TaskCallback(TaskCallBackInput input) { - Logger.Information("--------------------------------------------------------"); Logger.Information($"任务状态上报->接收参数:{JsonConvert.SerializeObject(input)}"); try @@ -373,7 +368,6 @@ namespace Tnb.WarehouseMgr { _ = InvokeGenPretaskExcute(); } - Logger.Information("--------------------------------------------------------"); return await ToApiResult(HttpStatusCode.OK, "成功"); } @@ -464,5 +458,26 @@ namespace Tnb.WarehouseMgr } return result; } + + /// + /// CTU放货申请 + /// + /// + /// + [HttpPost, NonUnify, AllowAnonymous] + public Task CTUUnloadConfirm(ConfirmInput input) + { + var data = ""; + try + { + data = "允许放货"; + } + catch (Exception) + { + data = "不允许放货"; + throw; + } + return ToApiResult(HttpStatusCode.OK, data); + } } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs index e319f6e6..95db0087 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs @@ -42,6 +42,7 @@ namespace Tnb.WarehouseMgr private readonly IElevatorControlService _elevatorControlService; private static readonly Dictionary _elevatorAgvCtlStatusMap = new(StringComparer.OrdinalIgnoreCase); private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build(); + private static Dictionary locMap = new Dictionary(StringComparer.OrdinalIgnoreCase); public Func AddUnExecuteTask { get; set; } public WareHouseService(ISqlSugarRepository repository, IDictionaryDataService dictionaryDataService, @@ -215,6 +216,7 @@ namespace Tnb.WarehouseMgr List items = await cyDb.Queryable().LeftJoin((a, b) => a.id == b.carry_id) .LeftJoin((a, b, c) => a.location_id == c.id) .Where(whereExpr) + //.OrderByIF((a,b,c)=>SqlFunc.IsNullOrEmpty()) .OrderBy(policy.policy) .Select() .ToListAsync(); @@ -318,8 +320,11 @@ namespace Tnb.WarehouseMgr if (areaPreTasks.Any(x => x.third_eqp_type.ToEnum() != EnumTaskChainType.CTU)) { - foreach (var x in items) + Logger.Information("非CTU任务链生成"); + for (int i = 0; i < items.Count; i++) { + var num = (i + 1); + var x = items[i]; string groupCode = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE).Result; x.is_chain = 0; x.groups = groupCode; @@ -328,6 +333,8 @@ namespace Tnb.WarehouseMgr } else if ((moveNum >= areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum <= areaPreTasks.Count) { + Logger.Information("CTU任务链生成"); + string groupCode = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE); items.ForEach(x => x.is_chain = 1); @@ -445,15 +452,16 @@ namespace Tnb.WarehouseMgr { await ExecuteTargetFloorTask(elevatorTask); } - - } - ////调用AGV创建任务链接口 - List agvTasks = disTasks.Where(it => !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); - if (agvTasks?.Count > 0) - { - await AgvDispatch(agvTasks, agvCts.Token); } } + ////调用AGV创建任务链接口 + List agvTasks = disTasks.Where(it => !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); + if (agvTasks?.Count > 0) + { + Logger.Information($"Agv任务数量:{agvTasks.Count},taskCodes:{string.Join(",", agvTasks.Select(x => x.bill_code).Distinct())}"); + await AgvDispatch(agvTasks, agvCts.Token); + } + } } @@ -481,7 +489,6 @@ namespace Tnb.WarehouseMgr /// private async Task CallingLanding(List<(string endlocation_code, string device_id, string id, int floorNO)> endLocCodes) { - Logger.Information("--------------------------------------------------------"); Logger.Information($" 开始呼梯操作............."); Logger.Information($"电梯信息:{JsonConvert.SerializeObject(s_elevatorMap)}"); try @@ -559,7 +566,6 @@ namespace Tnb.WarehouseMgr Logger.Error($"呼梯操作错误堆栈跟踪:{Environment.NewLine}{ex.StackTrace}"); throw; } - Logger.Information("--------------------------------------------------------"); } /// @@ -569,7 +575,6 @@ namespace Tnb.WarehouseMgr /// private async Task ExecuteTargetFloorTask(WmsDistaskH disTask) { - Logger.Information("--------------------------------------------------------"); //收到放货确认通知,向电梯发送到3楼的指令 Logger.Information($"开始执行电梯任务,任务ID:{disTask.id}"); try @@ -648,7 +653,6 @@ namespace Tnb.WarehouseMgr Logger.Error("执行到目标楼层电梯任务失败", ex); throw; } - Logger.Information("--------------------------------------------------------"); } /// /// Agv调度 @@ -1167,49 +1171,61 @@ namespace Tnb.WarehouseMgr #endregion #region dijkstra - List? points = await _db.Queryable().ToListAsync(); - WmsPointH? startObj = points.Find(x => x.id == pStartId); - WmsPointH? endObj = points.Find(x => x.id == pEndId); - int sIndex = points.IndexOf(startObj); - int eIndex = points.IndexOf(endObj); - if (eIndex < sIndex) - { - (eIndex, sIndex) = (sIndex, eIndex); - (points[eIndex], points[sIndex]) = (points[sIndex], points[eIndex]); - } + List results = new(); - string[] vexs = points.Select(p => p.id).ToArray(); - EData[] edges = new EData[roads.Count]; - for (int i = 0; i < edges.Length; i++) + try { - string start = roads[i].startpoint_id; - string end = roads[i].endpoint_id; - int weight = roads[i].distance; - edges[i] = new EData(start, end, weight); - } - - Dijkstra pG = new(vexs, edges); - int[] prev = new int[pG.mVexs.Length]; - int[] dist = new int[pG.mVexs.Length]; - List vertexs = new() { startObj }; - pG.CalcDijkstra(sIndex, prev, dist); - List pointIds = points.Select(p => p.id).ToList(); - Stack result = new(); - GetPoints(pointIds, prev, result, eIndex); - - List results = new() { startObj }; - if (points?.Count > 0) - { - //points.Where(it => result.Contains(it.id)); - foreach (string i in result) + List? points = await _db.Queryable().ToListAsync(); + WmsPointH? startObj = points.Find(x => x.id == pStartId); + WmsPointH? endObj = points.Find(x => x.id == pEndId); + int sIndex = points.IndexOf(startObj); + int eIndex = points.IndexOf(endObj); + if (eIndex < sIndex) { - WmsPointH? point = points?.Find(x => x.id == i); - if (point != null) + (eIndex, sIndex) = (sIndex, eIndex); + (points[eIndex], points[sIndex]) = (points[sIndex], points[eIndex]); + } + + string[] vexs = points.Select(p => p.id).ToArray(); + EData[] edges = new EData[roads.Count]; + for (int i = 0; i < edges.Length; i++) + { + string start = roads[i].startpoint_id; + string end = roads[i].endpoint_id; + int weight = roads[i].distance; + edges[i] = new EData(start, end, weight); + } + + Dijkstra pG = new(vexs, edges); + + + int[] prev = new int[pG.mVexs.Length]; + int[] dist = new int[pG.mVexs.Length]; + List vertexs = new() { startObj }; + pG.CalcDijkstra(sIndex, prev, dist); + List pointIds = points.Select(p => p.id).ToList(); + Stack result = new(); + GetPoints(pointIds, prev, result, eIndex); + + results = new() { startObj }; + if (points?.Count > 0) + { + //points.Where(it => result.Contains(it.id)); + foreach (string i in result) { - results.Add(point); + WmsPointH? point = points?.Find(x => x.id == i); + if (point != null) + { + results.Add(point); + } } } } + catch (Exception ex) + { + Logger.Error("路径算法错误", ex); + throw; + } return results; #endregion diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyInstockService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyInstockService.cs index 25ebbc91..92b5e63b 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyInstockService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyInstockService.cs @@ -1,4 +1,5 @@ using System.Threading.Channels; +using Aop.Api.Domain; using JNPF.Common.Core.Manager; using JNPF.Common.Dtos.VisualDev; using JNPF.Common.Enums; @@ -12,6 +13,8 @@ using JNPF.VisualDev.Entitys; using JNPF.VisualDev.Interfaces; using Mapster; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using NPOI.SS.Formula.PTG; using SqlSugar; using Tnb.BasicData.Entities; using Tnb.WarehouseMgr.Entities; @@ -79,6 +82,7 @@ namespace Tnb.WarehouseMgr { WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.id == input.data[nameof(WmsCarryD.carry_id)].ToString()); BasLocation loc = await _db.Queryable().SingleAsync(it => it.id == endLocations[0].id); + Logger.Information($"loc.location_code={loc?.location_code}"); bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, loc); if (!isMatch) { @@ -92,8 +96,10 @@ namespace Tnb.WarehouseMgr VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSEMPTYINSTOCK_ID, true); await _runService.Create(templateEntity, input); + if (sPoint != null && ePoint != null) { + Logger.Information($"sPoint.id={sPoint.id},ePoint.id={ePoint.id}"); List points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id); if (points.Count <= 2) { @@ -123,21 +129,24 @@ namespace Tnb.WarehouseMgr bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(), status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, biz_type = WmsWareHouseConst.BIZTYPE_WMSEMPTYINSTOCK_ID, - task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID + task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID, + carry_id = input.data[nameof(preTask.carry_id)]?.ToString()!, + carry_code = input.data[nameof(preTask.carry_code)]?.ToString()!, + area_id = sPoint?.area_id!, + area_code = it.Key, + require_id = input.data["ReturnIdentity"].ToString(), + require_code = input.data[nameof(preTask.bill_code)]?.ToString()!, + create_id = _userManager.UserId, + create_time = DateTime.Now, }; - preTask.carry_id = input.data[nameof(preTask.carry_id)]?.ToString()!; - preTask.carry_code = input.data[nameof(preTask.carry_code)]?.ToString()!; - preTask.area_id = sPoint?.area_id!; - preTask.area_code = it.Key; - preTask.require_id = input.data["ReturnIdentity"].ToString(); - preTask.require_code = input.data[nameof(preTask.bill_code)]?.ToString()!; - preTask.create_id = _userManager.UserId; - preTask.create_time = DateTime.Now; + return preTask; }).ToList(); + bool isOk = await _wareHouseService.GenPreTask(preTasks, null!); if (isOk) { + GenPreTaskUpInput preTaskUpInput = new() { RquireId = input.data["ReturnIdentity"].ToString()!, @@ -167,6 +176,7 @@ namespace Tnb.WarehouseMgr //根据空载具入库Id,回更单据状态 _ = await _db.Updateable().SetColumns(it => new WmsEmptyInstock { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == preTaskUpInput.RquireId).ExecuteCommandAsync(); + await _wareHouseService.GenInStockTaskHandleAfter(preTaskUpInput, it => new WmsCarryH { is_lock = 1, location_id = preTaskUpInput.CarryStartLocationId, location_code = preTaskUpInput.CarryStartLocationCode }, it => new BasLocation { is_lock = 1 }); @@ -186,8 +196,9 @@ namespace Tnb.WarehouseMgr await _db.Ado.CommitTranAsync(); } - catch (Exception) + catch (Exception ex) { + Logger.Error("空载具入库失败", ex); await _db.Ado.RollbackTranAsync(); throw; } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyOutstockService .cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyOutstockService .cs index ca9358cb..019c898d 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyOutstockService .cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsEmptyOutstockService .cs @@ -72,14 +72,15 @@ namespace Tnb.WarehouseMgr var endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput);*/ //判断目标库位是否自动签收 BasLocation loc = await _db.Queryable().SingleAsync(it => it.id == input.data[nameof(WmsPointH.location_id)].ToString()); + //出库取起点,获取所有符合输入的载具规格的载具 OutStockStrategyQuery OutStockStrategyInput = new() { carrystd_id = input.data[nameof(OutStockStrategyQuery.carrystd_id)].ToString(), warehouse_id = input.data[nameof(OutStockStrategyQuery.warehouse_id)].ToString(), - }; List? carrys = await _wareHouseService.OutStockStrategy(OutStockStrategyInput); + Logger.Information($"根据出库策略获取的载具数量:{carrys?.Count}"); //var carrys = await _db.Queryable().LeftJoin((a, b) => a.location_id == b.id) // .Where((a, b) => a.carrystd_id == input.data[nameof(WmsEmptyOutstockH.carrystd_id)].ToString() // && a.carry_status == ((int)EnumCarryStatus.空闲).ToString() && a.is_lock == 0 && b.is_lock == 0 && b.is_type == ((int)EnumLocationType.存储库位).ToString()) @@ -100,7 +101,6 @@ namespace Tnb.WarehouseMgr } - WmsEmptyOutstockH setQty = await _db.Queryable().FirstAsync(it => it.bill_code == input.data[nameof(WmsEmptyOutstockH.bill_code)].ToString()); WmsPointH? sPoint = null; WmsPointH? ePoint = null; if (input.data.ContainsKey(nameof(WmsPointH.location_id))) @@ -110,7 +110,11 @@ namespace Tnb.WarehouseMgr //根据每个载具的起始库位做路径运算 if (carrys?.Count > 0) { + WmsEmptyOutstockH setQty = await _db.Queryable().FirstAsync(it => it.bill_code == input.data[nameof(WmsEmptyOutstockH.bill_code)].ToString()); + int min = (carrys.Count > setQty.qty) ? setQty.qty : carrys.Count; + Logger.Information($"min={min}"); + for (int i = 0; i < min; i++) { sPoint = await _db.Queryable().FirstAsync(it => it.location_id == carrys[i].location_id); @@ -162,6 +166,7 @@ namespace Tnb.WarehouseMgr }).ToList(); //更新页面 //赋值签收状态 + Logger.Information($"空载具出库生成的预任务数量:{preTasks.Count}"); if (loc.is_sign == 0) { preTasks[^1].is_sign = 0; // 修改最后一个元素的是否签收值 @@ -211,7 +216,7 @@ namespace Tnb.WarehouseMgr else { throw new AppFriendlyException("没有匹配的空载具可以出库", 500); } - + await _db.Ado.CommitTranAsync(); } catch (Exception)