From 525fcb428a1d9d468206e073c56764d5c7db228a Mon Sep 17 00:00:00 2001 From: zhou keda <1315948824@qq.com> Date: Mon, 22 Jul 2024 11:29:39 +0800 Subject: [PATCH 1/6] bug --- .../Tnb.ProductionMgr/TimeWorkService.cs | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs index a843929e..1fb34736 100644 --- a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs @@ -807,19 +807,38 @@ namespace Tnb.ProductionMgr string[] unitArr = erpBdMaterial.MEASRATE.Split("/"); if (erpExtendFields.All(x => x.cmaterialoid != erpBdMaterial.ID)) { - BasMaterial basMaterial = new BasMaterial() + BasMaterial basMaterial = null; + ErpExtendField tempExtendField = insertExtendFields.Find(x => x.cmaterialoid == erpBdMaterial.ID); + if (tempExtendField!=null) { - id = SnowflakeIdHelper.NextId(), - name = erpBdMaterial.NAME, - code = erpBdMaterial.CODE, - org_id = WmsWareHouseConst.AdministratorOrgId, - material_specification = erpBdMaterial.MATERIALSPEC, - material_standard = erpBdMaterial.MATERIALTYPE, - category_id = "[\"CGJCJ\"]", - unit_id = unitId, - create_time = DateTime.Now - }; - insertMaterial.Add(basMaterial); + basMaterial = insertMaterial.Find(x => x.id == tempExtendField.table_id); + } + else + { + basMaterial = new BasMaterial() + { + id = SnowflakeIdHelper.NextId(), + name = erpBdMaterial.NAME, + code = erpBdMaterial.CODE, + org_id = WmsWareHouseConst.AdministratorOrgId, + material_specification = erpBdMaterial.MATERIALSPEC, + material_standard = erpBdMaterial.MATERIALTYPE, + category_id = "[\"CGJCJ\"]", + unit_id = unitId, + create_time = DateTime.Now + }; + insertMaterial.Add(basMaterial); + + ErpExtendField erpExtendField = new ErpExtendField() + { + table_name = "bas_material", + table_id = basMaterial.id, + cmaterialoid = erpBdMaterial.ID, + cmaterialvid = erpBdMaterial.VID, + + }; + insertExtendFields.Add(erpExtendField); + } if (unitId != auxiliaryUnitId) { @@ -892,6 +911,7 @@ namespace Tnb.ProductionMgr await _db.Insertable(insertMaterial).ExecuteCommandAsync(); await _db.Insertable(insertMaterialUnits).ExecuteCommandAsync(); + await _db.Insertable(insertExtendFields).ExecuteCommandAsync(); //物料清单开始同步 materials = await _db.Queryable().ToListAsync(); From 3a88deb159db9e86d03af8ea2b030f6098259d2a Mon Sep 17 00:00:00 2001 From: zhou keda <1315948824@qq.com> Date: Mon, 22 Jul 2024 12:46:46 +0800 Subject: [PATCH 2/6] bug --- .../Entity/ErpEntity/BomList.cs | 2 + .../Tnb.ProductionMgr/TimeWorkService.cs | 4 +- .../Tnb.WarehouseMgr/WareHouseService.cs | 6781 +++++++++-------- 3 files changed, 3396 insertions(+), 3391 deletions(-) diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs index 0b03655a..bbefd45c 100644 --- a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs @@ -38,5 +38,7 @@ namespace Tnb.ProductionMgr.Entities.Entity.ErpEntity /// 修改时间 /// public string MODIFIEDTIME { get; set; } + + public int ROWNO { get; set; } } } \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs index 1fb34736..87407b95 100644 --- a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs @@ -778,7 +778,7 @@ namespace Tnb.ProductionMgr string[] tables = new[] { "base_dictionarydata", "bas_material" }; var erpdb = _db.AsTenant().GetConnection("erpdb"); List list = await erpdb.Queryable().ToListAsync(); - List bomList = erpdb.Queryable().ToList(); + List bomList = await erpdb.Queryable().OrderBy(x=>x.BOMID).OrderBy(x=>x.ROWNO).ToListAsync(); List erpExtendFields = await _db.Queryable() .Where(x => tables.Contains(x.table_name)).ToListAsync(); Dictionary unitDic = await _db.Queryable() @@ -923,7 +923,7 @@ namespace Tnb.ProductionMgr BomList firstItemInList = itemList[0]; BasMaterial material = materials.Find(x => x.code==firstItemInList.MPRODID); if (material == null) continue; - string unitId = unitDic.ContainsKey(firstItemInList.UNIT) ? unitDic[firstItemInList.UNIT].ToString() : ""; + string unitId = unitDic2.ContainsKey(firstItemInList.UNIT) ? unitDic2[firstItemInList.UNIT].ToString() : ""; if (basEbomHs.All(x => x.material_id != material.id && x.version != firstItemInList.HVERSION)) { BasEbomH basEbomH = new BasEbomH() diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs index fd0770c7..01ea9053 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs @@ -1,3139 +1,3142 @@ -using System; -using System.Diagnostics; -using System.Dynamic; -using System.Linq; -using System.Linq.Expressions; -using System.Net; -using System.Security.Policy; -using System.Text; -using System.Threading.Tasks; -using Aop.Api.Domain; -using Aspose.Cells; -using JNPF; -using JNPF.Common.Contracts; -using JNPF.Common.Core.Manager; -using JNPF.Common.Dtos.VisualDev; -using JNPF.Common.Enums; -using JNPF.Common.Extension; -using JNPF.Common.Manager; -using JNPF.Common.Security; -using JNPF.FriendlyException; -using JNPF.Systems.Entitys.System; -using JNPF.Systems.Interfaces.System; -using JNPF.VisualDev.Entitys; -using JNPF.VisualDev.Interfaces; -using Mapster; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.CodeAnalysis; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using NetTaste; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using NPOI.OpenXmlFormats.Dml; -using NPOI.SS.Formula.Functions; -using Org.BouncyCastle.Crypto; -using SqlSugar; -using Tnb.BasicData.Entities; -using Tnb.Common.Extension; -using Tnb.Common.Redis; -using Tnb.Common.Utils; -using Tnb.ProductionMgr.Entities; -using Tnb.ProductionMgr.Entities.Entity; -using Tnb.QcMgr.Entities; -using Tnb.WarehouseMgr.Entities; -using Tnb.WarehouseMgr.Entities.Configs; -using Tnb.WarehouseMgr.Entities.Consts; -using Tnb.WarehouseMgr.Entities.Dto; -using Tnb.WarehouseMgr.Entities.Dto.Inputs; -using Tnb.WarehouseMgr.Entities.Dto.Outputs; -using Tnb.WarehouseMgr.Entities.Dto.Queries; -using Tnb.WarehouseMgr.Entities.Entity; -using Tnb.WarehouseMgr.Entities.Enums; -using Tnb.WarehouseMgr.Interfaces; -using static NPOI.HSSF.Util.HSSFColor; -using Tnb.BasicData; -using System.Reflection; - -namespace Tnb.WarehouseMgr -{ - /// - /// 库房业务类(出入库) - /// - public class WareHouseService : DevServBase, IWareHouseService - { - private readonly ISqlSugarClient _db; - private readonly IDictionaryDataService _dictionaryDataService; - private readonly IBillRullService _billRullService; - private readonly IUserManager _userManager; - private readonly ICacheManager _cacheManager; - private readonly IElevatorControlService _elevatorControlService; - private readonly IWmsCarryBindService _wmsCarryBindService; - private readonly IWmsCarryUnbindService _wmsCarryUnbindService; - private static readonly Dictionary _elevatorAgvCtlStatusMap = new(StringComparer.OrdinalIgnoreCase); - private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build(); - private static Dictionary locMap = new Dictionary(StringComparer.OrdinalIgnoreCase); - private readonly IConfiguration _configuration; - private readonly StackExRedisHelper _redisData; - private readonly IVisualDevService _visualDevService; - private readonly IRunService _runService; - - public static SemaphoreSlim s_floor2CreatePretask = new(1); - public static SemaphoreSlim s_taskCommonCreatePretask = new(1); - public static SemaphoreSlim s_taskGenPreTask = new(1); - public static SemaphoreSlim s_GenTaskExecute = new(1); - - public Func AddUnExecuteTask { get; set; } - - - public WareHouseService(ISqlSugarRepository repository, IDictionaryDataService dictionaryDataService, StackExRedisHelper redisData, - IBillRullService billRullService, IUserManager userManager, ICacheManager cacheManager, IElevatorControlService elevatorControlService, - IWmsCarryBindService wmsCarryBindService, - IWmsCarryUnbindService wmsCarryUnbindService, - IRunService runService, - IVisualDevService visualDevService - //IConfiguration configuration - ) : base(repository.AsSugarClient()) - { - _db = repository.AsSugarClient(); - _dictionaryDataService = dictionaryDataService; - _billRullService = billRullService; - _userManager = userManager; - _cacheManager = cacheManager; - _elevatorControlService = elevatorControlService; - _redisData = redisData; - _wmsCarryBindService = wmsCarryBindService; - _wmsCarryUnbindService = wmsCarryUnbindService; - _runService = runService; - _visualDevService = visualDevService; - //_configuration = configuration; - - } - - /// - /// 根据载具Id带出库位、仓库信息 - /// - /// 载具id - /// - /// returns: - ///
{ - ///
carry_id:载具Id - ///
carry_name:载具名称 - ///
location_id:库位Id - ///
location_name:库位名称 - ///
warehouse_id:库房Id - ///
warehouse_name:库房名称 - ///
} - ///
- [HttpGet] - public async Task GetLocationAndWorkHouseByCarryId([FromRoute] string carryId) - { - var items = await _db.Queryable().LeftJoin((a, b) => a.location_id == b.id) - .LeftJoin((a, b, c) => b.wh_id == c.id) - .Where(a => a.id == carryId) - .Select((a, b, c) => new - { - carry_id = a.id, - a.carry_name, - location_id = b.id, - - b.location_name, - warehouse_id = c.id, - warehouse_name = c.whname, - }) - .ToListAsync(); - return items ?? Enumerable.Empty(); - } - /// - /// 库房业务,入库、出库申请新增修改功能 - /// - /// - /// - [HttpPost] - public async Task ApplyFor(InOutStockApplyforUpInput input) - { - if (input == null) - { - throw new ArgumentNullException(nameof(input)); - } - - async Task _updateLocalFunc(InOutStockApplyforUpInput input) - where TStockD : BaseEntity, new() - where TStockCode : BaseEntity, IInOutStockCode, new() - { - TStockD instockD = input.Adapt(); - global::System.Collections.Generic.List? stockCodes = input.InstockCodes?.Adapt>(); - if (stockCodes?.Count > 0) - { - stockCodes.ForEach(x => - { - if (x.id.IsNullOrWhiteSpace()) - { - x.id = SnowflakeIdHelper.NextId(); - } - x.bill_d_id = instockD.id; - }); - } - return await Update(instockD, stockCodes!); - } - - bool isOk = input.inoutStockType switch - { - EnumInOutStockType.In => await _updateLocalFunc(input), - EnumInOutStockType.Out => await _updateLocalFunc(input), - _ => throw new ArgumentOutOfRangeException(nameof(input.inoutStockType), $"Not expected EnumInOutStockType value: {input.inoutStockType}"), - }; - if (!isOk) - { - throw Oops.Oh(ErrorCode.COM1001); - } - } - /// - /// 根据明细Id获取出入库明细信息 - /// - /// - [HttpGet] - public async Task GetInOutStockCodesById([FromQuery] InOutStockDetailQuery input) - { - dynamic? result = input.inoutStockType switch - { - EnumInOutStockType.In => await FetchInOutStockCodesById(input.bill_d_id), - EnumInOutStockType.Out => await FetchInOutStockCodesById(input.bill_d_id), - _ => throw new NotImplementedException(), - }; - return result ?? Enumerable.Empty(); - } - /// - /// 入库策略 - /// - /// - [HttpGet] - public async Task> InStockStrategy([FromQuery] InStockStrategyQuery input) - { - List items = new(); - try - { - WmsInstockPolicies policy = await _db.CopyNew().Queryable().Where(it => it.status == 1).FirstAsync(); - if (policy == null) - { - throw new AppFriendlyException("没有可用的策略", 500); - } - - Expression> whereExp = Expressionable.Create() - .And(it => it.wh_id == input.warehouse_id) - .And(it => it.is_lock == 0) - .And(it => it.is_type == ((int)EnumLocationType.存储库位).ToString()) - .And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString()) - .ToExpression(); - items = await _db.CopyNew().Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync(); - } - catch (Exception) - { - throw; - } - return items.Take(input.Size).ToList(); - } - /// - /// 入库策略 - /// - /// - [HttpGet] - public async Task> InStockStrategyBCK([FromQuery] InStockStrategyQuery input) - { - List items = new(); - try - { - WmsInstockPolicies policy = await _db.CopyNew().Queryable().Where(it => it.status == 1).FirstAsync(); - if (policy == null) - { - throw new AppFriendlyException("没有可用的策略", 500); - } - - Expression> whereExp = Expressionable.Create() - .And(it => it.wh_id == input.warehouse_id) - .And(it => it.is_lock == 0) - .And(it => it.is_type == ((int)EnumLocationType.分拣库位).ToString()) - .And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString()) - .ToExpression(); - items = await _db.CopyNew().Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync(); - } - catch (Exception) - { - throw; - } - return items.Take(input.Size).ToList(); - } - - /// - /// 包材库2楼入库策略 - /// - /// - [HttpGet] - public async Task> BCKF2InStockStrategy([FromQuery] InStockStrategyQuery input) - { - List items = new(); - try - { - WmsInstockPolicies policy = await _db.CopyNew().Queryable().Where(it => it.status == 1).FirstAsync(); - if (policy == null) - { - throw new AppFriendlyException("没有可用的策略", 500); - } - - Expression> whereExp = Expressionable.Create() - .And(it => it.wh_id == input.warehouse_id) - .And(it => it.is_lock == 0) - .And(it => it.is_type == ((int)EnumLocationType.出入库位).ToString()) - .And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString()) - .ToExpression(); - items = await _db.CopyNew().Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync(); - } - catch (Exception) - { - throw; - } - return items.Take(input.Size).ToList(); - } - - - /// - /// 是否为一楼出库工位 - /// - /// - /// - public string[] GetFloor1OutstockLocation() - { - return new string[23] { "30018211902485", "34355463261205", "34355450098709", "34355446145813" - , "34355443336981", "34355440377365", "34355436327189", "34355432397077", "34355428852501", "34355424568341" - , "34355421064213", "34355416966165", "34355407509269", "34355402216469", "34355397484565", "34355394965013" - , "34355391740181", "34355387110933", "34355383562005", "34355377989397", "34355374481173", "34355369617173" - , "30018211902485"}; - } - - /// - /// 是否为二楼包材出库工位 - /// - /// - /// - public string[] GetFloor2BCOutstockLocation() - { - return new string[1] { "30018211902485" }; - } - - /// - /// 是否为供料三工位库位 - /// - /// - /// - public string[] GetFloor1GLSGWOutstockLocation() - { - return new string[5] { WmsWareHouseConst.Floor1GLSGWOutstockStation1 , WmsWareHouseConst.Floor1GLSGWOutstockStation2 - , WmsWareHouseConst.Floor1GLSGWOutstockStation3, WmsWareHouseConst.Floor1GLSGWOutstockStation4, WmsWareHouseConst.Floor1GLSGWOutstockStation5 }; - } - - /// - /// 是否为外协三工位库位 - /// - /// - /// - public string[] GetFloor1WXSGWOutstockLocation() - { - return new string[3] { WmsWareHouseConst.Floor1WXSGWOutstockStation1 , WmsWareHouseConst.Floor1WXSGWOutstockStation2 - , WmsWareHouseConst.Floor1WXSGWOutstockStation3 }; - } - - /// - /// 出库策略-销售出库下发 - /// - /// - [HttpGet] - public async Task>> OutStockStrategy_saleRelease([FromQuery] OutStockStrategyQuery input) - { - Expressionable whereExprable = Expressionable.Create() - .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) - .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) - .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) - .And((a, b, c) => a.out_status == "0") - .And((a, b, c) => c.wh_id == input.warehouse_id) - .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) - .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) - .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) - .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) - .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); - Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() - ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() - : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); - _ = whereExprable.And(carryStatusFilterExp); - Expression> whereExpr = whereExprable.ToExpression(); - - SqlSugarClient cyDb = _db.CopyNew(); - - - List> items = 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("a.location_code,layers,loc_line,loc_column") - .Select((a, b, c) => new - { - WmsCarryH = a, - WmsCarryCode = b, - BasLocation = c, - codeqty = b.codeqty - }).ToList().Select(r => - { - // 如果可出库数量已经扣减完 - if (input.qty <= 0) - { - return new Tuple("", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); - } - - // 扣减可出库数量 - input.qty = input.qty - r.codeqty; - - // 出库数量与托盘上的数量不一致需要进行分拣 - if (input.qty < 0) - { - r.WmsCarryCode.codeqty = input.qty + r.codeqty; - return new Tuple("分拣任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); - } - else - { - // 正常预任务出库 - return new Tuple("预任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); - } - }).Where(r => r.Item1 != "").ToList(); - return items; - } - - public async Task> OutStockStrategy([FromQuery] OutStockStrategyQuery input) - { - Expressionable whereExprable = Expressionable.Create() - .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) - .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) - .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) - .And((a, b, c) => a.out_status == "0") - .And((a, b, c) => c.wh_id == input.warehouse_id) - .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) - .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) - .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) - .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) - .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); - Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() - ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() - : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); - _ = whereExprable.And(carryStatusFilterExp); - Expression> whereExpr = whereExprable.ToExpression(); - - SqlSugarClient cyDb = _db.CopyNew(); - WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); - if (policy == null) - { - throw new AppFriendlyException("没有可用策略", 500); - } - - 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(); - return input.Size > 0 ? items.Take(input.Size).ToList() : items; - } - - /// - /// 原材料仓出库策略 - /// - /// - /// - /// - public async Task> OutStockStrategyYCL([FromQuery] OutStockStrategyQuery input) - { - Expressionable whereExprable = Expressionable.Create() - .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) - .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) - .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) - .And((a, b, c) => a.out_status == "0") - .And((a, b, c) => c.wh_id == input.warehouse_id) - .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) - .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) - .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) - .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) - .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); - Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() - ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() - : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); - _ = whereExprable.And(carryStatusFilterExp); - Expression> whereExpr = whereExprable.ToExpression(); - - SqlSugarClient cyDb = _db.CopyNew(); - WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); - if (policy == null) - { - throw new AppFriendlyException("没有可用策略", 500); - } - - 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(); - - items = items.Distinct().ToList(); - return input.Size > 0 ? items.Take(input.Size).ToList() : items; - } - - /// - /// 缓存仓出库策略 - /// - /// - /// - /// - public async Task> OutStockStrategyHCC([FromQuery] OutStockStrategyQuery input) - { - Expressionable whereExprable = Expressionable.Create() - .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) - .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) - .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) - .And((a, b, c) => a.out_status == "0") - .And((a, b, c) => c.wh_id == input.warehouse_id) - .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) - .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) - .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) - .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) - .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); - Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() - ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() - : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); - _ = whereExprable.And(carryStatusFilterExp); - Expression> whereExpr = whereExprable.ToExpression(); - - SqlSugarClient cyDb = _db.CopyNew(); - WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); - if (policy == null) - { - throw new AppFriendlyException("没有可用策略", 500); - } - - 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(); - - - items = items.Distinct().ToList(); - return input.Size > 0 ? items.Take(input.Size).ToList() : items; - } - - /// - /// 1->2出库策略 - /// - /// - /// - /// - public async Task>> OutStockStrategyZCC2Floor2([FromQuery] OutStockStrategyZCC2Floor2Query input) - { - Expressionable whereExprable = Expressionable.Create() - .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) - .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) - .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) - .And((a, b, c) => a.out_status == "0") - .And((a, b, c) => c.wh_id == input.warehouse_id) - .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) - .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) - .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) - .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) - .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); - Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() - ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() - : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); - _ = whereExprable.And(carryStatusFilterExp); - Expression> whereExpr = whereExprable.ToExpression(); - - SqlSugarClient cyDb = _db.CopyNew(); - WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); - if (policy == null) - { - throw new AppFriendlyException("没有可用策略", 500); - } - - #region 只解决少数情况(比如只有60 59 60 60四个料箱,下发180,要取60 60 60) 其它情况不考虑 - - var itemsASC = 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) - .OrderBy("codeqty desc,a.location_code,layers,loc_line,loc_column") - - .Select((a, b) => new { wmsCarryH = a, wmsCarryCode = b }) - .ToListAsync(); - //items = itemsASC.Count < itemsDESC.Count ? itemsASC : itemsDESC; - - itemsASC = itemsASC.Distinct().ToList(); - +using System; +using System.Diagnostics; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Net; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; +using Aop.Api.Domain; +using Aspose.Cells; +using JNPF; +using JNPF.Common.Contracts; +using JNPF.Common.Core.Manager; +using JNPF.Common.Dtos.VisualDev; +using JNPF.Common.Enums; +using JNPF.Common.Extension; +using JNPF.Common.Manager; +using JNPF.Common.Security; +using JNPF.FriendlyException; +using JNPF.Systems.Entitys.System; +using JNPF.Systems.Interfaces.System; +using JNPF.VisualDev.Entitys; +using JNPF.VisualDev.Interfaces; +using Mapster; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.CodeAnalysis; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NetTaste; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NPOI.OpenXmlFormats.Dml; +using NPOI.SS.Formula.Functions; +using Org.BouncyCastle.Crypto; +using SqlSugar; +using Tnb.BasicData.Entities; +using Tnb.Common.Extension; +using Tnb.Common.Redis; +using Tnb.Common.Utils; +using Tnb.ProductionMgr.Entities; +using Tnb.ProductionMgr.Entities.Entity; +using Tnb.QcMgr.Entities; +using Tnb.WarehouseMgr.Entities; +using Tnb.WarehouseMgr.Entities.Configs; +using Tnb.WarehouseMgr.Entities.Consts; +using Tnb.WarehouseMgr.Entities.Dto; +using Tnb.WarehouseMgr.Entities.Dto.Inputs; +using Tnb.WarehouseMgr.Entities.Dto.Outputs; +using Tnb.WarehouseMgr.Entities.Dto.Queries; +using Tnb.WarehouseMgr.Entities.Entity; +using Tnb.WarehouseMgr.Entities.Enums; +using Tnb.WarehouseMgr.Interfaces; +using static NPOI.HSSF.Util.HSSFColor; +using Tnb.BasicData; +using System.Reflection; + +namespace Tnb.WarehouseMgr +{ + /// + /// 库房业务类(出入库) + /// + public class WareHouseService : DevServBase, IWareHouseService + { + private readonly ISqlSugarClient _db; + private readonly IDictionaryDataService _dictionaryDataService; + private readonly IBillRullService _billRullService; + private readonly IUserManager _userManager; + private readonly ICacheManager _cacheManager; + private readonly IElevatorControlService _elevatorControlService; + private readonly IWmsCarryBindService _wmsCarryBindService; + private readonly IWmsCarryUnbindService _wmsCarryUnbindService; + private static readonly Dictionary _elevatorAgvCtlStatusMap = new(StringComparer.OrdinalIgnoreCase); + private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build(); + private static Dictionary locMap = new Dictionary(StringComparer.OrdinalIgnoreCase); + private readonly IConfiguration _configuration; + private readonly StackExRedisHelper _redisData; + private readonly IVisualDevService _visualDevService; + private readonly IRunService _runService; + + public static SemaphoreSlim s_floor2CreatePretask = new(1); + public static SemaphoreSlim s_taskCommonCreatePretask = new(1); + public static SemaphoreSlim s_taskGenPreTask = new(1); + public static SemaphoreSlim s_GenTaskExecute = new(1); + + public Func AddUnExecuteTask { get; set; } + + + public WareHouseService(ISqlSugarRepository repository, IDictionaryDataService dictionaryDataService, StackExRedisHelper redisData, + IBillRullService billRullService, IUserManager userManager, ICacheManager cacheManager, IElevatorControlService elevatorControlService, + IWmsCarryBindService wmsCarryBindService, + IWmsCarryUnbindService wmsCarryUnbindService, + IRunService runService, + IVisualDevService visualDevService + //IConfiguration configuration + ) : base(repository.AsSugarClient()) + { + _db = repository.AsSugarClient(); + _dictionaryDataService = dictionaryDataService; + _billRullService = billRullService; + _userManager = userManager; + _cacheManager = cacheManager; + _elevatorControlService = elevatorControlService; + _redisData = redisData; + _wmsCarryBindService = wmsCarryBindService; + _wmsCarryUnbindService = wmsCarryUnbindService; + _runService = runService; + _visualDevService = visualDevService; + //_configuration = configuration; + + } + + /// + /// 根据载具Id带出库位、仓库信息 + /// + /// 载具id + /// + /// returns: + ///
{ + ///
carry_id:载具Id + ///
carry_name:载具名称 + ///
location_id:库位Id + ///
location_name:库位名称 + ///
warehouse_id:库房Id + ///
warehouse_name:库房名称 + ///
} + ///
+ [HttpGet] + public async Task GetLocationAndWorkHouseByCarryId([FromRoute] string carryId) + { + var items = await _db.Queryable().LeftJoin((a, b) => a.location_id == b.id) + .LeftJoin((a, b, c) => b.wh_id == c.id) + .Where(a => a.id == carryId) + .Select((a, b, c) => new + { + carry_id = a.id, + a.carry_name, + location_id = b.id, + + b.location_name, + warehouse_id = c.id, + warehouse_name = c.whname, + }) + .ToListAsync(); + return items ?? Enumerable.Empty(); + } + /// + /// 库房业务,入库、出库申请新增修改功能 + /// + /// + /// + [HttpPost] + public async Task ApplyFor(InOutStockApplyforUpInput input) + { + if (input == null) + { + throw new ArgumentNullException(nameof(input)); + } + + async Task _updateLocalFunc(InOutStockApplyforUpInput input) + where TStockD : BaseEntity, new() + where TStockCode : BaseEntity, IInOutStockCode, new() + { + TStockD instockD = input.Adapt(); + global::System.Collections.Generic.List? stockCodes = input.InstockCodes?.Adapt>(); + if (stockCodes?.Count > 0) + { + stockCodes.ForEach(x => + { + if (x.id.IsNullOrWhiteSpace()) + { + x.id = SnowflakeIdHelper.NextId(); + } + x.bill_d_id = instockD.id; + }); + } + return await Update(instockD, stockCodes!); + } + + bool isOk = input.inoutStockType switch + { + EnumInOutStockType.In => await _updateLocalFunc(input), + EnumInOutStockType.Out => await _updateLocalFunc(input), + _ => throw new ArgumentOutOfRangeException(nameof(input.inoutStockType), $"Not expected EnumInOutStockType value: {input.inoutStockType}"), + }; + if (!isOk) + { + throw Oops.Oh(ErrorCode.COM1001); + } + } + /// + /// 根据明细Id获取出入库明细信息 + /// + /// + [HttpGet] + public async Task GetInOutStockCodesById([FromQuery] InOutStockDetailQuery input) + { + dynamic? result = input.inoutStockType switch + { + EnumInOutStockType.In => await FetchInOutStockCodesById(input.bill_d_id), + EnumInOutStockType.Out => await FetchInOutStockCodesById(input.bill_d_id), + _ => throw new NotImplementedException(), + }; + return result ?? Enumerable.Empty(); + } + /// + /// 入库策略 + /// + /// + [HttpGet] + public async Task> InStockStrategy([FromQuery] InStockStrategyQuery input) + { + List items = new(); + try + { + WmsInstockPolicies policy = await _db.CopyNew().Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用的策略", 500); + } + + Expression> whereExp = Expressionable.Create() + .And(it => it.wh_id == input.warehouse_id) + .And(it => it.is_lock == 0) + .And(it => it.is_type == ((int)EnumLocationType.存储库位).ToString()) + .And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString()) + .ToExpression(); + items = await _db.CopyNew().Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync(); + } + catch (Exception) + { + throw; + } + return items.Take(input.Size).ToList(); + } + /// + /// 入库策略 + /// + /// + [HttpGet] + public async Task> InStockStrategyBCK([FromQuery] InStockStrategyQuery input) + { + List items = new(); + try + { + WmsInstockPolicies policy = await _db.CopyNew().Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用的策略", 500); + } + + Expression> whereExp = Expressionable.Create() + .And(it => it.wh_id == input.warehouse_id) + .And(it => it.is_lock == 0) + .And(it => it.is_type == ((int)EnumLocationType.分拣库位).ToString()) + .And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString()) + .ToExpression(); + items = await _db.CopyNew().Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync(); + } + catch (Exception) + { + throw; + } + return items.Take(input.Size).ToList(); + } + + /// + /// 包材库2楼入库策略 + /// + /// + [HttpGet] + public async Task> BCKF2InStockStrategy([FromQuery] InStockStrategyQuery input) + { + List items = new(); + try + { + WmsInstockPolicies policy = await _db.CopyNew().Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用的策略", 500); + } + + Expression> whereExp = Expressionable.Create() + .And(it => it.wh_id == input.warehouse_id) + .And(it => it.is_lock == 0) + .And(it => it.is_type == ((int)EnumLocationType.出入库位).ToString()) + .And(it => it.is_use == ((int)EnumCarryStatus.空闲).ToString()) + .ToExpression(); + items = await _db.CopyNew().Queryable().Where(whereExp).OrderBy(policy.policy).ToListAsync(); + } + catch (Exception) + { + throw; + } + return items.Take(input.Size).ToList(); + } + + + /// + /// 是否为一楼出库工位 + /// + /// + /// + public string[] GetFloor1OutstockLocation() + { + return new string[23] { "30018211902485", "34355463261205", "34355450098709", "34355446145813" + , "34355443336981", "34355440377365", "34355436327189", "34355432397077", "34355428852501", "34355424568341" + , "34355421064213", "34355416966165", "34355407509269", "34355402216469", "34355397484565", "34355394965013" + , "34355391740181", "34355387110933", "34355383562005", "34355377989397", "34355374481173", "34355369617173" + , "30018211902485"}; + } + + /// + /// 是否为二楼包材出库工位 + /// + /// + /// + public string[] GetFloor2BCOutstockLocation() + { + return new string[1] { "30018211902485" }; + } + + /// + /// 是否为供料三工位库位 + /// + /// + /// + public string[] GetFloor1GLSGWOutstockLocation() + { + return new string[5] { WmsWareHouseConst.Floor1GLSGWOutstockStation1 , WmsWareHouseConst.Floor1GLSGWOutstockStation2 + , WmsWareHouseConst.Floor1GLSGWOutstockStation3, WmsWareHouseConst.Floor1GLSGWOutstockStation4, WmsWareHouseConst.Floor1GLSGWOutstockStation5 }; + } + + /// + /// 是否为外协三工位库位 + /// + /// + /// + public string[] GetFloor1WXSGWOutstockLocation() + { + return new string[3] { WmsWareHouseConst.Floor1WXSGWOutstockStation1 , WmsWareHouseConst.Floor1WXSGWOutstockStation2 + , WmsWareHouseConst.Floor1WXSGWOutstockStation3 }; + } + + /// + /// 出库策略-销售出库下发 + /// + /// + [HttpGet] + public async Task>> OutStockStrategy_saleRelease([FromQuery] OutStockStrategyQuery input) + { + Expressionable whereExprable = Expressionable.Create() + .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) + .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) + .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) + .And((a, b, c) => a.out_status == "0") + .And((a, b, c) => c.wh_id == input.warehouse_id) + .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) + .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) + .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) + .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) + .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); + Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() + ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() + : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); + _ = whereExprable.And(carryStatusFilterExp); + Expression> whereExpr = whereExprable.ToExpression(); + + SqlSugarClient cyDb = _db.CopyNew(); + + + List> items = 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("a.location_code,layers,loc_line,loc_column") + .Select((a, b, c) => new + { + WmsCarryH = a, + WmsCarryCode = b, + BasLocation = c, + codeqty = b.codeqty + }).ToList().Select(r => + { + // 如果可出库数量已经扣减完 + if (input.qty <= 0) + { + return new Tuple("", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); + } + + // 扣减可出库数量 + input.qty = input.qty - r.codeqty; + + // 出库数量与托盘上的数量不一致需要进行分拣 + if (input.qty < 0) + { + r.WmsCarryCode.codeqty = input.qty + r.codeqty; + return new Tuple("分拣任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); + } + else + { + // 正常预任务出库 + return new Tuple("预任务", r.WmsCarryH, r.WmsCarryCode, r.BasLocation); + } + }).Where(r => r.Item1 != "").ToList(); + return items; + } + + public async Task> OutStockStrategy([FromQuery] OutStockStrategyQuery input) + { + Expressionable whereExprable = Expressionable.Create() + .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) + .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) + .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) + .And((a, b, c) => a.out_status == "0") + .And((a, b, c) => c.wh_id == input.warehouse_id) + .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) + .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) + .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) + .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) + .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); + Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() + ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() + : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); + _ = whereExprable.And(carryStatusFilterExp); + Expression> whereExpr = whereExprable.ToExpression(); + + SqlSugarClient cyDb = _db.CopyNew(); + WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用策略", 500); + } + + 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(); + return input.Size > 0 ? items.Take(input.Size).ToList() : items; + } + + /// + /// 原材料仓出库策略 + /// + /// + /// + /// + public async Task> OutStockStrategyYCL([FromQuery] OutStockStrategyQuery input) + { + Expressionable whereExprable = Expressionable.Create() + .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) + .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) + .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) + .And((a, b, c) => a.out_status == "0") + .And((a, b, c) => c.wh_id == input.warehouse_id) + .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) + .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) + .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) + .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) + .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); + Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() + ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() + : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); + _ = whereExprable.And(carryStatusFilterExp); + Expression> whereExpr = whereExprable.ToExpression(); + + SqlSugarClient cyDb = _db.CopyNew(); + WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用策略", 500); + } + + 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(); + + items = items.Distinct().ToList(); + return input.Size > 0 ? items.Take(input.Size).ToList() : items; + } + + /// + /// 缓存仓出库策略 + /// + /// + /// + /// + public async Task> OutStockStrategyHCC([FromQuery] OutStockStrategyQuery input) + { + Expressionable whereExprable = Expressionable.Create() + .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) + .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) + .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) + .And((a, b, c) => a.out_status == "0") + .And((a, b, c) => c.wh_id == input.warehouse_id) + .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) + .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) + .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) + .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) + .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); + Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() + ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() + : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); + _ = whereExprable.And(carryStatusFilterExp); + Expression> whereExpr = whereExprable.ToExpression(); + + SqlSugarClient cyDb = _db.CopyNew(); + WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用策略", 500); + } + + 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(); + + + items = items.Distinct().ToList(); + return input.Size > 0 ? items.Take(input.Size).ToList() : items; + } + + /// + /// 1->2出库策略 + /// + /// + /// + /// + public async Task>> OutStockStrategyZCC2Floor2([FromQuery] OutStockStrategyZCC2Floor2Query input) + { + Expressionable whereExprable = Expressionable.Create() + .And((a, b, c) => a.is_lock == 0 && c.is_lock == 0) + .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) + .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) + .And((a, b, c) => a.out_status == "0") + .And((a, b, c) => c.wh_id == input.warehouse_id) + .AndIF(!string.IsNullOrEmpty(input.material_id), (a, b, c) => b.material_id == input.material_id) + .AndIF(!string.IsNullOrEmpty(input.code_batch), (a, b, c) => b.code_batch == input.code_batch) + .AndIF(!string.IsNullOrEmpty(input.material_specification), (a, b, c) => b.material_specification == input.material_specification) + .AndIF(!string.IsNullOrEmpty(input.container_no), (a, b, c) => b.container_no == input.container_no) + .AndIF(!string.IsNullOrEmpty(input.carrystd_id), (a, b, c) => a.carrystd_id == input.carrystd_id); + Expression> carryStatusFilterExp = !input.material_id.IsNullOrWhiteSpace() + ? (a, b, c) => a.carry_status == ((int)EnumCarryStatus.占用).ToString() + : (a, b, c) => a.carry_status == ((int)EnumCarryStatus.空闲).ToString(); + _ = whereExprable.And(carryStatusFilterExp); + Expression> whereExpr = whereExprable.ToExpression(); + + SqlSugarClient cyDb = _db.CopyNew(); + WmsInstockPolicies policy = await cyDb.Queryable().Where(it => it.status == 1).FirstAsync(); + if (policy == null) + { + throw new AppFriendlyException("没有可用策略", 500); + } + + #region 只解决少数情况(比如只有60 59 60 60四个料箱,下发180,要取60 60 60) 其它情况不考虑 + + var itemsASC = 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) + .OrderBy("codeqty desc,a.location_code,layers,loc_line,loc_column") + + .Select((a, b) => new { wmsCarryH = a, wmsCarryCode = b }) + .ToListAsync(); + //items = itemsASC.Count < itemsDESC.Count ? itemsASC : itemsDESC; + + itemsASC = itemsASC.Distinct().ToList(); + List>? carrys = new List>(); // 6个下发一条任务链 - int move_num = 6; int endlocation_index = 0; + int move_num = 6; + int endlocation_index = 0; BasLocation endlocation_ssx = null; - for (int i = 0; i < itemsASC.Count; i++) - { - WmsCarryH wmsCarryH = itemsASC[i].wmsCarryH; - WmsCarryCode wmsCarryCode = itemsASC[i].wmsCarryCode; - - if (input.needOut <= 0) - { - break; + for (int i = 0; i < itemsASC.Count; i++) + { + WmsCarryH wmsCarryH = itemsASC[i].wmsCarryH; + WmsCarryCode wmsCarryCode = itemsASC[i].wmsCarryCode; + + if (input.needOut <= 0) + { + break; } // 每6个重新获取一次终点 if (i % move_num == 0) { endlocation_ssx = await _db.Queryable().Where(r => input.endlocations.Contains(r.id)).OrderBy("is_lock, task_nums, location_code").FirstAsync(); - } - - // 查找是否有一个料箱可以正好满足剩余需求数量(目前只做这个额外判断,其它情形不考虑) - bool isFind = false; - for (int j = i + 1; j < itemsASC.Count; j++) - { - WmsCarryCode _wmsCarryCode = itemsASC[j].wmsCarryCode; - if (_wmsCarryCode.codeqty == input.needOut) - { - input.needOut -= _wmsCarryCode.codeqty; - WmsCarryH _wmsCarryH = itemsASC[j].wmsCarryH; - - await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync(); - - carrys.Add(new Tuple(_wmsCarryH, _wmsCarryCode.codeqty, endlocation_ssx)); - - isFind = true; - break; - } - - } - if (isFind) - break; - - // 目前只支持一个料箱只有一个物料 - input.needOut -= wmsCarryCode.codeqty; - - await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync(); - - carrys.Add(new Tuple(wmsCarryH, wmsCarryCode.codeqty, endlocation_ssx)); - } - #endregion - - if (input.needOut > 0) - { - throw new AppFriendlyException($"物料{input.material_code}没有足够的库存!,缺失数量为{input.needOut}", 500); - } - - - return carrys; - } - - /// - /// 判断CTU是否可以放货 - /// - /// - [HttpPost] - [AllowAnonymous] - public async Task CheckPut(CheckPutInput input) - { - Logger.Information("联核请求CheckPut接口传入参数为:" + JsonConvert.SerializeObject(input)); - - Dictionary putdic = new Dictionary(); - - putdic.Add("SSX-011-006", new string[] { "YTCS", "AllowEmptyIn_CS06" }); - putdic.Add("SSX-021-007", new string[] { "东面提升机输送线", "出库输送线7允许入箱" }); - putdic.Add("SSX-121-009", new string[] { "东面提升机输送线", "上升降机9允许入箱" }); - putdic.Add("SSX-121-010", new string[] { "东面提升机输送线", "上升降机10允许入箱" }); - putdic.Add("SSX-021-003", new string[] { "YTCS", "AllowCtuEmptyIn_CS03" }); - putdic.Add("SSX-021-001", new string[] { "YTCS", "AllowCtuEmptyIn_CS01" }); - putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowCtuFullOut_CS04", }); - putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowCtuFullOut_CS02", }); - var strs = new string[] { }; - - if (!putdic.ContainsKey(input.targetName)) - throw new AppFriendlyException("点位" + input.targetName + "不存在", 500); - strs = putdic.Where(p => p.Key == input.targetName).First().Value; - - bool flag = await _redisData.HashExists(strs[0], strs[1]); - if (!flag) - { - throw new AppFriendlyException("点位" + input.targetName + "不存在", 500); - } - string data = await _redisData.GetHash(strs[0], strs[1]); - Logger.Information("wcs请求CheckPut接口查询X2Server数据:" + data); - JObject? res = JsonConvert.DeserializeObject(data); - bool result = res != null && res["Value"] != null ? res.Value("Value") : false; - if (!result) - throw new AppFriendlyException("点位" + input.targetName + "不可放", 500); - Logger.Information("wcs请求CheckPut接口结果:CTU可放货" + data); - } - - /// - /// 判断CTU是否可以取货 - /// - /// - - public async Task Check(string code, string action) - { - Logger.Information($"【Check】 判断KIVA是否可以{action} {code}"); - Dictionary putdic = new Dictionary(); - Dictionary getdic = new Dictionary(); - - putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowAgvFullIn_CS04", }); - putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowAgvFullIn_CS02", }); - getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowAgvEmptyOut_CS01" }); - getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowAgvEmptyOut_CS03" }); - - #region 注塑车间点位 - putdic.Add("ZS-C01-1", new string[] { "hxjC", "A2允许入空箱", }); - getdic.Add("ZS-C01-2", new string[] { "hxjC", "A2允许取满箱" }); - - putdic.Add("ZS-C02-1", new string[] { "hxjC", "A3允许入空箱", }); - getdic.Add("ZS-C02-2", new string[] { "hxjC", "A3允许取满箱" }); - - putdic.Add("ZS-C03-1", new string[] { "hxjC", "A4允许入空箱", }); - getdic.Add("ZS-C03-2", new string[] { "hxjC", "A4允许取满箱" }); - - putdic.Add("ZS-C04-1", new string[] { "hxjC", "A5允许入空箱", }); - getdic.Add("ZS-C04-2", new string[] { "hxjC", "A5允许取满箱" }); - - putdic.Add("ZS-C05-1", new string[] { "hxjC", "A6允许入空箱", }); - getdic.Add("ZS-C05-2", new string[] { "hxjC", "A6允许取满箱" }); - - putdic.Add("ZS-C06-1", new string[] { "hxjC", "A7允许入空箱", }); - getdic.Add("ZS-C06-2", new string[] { "hxjC", "A7允许取满箱" }); - - putdic.Add("ZS-C07-1", new string[] { "hxjC", "A8允许入空箱", }); - getdic.Add("ZS-C07-2", new string[] { "hxjC", "A8允许取满箱" }); - - putdic.Add("ZS-C08-1", new string[] { "hxjC", "A9允许入空箱", }); - getdic.Add("ZS-C08-2", new string[] { "hxjC", "A9允许取满箱" }); - - putdic.Add("ZS-C09-1", new string[] { "hxjC", "A10允许入空箱", }); - getdic.Add("ZS-C09-2", new string[] { "hxjC", "A10允许取满箱" }); - - putdic.Add("ZS-C10-1", new string[] { "hxjC", "A11允许入空箱", }); - getdic.Add("ZS-C10-2", new string[] { "hxjC", "A11允许取满箱" }); - - putdic.Add("ZS-C11-1", new string[] { "hxjC", "A12允许入空箱", }); - getdic.Add("ZS-C11-2", new string[] { "hxjC", "A12允许取满箱" }); - - putdic.Add("ZS-C12-1", new string[] { "hxjC", "A13允许入空箱", }); - getdic.Add("ZS-C12-2", new string[] { "hxjC", "A13允许取满箱" }); - - putdic.Add("ZS-C13-1", new string[] { "hxjC", "A14允许入空箱", }); - getdic.Add("ZS-C13-2", new string[] { "hxjC", "A14允许取满箱" }); - - putdic.Add("ZS-C14-1", new string[] { "hxjC", "A1允许入空箱", }); - getdic.Add("ZS-C14-2", new string[] { "hxjC", "A1允许取满箱" }); - - - putdic.Add("ZS-A01-1", new string[] { "hxjA", "A3允许入空箱", }); - getdic.Add("ZS-A01-2", new string[] { "hxjA", "A3允许取满箱" }); - - putdic.Add("ZS-A02-1", new string[] { "hxjA", "A4允许入空箱", }); - getdic.Add("ZS-A02-2", new string[] { "hxjA", "A4允许取满箱" }); - - putdic.Add("ZS-A03-1", new string[] { "hxjA", "A5允许入空箱", }); - getdic.Add("ZS-A03-2", new string[] { "hxjA", "A5允许取满箱" }); - - putdic.Add("ZS-A04-1", new string[] { "hxjA", "A6允许入空箱", }); - getdic.Add("ZS-A04-2", new string[] { "hxjA", "A6允许取满箱" }); - - putdic.Add("ZS-A05-1", new string[] { "hxjA", "A7允许入空箱", }); - getdic.Add("ZS-A05-2", new string[] { "hxjA", "A7允许取满箱" }); - - putdic.Add("ZS-A06-1", new string[] { "hxjA", "A8允许入空箱", }); - getdic.Add("ZS-A06-2", new string[] { "hxjA", "A8允许取满箱" }); - - putdic.Add("ZS-A07-1", new string[] { "hxjA", "A9允许入空箱", }); - getdic.Add("ZS-A07-2", new string[] { "hxjA", "A9允许取满箱" }); - - putdic.Add("ZS-A08-1", new string[] { "hxjA", "A10允许入空箱", }); - getdic.Add("ZS-A08-2", new string[] { "hxjA", "A10允许取满箱" }); - - putdic.Add("ZS-A09-1", new string[] { "hxjA", "A11允许入空箱", }); - getdic.Add("ZS-A09-2", new string[] { "hxjA", "A11允许取满箱" }); - - putdic.Add("ZS-A10-1", new string[] { "hxjA", "A12允许入空箱", }); - getdic.Add("ZS-A10-2", new string[] { "hxjA", "A12允许取满箱" }); - - putdic.Add("ZS-A11-1", new string[] { "hxjA", "A13允许入空箱", }); - getdic.Add("ZS-A11-2", new string[] { "hxjA", "A13允许取满箱" }); - - putdic.Add("ZS-A12-1", new string[] { "hxjA", "A14允许入空箱", }); - getdic.Add("ZS-A12-2", new string[] { "hxjA", "A14允许取满箱" }); - #endregion - - var strs = new string[] { }; - - if (action == "LOAD")//取货 - { - if (!getdic.ContainsKey(code)) - { - return false; - } - strs = getdic.Where(p => p.Key == code).First().Value; - - bool flag = await _redisData.HashExists(strs[0], strs[1]); - Logger.Information($"【Check】{action} 判断KIVA是否可以取货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); - if (!flag) - { - throw new Exception($"【Check】{action} 判断KIVA是否可以取货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); - } - string data = _redisData.GetHash(strs[0], strs[1]).Result; - JObject? res = JsonConvert.DeserializeObject(data); - bool result = res != null && res["Value"] != null ? res.Value("Value") : false; - Logger.Information($"【Check】{action} 判断KIVA是否可以取货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} "); - if (!result) - { - throw new Exception($"【Check】{action} 判断KIVA是否可以取货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} "); - } - return true; - } - else if (action == "UNLOAD")//放货 - { - if (!putdic.ContainsKey(code)) - return false; - strs = putdic.Where(p => p.Key == code).First().Value; - - bool flag = await _redisData.HashExists(strs[0], strs[1]); - Logger.Information($"【Check】 判断CTU是否可以放货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); - if (!flag) - { - throw new Exception($"【Check】 判断CTU是否可以放货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); - } - string data = _redisData.GetHash(strs[0], strs[1]).Result; - JObject? res = JsonConvert.DeserializeObject(data); - bool result = res != null && res["Value"] != null ? res.Value("Value") : false; - Logger.Information($"【Check】 判断CTU是否可以放货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result}"); - if (!result) - { - throw new Exception($"【Check】 判断CTU是否可以放货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} "); - } - return true; - } - return false; - } - public async Task SsxControl(WmsDistaskH disTask, string action) - { - Logger.Information($"输送线控制SsxControl传入参数: {JsonConvert.SerializeObject(disTask)} {action}"); - - Dictionary putdic = new Dictionary(); - Dictionary getdic = new Dictionary(); - getdic.Add("SSX-021-005", new string[] { "YTCS", "FullOut_CS05Done", "true" }); - getdic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11出箱完毕", "true" }); - getdic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12出箱完毕", "true" }); - getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线上层允许出箱3", "true" }); - getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线上层允许出箱1", "true" }); - getdic.Add("SSX-011-008", new string[] { "东面提升机输送线", "入库输送线8出箱完毕", "true" }); - getdic.Add("ZS-C01-2", new string[] { "hxjC", "A2AGV允许入满箱", "true" }); - getdic.Add("ZS-C02-2", new string[] { "hxjC", "A3AGV允许入满箱", "true" }); - getdic.Add("ZS-C03-2", new string[] { "hxjC", "A4AGV允许入满箱", "true" }); - getdic.Add("ZS-C04-2", new string[] { "hxjC", "A5AGV允许入满箱", "true" }); - getdic.Add("ZS-C05-2", new string[] { "hxjC", "A6AGV允许入满箱", "true" }); - getdic.Add("ZS-C06-2", new string[] { "hxjC", "A7AGV允许入满箱", "true" }); - getdic.Add("ZS-C07-2", new string[] { "hxjC", "A8AGV允许入满箱", "true" }); - getdic.Add("ZS-C08-2", new string[] { "hxjC", "A9AGV允许入满箱", "true" }); - getdic.Add("ZS-C09-2", new string[] { "hxjC", "A10AGV允许入满箱", "true" }); - getdic.Add("ZS-C10-2", new string[] { "hxjC", "A11AGV允许入满箱", "true" }); - getdic.Add("ZS-C11-2", new string[] { "hxjC", "A12AGV允许入满箱", "true" }); - getdic.Add("ZS-C12-2", new string[] { "hxjC", "A13AGV允许入满箱", "true" }); - getdic.Add("ZS-C13-2", new string[] { "hxjC", "A14AGV允许入满箱", "true" }); - getdic.Add("ZS-C14-2", new string[] { "hxjC", "A1AGV允许入满箱", "true" }); - - getdic.Add("ZS-A01-2", new string[] { "hxjA", "A3AGV允许入满箱", "true" }); - getdic.Add("ZS-A02-2", new string[] { "hxjA", "A4AGV允许入满箱", "true" }); - getdic.Add("ZS-A03-2", new string[] { "hxjA", "A5AGV允许入满箱", "true" }); - getdic.Add("ZS-A04-2", new string[] { "hxjA", "A6AGV允许入满箱", "true" }); - getdic.Add("ZS-A05-2", new string[] { "hxjA", "A7AGV允许入满箱", "true" }); - getdic.Add("ZS-A06-2", new string[] { "hxjA", "A8AGV允许入满箱", "true" }); - getdic.Add("ZS-A07-2", new string[] { "hxjA", "A9AGV允许入满箱", "true" }); - getdic.Add("ZS-A08-2", new string[] { "hxjA", "A10AGV允许入满箱", "true" }); - getdic.Add("ZS-A09-2", new string[] { "hxjA", "A11AGV允许入满箱", "true" }); - getdic.Add("ZS-A10-2", new string[] { "hxjA", "A12AGV允许入满箱", "true" }); - getdic.Add("ZS-A11-2", new string[] { "hxjA", "A13AGV允许入满箱", "true" }); - getdic.Add("ZS-A12-2", new string[] { "hxjA", "A14AGV允许入满箱", "true" }); - - - - putdic.Add("SSX-021-007", new string[] { "东面提升机输送线", "出库输送线7入箱完毕", "true" }); - putdic.Add("SSX-011-006", new string[] { "YTCS", "EmptyIn_CS06Done", "true" }); - putdic.Add("SSX-021-003", new string[] { "YTCS", "AgvFullIn_CS03Done", "true" }); - putdic.Add("SSX-021-001", new string[] { "YTCS", "CtuEmptyIn_CS01Done", "true" }); - putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线下层允许入箱4", "true" }); - putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线下层允许入箱2", "true" }); - putdic.Add("SSX-121-009", new string[] { "东面提升机输送线", "上升降机9入箱完毕", "true" }); - putdic.Add("SSX-121-010", new string[] { "东面提升机输送线", "上升降机10入箱完毕", "true" }); - putdic.Add("YCLCKBGW", new string[] { "CP8", "PutDoneEmptyBox", "true" }); - putdic.Add("ZS-C01-1", new string[] { "hxjC", "A2AGV允许出空箱", "true" }); - putdic.Add("ZS-C02-1", new string[] { "hxjC", "A3AGV允许出空箱", "true" }); - putdic.Add("ZS-C03-1", new string[] { "hxjC", "A4AGV允许出空箱", "true" }); - putdic.Add("ZS-C04-1", new string[] { "hxjC", "A5AGV允许出空箱", "true" }); - putdic.Add("ZS-C05-1", new string[] { "hxjC", "A6AGV允许出空箱", "true" }); - putdic.Add("ZS-C06-1", new string[] { "hxjC", "A7AGV允许出空箱", "true" }); - putdic.Add("ZS-C07-1", new string[] { "hxjC", "A8AGV允许出空箱", "true" }); - putdic.Add("ZS-C08-1", new string[] { "hxjC", "A9AGV允许出空箱", "true" }); - putdic.Add("ZS-C09-1", new string[] { "hxjC", "A10AGV允许出空箱", "true" }); - putdic.Add("ZS-C10-1", new string[] { "hxjC", "A11AGV允许出空箱", "true" }); - putdic.Add("ZS-C11-1", new string[] { "hxjC", "A12AGV允许出空箱", "true" }); - putdic.Add("ZS-C12-1", new string[] { "hxjC", "A13AGV允许出空箱", "true" }); - putdic.Add("ZS-C13-1", new string[] { "hxjC", "A14AGV允许出空箱", "true" }); - putdic.Add("ZS-C14-1", new string[] { "hxjC", "A1AGV允许出空箱", "true" }); - - putdic.Add("ZS-A01-1", new string[] { "hxjA", "A3AGV允许出空箱", "true" }); - putdic.Add("ZS-A02-1", new string[] { "hxjA", "A4AGV允许出空箱", "true" }); - putdic.Add("ZS-A03-1", new string[] { "hxjA", "A5AGV允许出空箱", "true" }); - putdic.Add("ZS-A04-1", new string[] { "hxjA", "A6AGV允许出空箱", "true" }); - putdic.Add("ZS-A05-1", new string[] { "hxjA", "A7AGV允许出空箱", "true" }); - putdic.Add("ZS-A06-1", new string[] { "hxjA", "A8AGV允许出空箱", "true" }); - putdic.Add("ZS-A07-1", new string[] { "hxjA", "A9AGV允许出空箱", "true" }); - putdic.Add("ZS-A08-1", new string[] { "hxjA", "A10AGV允许出空箱", "true" }); - putdic.Add("ZS-A09-1", new string[] { "hxjA", "A11AGV允许出空箱", "true" }); - putdic.Add("ZS-A10-1", new string[] { "hxjA", "A12AGV允许出空箱", "true" }); - putdic.Add("ZS-A11-1", new string[] { "hxjA", "A13AGV允许出空箱", "true" }); - putdic.Add("ZS-A12-1", new string[] { "hxjA", "A14AGV允许出空箱", "true" }); - - if (action == "LOAD")//取货 - { - if (getdic.Keys.Contains(disTask.startlocation_code)) - { - var strarr = getdic.Where(p => p.Key == disTask.startlocation_code).First().Value; - Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase) - { - ["DevName"] = strarr[0], - ["token"] = _eleCtlCfg.token, - ["TagName"] = strarr[1], - ["Value"] = strarr[2], - }; - Logger.Information($"SsxControlLOAD:{JsonConvert.SerializeObject(dicCommand)}"); - var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); - Logger.Information($"SsxControlLOAD:{str}"); - } - } - else if (action == "UNLOAD")//放货 - { - if (putdic.Keys.Contains(disTask.endlocation_code)) - { - var strarr = putdic.Where(p => p.Key == disTask.endlocation_code).First().Value; - Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase) - { - ["DevName"] = strarr[0], - ["token"] = _eleCtlCfg.token, - ["TagName"] = strarr[1], - ["Value"] = strarr[2], - }; - Logger.Information($"SsxControlUNLOAD:{JsonConvert.SerializeObject(dicCommand)}"); - var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); - Logger.Information($"SsxControlUNLOAD:{str}"); - } - } - - } - - /// - /// 二楼机械臂 - /// - /// - public async Task Floor2MechanicalConfirm(WmsDistaskH disTask, string action) - { - List rackAreaPointsUp = new List(); - List rackAreaPointsDown = new List(); - // 二楼上升降区料架区点位 - rackAreaPointsUp.Add("AS01"); - rackAreaPointsUp.Add("AS02"); - // 二楼下升降区料架区点位 - rackAreaPointsDown.Add("AX01"); - rackAreaPointsDown.Add("AX02"); - - try { - List basLocations = _db.Queryable().Where(r => (r.location_code == disTask.endlocation_code || r.location_code == disTask.startlocation_code) - && r.wh_id != "33780009364245").ToList(); - - // 暂存仓内任务 - if (disTask.area_code == "E" && basLocations.Count() == 0) - { - await _db.Ado.BeginTranAsync(); - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】收到到货确认信号 传入参数: {disTask.bill_code} {action}"); - - if (action == "UNLOAD") - { - // 去料架区放货 - if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) - { - ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.endlocation_code); - if (WmsMechanicalArmHs.Count() == 0) - { - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); - throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); - } - WmsMechanicalArmH target = WmsMechanicalArmHs.First(); - - // 回写料架和AGV确认 - await _db.Updateable().SetColumns(r => new WmsMechanicalArmH - { - agvconfirm = 1, - rackid = disTask.carry_id, - rackcode = disTask.carry_code - }).Where(r => r.id == target.id).ExecuteCommandAsync(); - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV已到货 {disTask.endpoint_code} 更新缓存表{target.id}"); - - if (rackAreaPointsDown.Contains(disTask.endlocation_code)) - { - int LXCount = _db.Queryable().Where(a => a.carry_id == disTask.carry_id).Count(); - - // 绑定料架 - await _db.Updateable().SetColumns(r => new WmsMechanicalArmH - { - mechanicalconfirm = 1, - maxnum = LXCount - }).Where(r => r.id == target.id).ExecuteCommandAsync(); - - Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱开始生成预任务"); - bool pretask_result = await Floor2EmptyCarryCreateZZCPretask(disTask.carry_id); - if (pretask_result) - { - Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务完成"); - } - else - { - Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务失败"); - throw new Exception($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务失败"); - } - } - } - else // 去暂存仓放货 - { - // 回写料架料箱绑定表的库位 - ISugarQueryable WmsCarryCodes = _db.Queryable() - .InnerJoin((a, b) => b.membercarry_id == a.carry_id) - .Where((a, b) => b.carry_id == disTask.carry_id); - var WmsCarryCodeList = WmsCarryCodes.ToList(); - WmsCarryCodeList.ForEach(r => - { - r.location_id = disTask.endlocation_id; - r.location_code = disTask.endlocation_code; - }); - await _db.Updateable(WmsCarryCodeList).ExecuteCommandAsync(); - } - } - else - { - // 去暂存仓取货 - if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) - { - - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在暂存仓取货确认完成"); - } - else // 去料架区取货 - { - ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.startlocation_code); - if (WmsMechanicalArmHs.Count() == 0) - { - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); - throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); - } - WmsMechanicalArmH target = WmsMechanicalArmHs.First(); - - if (target.note == "上升降机") - { - bool result = await Floor2UpDownMachinecode_SetTag($"上升降机满托{target.stackingposition}移走", "true"); - Logger.LogInformation($@"【上升降机】设定升上升降机满托{target.stackingposition}移走 结果为 {result}"); - if (!result) - { - throw new Exception($@"【上升降机】设定升上升降机满托{target.stackingposition}移走 结果为 {result}"); - } - - // 更新料架在二楼配送的目标工位 - // todo erp工位字段取数位置未确定 - WmsMaterialTransferD wmsMaterialTransferD = await _db.Queryable() - .LeftJoin((a, b) => a.id == b.bill_id).Where((a, b) => a.bill_code == target.outbill) - .Select((a, b) => b).FirstAsync(); - if (wmsMaterialTransferD == null) - { - Logger.LogWarning($@"【上升降机】 发生异常!,转库单{target.outbill}没有载具明细"); - // 转库单删除 不执行后续,不返回失败是为了不卡流程 - return; - } - - string targetWorkstation = wmsMaterialTransferD.station_code; - if (string.IsNullOrEmpty(wmsMaterialTransferD.station_code)) - { - throw new Exception($@"【上升降机】 发生异常!,转库单{target.outbill}的工位为空"); - } - - Logger.LogInformation($@"【上升降机】更新料架 {target.rackcode} 在二楼配送的目标工位 {targetWorkstation}"); - await _db.Updateable().SetColumns(r => new WmsCarryH - { - work_station = targetWorkstation - }).Where(r => r.id == target.rackid).ExecuteCommandAsync(); - } - else if (target.note == "下升降机") - { - bool result = await Floor2UpDownMachinecode_SetTag($"下升降机空托{target.stackingposition}移走", "true"); - Logger.LogInformation($@"【上升降机】设定升下升降机空托{target.stackingposition}移走 结果为 {result}"); - if (!result) - { - throw new Exception($@"【上升降机】设定升下升降机空托{target.stackingposition}移走 结果为 {result}"); - } - } - - // 重置料架区 - await _db.Updateable().SetColumns(r => new WmsMechanicalArmH - { - stackingcount = 0, - barcodes = "", - outbill = "", - maxnum = 0, - iscreatepretask = 0, - rackcode = "", - rackid = "", - agvconfirm = 0, - mechanicalconfirm = 0 - }).Where(r => r.id == target.id).ExecuteCommandAsync(); - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在料架区取货完成"); - } - } - await _db.Ado.CommitTranAsync(); - } - } - catch(Exception ex) - { - Logger.LogError("【Floor2MechanicalComplete】" + ex.ToString()); - await _db.Ado.RollbackTranAsync(); - throw; - } - } - - - - /// - /// 二楼机械臂 - /// - /// - public async Task Floor2MechanicalComplete(WmsDistaskH disTask, string action) - { - List rackAreaPointsUp = new List(); - List rackAreaPointsDown = new List(); - // 二楼上升降区料架区点位 - rackAreaPointsUp.Add("AS01"); - rackAreaPointsUp.Add("AS02"); - // 二楼下升降区料架区点位 - rackAreaPointsDown.Add("AX01"); - rackAreaPointsDown.Add("AX02"); - - try - { - List basLocations = _db.Queryable().Where(r => (r.location_code == disTask.endlocation_code || r.location_code == disTask.startlocation_code) - && r.wh_id != "33780009364245").ToList(); - - // 暂存仓内任务 - if (disTask.area_code == "E" && basLocations.Count() == 0) - { - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】收到到货完成信号 传入参数: {disTask.bill_code} {action}"); - - if (action == "UNLOAD") - { - // 去料架区放货 - if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) - { - ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.endlocation_code); - if (WmsMechanicalArmHs.Count() == 0) - { - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); - throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); - } - WmsMechanicalArmH target = WmsMechanicalArmHs.First(); - - // 下升降机写满托数量和送到信号 - if (rackAreaPointsDown.Contains(disTask.endlocation_code)) - { - int LXCount = _db.Queryable().Where(a => a.carry_id == disTask.carry_id).Count(); - - bool result = await Floor2UpDownMachinecode_SetTag($"下升降机满托{target.stackingposition}数量", LXCount.ToString()); - Logger.LogInformation($@"【送满托到下升降区】设定下升降机满托{target.stackingposition}满托数量为 {LXCount} 结果为 {result}"); - if (!result) - { - throw new Exception($"下升降机满托{target.stackingposition}数量 写入失败"); - } - - // 尝试写入满托送到信号 - bool result下升降机空托送到 = await Floor2UpDownMachinecode_SetTag($"下升降机满托{target.stackingposition}送到", "true"); - Logger.LogInformation($@"【送满托到下升降区】回写 下升降机满托{target.stackingposition}送到 结果为{result下升降机空托送到}"); - if (!result下升降机空托送到) - { - throw new Exception($"下升降机满托{target.stackingposition}送到 写入失败"); - } - } - } - else // 去暂存仓放货 - { - - } - } - else - { - // 去暂存仓取货 - if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) - { - Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在暂存仓取货完成"); - } - else // 去料架区取货 - { - } - } - } - } - catch (Exception ex) - { - Logger.LogError("【Floor2MechanicalComplete】" + ex.ToString()); - throw; - } - } - - - - - private async Task Floor2UpDownMachinecode_SetTag(string tag, string value) - { - string DevName = "东面提升机输送线"; - Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase) - { - ["DevName"] = DevName, - ["token"] = _eleCtlCfg.token, - ["TagName"] = tag, - ["Value"] = value, - }; - string result = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); - - return result.Contains("Ok"); - - // 测试 - //string DevName = "东面提升机输送线"; - - //JObject valueJson = new JObject(); - //valueJson["Value"] = value; - - //_redisData.SetHash(DevName, tag, valueJson.ToString()); - //return true; - } - - - /// - /// 生成任务执行 - /// - /// - [HttpPost] - public async Task GenTaskExecute() - { - if (s_GenTaskExecute.CurrentCount == 0) - { - Logger.Information("【GenTaskExecute】 【测试】 丢弃此执行"); - return; - } - await s_GenTaskExecute.WaitAsync(); - Stopwatch sw = Stopwatch.StartNew(); - CancellationTokenSource agvCts = new(); - SqlSugarClient db = _db.CopyNew(); - try - { - await CTUTaskExecute(); - - //获取所有未下发的预任务申请 - Logger.Information("【GenTaskExecute】 开始获取未下发的预任务..."); - - ISugarQueryable sugarQueryable = db.Queryable() - .LeftJoin((a, b) => a.carry_id == b.id) - .InnerJoin((a, b, c) => a.area_id == c.id) - .InnerJoin((a, b, c, d) => a.endlocation_id == d.id && d.is_use == "0") - .Where((a, b) => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID && !string.IsNullOrWhiteSpace(a.startlocation_id) - // 载具为空时 不校验载具当前位置是否与预任务起点相同 - && (string.IsNullOrEmpty(a.carry_id) || (!string.IsNullOrEmpty(a.carry_id) && a.startlocation_id == b.location_id))) - .OrderBy(a => new { priority = SqlFunc.Desc(a.priority), a.bill_code }) - .Select((a, b, c, d) => new WmsPretaskH - { - move_num = c.move_num, - third_eqp_type = c.third_eqp_type, - }, true); - - Logger.Information($"【GenTaskExecute】 获取到{sugarQueryable.Count()}条可执行的预任务..."); - if (sugarQueryable.Count() == 0) - return; - - //Logger.Information("【GenTaskExecute】 执行SQL: " + sugarQueryable.ToSqlString()); - - List preTasks = await sugarQueryable.ToListAsync(); - - - - //List executedPreTasks = await db.Queryable().Where(it => it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID && it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID).ToListAsync(); - - List agvElevatorTasks = preTasks - .Where(it => it.endlocation_code.StartsWith("DT", StringComparison.OrdinalIgnoreCase) && - !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)) - .ToList(); - - - var elePreTasks = preTasks.Where(it => it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); - var normalPreTasks = preTasks.Where(it => it.area_code != "B" && !agvElevatorTasks.Concat(elePreTasks).Select(x => x.endlocation_code).Contains(it.endlocation_code)).ToList(); - - - //Logger.Information("【GenTaskExecute】 电梯预任务elePreTasks:" + JsonConvert.SerializeObject(elePreTasks)); - //Logger.Information("【GenTaskExecute】 AGV/CTU/KIVA预任务normalPreTasks:" + JsonConvert.SerializeObject(normalPreTasks)); - //Logger.Information("【GenTaskExecute】 AGV电梯预任务agvElevatorTasks:" + JsonConvert.SerializeObject(agvElevatorTasks)); - - /* IEnumerable firstEleGrp = agvElevatorTasks.GroupBy(g => g.endlocation_code).Select(t => t.OrderBy(o => o.bill_code).FirstOrDefault()); - agvElevatorTasks = firstEleGrp?.ToList() ?? Enumerable.Empty().ToList()!; - */ - - //如果电梯任务,预Agv任务存在相同目标库位,删除Agv任务保证电梯任务先行 - var equalEndLocPreTasks = elePreTasks.Select(x => x.endlocation_code).Intersect(agvElevatorTasks.Select(x => x.endlocation_code)); - if (equalEndLocPreTasks.Any()) - { - Logger.Information("【GenTaskExecute】 执行:如果电梯任务,预Agv任务存在相同目标库位,删除Agv任务保证电梯任务先行 "); - agvElevatorTasks = agvElevatorTasks.Where(x => !equalEndLocPreTasks.Contains(x.endlocation_code)).ToList(); - } - preTasks = normalPreTasks.Concat(agvElevatorTasks).Concat(elePreTasks).ToList(); - - //一楼中储仓CTU - - List ids = preTasks.Select(x => x.id).Distinct().ToList(); - List? preTaskCodes = await db.Queryable().Where(it => ids.Contains(it.bill_id)).ToListAsync(); - if (preTasks.Count > 0) - { - //根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链,通过管理区ID - List> preTaskGroups = preTasks.GroupBy(g => g.area_code).ToList(); - List disTasks = new(); - List distaskCodes = new(); - foreach (IGrouping? itGroup in preTaskGroups) - { - List items = itGroup.Adapt>(); - for (int i = 0, cnt = items.Count; i < cnt; i++) - { - items[i].id = SnowflakeIdHelper.NextId(); - items[i].create_time = DateTime.Now; - items[i].status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID; - } - int moveNum = itGroup.First().move_num; - int itemsCount = items.Count; - int mod = itemsCount % moveNum > 0 ? (itemsCount / moveNum) + 1 : itemsCount / moveNum; - WmsDistaskH[] arrary = items.ToArray(); - //for (int i = 1; i <= mod; i++) - { - - if (moveNum >= 1) - { - List areaPreTasks = itGroup.ToList(); - - if (areaPreTasks.Any(x => x.third_eqp_type.ToEnum() != EnumTaskChainType.CTU)) - { - 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; - x.bill_code = $"{groupCode}-1"; - } - } - 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); - - int start = 0; - int end = Math.Min(itemsCount, moveNum); - List arrList = new(mod); - - while (start < itemsCount) - { - WmsDistaskH[] subArray = arrary[start..end]; - arrList.Add(subArray); - start = end; - end = Math.Min(end + moveNum, arrary.Length); - } - foreach (WmsDistaskH[] arr in arrList) - { - for (int j = 1, len = arr.Length; j <= len; j++) - { - arr[j - 1].groups = groupCode; - arr[j - 1].bill_code = $"{groupCode}-{j}"; - } - } - } - Logger.Information($"已生成任务执行编码"); - } - } - - if (preTaskCodes?.Count > 0) - { - foreach (WmsDistaskH disTask in items) - { - List curPreTaskCodes = preTaskCodes.FindAll(x => x.bill_id == disTask.pretask_id); - List curDisTaskCodes = curPreTaskCodes.Adapt>(); - curDisTaskCodes.ForEach(x => - { - x.id = SnowflakeIdHelper.NextId(); - x.bill_id = disTask.id; - x.create_time = DateTime.Now; - }); - distaskCodes.AddRange(curDisTaskCodes); - } - } - - disTasks.AddRange(items); - } - await db.Ado.BeginTranAsync(); - - int row = await db.Insertable(disTasks).ExecuteCommandAsync(); - Logger.Information("【GenTaskExecute】 插入任务执行表数据: " + JsonConvert.SerializeObject(disTasks)); - if (preTaskCodes?.Count > 0) - { - row = await db.Insertable(distaskCodes).ExecuteCommandAsync(); - Logger.Information("【GenTaskExecute】 插入任务执行条码表数据: " + JsonConvert.SerializeObject(disTasks)); - } - if (row > 0) - { - List preTaskIds = preTasks.Select(x => x.id).ToList(); - List preTaskBill_codes = preTasks.Select(x => x.bill_code).ToList(); - row = await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); - Logger.Information("【GenTaskExecute】 更改这些预任务执行状态为 已下发: " + JsonConvert.SerializeObject(preTaskBill_codes)); - } - - await db.Ado.CommitTranAsync(); - - Logger.Information("【GenTaskExecute】 预任务执行完成"); - Logger.Information($"【GenTaskExecute】_eleCtlCfg.Environment={_eleCtlCfg.Environment}"); - - - if (string.Equals(_eleCtlCfg.Environment, ElevatorConsts.EnvironmentName, StringComparison.OrdinalIgnoreCase)) - { - //呼梯操作 - //获取目标库位为电梯库位的任务 - Logger.Information("【GenTaskExecute】操作设备"); - - var agvDTTasks = disTasks.Where(it => it.endlocation_code.StartsWith("DT", StringComparison.OrdinalIgnoreCase) && - !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); - - foreach (var task in agvDTTasks) - { - ElevagorInfoQuery q = new() { endlocation_id = task.endlocation_id, taskCode = task.bill_code }; - Logger.Information($"【GenTaskExecute】呼梯时 根据任务单号获取电梯参数 {JsonConvert.SerializeObject(q)}"); - var e = await FindElevatorFromPars(q); - Logger.Information($"【GenTaskExecute】呼梯时 根据任务单号获取电梯结果 {JsonConvert.SerializeObject(e)}"); - - var tags = _eleCtlCfg.tags; - (int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) = await _elevatorControlService.GetElevatorStatus(e.elevator_code, tags, CancellationToken.None); - Logger.Information($"【GenTaskExecute】 电梯当前状态->系统状态:{sysStatus.ToEnum()},运行状态:{runStatus.ToEnum()},Agv状态:{agvStatus.ToEnum()},当前楼层:{floorNo},电梯占用状态{s_eleUseStatusDic[e.device_id]}"); - var curFloor = await GetRealFloor(e.end_floor); - - if (e != null && s_eleUseStatusDic[e.device_id] == (int)EnumElevatorUseStatus.空闲 && curFloor != floorNo) - { - task.device_id = e.device_id; - } - } - - Logger.Information($"【GenTaskExecute】呼梯任务数:{agvDTTasks.Count}"); - List<(string endlocation_code, string device_id, string id, int start_floor)> endLocCodes = agvDTTasks.Where(r => !string.IsNullOrEmpty(r.device_id)) - .Select(it => (it.endlocation_code, it.device_id, it.id, it.start_floor)).ToList(); - var callLiftCnt = endLocCodes?.Count ?? 0; - Logger.Information($"【GenTaskExecute】实际可呼梯任务数:{callLiftCnt}"); - - if (endLocCodes?.Count > 0) - { - if (endLocCodes.Select(x => x.device_id).All(x => !x.IsNullOrWhiteSpace())) - { - Logger.Information("【GenTaskExecute】呼梯操作"); - _ = CallingLanding(endLocCodes); - } - else - { - Logger.Error("【GenTaskExecute】呼梯失败,没有设备ID"); - return; - } - } - - //执行电梯任务 - List? elevatorTasks = disTasks.Where(it => it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); - - Logger.Information($"【GenTaskExecute】当前电梯任务数:{elevatorTasks?.Count ?? 0}"); - if (elevatorTasks?.Count > 0) - { - foreach (WmsDistaskH? elevatorTask in elevatorTasks) - { - ElevagorInfoQuery q = new() { endlocation_id = elevatorTask.endlocation_id, taskCode = elevatorTask.bill_code}; - Logger.Information($"【GenTaskExecute】执行电梯任务时 根据任务单号获取电梯参数 {JsonConvert.SerializeObject(q)}"); - var e = await FindElevatorFromPars(q); - Logger.Information($"【GenTaskExecute】执行电梯任务时 根据任务单号获取电梯结果 {JsonConvert.SerializeObject(e)}"); - if (e != null) - { - elevatorTask.device_id = e.device_id; - } - - _ = ExecuteTargetFloorTask(elevatorTask); - } - } - List agvTasks = disTasks.Where(it => !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); - - if (agvTasks?.Count > 0) - { - Logger.Information($"【GenTaskExecute】Agv任务数量:{agvTasks.Count},taskCodes:{string.Join(",", agvTasks.Select(x => x.bill_code).Distinct())}"); - _ = AgvDispatch(agvTasks, agvCts.Token); - } - } - } - - - } - catch (Exception ex) when (ex is HttpRequestException hReqEx) - { - agvCts.Cancel(); - } - catch (Exception ex) - { - Logger.Error("【GenTaskExecute】任务执行时出现错误", ex); - Logger.Error(ex.StackTrace!); - await db.Ado.RollbackTranAsync(); - throw; - } - finally - { - _ = s_GenTaskExecute.Release(); - agvCts.Dispose(); - sw.Stop(); - Logger.Information($"【GenTaskExecute】 任务执行耗时{sw.ElapsedMilliseconds}毫秒"); - - } - } - - - /// - /// 获取电梯根据任务单号 - /// - /// - /// taskCode:子任务编号 - /// endlocation_id:目标库位ID - /// - /// - - public async Task FindElevatorFromPars(ElevagorInfoQuery input) - { - var whereExpable = Expressionable.Create() - .And((a, b, c) => a.enabled == 1); - - Logger.Information($"【FindElevatorFromPars】 {JsonConvert.SerializeObject(input)}"); - - if (!input.taskCode.IsNullOrEmpty()) - { - whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.taskCode), (a, b, c) => c.bill_code == input.taskCode); - } - if (!input.endlocation_id.IsNullOrEmpty()) - { - whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.endlocation_id), (a, b, c) => b.location_id == input.endlocation_id); - } - if (!input.startlocation_id.IsNullOrEmpty()) - { - whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.startlocation_id), (a, b, c) => b.location_id == input.startlocation_id); - } - - ISugarQueryable queryable = _db.CopyNew().Queryable().InnerJoin((a, b) => a.id == b.bill_id) - .InnerJoin((a, b, c) => b.location_code == c.endlocation_code || b.location_code == c.startlocation_code) - .Where(whereExpable.ToExpression()) - .WhereIF(!SqlFunc.IsNullOrEmpty(input.sourceName) && SqlFunc.StartsWith("DT-R", input.sourceName), (a, b, c) => c.startpoint_code == input.sourceName) - .WhereIF(!SqlFunc.IsNullOrEmpty(input.sourceName) && SqlFunc.StartsWith("DT-C", input.sourceName), (a, b, c) => c.endpoint_code == input.sourceName) - .Select((a, b, c) => new WmsElevatorH - { - bill_code = c.bill_code, - device_id = a.elevator_id, - end_floor = c.end_floor - }, true); - - var ele = await queryable.FirstAsync(); - - Logger.Information($"【FindElevatorFromPars】 " + queryable.ToSqlString()); - - return ele; - - } - - - #region CTU - /// - /// 生成CTU任务执行 - /// - /// - [HttpPost] - public async Task CTUTaskExecute() - { - try - { - Dictionary indic = new Dictionary(); - indic.Add("SSX-021-005", new string[] { "YTCS", "CallCtuFullIn_CS05" }); - indic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11呼叫CTU" }); - indic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12呼叫CTU" }); - var db = _db.CopyNew(); - List CTUTasks = await db.Queryable() - .InnerJoin((a, b) => a.area_id == b.id) - .Where(a => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID) - .Where((a, b) => b.code == "B")//一楼中储仓 - .OrderBy(a => a.create_id) - .Select((a, b) => new WmsPretaskH - { - move_num = b.move_num, - third_eqp_type = b.third_eqp_type, - }, true).ToListAsync(); - - if (CTUTasks.Count == 0) - return; - - List TaskCodes = await db.Queryable().Where(it => CTUTasks.Select(p => p.id).ToList().Contains(it.bill_id)).ToListAsync(); - - //Logger.Information($@"【CTUTaskExecute】 获取任务TaskCodes: {JsonConvert.SerializeObject(TaskCodes)}"); - - var InTasks = CTUTasks.Where(a => a.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID).ToList(); - var OutTasks = CTUTasks.Where(a => a.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID || a.task_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFER_ID).ToList(); - - //Logger.Information($@"【CTUTaskExecute】 获取任务InTasks: {JsonConvert.SerializeObject(InTasks)}"); - //Logger.Information($@"【CTUTaskExecute】 获取任务OutTasks: {JsonConvert.SerializeObject(OutTasks)}"); - - var OriginDistaskHs = await db.Queryable() - .InnerJoin((a, b) => a.area_id == b.id) - .Where((a, b) => b.code == "B" && a.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID) - .OrderBy(a => a.bill_code) - .ToListAsync(); - - - //Logger.Information($@"【CTUTaskExecute】 OriginDistaskHs: {JsonConvert.SerializeObject(OriginDistaskHs)}"); - - - List DistaskHs = new List(); - List UpDistaskHs = new List(); - List DistaskCodes = new List(); - var inCtuExec = new List(); - var outCtuExec = new List(); - - foreach (var item in InTasks) - { - - - /* - if (indic.Keys.Contains(item.startlocation_code)) - { - var strs = indic.Where(p => p.Key == item.startlocation_code).First().Value; - bool flag = _redisData.HashExist(strs[0], strs[1]).Result; - if (!flag) - continue; - string data = _redisData.GetHash(strs[0], strs[1]).Result; - JObject? res = JsonConvert.DeserializeObject(data); - bool result = res != null && res["Value"] != null ? res.Value("Value") : false; - if (!result) - continue; - }*/ - - WmsDistaskH distaskH = item.Adapt(); - distaskH.id = SnowflakeIdHelper.NextId(); - distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID; - distaskH.is_chain = 1; - distaskH.create_time = DateTime.Now; - var billcode = GetBillCode(OriginDistaskHs, DistaskHs, distaskH); - distaskH.groups = billcode.Substring(0, billcode.Length - 2); - distaskH.bill_code = billcode; - var num = int.Parse(distaskH.bill_code.Substring(billcode.Length - 1, 1)); - Logger.Information($@"【CTUTaskExecute】 比对billcode:{num}和单次搬运数量move_num:{item.move_num},如果一致 会添加到inCtuExec"); - if (num == item.move_num) - { - distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID; - inCtuExec.Add(distaskH); - if (OriginDistaskHs.Where(p => p.groups == distaskH.groups).Any()) - { - OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); - - UpDistaskHs.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); - inCtuExec.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); - } - if (DistaskHs.Where(p => p.groups == distaskH.groups).Any()) - { - DistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); - inCtuExec.AddRange(DistaskHs.Where(p => p.groups == distaskH.groups).ToList()); - } - } - - - List preTaskCodes = TaskCodes.FindAll(x => x.bill_id == distaskH.pretask_id); - List disTaskCodes = preTaskCodes.Adapt>(); - disTaskCodes.ForEach(x => - { - x.id = SnowflakeIdHelper.NextId(); - x.bill_id = distaskH.id; - x.create_time = DateTime.Now; - }); - DistaskHs.Add(distaskH); - DistaskCodes.AddRange(disTaskCodes); - - } - foreach (var item in OutTasks) - { - WmsDistaskH distaskH = item.Adapt(); - distaskH.id = SnowflakeIdHelper.NextId(); - distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID; - distaskH.is_chain = 1; - distaskH.create_time = DateTime.Now; - var billcode = GetBillCode(OriginDistaskHs, DistaskHs, distaskH); - distaskH.groups = billcode.Substring(0, billcode.Length - 2); - distaskH.bill_code = billcode; - var num = int.Parse(distaskH.bill_code.Substring(billcode.Length - 1, 1)); - - Logger.Information($@"【CTUTaskExecute】 比对billcode:{num}和单次搬运数量move_num:{item.move_num},如果一致 会添加到outCtuExec"); - if (num == item.move_num) - { - distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID; - outCtuExec.Add(distaskH); - if (OriginDistaskHs.Where(p => p.groups == distaskH.groups).Any()) - { - OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); - - UpDistaskHs.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); - outCtuExec.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); - } - if (DistaskHs.Where(p => p.groups == distaskH.groups).Any()) - { - DistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); - outCtuExec.AddRange(DistaskHs.Where(p => p.groups == distaskH.groups).ToList()); - } - } - - List preTaskCodes = TaskCodes.FindAll(x => x.bill_id == distaskH.pretask_id); - List disTaskCodes = preTaskCodes.Adapt>(); - disTaskCodes.ForEach(x => - { - x.id = SnowflakeIdHelper.NextId(); - x.bill_id = distaskH.id; - x.create_time = DateTime.Now; - }); - DistaskHs.Add(distaskH); - DistaskCodes.AddRange(disTaskCodes); - } - await db.Ado.BeginTranAsync(); - int row = 0; - if (UpDistaskHs.Count > 0) - { - await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => UpDistaskHs.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); - } - if (DistaskHs.Count > 0) - { - row = await db.Insertable(DistaskHs).ExecuteCommandAsync(); - } - if (DistaskCodes.Count > 0) - { - await db.Insertable(DistaskCodes).ExecuteCommandAsync(); - } - if (row > 0) - { - List preTaskIds = DistaskHs.Select(x => x.pretask_id).ToList(); - await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); - } - await db.Ado.CommitTranAsync(); - //判断 - Logger.Information($"【CTUTaskExecute】 判断单据状态(status)是否为待执行 {JsonConvert.SerializeObject(DistaskHs)}"); - if (DistaskHs.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID).Any()) - { - var time = int.Parse(db.Queryable().Where(P => P.key == "getinterval").First().value); - timer = new Timer(TimerExec, null, TimeSpan.FromMinutes(time), TimeSpan.FromMinutes(time)); - } - //Logger.Information($@"【CTUTaskExecute】 可执行的CTU任务inCtuExec: {JsonConvert.SerializeObject(inCtuExec)}"); - if (inCtuExec.Count > 0) - { - Logger.Information($"开始执行CTU入库任务: {JsonConvert.SerializeObject(inCtuExec)}"); - //呼叫ctu入库 - // await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID }).Where(it => inCtuExec.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); - // await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => inCtuExec.Select(x => x.pretask_id).ToList().Contains(it.id)).ExecuteCommandAsync(); - CancellationTokenSource Ctu = new(); - - await CallingCTU(inCtuExec, Ctu.Token, 1); - Ctu.Dispose(); - } - //Logger.Information($@"【CTUTaskExecute】 可执行的CTU任务outCtuExec: {JsonConvert.SerializeObject(outCtuExec)}"); - if (outCtuExec.Count > 0) - { - Logger.Information($"开始执行CTU出库任务: {JsonConvert.SerializeObject(outCtuExec)}"); - //呼叫ctu出库 - // await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID }).Where(it => outCtuExec.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); - // await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => outCtuExec.Select(x => x.pretask_id).ToList().Contains(it.id)).ExecuteCommandAsync(); - CancellationTokenSource Ctu = new(); - await CallingCTU(outCtuExec, Ctu.Token, 0); - Ctu.Dispose(); - } - } - catch (Exception ex) - { - throw; - } - } - //判断生成bill_code - private string GetBillCode(List OriginDistaskH, List NewdistaskHs, WmsDistaskH distaskH) - { - string BillCode = string.Empty; - //入库 - if (distaskH.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID) - { - var orgdistaskHs = OriginDistaskH.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID && p.startpoint_id == distaskH.startpoint_id).ToList(); - var newdistaskHs = NewdistaskHs.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID && p.startpoint_id == distaskH.startpoint_id).ToList(); - if ((orgdistaskHs.Count + newdistaskHs.Count) == 0) - { - var groups = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE).Result; - BillCode = $"{groups}-1"; - } - else - { - var groups = orgdistaskHs.Count > 0 ? orgdistaskHs.First().groups : newdistaskHs.First().groups; - BillCode = $"{groups}-" + (orgdistaskHs.Count + newdistaskHs.Count + 1); - } - } - else if (distaskH.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID || distaskH.task_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFER_ID) - { - var orgdistaskHs = OriginDistaskH.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID && p.endpoint_id == distaskH.endpoint_id).ToList(); - var newdistaskHs = NewdistaskHs = OriginDistaskH.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID && p.endpoint_id == distaskH.endpoint_id).ToList(); - if ((orgdistaskHs.Count + newdistaskHs.Count) == 0) - { - var groups = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE).Result; - BillCode = $"{groups}-1"; - } - else - { - var groups = orgdistaskHs.Count > 0 ? orgdistaskHs.First().groups : newdistaskHs.First().groups; - BillCode = $"{groups}-" + (orgdistaskHs.Count + newdistaskHs.Count + 1); - } - } - return BillCode; - } - private Timer? timer; - private async void TimerExec(object e) - { - try - { - SqlSugarClient db = _db.CopyNew(); - var list = db.Queryable().InnerJoin((a, b) => a.area_id == b.id) - .Where((a, b) => b.code == "B" && a.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID) - .OrderBy(a => a.bill_code) - .ToList(); - var data = list.GroupBy(p => p.groups).Select(p => new - { - groups = p.Key, - time = p.Max(a => a.create_time) - - }).ToList(); - var date = DateTime.Now; - var time = int.Parse(db.Queryable().Where(P => P.key == "getinterval").First().value); - foreach (var item in data) - { - if (date.Subtract(item.time).Minutes >= time) - { - var execlist = list.Where(p => p.groups == item.groups).ToList(); - await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => execlist.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); - // await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => execlist.Select(x => x.pretask_id).ToList().Contains(it.id)).ExecuteCommandAsync(); - CancellationTokenSource Ctu = new(); - int type = execlist.First().task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID ? 1 : 0; - await CallingCTU(execlist, Ctu.Token, type); - Ctu.Dispose(); - } - } - } - catch (Exception ex) - { - } - finally - { - timer?.Dispose(); - } - - } - private async Task CallingCTU(List distaskHs, CancellationToken token, int type) - { - try - { - AgvRequestConfig requestCfg = App.Configuration.Build(); - string url = requestCfg.AgvRequestUrls.CreateTaskChainUrl; - var taskChainCodeDic = distaskHs.Where(t => !t.groups.IsNullOrWhiteSpace()).GroupBy(g => g.groups!) - .ToDictionary(x => x.Key, x => x.Select(it => new - { - taskCode = it.bill_code, - sourceName = it.startpoint_code, - targetName = it.endpoint_code, - containerCode = it.carry_code, - })); - foreach ((string k, object v) in taskChainCodeDic) - { - dynamic reqBody = new ExpandoObject(); - reqBody.taskChainCode = k; - reqBody.type = (int)EnumTaskChainType.CTU; - reqBody.sequential = false; - reqBody.taskChainPriority = 0; - reqBody.taskList = v; - reqBody.inOut = type; - Logger.Information($"【CallingCTU】 CTU任务下发 开始请求联核/task-chain/create接口 请求地址:{url} 请求参数:{JsonConvert.SerializeObject(reqBody)} type:{(type == 0 ? "CTU出库" : "CTU入库")}"); - dynamic respBody = await HttpClientHelper.PostStreamAsync(url, reqBody, token); - Logger.Information($"【CallingCTU】 CTU任务下发 接收到联核/task-chain/create接口信息:{respBody}"); - } - } - catch (Exception ex) - { - Logger.Information($"【CallingCTU】 CTU任务下发 请求联核/task-chain/create接口失败 异常信息:{ex}"); - } - } - #endregion - /// - /// 呼梯操作 - /// - /// - /// - private async Task CallingLanding(List<(string endlocation_code, string device_id, string id, int floorNO)> endLocCodes) - { - Logger.Information($"【CallingLanding】 开始呼梯操作............."); - try - { - foreach ((_, string devId, string disTaskId, int floorNO) in endLocCodes) - { - Logger.Information($"【CallingLanding】 devId:{devId}"); - if (!s_elevatorMap.TryGetValue(devId, out object? elevatorCode)) - { - continue; - } - - string? devName = elevatorCode.ToString(); - Logger.Information($"【CallingLanding】 电梯编号:{devName}"); - Logger.Information($"【CallingLanding】 当前:{devName.Match(@"\d+")}#梯"); - - await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.AGVControl, 1); - (int sysStatus, int runStatus, int curFloorNo, int doorStatus, int agvStatus) eleStatusMulti = (-1, -1, -1, -1, -1); - Logger.Information("【CallingLanding】 获取电梯AGV运行状态"); - if (!_elevatorAgvCtlStatusMap.TryGetValue(devId, out int agvCtlStatus) || agvCtlStatus != (int)EnumAgvStatus.AGV运行状态) - { - var tags = new[] { "SysStatus", "RunStatus", "FloorNo", "DoorStatus", "AGVStatus" }; - do - { - eleStatusMulti = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); - await Task.Delay(1000); - } while (eleStatusMulti.agvStatus != (int)EnumAgvStatus.AGV运行状态); - Logger.Information($"{devName.Match(@"\d+")}#, 当前Agv状态:{eleStatusMulti.agvStatus.ToEnum()}"); - _elevatorAgvCtlStatusMap[devId] = eleStatusMulti.agvStatus; - } - else - { - Logger.Information("【CallingLanding】 AGV运行状态:" + agvCtlStatus); - } - - Logger.Information($"【CallingLanding】 任务开始目标楼层为:{floorNO}"); - - int floorN = await GetRealFloor(floorNO); - //如果电梯在当前楼层则不呼梯 - if (floorN == eleStatusMulti.curFloorNo) - { - Logger.Information($"【CallingLanding】 {devName.Match(@"\d+")}#,在当前楼层,无需呼梯"); - continue; - } - - Logger.Information($"【CallingLanding】 实际目标楼层为:{floorN}"); - - WmsElevatorUnexecute elevatorQueueItem = new() - { - distask_id = disTaskId, - elevator_id = devId, - elevator_code = devName, - floor = floorN, //5代表4楼 - task_status = "待执行", - create_id = _userManager.UserId, - create_time = DateTime.Now - }; - List elevatorQueue = await _db.Queryable().Where(it => it.distask_id == disTaskId && it.task_status == "执行中").ToListAsync(); - - Logger.Information($"【CallingLanding】 电梯{devName}状态为{s_eleUseStatusDic[devId]}"); - Logger.Information($"【CallingLanding】 电梯{devName} 任务id{disTaskId} 执行中的队列数量为{elevatorQueue.Count}"); - if ((elevatorQueue.IsNull() || elevatorQueue.Count < 1) && floorN != eleStatusMulti.curFloorNo && s_eleUseStatusDic[devId] == (int)EnumElevatorUseStatus.空闲) - { - Logger.Information($"【CallingLanding】 判断当前电梯{devName.Match(@"\d+")}#梯 无任务在做执行呼梯"); - - elevatorQueueItem.task_status = "执行中"; - bool callLiftRes = await _elevatorControlService.CallLift(devName, floorN, CancellationToken.None); - string successful = "成功", fail = "失败"; - string callLiftResult = callLiftRes ? successful : fail; - Logger.Information($"{devName.Match(@"\d+")}#, 呼梯结果:{callLiftResult}"); - } - else - { - Logger.Information("【CallingLanding】 当前有任务在做,不会呼梯"); - } - - //如果当前电梯有任务在做,将当前呼梯任务放入待执行队列 - _ = await _db.Insertable(elevatorQueueItem).ExecuteCommandAsync(); - - Logger.Information("【CallingLanding】 呼梯任务执行完成"); - } - } - catch (Exception ex) - { - Logger.Error("【CallingLanding】 呼梯操作错误", ex); - Logger.Error($"【CallingLanding】 呼梯操作错误堆栈跟踪:{Environment.NewLine}{ex.StackTrace}"); - throw; - } - } - - /// - /// 执行到目标楼层电梯任务 - /// - /// - /// - public async Task ExecuteTargetFloorTask(WmsDistaskH disTask) - { - //收到放货确认通知,向电梯发送到3楼的指令 - Logger.Information($"开始执行电梯任务,任务ID:{disTask.id}"); - try - { - if (!s_elevatorMap.TryGetValue(disTask.device_id, out object? elevatorCode)) - { - Logger.Information($"开始执行电梯任务,没有取到设备{disTask.device_id}的 elevatorCode! s_elevatorMap: {JsonConvert.SerializeObject(s_elevatorMap)}"); - return; - } - string devName = s_elevatorMap[disTask.device_id]?.ToString() ?? _eleCtlCfg.DevName3; - - Logger.Information($"当前:{devName.Match(@"\d+")}#梯"); - - var tags = new[] { "SysStatus", "RunStatus", "FloorNo", "DoorStatus", "AGVStatus" }; - (int sysStatus, int runStatus, int curFloorNo, int doorStatus, int agvStatus) eleStatusMulti = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); - if (eleStatusMulti.agvStatus != (int)EnumAgvStatus.AGV运行状态) - { - _ = await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.AGVControl, 1); - } - - if (!_elevatorAgvCtlStatusMap.TryGetValue(disTask.id, out int agvCtlStatus) || agvCtlStatus != (int)EnumAgvStatus.AGV运行状态) - { - do - { - eleStatusMulti = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); - Logger.Information($"{devName.Match(@"\d+")}#, 当前Agv状态:{eleStatusMulti.agvStatus.ToEnum()}"); - await Task.Delay(1000); - } while (eleStatusMulti.agvStatus != (int)EnumAgvStatus.AGV运行状态 ); - Logger.Information($"{devName.Match(@"\d+")}#, 当前Agv状态:{eleStatusMulti.agvStatus.ToEnum()}"); - _elevatorAgvCtlStatusMap[disTask.id] = eleStatusMulti.agvStatus; - } - - int doorStatus = -1; - bool closeDoorRes = await _elevatorControlService.SendOpenCloseCmd(devName, 4); //向电梯发送前门关门指令 - Logger.Information($"关门结果:{closeDoorRes}"); - do - { - doorStatus = await _elevatorControlService.GetTagAsync(devName, ElevatorConsts.DoorStatus); - await Task.Delay(1000); - } while (doorStatus != 4); - Logger.Information($"当前门状态:{doorStatus}"); - - int floor = await GetRealFloor(disTask.end_floor); - - //电梯任务手动执行任务状态上报 - (int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) tuple = (-1, -1, -1, -1, -1); - tuple = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); - Logger.Information($"目标楼层:{floor} 当前楼层:{tuple.floorNo}"); - - Logger.Information($"开始呼梯 {devName}到{floor}"); - //发送到目标楼的指令 - dynamic result = await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.FloorExecute, floor); - - do - { - tuple = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); - await Task.Delay(1000); - } while (tuple.sysStatus != 3 || tuple.runStatus != 0 || floor != tuple.floorNo); - - Logger.Information($"sysStatus:{tuple.sysStatus},runStatus:{tuple.runStatus},当前楼层floorNo:{tuple.floorNo},目标楼层disTask.end_floor={floor}"); - - if (tuple.sysStatus.ToEnum() == EnumSysStatus.正常状态 && tuple.runStatus.ToEnum() == EnumRunStatus.停梯) - { - Logger.Information($"disTask.require_id={disTask.require_id}"); - List disTaskIds = new() { disTask.id }; - var upInput = new { disTaskIds = disTask.id }; - TaskExecuteAfterUpInput teaUpInput = new() - { - disTaskIds = disTaskIds, - }; - await TaskExecuteAfter(teaUpInput); - TaskCompleUpInput tcUpInput = new() - { - disTaskIds = disTaskIds, - }; - await TaskComplate(tcUpInput); - - Logger.Information("电梯任务执行完成"); - } - - } - catch (Exception ex) - { - Logger.Error("执行到目标楼层电梯任务失败", ex); - throw; - } - } - /// - /// Agv调度 - /// - /// - /// - /// - private async Task AgvDispatch(List disTasks, CancellationToken token) - { - Logger.Information("【AgvDispatch】 Agv任务执行...."); - List kiva = new List(); - // 一楼中储仓 - kiva.Add("ZSSSXCTU02"); - kiva.Add("ZSSSXCTU01"); - List floor2 = new List(); - // 二楼暂存仓 - //floor2.Add("AS01"); - //floor2.Add("AS02"); - //floor2.Add("AX01"); - //floor2.Add("AX02"); - //调用AGV创建任务链接口 - try - { - AgvRequestConfig requestCfg = App.Configuration.Build(); - string url = requestCfg.AgvRequestUrls.CreateTaskChainUrl; - - Logger.Information($"【AgvDispatch】 Agv任务执行的disTasks:{JsonConvert.SerializeObject(disTasks)}"); - - var taskChainCodeDic = disTasks.Where(t => !t.groups.IsNullOrWhiteSpace()).GroupBy(g => g.groups!) - .ToDictionary(x => x.Key, x => x.Select(it => new - { - taskCode = it.bill_code, - sourceName = it.startpoint_code, - targetName = it.endpoint_code, - containerCode = it.carry_code, - shelfNumber = it.area_code == "E" ? it.carry_code : "" // 二楼暂存仓传料架 - })); - - Logger.Information($"【AgvDispatch】 Agv任务执行的taskChainCodeDic:{JsonConvert.SerializeObject(taskChainCodeDic)}"); - - foreach ((string k, object v) in taskChainCodeDic) - { - var typeflag = false; - var dis = disTasks.Where(p => p.groups == k).First(); - if (kiva.Contains(dis.startlocation_code) || kiva.Contains(dis.endlocation_code) - //|| floor2.Contains(dis.startlocation_code) || floor2.Contains(dis.endlocation_code) - ) - { - typeflag = true; - } - - // 如果管理区是E(二楼暂存仓和二楼缓存仓) 统一发KIVA - if (dis.area_code == "E") - { - typeflag = true; - } - - dynamic reqBody = new ExpandoObject(); - reqBody.taskChainCode = k; - reqBody.type = typeflag ? (int)EnumTaskChainType.KIVA : (int)EnumTaskChainType.AGV; - reqBody.sequential = false; - reqBody.taskChainPriority = 0; - reqBody.taskList = v; - reqBody.floor = dis.end_floor; - Logger.Information($"【AgvDispatch】 Agv任务执行 开始请求联核/task-chain/create接口 请求地址:{url} 请求参数:{JsonConvert.SerializeObject(reqBody)} "); - dynamic respBody = await HttpClientHelper.PostStreamAsync(url, reqBody, token); - Logger.Information($"【AgvDispatch】 Agv任务执行 接收到联核/task-chain/create接口信息:{respBody}"); - } - } - catch (Exception ex) - { - Logger.Information($"【AgvDispatch】 agv任务执行 请求联核/task-chain/create接口失败 异常信息:{ex}"); - throw; - } - } - - - - /// - /// 任务执行 - /// - /// - /// - [HttpPost] - public async Task TaskExecute(TaskExecuteUpInput input) - { - try - { - await _db.Ado.BeginTranAsync(); - - //更任务执行 - for (int i = 0, cnt = input.disTaskIds.Count; i < cnt; i++) - { - _ = input.EqpIds?.Count > 0 - ? await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID, device_id = input.EqpIds[i] }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync() - : await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); - //await _db.Updateable().SetColumns(it => setColVal).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); - } - List preTaskIds = await _db.Queryable().Where(it => input.disTaskIds.Contains(it.id)).Select(it => it.pretask_id).ToListAsync(); - if (preTaskIds.Count > 0) - { - //更预任务申请表状态 - _ = await _db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); - } - - await _db.Ado.CommitTranAsync(); - } - catch (Exception ex) - { - Logger.Error("任务执行失败", ex); - await _db.Ado.RollbackTranAsync(); - throw; - } - } - /// - /// 任务执行取操作返回(后续操作) - /// - /// - [HttpPost] - public async Task TaskExecuteAfter(TaskExecuteAfterUpInput input) - { - //更新任务执行表单据状态 - try - { - await _db.Ado.BeginTranAsync(); - - _ = await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID, act_start_date = DateTime.Now }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); - //清空载具库位数据 - var carryAndLocIds = await _db.Queryable().Where(it => input.disTaskIds.Contains(it.id)).Select(it => new { it.carry_id, it.startlocation_id }).ToListAsync(); - if (carryAndLocIds?.Count > 0) - { - List carryIds = carryAndLocIds.Select(x => x.carry_id).ToList(); - _ = await _db.Updateable().SetColumns(it => new WmsCarryH { location_id = null, location_code = null }).Where(it => carryIds.Contains(it.id)).ExecuteCommandAsync(); - } - //更新起始库位,状态改为空闲、锁定状态,未锁定 - if (carryAndLocIds?.Count > 0) - { - List startLocationIds = carryAndLocIds.Select(x => x.startlocation_id).ToList(); - _ = await _db.Updateable().SetColumns(it => new BasLocation { is_use = ((int)EnumCarryStatus.空闲).ToString(), is_lock = 0 }).Where(it => startLocationIds.Contains(it.id)).ExecuteCommandAsync(); - } - - await _db.Ado.CommitTranAsync(); - - - } - catch (Exception ex) - { - Logger.Error("设备取返回操作失败", ex); - await _db.Ado.RollbackTranAsync(); - } - } - /// - /// 任务完成 - /// - /// - [HttpPost] - public async Task TaskComplate(TaskCompleUpInput input) - { - try - { - Logger.Information($"【TaskComplate】 开始执行TaskComplate"); - await _db.Ado.BeginTranAsync(); - - //更新任务执行表,单据状态为 完成 - _ = await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID, act_end_date = DateTime.Now }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); - List disTasks = await _db.Queryable().InnerJoin((a, b) => a.carry_id == b.id).Where(a => input.disTaskIds.Contains(a.id)).Select((a, b) => new WmsDistaskH { carry_status = b.carry_status }, true).ToListAsync(); - - Logger.Information($"【TaskComplate】 disTasks 值 {JsonConvert.SerializeObject(disTasks)}"); - if (disTasks?.Count > 0) - { - // 更新预任务申请表,单据状态为 已完成 - List preTaskIds = disTasks.Select(x => x.pretask_id).ToList(); - _ = await _db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); - - //更新电梯任务数量 - _ = await _db.Updateable().SetColumns(it => new WmsElevatorH { task_nums = it.task_nums - 1}).Where(it => disTasks.Select(x => x.area_code).Contains(it.area_code)).ExecuteCommandAsync(); - - // 更新任务数量 - _ = await _db.Updateable().SetColumns(it => new BasLocation { task_nums = it.task_nums - 1 }).Where(it => disTasks.Select(x => x.endlocation_code).Contains(it.location_code)).ExecuteCommandAsync(); - - - //更新载具,锁定状态为未锁定,更新载具的库位当前任务的目标库位 - - List<(string carry_id, string carry_status, string endlocation_id, string endlocation_code)> multiList = disTasks.Select(it => (it.carry_id, it.carry_status, it.endlocation_id, it.endlocation_code)).ToList(); - Dictionary locWhIdMap = await _db.Queryable().Where(it => multiList.Select(x => x.endlocation_id).Contains(it.id)).ToDictionaryAsync(it => it.id, it => it.wh_id); - Dictionary locTypeMap = await _db.Queryable().Where(it => multiList.Select(x => x.endlocation_id).Contains(it.id)).ToDictionaryAsync(it => it.id, it => it.is_type); - List carryIts = new(); - List carryCodeIts = new(); - List locIts = new(); - - Logger.Information($"【TaskComplate】 multiList 值 {JsonConvert.SerializeObject(multiList)}"); - for (int i = 0, cnt = multiList.Count; i < cnt; i++) - { - WmsCarryH carry = new() - { - id = multiList[i].carry_id, - is_lock = 0, - location_id = multiList[i].endlocation_id, - location_code = multiList[i].endlocation_code, - instock_time = DateTime.Now - }; - string endLocId = multiList[i].endlocation_id; + } - WmsCarryH wmsCarryH = await _db.Queryable().Where(r => r.id == carry.id).FirstAsync(); - // 同步料架下的载具位置 - if (wmsCarryH != null && wmsCarryH.carrystd_id == WmsWareHouseConst.CARRY_LJSTD_ID) - { - List carrys = _db.Queryable() - .InnerJoin((a, b) => a.membercarry_id == b.id).Where((a, b) => a.carry_id == carry.id).Select((a, b) => b).ToList(); - carrys.ForEach(r => - { - r.location_id = carry.location_id; - r.location_code = carry.location_code; - carryIts.Add(r); - }); - } - - WmsCarryCode carryCode = new() - { - warehouse_id = locWhIdMap.ContainsKey(endLocId) ? locWhIdMap[endLocId].ToString() : "", - location_id = multiList[i].endlocation_id, - location_code = multiList[i].endlocation_code - }; - carryIts.Add(carry); - carryCodeIts.Add(carryCode); - - BasLocation loc = new() - { - id = multiList[i].endlocation_id, - is_lock = 0, - is_use = string.IsNullOrEmpty(multiList[i].carry_status) ? ((int)EnumCarryStatus.占用).ToString() : multiList[i].carry_status - }; - if (!string.IsNullOrEmpty(multiList[i].carry_status)) - { - loc.is_use = ((int)EnumCarryStatus.占用).ToString(); - } - - - - // 如果是出入库位 完成后解除占用 - string? is_type = locTypeMap.ContainsKey(endLocId) ? locTypeMap[endLocId].ToString() : ""; - if (is_type == ((int)EnumLocationType.出入库位).ToString()) - loc.is_use = ((int)EnumCarryStatus.空闲).ToString(); - - locIts.Add(loc); - } - - _ = await _db.Updateable(carryIts).UpdateColumns(it => new { it.is_lock, it.location_id, it.location_code, it.instock_time }).ExecuteCommandAsync(); - Logger.Information($"【TaskComplate】 更新载具 {JsonConvert.SerializeObject(carryIts)}"); - //更新条码的库位和仓库信息 - _ = await _db.Updateable(carryCodeIts).UpdateColumns(it => new { it.warehouse_id, it.location_id, it.location_code }).Where(it => multiList.Select(x => x.carry_id).Contains(it.carry_id)).ExecuteCommandAsync(); - //更新库位信息,使用状态为 使用,锁定状态为未锁定 - _ = await _db.Updateable(locIts).UpdateColumns(it => new { it.is_use, it.is_lock }).ExecuteCommandAsync(); - Logger.Information($"【TaskComplate】 更新库位 {JsonConvert.SerializeObject(locIts)}"); - /* var loginType= _userManager?.LoginType ?? "web"; - Log.Information($"_userManager.LoginType={loginType}"); - */ //更新业务主表的单据状态 - foreach (WmsDistaskH? dt in disTasks) - { - #region todo 移到service中 - // 销售出库 - if (dt.biz_type == WmsWareHouseConst.BIZTYPE_WMSSALERELEASE_ID) - { - // TODO 一楼工位放货完成后更新出库明细的实际出库数量 - if (dt.start_floor == 1 && dt.end_floor == 1) - { - WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == dt.carry_id).FirstAsync(); - await _db.Updateable().SetColumns(r => r.purchase_prqty == r.purchase_prqty + wmsCarryCode.codeqty).Where(r => r.id == dt.require_id).ExecuteCommandAsync(); - - CarryCodeUnbindInput carryCodeUnbindInput = new CarryCodeUnbindInput(); - carryCodeUnbindInput.carry_id = dt.carry_id; - await _wmsCarryUnbindService.CarryCodeUnbind(carryCodeUnbindInput, _db); - } - } - // 成品调拨入库 - else if (dt.biz_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFERINSTOCK_ID) - { - if (dt.start_floor == 3 && dt.end_floor == 3) - { - WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == dt.carry_id).FirstAsync(); - await _db.Updateable().SetColumns(r => r.qty == r.qty + wmsCarryCode.codeqty).Where(r => r.id == dt.require_id).ExecuteCommandAsync(); - } - } - // 二楼物料呼叫任务结束后清空工位信息 - else if (dt.biz_type == "FloorCallMaterial") - { - await _db.Updateable().SetColumns(r => new WmsCarryH - { - work_station = "" - }).Where(r => r.id == dt.carry_id).ExecuteCommandAsync(); - - // require_code是任务单 - //string mo_task_code = dt.require_code; - } - else if (dt.biz_type == "erp_qtrk") - { - WmsMaterialTransfer wmsMaterialTransfer = await _db.Queryable().SingleAsync(x=>x.id==dt.source_id); - List wmsMaterialTransferDs = await _db.Queryable().Where(x=>x.bill_id==dt.source_id).ToListAsync(); - List materialIds = wmsMaterialTransferDs.Select(x=>x.material_id).Distinct().ToList(); - List unitCodes = wmsMaterialTransferDs.Select(x => x.unit_id).Distinct().ToList(); - List unitDatas = await _db.Queryable() - .LeftJoin((x, y) => x.Id == y.DictionaryTypeId) - .Where((x, y) => x.EnCode == DictConst.MeasurementUnit && unitCodes.Contains(y.EnCode)) - .Select((x,y)=>y) - .ToListAsync(); - - List ids = new List(); - ids.Add(wmsMaterialTransfer.create_id); - ids.Add(WmsWareHouseConst.AdministratorOrgId); - ids.Add(wmsMaterialTransfer.warehouse_instock); - ids.AddRange(materialIds); - ids.AddRange(unitDatas.Select(x=>x.Id).ToList()); - - List erpExtendFields = await _db.Queryable().Where(x=>ids.Contains(x.table_id)).ToListAsync(); - string erpCreateId = erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.create_id)?.user_id ?? ""; - ErpExtendField erpOrg = erpExtendFields.Find(x => x.table_id == (wmsMaterialTransfer.org_id ?? WmsWareHouseConst.AdministratorOrgId)); - string nowStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - - List> requestData = new List>(); - Dictionary erpRequestData = new Dictionary(); - erpRequestData.Add("approver",erpCreateId); - erpRequestData.Add("billmaker",erpCreateId); - erpRequestData.Add("corpoid",erpOrg.corpoid); - erpRequestData.Add("corpvid",erpOrg.corpvid); - erpRequestData.Add("creationtime",nowStr); - erpRequestData.Add("creator",erpCreateId); - erpRequestData.Add("ctrantypeid","0001H11000000000D30Z"); - erpRequestData.Add("cwarehouseid",erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.warehouse_instock)?.cotherwhid ?? ""); - erpRequestData.Add("cwhsmanagerid",""); - erpRequestData.Add("dbilldate",nowStr); - erpRequestData.Add("dmakedate",nowStr); - erpRequestData.Add("ntotalnum",wmsMaterialTransferDs.Sum(x=>x.qty)); - erpRequestData.Add("pk_group",erpOrg.pk_group); - erpRequestData.Add("pk_org",erpOrg.pk_org); - erpRequestData.Add("pk_org_v",erpOrg.pk_org_v); - erpRequestData.Add("vbillcode",wmsMaterialTransfer.bill_code); - erpRequestData.Add("vtrantypecode","4A-01"); - List> erpRequestDataDetails = new List>(); - foreach(WmsMaterialTransferD item in wmsMaterialTransferDs) - { - erpRequestDataDetails.Add(new Dictionary() - { - ["cbodytranstypecode"] = "4A-01", - ["cbodywarehouseid"] = erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.warehouse_instock)?.cotherwhid ?? "", - ["cgeneralbid"] = erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.warehouse_instock)?.cotherwhid ?? "", - ["cgeneralbid"] = item.erp_line_pk, - ["cgeneralhid"] = wmsMaterialTransfer.erp_pk, - ["cmaterialoid"] = erpExtendFields.Find(x=>x.table_id==item.material_id)?.cmaterialoid ?? "", - ["cmaterialvid"] = erpExtendFields.Find(x=>x.table_id==item.material_id)?.cmaterialvid ?? "", - ["corpoid"] = erpOrg.corpoid, - ["corpvid"] = erpOrg.corpvid, - ["crowno"] = (wmsMaterialTransferDs.FindIndex(x=>x.id==item.id)+1) * 10, - ["cunitid"] = erpExtendFields.Find(x=>x.table_id==(unitDatas.Find(x=>x.EnCode==item.unit_id)?.Id ?? ""))?.cunitid ?? "", - ["cvendorid"] = "", - ["cvendorvid"] = "", - ["dbizdate"] = nowStr, - ["nnum"] = item.qty, - ["pk_group"] = erpOrg.pk_group, - ["pk_org"] = erpOrg.pk_org, - ["pk_org_v"] = erpOrg.pk_org_v, - ["vbatchcode"] = item.code_batch, - }); - } - erpRequestData.Add("dtls",erpRequestDataDetails); - requestData.Add(erpRequestData); - - ThirdWebapiRecord thirdWebapiRecord = new ThirdWebapiRecord(); - thirdWebapiRecord.id = SnowflakeIdHelper.NextId(); - thirdWebapiRecord.third_name = WmsWareHouseConst.BIP; - thirdWebapiRecord.name = "其它入库"; - thirdWebapiRecord.method = "POST"; - thirdWebapiRecord.url = WmsWareHouseConst.BIP_DOMAIN+"uapws/rest/generalin/save"; - thirdWebapiRecord.request_data = JsonConvert.SerializeObject(requestData); - thirdWebapiRecord.create_time = DateTime.Now; - - await _db.Insertable(thirdWebapiRecord).ExecuteCommandAsync(); - } - #endregion - - List disTaskCodes = await _db.Queryable().Where(it => it.bill_id == dt.id).ToListAsync(); - WareHouseUpInput upInput = new() { bizTypeId = dt.biz_type, requireId = dt.require_id!, require_code = dt.require_code!, source_id = dt.source_id! - , source_code = dt.source_code!, distaskCodes = disTaskCodes, carryIds = disTasks.Select(x => x.carry_id).ToList(), - bill_code = dt.bill_code!,area_code= dt.area_code!,wmsDistaskH = dt! - }; - - /*if (!_userManager?.LoginType.IsNullOrEmpty() ?? false) - { - upInput.loginType = "app"; - } - else - { - upInput.loginType = "web"; - }*/ - upInput.loginType = "web";//(!string.IsNullOrEmpty(_userManager?.LoginType) ? "app" : "web") ?? "web"; - if (dt.is_sign == 1 && dt.chain_type == "3") - { - await DoUpdate(upInput); - } - } - } - Logger.Information($"【TaskComplate】 任务操作完成提交事务 {string.Join(",", input.disTaskIds)}"); - await _db.Ado.CommitTranAsync(); - - Logger.Information($"【TaskComplate】 任务操作完成 {string.Join(",", input.disTaskIds)}"); - } - catch (Exception ex) - { - Logger.Error($"任务结束失败", ex); - Logger.Error($"任务结束失败堆栈异常", ex); - await _db.Ado.RollbackTranAsync(); - throw; - } - finally - { - _ = GenTaskExecute(); - } - } - /// - /// 出入库策略启用、禁用状态修改 - /// - /// - /// - [HttpPost] - public async Task ModifyPoliciesStatus(ModifyEnabledInput input) - { - async Task _updateStatus(ModifyEnabledInput input) where T : BaseEntity, IUpdatePoliciesStatus, new() - { - T obj = new() { status = input.status }; - _ = await _db.Updateable(obj).UpdateColumns(it => it.status).Where(it => input.ids.Contains(it.id)).ExecuteCommandAsync(); - } - - switch (input.strategyType) - { - case EnumInOutStockType.In: - await _updateStatus(input); - break; - case EnumInOutStockType.Out: - await _updateStatus(input); - break; - } - } - - /// - /// 生成预任务 - /// - /// 预任务集合 - /// 预任务编码集合 - /// - public async Task GenPreTask(List preTasks, List preTaskCodes, ISqlSugarClient dbConn = null) - { - try - { - await s_taskGenPreTask.WaitAsync(); - - var db = _db; - if (dbConn != null) - db = dbConn; - - //如果预任务出现起终库位相同,则删除对应预任务 - //modifiy by ly on 20230922 将当前预任务操作者设为四场管理员 - preTasks.ForEach(pt => - { - pt.org_id = WmsWareHouseConst.AdministratorOrgId; - pt.create_id = WmsWareHouseConst.AdministratorUserId; - }); - if (preTasks.FindAll(it => it.startlocation_id == it.endlocation_id)?.Count > 0) - { - _ = preTasks.RemoveAll(it => it.startlocation_id == it.endlocation_id); - } - List> grpList = preTasks.OrderBy(o => o.bill_code).GroupBy(g => g.carry_id).ToList(); - if (grpList?.Count > 0) - { - foreach (IGrouping? grp in grpList) - { - WmsPretaskH[] arr = grp.ToArray(); - if (arr.Length > 1) - { - WmsPretaskH[] subArr = arr[..^1]; - System.Array.ForEach(subArr, a => a.chain_type = "1"); - } - } - } - int row = await db.Insertable(preTasks).ExecuteCommandAsync(); - if (preTaskCodes?.Count > 0) - { - row = await db.Insertable(preTaskCodes).ExecuteCommandAsync(); - } - var eleP = preTasks.Find(x => x.area_code.Contains("ELE")); - if (eleP != null) - { - row = await db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => it.area_code == eleP.area_code).ExecuteCommandAsync(); - } - - // 累加终点库位任务数 - row = await db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1) - .Where(it => preTasks.Select(r => r.endlocation_id).Contains(it.id)).ExecuteCommandAsync(); - - return row > 0; - } - catch (Exception ex) - { - throw; - } - finally - { - s_taskGenPreTask.Release(); - } - } - - - /// - /// 生成预任务后续处理 - /// - /// - [NonAction] - public async Task GenInStockTaskHandleAfter(GenPreTaskUpInput input, Expression> setCarryColumnsExp, Expression> setLocaionColumbExp, ISqlSugarClient dbConn = null) - { - try - { - var db = _db; - if (dbConn != null) - db = dbConn; - - //根据生成的预任务,插入预任务操作记录 - if (input.PreTaskRecord != null) - { - _ = await db.Insertable(input.PreTaskRecord).ExecuteCommandAsync(); - } - if (input.PreTaskHandleCodes.Count > 0) - { - _ = await db.Insertable(input.PreTaskHandleCodes).ExecuteCommandAsync(); - } - //根据载具ID,更新是否锁定和赋值起始库位 - if (setCarryColumnsExp != null) - { - Expression> whereExp = input.CarryIds?.Count > 0 ? it => input.CarryIds.Contains(it.id) : it => it.id == input.CarryId; - _ = await db.Updateable().SetColumns(setCarryColumnsExp).Where(whereExp).ExecuteCommandAsync(); - } - if (input.CarryStartLocationId.IsNullOrWhiteSpace() == false) - { - _ = await db.Updateable().SetColumns(setLocaionColumbExp).Where(it => input.LocationIds.Contains(it.id)).ExecuteCommandAsync(); - } - //根据所有库位更新库位的锁定状态为“锁定” - if (setLocaionColumbExp != null && input.LocationIds?.Count > 0) - { - _ = await db.Updateable().SetColumns(setLocaionColumbExp).Where(it => input.LocationIds.Contains(it.id)).ExecuteCommandAsync(); - } - } - catch (Exception ex) - { - Logger.LogError("【GenInStockTaskHandleAfter】" + ex.Message); - Logger.LogError("【GenInStockTaskHandleAfter】" + ex.StackTrace); - throw; - } - } - - /// - /// 路径算法 - /// - /// - /// - /// - [NonAction] - public async Task> PathAlgorithms(string pStartId, string pEndId) - { - /* - var sp= await _db.Queryable().Where(it => it.id == pStartId).FirstAsync(); - var ep = await _db.Queryable().Where(it => it.id == pEndId).FirstAsync(); - - if (sp.area_code == "B" || ep.area_code == "B") - { - List Points = new List(); - var zp = await _db.Queryable().Where(it => it.point_code == "ZSCJZJD").FirstAsync(); - Points.Add(sp); - Points.Add(ep); - Points.Add(zp); - Points.ForEach(p => - { - p.area_code = zp.area_code; - p.area_id = zp.area_id; - }); - return Points; - }*/ - - - - List wmsPointHs = await _db.Queryable().Where(it => it.status == 1).ToListAsync(); - - List points = new List(); - - // 待验证 算法太慢 电梯不跑算法 电梯起终点仓库对应表 - BasLocation startlocation = await _db.Queryable().InnerJoin((a, b) => a.id == b.location_id).Where((a, b) => b.id == pStartId).FirstAsync(); - BasLocation endlocation = await _db.Queryable().InnerJoin((a, b) => a.id == b.location_id).Where((a, b) => b.id == pEndId).FirstAsync(); - - // 后续可整理成配置表 - // 3-1 - if (startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CP_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CPCRK_ID) - { - WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "2" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); - string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); - - points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-03-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-3-{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-1-{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-01-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); - } - //1-3 - else if (startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CPCRK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CP_ID) - { - WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "2" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); - string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); - - points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-01-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-1-{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-3-{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-03-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); - } - // 2-4 - else if(startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_ZZXBK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_DMJC_ID) - { - WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "1" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); - string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); - - points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-02-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-02-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-04-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-04-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); - } - // 1-4 - else if(startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_F1BCK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_BCK_ID) - { - WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "1" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); - string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); - - points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-01-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-01-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-04-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-04-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); - } - // 4-2 - else if (startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_BCK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_F2BCQ_ID) - { - WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "1" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); - string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); - - points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-04-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-04-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-02-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-02-0{elevatorSno}").First()); - points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); - } - else - { - List roads = await _db.Queryable().Where(it => it.status == 1).ToListAsync(); - points = await LocPathCalcAlgorithms(pStartId, pEndId, roads); - } - - - Logger.Information($"起点{startlocation.location_code} 终点{endlocation.location_code} 获取到路径 {JsonConvert.SerializeObject(points)}"); - if (points.Count < 6) - { - throw new AppFriendlyException($"路径错误,需要检查路径配置{JsonConvert.SerializeObject(points)}", 500); - } - - //List wmsRoads = await _db.Queryable().Where(r => r.startpoint_id == pStartId).ToListAsync(); - //if (wmsRoads?.FindAll(x => x.endpoint_code != null && x.location_code.Contains("dt", StringComparison.OrdinalIgnoreCase))?.Count > 0) - //{ - - //} - - //List wmsRoads = await _db.Queryable().Where(r => r.startpoint_id == pStartId).ToListAsync(); - - - - - //try - //{ - // if (points?.FindAll(x => x.location_code != null && x.location_code.Contains("dt", StringComparison.OrdinalIgnoreCase))?.Count > 0) - // { - // //查询当前电梯点 - // List curEleDs = await _db.Queryable().InnerJoin((a, b) => a.bill_id == b.id).Where((a, b) => points.Select(x => x.id).Contains(a.point_id)).ToListAsync(); - // Logger.Information($"curEleDs==null :{curEleDs == null},curEleDs:{string.Join(",", curEleDs.Select(x => x.bill_id))}"); - // //如果有电梯点,则会进行电梯的均匀分配 - // if (curEleDs?.Count > 0) - // { - // //当前电梯 - // WmsElevatorH curEle = await _db.Queryable().SingleAsync(it => it.id == curEleDs.First().bill_id); - - // //同电梯组电梯 - // List sGpEle = await _db.Queryable().Where(it => it.elevator_group == curEle.elevator_group && it.id != curEle.id && it.enabled == 1).ToListAsync(); - // if (curEle.enabled == 0 && (sGpEle == null || sGpEle.Count < 1)) - // { - // throw new AppFriendlyException("电梯被禁用或未配置", 500); - // } - // if ((sGpEle == null || sGpEle.Count < 1) && curEle.enabled == 1) - // { - // return points; - // } - // if (sGpEle?.Count > 0 && curEle.enabled == 0) - // { - // return points; - // } - // //判断电梯组中各电梯任务数 - // if (sGpEle.FindAll(x => Math.Abs(x.task_nums - curEle.task_nums) % 2 == 1)?.Count > 0) - // { - // List sGpDs = await _db.Queryable().Where(it => it.bill_id == sGpEle.First().id).ToListAsync(); - // if (sGpDs?.Count > 0) - // { - // List sGpPoints = await _db.Queryable().Where(it => sGpDs.Select(x => x.point_id).Contains(it.id)).ToListAsync(); - // string sFEndId = sGpDs.Single(x => x.floor == curEleDs.First().floor).point_id; - // string eFStartId = sGpDs.Single(x => x.floor == curEleDs.Last().floor).point_id; - // List sFPoints = await LocPathCalcAlgorithms(pStartId, sFEndId, roads); - // List elePoints = new(); - // foreach (WmsElevatorD pt in curEleDs) - // { - // WmsPointH? elePoint = sGpPoints.Find(x => x.floor == pt.floor); - // if (elePoint != null) - // { - // elePoints.Add(elePoint); - // } - // } - // List eFPoints = await LocPathCalcAlgorithms(eFStartId, pEndId, roads); - // _ = elePoints.Remove(elePoints.First()); - // _ = elePoints.Remove(elePoints.Last()); - // points.Clear(); - // points.AddRange(sFPoints); - // points.AddRange(elePoints); - // points.AddRange(eFPoints); - // } - // } - - // } - // } - //} - //catch (Exception ex) - //{ - // Logger.Error("路径算法异常", ex); - // throw; - //} - - return points; - } - /// - /// 路径算法 当出现多个载具同时出库,可能需要进入电梯时 - /// - /// - /// - /// - /// - [NonAction] - public async Task> PathAlgorithmsEle(string pStartId, string pEndId, int ele) - { - List roads = await _db.Queryable().Where(it => it.status == 1).ToListAsync(); - List points = await LocPathCalcAlgorithms(pStartId, pEndId, roads); - try - { - if (points.FindAll(x => x.location_code != null && x.location_code.Contains("dt", StringComparison.OrdinalIgnoreCase))?.Count > 0) - { - //查询当前电梯点 - List curEleDs = await _db.Queryable().Where(it => points.Select(x => x.id).Contains(it.point_id)).ToListAsync(); - //如果有电梯点,则会进行电梯的均匀分配 - if (curEleDs?.Count > 0) - { - //当前电梯 - WmsElevatorH curEle = await _db.Queryable().SingleAsync(it => it.id == curEleDs.First().bill_id && it.enabled == 1); - - - //同电梯组电梯 - List sGpEle = await _db.Queryable().Where(it => it.elevator_group == curEle.elevator_group && it.id != curEle.id && it.enabled == 1).ToListAsync(); - - - if (curEle == null && sGpEle?.Count > 0) - { - throw new AppFriendlyException("电梯被禁用或未配置", 500); - } - if (ele % 2 == 1) - { - //判断电梯组中各电梯任务数 - if (curEle == null || sGpEle.FindAll(x => Math.Abs(x.task_nums - curEle.task_nums) % 2 == 1)?.Count > 0) - { - List sGpDs = await _db.Queryable().Where(it => it.bill_id == sGpEle.First().id).ToListAsync(); - if (sGpDs?.Count > 0) - { - List sGpPoints = await _db.Queryable().Where(it => sGpDs.Select(x => x.point_id).Contains(it.id)).ToListAsync(); - string sFEndId = sGpDs.Single(x => x.floor == curEleDs.First().floor).point_id; - string eFStartId = sGpDs.Single(x => x.floor == curEleDs.Last().floor).point_id; - List sFPoints = await LocPathCalcAlgorithms(pStartId, sFEndId, roads); - List elePoints = new(); - foreach (WmsElevatorD pt in curEleDs) - { - WmsPointH? elePoint = sGpPoints.Find(x => x.floor == pt.floor); - if (elePoint != null) - { - elePoints.Add(elePoint); - } - } - List eFPoints = await LocPathCalcAlgorithms(eFStartId, pEndId, roads); - _ = elePoints.Remove(elePoints.First()); - _ = elePoints.Remove(elePoints.Last()); - points.Clear(); - points.AddRange(sFPoints); - points.AddRange(elePoints); - points.AddRange(eFPoints); - } - } - } - - } - } - } - catch (Exception ex) - { - Logger.Error("路径算法异常", ex); - throw; - } - - return points; - } - #region PrivateMethods - - private async Task> LocPathCalcAlgorithms(string pStartId, string pEndId, List roads) - { - Logger.Information($"【LocPathCalcAlgorithms】开始执行 pStartId:{pStartId} pEndId:{pEndId}"); - Stopwatch stopwatch = Stopwatch.StartNew(); - #region dp - //List results = new(); - //var points = await _db.Queryable().ToListAsync(); - //Dictionary isVisited = roads.Select(x => x.startpoint_id).Distinct().ToDictionary(x => x, x => false); - - //List pointIds = new(); - //List codes = new(); - //Dp dp = new(); - //dynamic obj = new ExpandoObject(); - //obj.isArrivedEpoint = false; - //dp.DpFunc(roads, pointIds, isVisited, pStartId, pEndId, obj); - //foreach (var pid in pointIds) - //{ - // var point = points.Find(x => x.id == pid); - // if (point != null) - // { - // results.Add(point); - // } - //} - //return results; - #endregion - - #region dijkstra - List results = new(); - - try - { - 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]); - } - - 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) - { - WmsPointH? point = points?.Find(x => x.id == i); - if (point != null) - { - results.Add(point); - } - } - } - } - catch (Exception ex) - { - Logger.Error("路径算法错误", ex); - throw; - } - finally - { - stopwatch.Stop(); - Logger.Information($"【LocPathCalcAlgorithms】耗时{stopwatch.ElapsedMilliseconds}"); - } - - - return results; - #endregion - - } - /// - /// 获取匹配的最短路径节点 - /// - /// - /// - /// - /// - /// - /// - private void MatchPoint(List results, List roads, List shortestPathPoints, Dictionary isVisited, string pStartId, string pEndId) - { - List sRoads = roads.Where(x => x.startpoint_id == pStartId).ToList(); - for (int j = 0; j < sRoads.Count; j++) - { - WmsPointH? sPoint = shortestPathPoints.Find(x => x.id == sRoads[j].endpoint_id); - if (sPoint != null && isVisited.ContainsKey(sPoint.id) && !isVisited[sPoint.id] && sPoint.id != pEndId) - { - string code = sPoint.point_code; - results.Add(sPoint); - isVisited[sPoint.id] = true; - MatchPoint(results, roads, shortestPathPoints, isVisited, sPoint.id, pEndId); - } - } - } - /// - /// 根据终止节点获取最短路径顶点 - /// - /// - /// - /// - /// - private static void GetPoints(List pointIds, int[] prev, Stack result, int eIdx) - { - int index = eIdx; - while (index != 0) - { - result.Push(pointIds[index]); - index = prev[index]; - } - } - - private async Task Update(T1 entity, List entities) where T1 : BaseEntity, new() where T2 : BaseEntity, new() - { - bool isOk = false; - try - { - await _db.Ado.BeginTranAsync(); - isOk = await _db.Updateable(entity).ExecuteCommandHasChangeAsync(); - if (entities?.Count > 0) - { - int row = await _db.Storageable(entities).ExecuteCommandAsync(); - isOk = row > 0; - } - await _db.Ado.CommitTranAsync(); - } - catch (Exception) - { - await _db.Ado.RollbackTranAsync(); - } - return isOk; - } - - /// - /// 根据明细Id获取出入库明细信息 - /// - /// 出入库明细 - /// 明细输出类 - /// 出入库条码 - /// 明细Id - /// - private async Task FetchInOutStockCodesById(string billDId) - where TStockD : BaseEntity, new() - where TOutput : IInOutStockDetail, new() - where TStockCode : BaseEntity, IInOutStockCode, new() - { - Dictionary dic = await _dictionaryDataService.GetDictionaryByTypeId(WmsWareHouseConst.WMS_INSTOCK_D_BILL_STATUS_TYPEID); - List data = await _db.Queryable() - .Where(a => a.id == billDId) - .Select(a => new TOutput - { - CodeDetails = SqlFunc.Subqueryable().Where(it => it.bill_d_id == a.id).ToList(), - }, true) - .Mapper(it => - { - it.line_status = it.line_status != null && dic.ContainsKey(key: it.line_status) ? dic[it.line_status]?.ToString() : ""; - it.warehouse_id = _db.Queryable().Single(y => y.id == it.warehouse_id)?.whname ?? ""; - }) - .ToListAsync(); - - return data; - } - - - /// - /// 二楼kiva把料架送到下升降机后生成中储仓入库任务 - /// - /// 料架id - /// - - public async Task Floor2EmptyCarryCreateZZCPretask(string rackid) - { - try - { - List wmsCarryCodes = _db.Queryable().Where(r => r.carry_id == rackid).ToList(); + // 查找是否有一个料箱可以正好满足剩余需求数量(目前只做这个额外判断,其它情形不考虑) + bool isFind = false; + for (int j = i + 1; j < itemsASC.Count; j++) + { + WmsCarryCode _wmsCarryCode = itemsASC[j].wmsCarryCode; + if (_wmsCarryCode.codeqty == input.needOut) + { + input.needOut -= _wmsCarryCode.codeqty; + WmsCarryH _wmsCarryH = itemsASC[j].wmsCarryH; + + await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync(); + + carrys.Add(new Tuple(_wmsCarryH, _wmsCarryCode.codeqty, endlocation_ssx)); + + isFind = true; + break; + } + + } + if (isFind) + break; + + // 目前只支持一个料箱只有一个物料 + input.needOut -= wmsCarryCode.codeqty; + + await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => endlocation_ssx.id == it.id).ExecuteCommandAsync(); + + carrys.Add(new Tuple(wmsCarryH, wmsCarryCode.codeqty, endlocation_ssx)); + } + #endregion + + if (input.needOut > 0) + { + throw new AppFriendlyException($"物料{input.material_code}没有足够的库存!,缺失数量为{input.needOut}", 500); + } + + + return carrys; + } + + /// + /// 判断CTU是否可以放货 + /// + /// + [HttpPost] + [AllowAnonymous] + public async Task CheckPut(CheckPutInput input) + { + Logger.Information("联核请求CheckPut接口传入参数为:" + JsonConvert.SerializeObject(input)); + + Dictionary putdic = new Dictionary(); + + putdic.Add("SSX-011-006", new string[] { "YTCS", "AllowEmptyIn_CS06" }); + putdic.Add("SSX-021-007", new string[] { "东面提升机输送线", "出库输送线7允许入箱" }); + putdic.Add("SSX-121-009", new string[] { "东面提升机输送线", "上升降机9允许入箱" }); + putdic.Add("SSX-121-010", new string[] { "东面提升机输送线", "上升降机10允许入箱" }); + putdic.Add("SSX-021-003", new string[] { "YTCS", "AllowCtuEmptyIn_CS03" }); + putdic.Add("SSX-021-001", new string[] { "YTCS", "AllowCtuEmptyIn_CS01" }); + putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowCtuFullOut_CS04", }); + putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowCtuFullOut_CS02", }); + var strs = new string[] { }; + + if (!putdic.ContainsKey(input.targetName)) + throw new AppFriendlyException("点位" + input.targetName + "不存在", 500); + strs = putdic.Where(p => p.Key == input.targetName).First().Value; + + bool flag = await _redisData.HashExists(strs[0], strs[1]); + if (!flag) + { + throw new AppFriendlyException("点位" + input.targetName + "不存在", 500); + } + string data = await _redisData.GetHash(strs[0], strs[1]); + Logger.Information("wcs请求CheckPut接口查询X2Server数据:" + data); + JObject? res = JsonConvert.DeserializeObject(data); + bool result = res != null && res["Value"] != null ? res.Value("Value") : false; + if (!result) + throw new AppFriendlyException("点位" + input.targetName + "不可放", 500); + Logger.Information("wcs请求CheckPut接口结果:CTU可放货" + data); + } + + /// + /// 判断CTU是否可以取货 + /// + /// + + public async Task Check(string code, string action) + { + Logger.Information($"【Check】 判断KIVA是否可以{action} {code}"); + Dictionary putdic = new Dictionary(); + Dictionary getdic = new Dictionary(); + + putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowAgvFullIn_CS04", }); + putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowAgvFullIn_CS02", }); + getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowAgvEmptyOut_CS01" }); + getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowAgvEmptyOut_CS03" }); + + #region 注塑车间点位 + putdic.Add("ZS-C01-1", new string[] { "hxjC", "A2允许入空箱", }); + getdic.Add("ZS-C01-2", new string[] { "hxjC", "A2允许取满箱" }); + + putdic.Add("ZS-C02-1", new string[] { "hxjC", "A3允许入空箱", }); + getdic.Add("ZS-C02-2", new string[] { "hxjC", "A3允许取满箱" }); + + putdic.Add("ZS-C03-1", new string[] { "hxjC", "A4允许入空箱", }); + getdic.Add("ZS-C03-2", new string[] { "hxjC", "A4允许取满箱" }); + + putdic.Add("ZS-C04-1", new string[] { "hxjC", "A5允许入空箱", }); + getdic.Add("ZS-C04-2", new string[] { "hxjC", "A5允许取满箱" }); + + putdic.Add("ZS-C05-1", new string[] { "hxjC", "A6允许入空箱", }); + getdic.Add("ZS-C05-2", new string[] { "hxjC", "A6允许取满箱" }); + + putdic.Add("ZS-C06-1", new string[] { "hxjC", "A7允许入空箱", }); + getdic.Add("ZS-C06-2", new string[] { "hxjC", "A7允许取满箱" }); + + putdic.Add("ZS-C07-1", new string[] { "hxjC", "A8允许入空箱", }); + getdic.Add("ZS-C07-2", new string[] { "hxjC", "A8允许取满箱" }); + + putdic.Add("ZS-C08-1", new string[] { "hxjC", "A9允许入空箱", }); + getdic.Add("ZS-C08-2", new string[] { "hxjC", "A9允许取满箱" }); + + putdic.Add("ZS-C09-1", new string[] { "hxjC", "A10允许入空箱", }); + getdic.Add("ZS-C09-2", new string[] { "hxjC", "A10允许取满箱" }); + + putdic.Add("ZS-C10-1", new string[] { "hxjC", "A11允许入空箱", }); + getdic.Add("ZS-C10-2", new string[] { "hxjC", "A11允许取满箱" }); + + putdic.Add("ZS-C11-1", new string[] { "hxjC", "A12允许入空箱", }); + getdic.Add("ZS-C11-2", new string[] { "hxjC", "A12允许取满箱" }); + + putdic.Add("ZS-C12-1", new string[] { "hxjC", "A13允许入空箱", }); + getdic.Add("ZS-C12-2", new string[] { "hxjC", "A13允许取满箱" }); + + putdic.Add("ZS-C13-1", new string[] { "hxjC", "A14允许入空箱", }); + getdic.Add("ZS-C13-2", new string[] { "hxjC", "A14允许取满箱" }); + + putdic.Add("ZS-C14-1", new string[] { "hxjC", "A1允许入空箱", }); + getdic.Add("ZS-C14-2", new string[] { "hxjC", "A1允许取满箱" }); + + + putdic.Add("ZS-A01-1", new string[] { "hxjA", "A3允许入空箱", }); + getdic.Add("ZS-A01-2", new string[] { "hxjA", "A3允许取满箱" }); + + putdic.Add("ZS-A02-1", new string[] { "hxjA", "A4允许入空箱", }); + getdic.Add("ZS-A02-2", new string[] { "hxjA", "A4允许取满箱" }); + + putdic.Add("ZS-A03-1", new string[] { "hxjA", "A5允许入空箱", }); + getdic.Add("ZS-A03-2", new string[] { "hxjA", "A5允许取满箱" }); + + putdic.Add("ZS-A04-1", new string[] { "hxjA", "A6允许入空箱", }); + getdic.Add("ZS-A04-2", new string[] { "hxjA", "A6允许取满箱" }); + + putdic.Add("ZS-A05-1", new string[] { "hxjA", "A7允许入空箱", }); + getdic.Add("ZS-A05-2", new string[] { "hxjA", "A7允许取满箱" }); + + putdic.Add("ZS-A06-1", new string[] { "hxjA", "A8允许入空箱", }); + getdic.Add("ZS-A06-2", new string[] { "hxjA", "A8允许取满箱" }); + + putdic.Add("ZS-A07-1", new string[] { "hxjA", "A9允许入空箱", }); + getdic.Add("ZS-A07-2", new string[] { "hxjA", "A9允许取满箱" }); + + putdic.Add("ZS-A08-1", new string[] { "hxjA", "A10允许入空箱", }); + getdic.Add("ZS-A08-2", new string[] { "hxjA", "A10允许取满箱" }); + + putdic.Add("ZS-A09-1", new string[] { "hxjA", "A11允许入空箱", }); + getdic.Add("ZS-A09-2", new string[] { "hxjA", "A11允许取满箱" }); + + putdic.Add("ZS-A10-1", new string[] { "hxjA", "A12允许入空箱", }); + getdic.Add("ZS-A10-2", new string[] { "hxjA", "A12允许取满箱" }); + + putdic.Add("ZS-A11-1", new string[] { "hxjA", "A13允许入空箱", }); + getdic.Add("ZS-A11-2", new string[] { "hxjA", "A13允许取满箱" }); + + putdic.Add("ZS-A12-1", new string[] { "hxjA", "A14允许入空箱", }); + getdic.Add("ZS-A12-2", new string[] { "hxjA", "A14允许取满箱" }); + #endregion + + var strs = new string[] { }; + + if (action == "LOAD")//取货 + { + if (!getdic.ContainsKey(code)) + { + return false; + } + strs = getdic.Where(p => p.Key == code).First().Value; + + bool flag = await _redisData.HashExists(strs[0], strs[1]); + Logger.Information($"【Check】{action} 判断KIVA是否可以取货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); + if (!flag) + { + throw new Exception($"【Check】{action} 判断KIVA是否可以取货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); + } + string data = _redisData.GetHash(strs[0], strs[1]).Result; + JObject? res = JsonConvert.DeserializeObject(data); + bool result = res != null && res["Value"] != null ? res.Value("Value") : false; + Logger.Information($"【Check】{action} 判断KIVA是否可以取货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} "); + if (!result) + { + throw new Exception($"【Check】{action} 判断KIVA是否可以取货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} "); + } + return true; + } + else if (action == "UNLOAD")//放货 + { + if (!putdic.ContainsKey(code)) + return false; + strs = putdic.Where(p => p.Key == code).First().Value; + + bool flag = await _redisData.HashExists(strs[0], strs[1]); + Logger.Information($"【Check】 判断CTU是否可以放货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); + if (!flag) + { + throw new Exception($"【Check】 判断CTU是否可以放货(信号是否存在) 获取{code}的标签{strs[1]}是否存在 结果为:{flag} "); + } + string data = _redisData.GetHash(strs[0], strs[1]).Result; + JObject? res = JsonConvert.DeserializeObject(data); + bool result = res != null && res["Value"] != null ? res.Value("Value") : false; + Logger.Information($"【Check】 判断CTU是否可以放货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result}"); + if (!result) + { + throw new Exception($"【Check】 判断CTU是否可以放货(信号是否允许) 获取{code}的标签{strs[1]}信号值 结果为:{result} "); + } + return true; + } + return false; + } + public async Task SsxControl(WmsDistaskH disTask, string action) + { + Logger.Information($"输送线控制SsxControl传入参数: {JsonConvert.SerializeObject(disTask)} {action}"); + + Dictionary putdic = new Dictionary(); + Dictionary getdic = new Dictionary(); + getdic.Add("SSX-021-005", new string[] { "YTCS", "FullOut_CS05Done", "true" }); + getdic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11出箱完毕", "true" }); + getdic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12出箱完毕", "true" }); + getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线上层允许出箱3", "true" }); + getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线上层允许出箱1", "true" }); + getdic.Add("SSX-011-008", new string[] { "东面提升机输送线", "入库输送线8出箱完毕", "true" }); + getdic.Add("ZS-C01-2", new string[] { "hxjC", "A2AGV允许入满箱", "true" }); + getdic.Add("ZS-C02-2", new string[] { "hxjC", "A3AGV允许入满箱", "true" }); + getdic.Add("ZS-C03-2", new string[] { "hxjC", "A4AGV允许入满箱", "true" }); + getdic.Add("ZS-C04-2", new string[] { "hxjC", "A5AGV允许入满箱", "true" }); + getdic.Add("ZS-C05-2", new string[] { "hxjC", "A6AGV允许入满箱", "true" }); + getdic.Add("ZS-C06-2", new string[] { "hxjC", "A7AGV允许入满箱", "true" }); + getdic.Add("ZS-C07-2", new string[] { "hxjC", "A8AGV允许入满箱", "true" }); + getdic.Add("ZS-C08-2", new string[] { "hxjC", "A9AGV允许入满箱", "true" }); + getdic.Add("ZS-C09-2", new string[] { "hxjC", "A10AGV允许入满箱", "true" }); + getdic.Add("ZS-C10-2", new string[] { "hxjC", "A11AGV允许入满箱", "true" }); + getdic.Add("ZS-C11-2", new string[] { "hxjC", "A12AGV允许入满箱", "true" }); + getdic.Add("ZS-C12-2", new string[] { "hxjC", "A13AGV允许入满箱", "true" }); + getdic.Add("ZS-C13-2", new string[] { "hxjC", "A14AGV允许入满箱", "true" }); + getdic.Add("ZS-C14-2", new string[] { "hxjC", "A1AGV允许入满箱", "true" }); + + getdic.Add("ZS-A01-2", new string[] { "hxjA", "A3AGV允许入满箱", "true" }); + getdic.Add("ZS-A02-2", new string[] { "hxjA", "A4AGV允许入满箱", "true" }); + getdic.Add("ZS-A03-2", new string[] { "hxjA", "A5AGV允许入满箱", "true" }); + getdic.Add("ZS-A04-2", new string[] { "hxjA", "A6AGV允许入满箱", "true" }); + getdic.Add("ZS-A05-2", new string[] { "hxjA", "A7AGV允许入满箱", "true" }); + getdic.Add("ZS-A06-2", new string[] { "hxjA", "A8AGV允许入满箱", "true" }); + getdic.Add("ZS-A07-2", new string[] { "hxjA", "A9AGV允许入满箱", "true" }); + getdic.Add("ZS-A08-2", new string[] { "hxjA", "A10AGV允许入满箱", "true" }); + getdic.Add("ZS-A09-2", new string[] { "hxjA", "A11AGV允许入满箱", "true" }); + getdic.Add("ZS-A10-2", new string[] { "hxjA", "A12AGV允许入满箱", "true" }); + getdic.Add("ZS-A11-2", new string[] { "hxjA", "A13AGV允许入满箱", "true" }); + getdic.Add("ZS-A12-2", new string[] { "hxjA", "A14AGV允许入满箱", "true" }); + + + + putdic.Add("SSX-021-007", new string[] { "东面提升机输送线", "出库输送线7入箱完毕", "true" }); + putdic.Add("SSX-011-006", new string[] { "YTCS", "EmptyIn_CS06Done", "true" }); + putdic.Add("SSX-021-003", new string[] { "YTCS", "AgvFullIn_CS03Done", "true" }); + putdic.Add("SSX-021-001", new string[] { "YTCS", "CtuEmptyIn_CS01Done", "true" }); + putdic.Add("ZSSSXCTU02", new string[] { "YTCS", "右输送线下层允许入箱4", "true" }); + putdic.Add("ZSSSXCTU01", new string[] { "YTCS", "左输送线下层允许入箱2", "true" }); + putdic.Add("SSX-121-009", new string[] { "东面提升机输送线", "上升降机9入箱完毕", "true" }); + putdic.Add("SSX-121-010", new string[] { "东面提升机输送线", "上升降机10入箱完毕", "true" }); + putdic.Add("YCLCKBGW", new string[] { "CP8", "PutDoneEmptyBox", "true" }); + putdic.Add("ZS-C01-1", new string[] { "hxjC", "A2AGV允许出空箱", "true" }); + putdic.Add("ZS-C02-1", new string[] { "hxjC", "A3AGV允许出空箱", "true" }); + putdic.Add("ZS-C03-1", new string[] { "hxjC", "A4AGV允许出空箱", "true" }); + putdic.Add("ZS-C04-1", new string[] { "hxjC", "A5AGV允许出空箱", "true" }); + putdic.Add("ZS-C05-1", new string[] { "hxjC", "A6AGV允许出空箱", "true" }); + putdic.Add("ZS-C06-1", new string[] { "hxjC", "A7AGV允许出空箱", "true" }); + putdic.Add("ZS-C07-1", new string[] { "hxjC", "A8AGV允许出空箱", "true" }); + putdic.Add("ZS-C08-1", new string[] { "hxjC", "A9AGV允许出空箱", "true" }); + putdic.Add("ZS-C09-1", new string[] { "hxjC", "A10AGV允许出空箱", "true" }); + putdic.Add("ZS-C10-1", new string[] { "hxjC", "A11AGV允许出空箱", "true" }); + putdic.Add("ZS-C11-1", new string[] { "hxjC", "A12AGV允许出空箱", "true" }); + putdic.Add("ZS-C12-1", new string[] { "hxjC", "A13AGV允许出空箱", "true" }); + putdic.Add("ZS-C13-1", new string[] { "hxjC", "A14AGV允许出空箱", "true" }); + putdic.Add("ZS-C14-1", new string[] { "hxjC", "A1AGV允许出空箱", "true" }); + + putdic.Add("ZS-A01-1", new string[] { "hxjA", "A3AGV允许出空箱", "true" }); + putdic.Add("ZS-A02-1", new string[] { "hxjA", "A4AGV允许出空箱", "true" }); + putdic.Add("ZS-A03-1", new string[] { "hxjA", "A5AGV允许出空箱", "true" }); + putdic.Add("ZS-A04-1", new string[] { "hxjA", "A6AGV允许出空箱", "true" }); + putdic.Add("ZS-A05-1", new string[] { "hxjA", "A7AGV允许出空箱", "true" }); + putdic.Add("ZS-A06-1", new string[] { "hxjA", "A8AGV允许出空箱", "true" }); + putdic.Add("ZS-A07-1", new string[] { "hxjA", "A9AGV允许出空箱", "true" }); + putdic.Add("ZS-A08-1", new string[] { "hxjA", "A10AGV允许出空箱", "true" }); + putdic.Add("ZS-A09-1", new string[] { "hxjA", "A11AGV允许出空箱", "true" }); + putdic.Add("ZS-A10-1", new string[] { "hxjA", "A12AGV允许出空箱", "true" }); + putdic.Add("ZS-A11-1", new string[] { "hxjA", "A13AGV允许出空箱", "true" }); + putdic.Add("ZS-A12-1", new string[] { "hxjA", "A14AGV允许出空箱", "true" }); + + if (action == "LOAD")//取货 + { + if (getdic.Keys.Contains(disTask.startlocation_code)) + { + var strarr = getdic.Where(p => p.Key == disTask.startlocation_code).First().Value; + Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase) + { + ["DevName"] = strarr[0], + ["token"] = _eleCtlCfg.token, + ["TagName"] = strarr[1], + ["Value"] = strarr[2], + }; + Logger.Information($"SsxControlLOAD:{JsonConvert.SerializeObject(dicCommand)}"); + var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); + Logger.Information($"SsxControlLOAD:{str}"); + } + } + else if (action == "UNLOAD")//放货 + { + if (putdic.Keys.Contains(disTask.endlocation_code)) + { + var strarr = putdic.Where(p => p.Key == disTask.endlocation_code).First().Value; + Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase) + { + ["DevName"] = strarr[0], + ["token"] = _eleCtlCfg.token, + ["TagName"] = strarr[1], + ["Value"] = strarr[2], + }; + Logger.Information($"SsxControlUNLOAD:{JsonConvert.SerializeObject(dicCommand)}"); + var str = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); + Logger.Information($"SsxControlUNLOAD:{str}"); + } + } + + } + + /// + /// 二楼机械臂 + /// + /// + public async Task Floor2MechanicalConfirm(WmsDistaskH disTask, string action) + { + List rackAreaPointsUp = new List(); + List rackAreaPointsDown = new List(); + // 二楼上升降区料架区点位 + rackAreaPointsUp.Add("AS01"); + rackAreaPointsUp.Add("AS02"); + // 二楼下升降区料架区点位 + rackAreaPointsDown.Add("AX01"); + rackAreaPointsDown.Add("AX02"); + + try { + List basLocations = _db.Queryable().Where(r => (r.location_code == disTask.endlocation_code || r.location_code == disTask.startlocation_code) + && r.wh_id != "33780009364245").ToList(); + + // 暂存仓内任务 + if (disTask.area_code == "E" && basLocations.Count() == 0) + { + await _db.Ado.BeginTranAsync(); + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】收到到货确认信号 传入参数: {disTask.bill_code} {action}"); + + if (action == "UNLOAD") + { + // 去料架区放货 + if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) + { + ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.endlocation_code); + if (WmsMechanicalArmHs.Count() == 0) + { + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); + throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); + } + WmsMechanicalArmH target = WmsMechanicalArmHs.First(); + + // 回写料架和AGV确认 + await _db.Updateable().SetColumns(r => new WmsMechanicalArmH + { + agvconfirm = 1, + rackid = disTask.carry_id, + rackcode = disTask.carry_code + }).Where(r => r.id == target.id).ExecuteCommandAsync(); + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV已到货 {disTask.endpoint_code} 更新缓存表{target.id}"); + + if (rackAreaPointsDown.Contains(disTask.endlocation_code)) + { + int LXCount = _db.Queryable().Where(a => a.carry_id == disTask.carry_id).Count(); + + // 绑定料架 + await _db.Updateable().SetColumns(r => new WmsMechanicalArmH + { + mechanicalconfirm = 1, + maxnum = LXCount + }).Where(r => r.id == target.id).ExecuteCommandAsync(); + + Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱开始生成预任务"); + bool pretask_result = await Floor2EmptyCarryCreateZZCPretask(disTask.carry_id); + if (pretask_result) + { + Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务完成"); + } + else + { + Logger.LogInformation($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务失败"); + throw new Exception($@"【送满托到下升降区】 料架{target.rackid}下的料箱生成预任务失败"); + } + } + } + else // 去暂存仓放货 + { + // 回写料架料箱绑定表的库位 + ISugarQueryable WmsCarryCodes = _db.Queryable() + .InnerJoin((a, b) => b.membercarry_id == a.carry_id) + .Where((a, b) => b.carry_id == disTask.carry_id); + var WmsCarryCodeList = WmsCarryCodes.ToList(); + WmsCarryCodeList.ForEach(r => + { + r.location_id = disTask.endlocation_id; + r.location_code = disTask.endlocation_code; + }); + await _db.Updateable(WmsCarryCodeList).ExecuteCommandAsync(); + } + } + else + { + // 去暂存仓取货 + if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) + { + + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在暂存仓取货确认完成"); + } + else // 去料架区取货 + { + ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.startlocation_code); + if (WmsMechanicalArmHs.Count() == 0) + { + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); + throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); + } + WmsMechanicalArmH target = WmsMechanicalArmHs.First(); + + if (target.note == "上升降机") + { + bool result = await Floor2UpDownMachinecode_SetTag($"上升降机满托{target.stackingposition}移走", "true"); + Logger.LogInformation($@"【上升降机】设定升上升降机满托{target.stackingposition}移走 结果为 {result}"); + if (!result) + { + throw new Exception($@"【上升降机】设定升上升降机满托{target.stackingposition}移走 结果为 {result}"); + } + + // 更新料架在二楼配送的目标工位 + // todo erp工位字段取数位置未确定 + WmsMaterialTransferD wmsMaterialTransferD = await _db.Queryable() + .LeftJoin((a, b) => a.id == b.bill_id).Where((a, b) => a.bill_code == target.outbill) + .Select((a, b) => b).FirstAsync(); + if (wmsMaterialTransferD == null) + { + Logger.LogWarning($@"【上升降机】 发生异常!,转库单{target.outbill}没有载具明细"); + // 转库单删除 不执行后续,不返回失败是为了不卡流程 + return; + } + + string targetWorkstation = wmsMaterialTransferD.station_code; + if (string.IsNullOrEmpty(wmsMaterialTransferD.station_code)) + { + throw new Exception($@"【上升降机】 发生异常!,转库单{target.outbill}的工位为空"); + } + + Logger.LogInformation($@"【上升降机】更新料架 {target.rackcode} 在二楼配送的目标工位 {targetWorkstation}"); + await _db.Updateable().SetColumns(r => new WmsCarryH + { + work_station = targetWorkstation + }).Where(r => r.id == target.rackid).ExecuteCommandAsync(); + } + else if (target.note == "下升降机") + { + bool result = await Floor2UpDownMachinecode_SetTag($"下升降机空托{target.stackingposition}移走", "true"); + Logger.LogInformation($@"【上升降机】设定升下升降机空托{target.stackingposition}移走 结果为 {result}"); + if (!result) + { + throw new Exception($@"【上升降机】设定升下升降机空托{target.stackingposition}移走 结果为 {result}"); + } + } + + // 重置料架区 + await _db.Updateable().SetColumns(r => new WmsMechanicalArmH + { + stackingcount = 0, + barcodes = "", + outbill = "", + maxnum = 0, + iscreatepretask = 0, + rackcode = "", + rackid = "", + agvconfirm = 0, + mechanicalconfirm = 0 + }).Where(r => r.id == target.id).ExecuteCommandAsync(); + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在料架区取货完成"); + } + } + await _db.Ado.CommitTranAsync(); + } + } + catch(Exception ex) + { + Logger.LogError("【Floor2MechanicalComplete】" + ex.ToString()); + await _db.Ado.RollbackTranAsync(); + throw; + } + } + + + + /// + /// 二楼机械臂 + /// + /// + public async Task Floor2MechanicalComplete(WmsDistaskH disTask, string action) + { + List rackAreaPointsUp = new List(); + List rackAreaPointsDown = new List(); + // 二楼上升降区料架区点位 + rackAreaPointsUp.Add("AS01"); + rackAreaPointsUp.Add("AS02"); + // 二楼下升降区料架区点位 + rackAreaPointsDown.Add("AX01"); + rackAreaPointsDown.Add("AX02"); + + try + { + List basLocations = _db.Queryable().Where(r => (r.location_code == disTask.endlocation_code || r.location_code == disTask.startlocation_code) + && r.wh_id != "33780009364245").ToList(); + + // 暂存仓内任务 + if (disTask.area_code == "E" && basLocations.Count() == 0) + { + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】收到到货完成信号 传入参数: {disTask.bill_code} {action}"); + + if (action == "UNLOAD") + { + // 去料架区放货 + if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) + { + ISugarQueryable WmsMechanicalArmHs = _db.Queryable().Where(r => r.location_code == disTask.endlocation_code); + if (WmsMechanicalArmHs.Count() == 0) + { + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); + throw new Exception($"【二楼机械臂Floor2MechanicalComplete】 任务执行终点{disTask.endpoint_code} 与料架区的点位不匹配"); + } + WmsMechanicalArmH target = WmsMechanicalArmHs.First(); + + // 下升降机写满托数量和送到信号 + if (rackAreaPointsDown.Contains(disTask.endlocation_code)) + { + int LXCount = _db.Queryable().Where(a => a.carry_id == disTask.carry_id).Count(); + + bool result = await Floor2UpDownMachinecode_SetTag($"下升降机满托{target.stackingposition}数量", LXCount.ToString()); + Logger.LogInformation($@"【送满托到下升降区】设定下升降机满托{target.stackingposition}满托数量为 {LXCount} 结果为 {result}"); + if (!result) + { + throw new Exception($"下升降机满托{target.stackingposition}数量 写入失败"); + } + + // 尝试写入满托送到信号 + bool result下升降机空托送到 = await Floor2UpDownMachinecode_SetTag($"下升降机满托{target.stackingposition}送到", "true"); + Logger.LogInformation($@"【送满托到下升降区】回写 下升降机满托{target.stackingposition}送到 结果为{result下升降机空托送到}"); + if (!result下升降机空托送到) + { + throw new Exception($"下升降机满托{target.stackingposition}送到 写入失败"); + } + } + } + else // 去暂存仓放货 + { + + } + } + else + { + // 去暂存仓取货 + if (rackAreaPointsUp.Contains(disTask.endlocation_code) || rackAreaPointsDown.Contains(disTask.endlocation_code)) + { + Logger.Information($"【二楼机械臂Floor2MechanicalComplete】{disTask.bill_code} AGV在暂存仓取货完成"); + } + else // 去料架区取货 + { + } + } + } + } + catch (Exception ex) + { + Logger.LogError("【Floor2MechanicalComplete】" + ex.ToString()); + throw; + } + } + + + + + private async Task Floor2UpDownMachinecode_SetTag(string tag, string value) + { + string DevName = "东面提升机输送线"; + Dictionary dicCommand = new(StringComparer.OrdinalIgnoreCase) + { + ["DevName"] = DevName, + ["token"] = _eleCtlCfg.token, + ["TagName"] = tag, + ["Value"] = value, + }; + string result = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand); + + return result.Contains("Ok"); + + // 测试 + //string DevName = "东面提升机输送线"; + + //JObject valueJson = new JObject(); + //valueJson["Value"] = value; + + //_redisData.SetHash(DevName, tag, valueJson.ToString()); + //return true; + } + + + /// + /// 生成任务执行 + /// + /// + [HttpPost] + public async Task GenTaskExecute() + { + if (s_GenTaskExecute.CurrentCount == 0) + { + Logger.Information("【GenTaskExecute】 【测试】 丢弃此执行"); + return; + } + await s_GenTaskExecute.WaitAsync(); + Stopwatch sw = Stopwatch.StartNew(); + CancellationTokenSource agvCts = new(); + SqlSugarClient db = _db.CopyNew(); + try + { + await CTUTaskExecute(); + + //获取所有未下发的预任务申请 + Logger.Information("【GenTaskExecute】 开始获取未下发的预任务..."); + + ISugarQueryable sugarQueryable = db.Queryable() + .LeftJoin((a, b) => a.carry_id == b.id) + .InnerJoin((a, b, c) => a.area_id == c.id) + .InnerJoin((a, b, c, d) => a.endlocation_id == d.id && d.is_use == "0") + .Where((a, b) => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID && !string.IsNullOrWhiteSpace(a.startlocation_id) + // 载具为空时 不校验载具当前位置是否与预任务起点相同 + && (string.IsNullOrEmpty(a.carry_id) || (!string.IsNullOrEmpty(a.carry_id) && a.startlocation_id == b.location_id))) + .OrderBy(a => new { priority = SqlFunc.Desc(a.priority), a.bill_code }) + .Select((a, b, c, d) => new WmsPretaskH + { + move_num = c.move_num, + third_eqp_type = c.third_eqp_type, + }, true); + + Logger.Information($"【GenTaskExecute】 获取到{sugarQueryable.Count()}条可执行的预任务..."); + if (sugarQueryable.Count() == 0) + return; + + //Logger.Information("【GenTaskExecute】 执行SQL: " + sugarQueryable.ToSqlString()); + + List preTasks = await sugarQueryable.ToListAsync(); + + + + //List executedPreTasks = await db.Queryable().Where(it => it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID && it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID).ToListAsync(); + + List agvElevatorTasks = preTasks + .Where(it => it.endlocation_code.StartsWith("DT", StringComparison.OrdinalIgnoreCase) && + !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)) + .ToList(); + + + var elePreTasks = preTasks.Where(it => it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); + var normalPreTasks = preTasks.Where(it => it.area_code != "B" && !agvElevatorTasks.Concat(elePreTasks).Select(x => x.endlocation_code).Contains(it.endlocation_code)).ToList(); + + + //Logger.Information("【GenTaskExecute】 电梯预任务elePreTasks:" + JsonConvert.SerializeObject(elePreTasks)); + //Logger.Information("【GenTaskExecute】 AGV/CTU/KIVA预任务normalPreTasks:" + JsonConvert.SerializeObject(normalPreTasks)); + //Logger.Information("【GenTaskExecute】 AGV电梯预任务agvElevatorTasks:" + JsonConvert.SerializeObject(agvElevatorTasks)); + + /* IEnumerable firstEleGrp = agvElevatorTasks.GroupBy(g => g.endlocation_code).Select(t => t.OrderBy(o => o.bill_code).FirstOrDefault()); + agvElevatorTasks = firstEleGrp?.ToList() ?? Enumerable.Empty().ToList()!; + */ + + //如果电梯任务,预Agv任务存在相同目标库位,删除Agv任务保证电梯任务先行 + var equalEndLocPreTasks = elePreTasks.Select(x => x.endlocation_code).Intersect(agvElevatorTasks.Select(x => x.endlocation_code)); + if (equalEndLocPreTasks.Any()) + { + Logger.Information("【GenTaskExecute】 执行:如果电梯任务,预Agv任务存在相同目标库位,删除Agv任务保证电梯任务先行 "); + agvElevatorTasks = agvElevatorTasks.Where(x => !equalEndLocPreTasks.Contains(x.endlocation_code)).ToList(); + } + preTasks = normalPreTasks.Concat(agvElevatorTasks).Concat(elePreTasks).ToList(); + + //一楼中储仓CTU + + List ids = preTasks.Select(x => x.id).Distinct().ToList(); + List? preTaskCodes = await db.Queryable().Where(it => ids.Contains(it.bill_id)).ToListAsync(); + if (preTasks.Count > 0) + { + //根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链,通过管理区ID + List> preTaskGroups = preTasks.GroupBy(g => g.area_code).ToList(); + List disTasks = new(); + List distaskCodes = new(); + foreach (IGrouping? itGroup in preTaskGroups) + { + List items = itGroup.Adapt>(); + for (int i = 0, cnt = items.Count; i < cnt; i++) + { + items[i].id = SnowflakeIdHelper.NextId(); + items[i].create_time = DateTime.Now; + items[i].status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID; + } + int moveNum = itGroup.First().move_num; + int itemsCount = items.Count; + int mod = itemsCount % moveNum > 0 ? (itemsCount / moveNum) + 1 : itemsCount / moveNum; + WmsDistaskH[] arrary = items.ToArray(); + //for (int i = 1; i <= mod; i++) + { + + if (moveNum >= 1) + { + List areaPreTasks = itGroup.ToList(); + + if (areaPreTasks.Any(x => x.third_eqp_type.ToEnum() != EnumTaskChainType.CTU)) + { + 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; + x.bill_code = $"{groupCode}-1"; + } + } + 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); + + int start = 0; + int end = Math.Min(itemsCount, moveNum); + List arrList = new(mod); + + while (start < itemsCount) + { + WmsDistaskH[] subArray = arrary[start..end]; + arrList.Add(subArray); + start = end; + end = Math.Min(end + moveNum, arrary.Length); + } + foreach (WmsDistaskH[] arr in arrList) + { + for (int j = 1, len = arr.Length; j <= len; j++) + { + arr[j - 1].groups = groupCode; + arr[j - 1].bill_code = $"{groupCode}-{j}"; + } + } + } + Logger.Information($"已生成任务执行编码"); + } + } + + if (preTaskCodes?.Count > 0) + { + foreach (WmsDistaskH disTask in items) + { + List curPreTaskCodes = preTaskCodes.FindAll(x => x.bill_id == disTask.pretask_id); + List curDisTaskCodes = curPreTaskCodes.Adapt>(); + curDisTaskCodes.ForEach(x => + { + x.id = SnowflakeIdHelper.NextId(); + x.bill_id = disTask.id; + x.create_time = DateTime.Now; + }); + distaskCodes.AddRange(curDisTaskCodes); + } + } + + disTasks.AddRange(items); + } + await db.Ado.BeginTranAsync(); + + int row = await db.Insertable(disTasks).ExecuteCommandAsync(); + Logger.Information("【GenTaskExecute】 插入任务执行表数据: " + JsonConvert.SerializeObject(disTasks)); + if (preTaskCodes?.Count > 0) + { + row = await db.Insertable(distaskCodes).ExecuteCommandAsync(); + Logger.Information("【GenTaskExecute】 插入任务执行条码表数据: " + JsonConvert.SerializeObject(disTasks)); + } + if (row > 0) + { + List preTaskIds = preTasks.Select(x => x.id).ToList(); + List preTaskBill_codes = preTasks.Select(x => x.bill_code).ToList(); + row = await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); + Logger.Information("【GenTaskExecute】 更改这些预任务执行状态为 已下发: " + JsonConvert.SerializeObject(preTaskBill_codes)); + } + + await db.Ado.CommitTranAsync(); + + Logger.Information("【GenTaskExecute】 预任务执行完成"); + Logger.Information($"【GenTaskExecute】_eleCtlCfg.Environment={_eleCtlCfg.Environment}"); + + + if (string.Equals(_eleCtlCfg.Environment, ElevatorConsts.EnvironmentName, StringComparison.OrdinalIgnoreCase)) + { + //呼梯操作 + //获取目标库位为电梯库位的任务 + Logger.Information("【GenTaskExecute】操作设备"); + + var agvDTTasks = disTasks.Where(it => it.endlocation_code.StartsWith("DT", StringComparison.OrdinalIgnoreCase) && + !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); + + foreach (var task in agvDTTasks) + { + ElevagorInfoQuery q = new() { endlocation_id = task.endlocation_id, taskCode = task.bill_code }; + Logger.Information($"【GenTaskExecute】呼梯时 根据任务单号获取电梯参数 {JsonConvert.SerializeObject(q)}"); + var e = await FindElevatorFromPars(q); + Logger.Information($"【GenTaskExecute】呼梯时 根据任务单号获取电梯结果 {JsonConvert.SerializeObject(e)}"); + + var tags = _eleCtlCfg.tags; + (int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) = await _elevatorControlService.GetElevatorStatus(e.elevator_code, tags, CancellationToken.None); + Logger.Information($"【GenTaskExecute】 电梯当前状态->系统状态:{sysStatus.ToEnum()},运行状态:{runStatus.ToEnum()},Agv状态:{agvStatus.ToEnum()},当前楼层:{floorNo},电梯占用状态{s_eleUseStatusDic[e.device_id]}"); + var curFloor = await GetRealFloor(e.end_floor); + + if (e != null && s_eleUseStatusDic[e.device_id] == (int)EnumElevatorUseStatus.空闲 && curFloor != floorNo) + { + task.device_id = e.device_id; + } + } + + Logger.Information($"【GenTaskExecute】呼梯任务数:{agvDTTasks.Count}"); + List<(string endlocation_code, string device_id, string id, int start_floor)> endLocCodes = agvDTTasks.Where(r => !string.IsNullOrEmpty(r.device_id)) + .Select(it => (it.endlocation_code, it.device_id, it.id, it.start_floor)).ToList(); + var callLiftCnt = endLocCodes?.Count ?? 0; + Logger.Information($"【GenTaskExecute】实际可呼梯任务数:{callLiftCnt}"); + + if (endLocCodes?.Count > 0) + { + if (endLocCodes.Select(x => x.device_id).All(x => !x.IsNullOrWhiteSpace())) + { + Logger.Information("【GenTaskExecute】呼梯操作"); + _ = CallingLanding(endLocCodes); + } + else + { + Logger.Error("【GenTaskExecute】呼梯失败,没有设备ID"); + return; + } + } + + //执行电梯任务 + List? elevatorTasks = disTasks.Where(it => it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); + + Logger.Information($"【GenTaskExecute】当前电梯任务数:{elevatorTasks?.Count ?? 0}"); + if (elevatorTasks?.Count > 0) + { + foreach (WmsDistaskH? elevatorTask in elevatorTasks) + { + ElevagorInfoQuery q = new() { endlocation_id = elevatorTask.endlocation_id, taskCode = elevatorTask.bill_code}; + Logger.Information($"【GenTaskExecute】执行电梯任务时 根据任务单号获取电梯参数 {JsonConvert.SerializeObject(q)}"); + var e = await FindElevatorFromPars(q); + Logger.Information($"【GenTaskExecute】执行电梯任务时 根据任务单号获取电梯结果 {JsonConvert.SerializeObject(e)}"); + if (e != null) + { + elevatorTask.device_id = e.device_id; + } + + _ = ExecuteTargetFloorTask(elevatorTask); + } + } + List agvTasks = disTasks.Where(it => !it.area_code.Contains("ELE", StringComparison.OrdinalIgnoreCase)).ToList(); + + if (agvTasks?.Count > 0) + { + Logger.Information($"【GenTaskExecute】Agv任务数量:{agvTasks.Count},taskCodes:{string.Join(",", agvTasks.Select(x => x.bill_code).Distinct())}"); + _ = AgvDispatch(agvTasks, agvCts.Token); + } + } + } + + + } + catch (Exception ex) when (ex is HttpRequestException hReqEx) + { + agvCts.Cancel(); + } + catch (Exception ex) + { + Logger.Error("【GenTaskExecute】任务执行时出现错误", ex); + Logger.Error(ex.StackTrace!); + await db.Ado.RollbackTranAsync(); + throw; + } + finally + { + _ = s_GenTaskExecute.Release(); + agvCts.Dispose(); + sw.Stop(); + Logger.Information($"【GenTaskExecute】 任务执行耗时{sw.ElapsedMilliseconds}毫秒"); + + } + } + + + /// + /// 获取电梯根据任务单号 + /// + /// + /// taskCode:子任务编号 + /// endlocation_id:目标库位ID + /// + /// + + public async Task FindElevatorFromPars(ElevagorInfoQuery input) + { + var whereExpable = Expressionable.Create() + .And((a, b, c) => a.enabled == 1); + + Logger.Information($"【FindElevatorFromPars】 {JsonConvert.SerializeObject(input)}"); + + if (!input.taskCode.IsNullOrEmpty()) + { + whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.taskCode), (a, b, c) => c.bill_code == input.taskCode); + } + if (!input.endlocation_id.IsNullOrEmpty()) + { + whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.endlocation_id), (a, b, c) => b.location_id == input.endlocation_id); + } + if (!input.startlocation_id.IsNullOrEmpty()) + { + whereExpable.AndIF(!SqlFunc.IsNullOrEmpty(input.startlocation_id), (a, b, c) => b.location_id == input.startlocation_id); + } + + ISugarQueryable queryable = _db.CopyNew().Queryable().InnerJoin((a, b) => a.id == b.bill_id) + .InnerJoin((a, b, c) => b.location_code == c.endlocation_code || b.location_code == c.startlocation_code) + .Where(whereExpable.ToExpression()) + .WhereIF(!SqlFunc.IsNullOrEmpty(input.sourceName) && SqlFunc.StartsWith("DT-R", input.sourceName), (a, b, c) => c.startpoint_code == input.sourceName) + .WhereIF(!SqlFunc.IsNullOrEmpty(input.sourceName) && SqlFunc.StartsWith("DT-C", input.sourceName), (a, b, c) => c.endpoint_code == input.sourceName) + .Select((a, b, c) => new WmsElevatorH + { + bill_code = c.bill_code, + device_id = a.elevator_id, + end_floor = c.end_floor + }, true); + + var ele = await queryable.FirstAsync(); + + Logger.Information($"【FindElevatorFromPars】 " + queryable.ToSqlString()); + + return ele; + + } + + + #region CTU + /// + /// 生成CTU任务执行 + /// + /// + [HttpPost] + public async Task CTUTaskExecute() + { + try + { + Dictionary indic = new Dictionary(); + indic.Add("SSX-021-005", new string[] { "YTCS", "CallCtuFullIn_CS05" }); + indic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11呼叫CTU" }); + indic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12呼叫CTU" }); + var db = _db.CopyNew(); + List CTUTasks = await db.Queryable() + .InnerJoin((a, b) => a.area_id == b.id) + .Where(a => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID) + .Where((a, b) => b.code == "B")//一楼中储仓 + .OrderBy(a => a.create_id) + .Select((a, b) => new WmsPretaskH + { + move_num = b.move_num, + third_eqp_type = b.third_eqp_type, + }, true).ToListAsync(); + + if (CTUTasks.Count == 0) + return; + + List TaskCodes = await db.Queryable().Where(it => CTUTasks.Select(p => p.id).ToList().Contains(it.bill_id)).ToListAsync(); + + //Logger.Information($@"【CTUTaskExecute】 获取任务TaskCodes: {JsonConvert.SerializeObject(TaskCodes)}"); + + var InTasks = CTUTasks.Where(a => a.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID).ToList(); + var OutTasks = CTUTasks.Where(a => a.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID || a.task_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFER_ID).ToList(); + + //Logger.Information($@"【CTUTaskExecute】 获取任务InTasks: {JsonConvert.SerializeObject(InTasks)}"); + //Logger.Information($@"【CTUTaskExecute】 获取任务OutTasks: {JsonConvert.SerializeObject(OutTasks)}"); + + var OriginDistaskHs = await db.Queryable() + .InnerJoin((a, b) => a.area_id == b.id) + .Where((a, b) => b.code == "B" && a.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID) + .OrderBy(a => a.bill_code) + .ToListAsync(); + + + //Logger.Information($@"【CTUTaskExecute】 OriginDistaskHs: {JsonConvert.SerializeObject(OriginDistaskHs)}"); + + + List DistaskHs = new List(); + List UpDistaskHs = new List(); + List DistaskCodes = new List(); + var inCtuExec = new List(); + var outCtuExec = new List(); + + foreach (var item in InTasks) + { + + + /* + if (indic.Keys.Contains(item.startlocation_code)) + { + var strs = indic.Where(p => p.Key == item.startlocation_code).First().Value; + bool flag = _redisData.HashExist(strs[0], strs[1]).Result; + if (!flag) + continue; + string data = _redisData.GetHash(strs[0], strs[1]).Result; + JObject? res = JsonConvert.DeserializeObject(data); + bool result = res != null && res["Value"] != null ? res.Value("Value") : false; + if (!result) + continue; + }*/ + + WmsDistaskH distaskH = item.Adapt(); + distaskH.id = SnowflakeIdHelper.NextId(); + distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID; + distaskH.is_chain = 1; + distaskH.create_time = DateTime.Now; + var billcode = GetBillCode(OriginDistaskHs, DistaskHs, distaskH); + distaskH.groups = billcode.Substring(0, billcode.Length - 2); + distaskH.bill_code = billcode; + var num = int.Parse(distaskH.bill_code.Substring(billcode.Length - 1, 1)); + Logger.Information($@"【CTUTaskExecute】 比对billcode:{num}和单次搬运数量move_num:{item.move_num},如果一致 会添加到inCtuExec"); + if (num == item.move_num) + { + distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID; + inCtuExec.Add(distaskH); + if (OriginDistaskHs.Where(p => p.groups == distaskH.groups).Any()) + { + OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); + + UpDistaskHs.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); + inCtuExec.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); + } + if (DistaskHs.Where(p => p.groups == distaskH.groups).Any()) + { + DistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); + inCtuExec.AddRange(DistaskHs.Where(p => p.groups == distaskH.groups).ToList()); + } + } + + + List preTaskCodes = TaskCodes.FindAll(x => x.bill_id == distaskH.pretask_id); + List disTaskCodes = preTaskCodes.Adapt>(); + disTaskCodes.ForEach(x => + { + x.id = SnowflakeIdHelper.NextId(); + x.bill_id = distaskH.id; + x.create_time = DateTime.Now; + }); + DistaskHs.Add(distaskH); + DistaskCodes.AddRange(disTaskCodes); + + } + foreach (var item in OutTasks) + { + WmsDistaskH distaskH = item.Adapt(); + distaskH.id = SnowflakeIdHelper.NextId(); + distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID; + distaskH.is_chain = 1; + distaskH.create_time = DateTime.Now; + var billcode = GetBillCode(OriginDistaskHs, DistaskHs, distaskH); + distaskH.groups = billcode.Substring(0, billcode.Length - 2); + distaskH.bill_code = billcode; + var num = int.Parse(distaskH.bill_code.Substring(billcode.Length - 1, 1)); + + Logger.Information($@"【CTUTaskExecute】 比对billcode:{num}和单次搬运数量move_num:{item.move_num},如果一致 会添加到outCtuExec"); + if (num == item.move_num) + { + distaskH.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID; + outCtuExec.Add(distaskH); + if (OriginDistaskHs.Where(p => p.groups == distaskH.groups).Any()) + { + OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); + + UpDistaskHs.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); + outCtuExec.AddRange(OriginDistaskHs.Where(p => p.groups == distaskH.groups).ToList()); + } + if (DistaskHs.Where(p => p.groups == distaskH.groups).Any()) + { + DistaskHs.Where(p => p.groups == distaskH.groups).ToList().ForEach(p => p.status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID); + outCtuExec.AddRange(DistaskHs.Where(p => p.groups == distaskH.groups).ToList()); + } + } + + List preTaskCodes = TaskCodes.FindAll(x => x.bill_id == distaskH.pretask_id); + List disTaskCodes = preTaskCodes.Adapt>(); + disTaskCodes.ForEach(x => + { + x.id = SnowflakeIdHelper.NextId(); + x.bill_id = distaskH.id; + x.create_time = DateTime.Now; + }); + DistaskHs.Add(distaskH); + DistaskCodes.AddRange(disTaskCodes); + } + await db.Ado.BeginTranAsync(); + int row = 0; + if (UpDistaskHs.Count > 0) + { + await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => UpDistaskHs.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); + } + if (DistaskHs.Count > 0) + { + row = await db.Insertable(DistaskHs).ExecuteCommandAsync(); + } + if (DistaskCodes.Count > 0) + { + await db.Insertable(DistaskCodes).ExecuteCommandAsync(); + } + if (row > 0) + { + List preTaskIds = DistaskHs.Select(x => x.pretask_id).ToList(); + await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); + } + await db.Ado.CommitTranAsync(); + //判断 + Logger.Information($"【CTUTaskExecute】 判断单据状态(status)是否为待执行 {JsonConvert.SerializeObject(DistaskHs)}"); + if (DistaskHs.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID).Any()) + { + var time = int.Parse(db.Queryable().Where(P => P.key == "getinterval").First().value); + timer = new Timer(TimerExec, null, TimeSpan.FromMinutes(time), TimeSpan.FromMinutes(time)); + } + //Logger.Information($@"【CTUTaskExecute】 可执行的CTU任务inCtuExec: {JsonConvert.SerializeObject(inCtuExec)}"); + if (inCtuExec.Count > 0) + { + Logger.Information($"开始执行CTU入库任务: {JsonConvert.SerializeObject(inCtuExec)}"); + //呼叫ctu入库 + // await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID }).Where(it => inCtuExec.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); + // await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => inCtuExec.Select(x => x.pretask_id).ToList().Contains(it.id)).ExecuteCommandAsync(); + CancellationTokenSource Ctu = new(); + + await CallingCTU(inCtuExec, Ctu.Token, 1); + Ctu.Dispose(); + } + //Logger.Information($@"【CTUTaskExecute】 可执行的CTU任务outCtuExec: {JsonConvert.SerializeObject(outCtuExec)}"); + if (outCtuExec.Count > 0) + { + Logger.Information($"开始执行CTU出库任务: {JsonConvert.SerializeObject(outCtuExec)}"); + //呼叫ctu出库 + // await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID }).Where(it => outCtuExec.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); + // await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => outCtuExec.Select(x => x.pretask_id).ToList().Contains(it.id)).ExecuteCommandAsync(); + CancellationTokenSource Ctu = new(); + await CallingCTU(outCtuExec, Ctu.Token, 0); + Ctu.Dispose(); + } + } + catch (Exception ex) + { + throw; + } + } + //判断生成bill_code + private string GetBillCode(List OriginDistaskH, List NewdistaskHs, WmsDistaskH distaskH) + { + string BillCode = string.Empty; + //入库 + if (distaskH.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID) + { + var orgdistaskHs = OriginDistaskH.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID && p.startpoint_id == distaskH.startpoint_id).ToList(); + var newdistaskHs = NewdistaskHs.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID && p.startpoint_id == distaskH.startpoint_id).ToList(); + if ((orgdistaskHs.Count + newdistaskHs.Count) == 0) + { + var groups = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE).Result; + BillCode = $"{groups}-1"; + } + else + { + var groups = orgdistaskHs.Count > 0 ? orgdistaskHs.First().groups : newdistaskHs.First().groups; + BillCode = $"{groups}-" + (orgdistaskHs.Count + newdistaskHs.Count + 1); + } + } + else if (distaskH.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID || distaskH.task_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFER_ID) + { + var orgdistaskHs = OriginDistaskH.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID && p.endpoint_id == distaskH.endpoint_id).ToList(); + var newdistaskHs = NewdistaskHs = OriginDistaskH.Where(p => p.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID && p.task_type == WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID && p.endpoint_id == distaskH.endpoint_id).ToList(); + if ((orgdistaskHs.Count + newdistaskHs.Count) == 0) + { + var groups = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE).Result; + BillCode = $"{groups}-1"; + } + else + { + var groups = orgdistaskHs.Count > 0 ? orgdistaskHs.First().groups : newdistaskHs.First().groups; + BillCode = $"{groups}-" + (orgdistaskHs.Count + newdistaskHs.Count + 1); + } + } + return BillCode; + } + private Timer? timer; + private async void TimerExec(object e) + { + try + { + SqlSugarClient db = _db.CopyNew(); + var list = db.Queryable().InnerJoin((a, b) => a.area_id == b.id) + .Where((a, b) => b.code == "B" && a.status == WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID) + .OrderBy(a => a.bill_code) + .ToList(); + var data = list.GroupBy(p => p.groups).Select(p => new + { + groups = p.Key, + time = p.Max(a => a.create_time) + + }).ToList(); + var date = DateTime.Now; + var time = int.Parse(db.Queryable().Where(P => P.key == "getinterval").First().value); + foreach (var item in data) + { + if (date.Subtract(item.time).Minutes >= time) + { + var execlist = list.Where(p => p.groups == item.groups).ToList(); + await db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => execlist.Select(p => p.id).ToList().Contains(it.id)).ExecuteCommandAsync(); + // await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => execlist.Select(x => x.pretask_id).ToList().Contains(it.id)).ExecuteCommandAsync(); + CancellationTokenSource Ctu = new(); + int type = execlist.First().task_type == WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID ? 1 : 0; + await CallingCTU(execlist, Ctu.Token, type); + Ctu.Dispose(); + } + } + } + catch (Exception ex) + { + } + finally + { + timer?.Dispose(); + } + + } + private async Task CallingCTU(List distaskHs, CancellationToken token, int type) + { + try + { + AgvRequestConfig requestCfg = App.Configuration.Build(); + string url = requestCfg.AgvRequestUrls.CreateTaskChainUrl; + var taskChainCodeDic = distaskHs.Where(t => !t.groups.IsNullOrWhiteSpace()).GroupBy(g => g.groups!) + .ToDictionary(x => x.Key, x => x.Select(it => new + { + taskCode = it.bill_code, + sourceName = it.startpoint_code, + targetName = it.endpoint_code, + containerCode = it.carry_code, + })); + foreach ((string k, object v) in taskChainCodeDic) + { + dynamic reqBody = new ExpandoObject(); + reqBody.taskChainCode = k; + reqBody.type = (int)EnumTaskChainType.CTU; + reqBody.sequential = false; + reqBody.taskChainPriority = 0; + reqBody.taskList = v; + reqBody.inOut = type; + Logger.Information($"【CallingCTU】 CTU任务下发 开始请求联核/task-chain/create接口 请求地址:{url} 请求参数:{JsonConvert.SerializeObject(reqBody)} type:{(type == 0 ? "CTU出库" : "CTU入库")}"); + dynamic respBody = await HttpClientHelper.PostStreamAsync(url, reqBody, token); + Logger.Information($"【CallingCTU】 CTU任务下发 接收到联核/task-chain/create接口信息:{respBody}"); + } + } + catch (Exception ex) + { + Logger.Information($"【CallingCTU】 CTU任务下发 请求联核/task-chain/create接口失败 异常信息:{ex}"); + } + } + #endregion + /// + /// 呼梯操作 + /// + /// + /// + private async Task CallingLanding(List<(string endlocation_code, string device_id, string id, int floorNO)> endLocCodes) + { + Logger.Information($"【CallingLanding】 开始呼梯操作............."); + try + { + foreach ((_, string devId, string disTaskId, int floorNO) in endLocCodes) + { + Logger.Information($"【CallingLanding】 devId:{devId}"); + if (!s_elevatorMap.TryGetValue(devId, out object? elevatorCode)) + { + continue; + } + + string? devName = elevatorCode.ToString(); + Logger.Information($"【CallingLanding】 电梯编号:{devName}"); + Logger.Information($"【CallingLanding】 当前:{devName.Match(@"\d+")}#梯"); + + await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.AGVControl, 1); + (int sysStatus, int runStatus, int curFloorNo, int doorStatus, int agvStatus) eleStatusMulti = (-1, -1, -1, -1, -1); + Logger.Information("【CallingLanding】 获取电梯AGV运行状态"); + if (!_elevatorAgvCtlStatusMap.TryGetValue(devId, out int agvCtlStatus) || agvCtlStatus != (int)EnumAgvStatus.AGV运行状态) + { + var tags = new[] { "SysStatus", "RunStatus", "FloorNo", "DoorStatus", "AGVStatus" }; + do + { + eleStatusMulti = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); + await Task.Delay(1000); + } while (eleStatusMulti.agvStatus != (int)EnumAgvStatus.AGV运行状态); + Logger.Information($"{devName.Match(@"\d+")}#, 当前Agv状态:{eleStatusMulti.agvStatus.ToEnum()}"); + _elevatorAgvCtlStatusMap[devId] = eleStatusMulti.agvStatus; + } + else + { + Logger.Information("【CallingLanding】 AGV运行状态:" + agvCtlStatus); + } + + Logger.Information($"【CallingLanding】 任务开始目标楼层为:{floorNO}"); + + int floorN = await GetRealFloor(floorNO); + //如果电梯在当前楼层则不呼梯 + if (floorN == eleStatusMulti.curFloorNo) + { + Logger.Information($"【CallingLanding】 {devName.Match(@"\d+")}#,在当前楼层,无需呼梯"); + continue; + } + + Logger.Information($"【CallingLanding】 实际目标楼层为:{floorN}"); + + WmsElevatorUnexecute elevatorQueueItem = new() + { + distask_id = disTaskId, + elevator_id = devId, + elevator_code = devName, + floor = floorN, //5代表4楼 + task_status = "待执行", + create_id = _userManager.UserId, + create_time = DateTime.Now + }; + List elevatorQueue = await _db.Queryable().Where(it => it.distask_id == disTaskId && it.task_status == "执行中").ToListAsync(); + + Logger.Information($"【CallingLanding】 电梯{devName}状态为{s_eleUseStatusDic[devId]}"); + Logger.Information($"【CallingLanding】 电梯{devName} 任务id{disTaskId} 执行中的队列数量为{elevatorQueue.Count}"); + if ((elevatorQueue.IsNull() || elevatorQueue.Count < 1) && floorN != eleStatusMulti.curFloorNo && s_eleUseStatusDic[devId] == (int)EnumElevatorUseStatus.空闲) + { + Logger.Information($"【CallingLanding】 判断当前电梯{devName.Match(@"\d+")}#梯 无任务在做执行呼梯"); + + elevatorQueueItem.task_status = "执行中"; + bool callLiftRes = await _elevatorControlService.CallLift(devName, floorN, CancellationToken.None); + string successful = "成功", fail = "失败"; + string callLiftResult = callLiftRes ? successful : fail; + Logger.Information($"{devName.Match(@"\d+")}#, 呼梯结果:{callLiftResult}"); + } + else + { + Logger.Information("【CallingLanding】 当前有任务在做,不会呼梯"); + } + + //如果当前电梯有任务在做,将当前呼梯任务放入待执行队列 + _ = await _db.Insertable(elevatorQueueItem).ExecuteCommandAsync(); + + Logger.Information("【CallingLanding】 呼梯任务执行完成"); + } + } + catch (Exception ex) + { + Logger.Error("【CallingLanding】 呼梯操作错误", ex); + Logger.Error($"【CallingLanding】 呼梯操作错误堆栈跟踪:{Environment.NewLine}{ex.StackTrace}"); + throw; + } + } + + /// + /// 执行到目标楼层电梯任务 + /// + /// + /// + public async Task ExecuteTargetFloorTask(WmsDistaskH disTask) + { + //收到放货确认通知,向电梯发送到3楼的指令 + Logger.Information($"开始执行电梯任务,任务ID:{disTask.id}"); + try + { + if (!s_elevatorMap.TryGetValue(disTask.device_id, out object? elevatorCode)) + { + Logger.Information($"开始执行电梯任务,没有取到设备{disTask.device_id}的 elevatorCode! s_elevatorMap: {JsonConvert.SerializeObject(s_elevatorMap)}"); + return; + } + string devName = s_elevatorMap[disTask.device_id]?.ToString() ?? _eleCtlCfg.DevName3; + + Logger.Information($"当前:{devName.Match(@"\d+")}#梯"); + + var tags = new[] { "SysStatus", "RunStatus", "FloorNo", "DoorStatus", "AGVStatus" }; + (int sysStatus, int runStatus, int curFloorNo, int doorStatus, int agvStatus) eleStatusMulti = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); + if (eleStatusMulti.agvStatus != (int)EnumAgvStatus.AGV运行状态) + { + _ = await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.AGVControl, 1); + } + + if (!_elevatorAgvCtlStatusMap.TryGetValue(disTask.id, out int agvCtlStatus) || agvCtlStatus != (int)EnumAgvStatus.AGV运行状态) + { + do + { + eleStatusMulti = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); + Logger.Information($"{devName.Match(@"\d+")}#, 当前Agv状态:{eleStatusMulti.agvStatus.ToEnum()}"); + await Task.Delay(1000); + } while (eleStatusMulti.agvStatus != (int)EnumAgvStatus.AGV运行状态 ); + Logger.Information($"{devName.Match(@"\d+")}#, 当前Agv状态:{eleStatusMulti.agvStatus.ToEnum()}"); + _elevatorAgvCtlStatusMap[disTask.id] = eleStatusMulti.agvStatus; + } + + int doorStatus = -1; + bool closeDoorRes = await _elevatorControlService.SendOpenCloseCmd(devName, 4); //向电梯发送前门关门指令 + Logger.Information($"关门结果:{closeDoorRes}"); + do + { + doorStatus = await _elevatorControlService.GetTagAsync(devName, ElevatorConsts.DoorStatus); + await Task.Delay(1000); + } while (doorStatus != 4); + Logger.Information($"当前门状态:{doorStatus}"); + + int floor = await GetRealFloor(disTask.end_floor); + + //电梯任务手动执行任务状态上报 + (int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) tuple = (-1, -1, -1, -1, -1); + tuple = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); + Logger.Information($"目标楼层:{floor} 当前楼层:{tuple.floorNo}"); + + Logger.Information($"开始呼梯 {devName}到{floor}"); + //发送到目标楼的指令 + dynamic result = await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.FloorExecute, floor); + + do + { + tuple = await _elevatorControlService.GetElevatorStatus(devName, tags, CancellationToken.None); + await Task.Delay(1000); + } while (tuple.sysStatus != 3 || tuple.runStatus != 0 || floor != tuple.floorNo); + + Logger.Information($"sysStatus:{tuple.sysStatus},runStatus:{tuple.runStatus},当前楼层floorNo:{tuple.floorNo},目标楼层disTask.end_floor={floor}"); + + if (tuple.sysStatus.ToEnum() == EnumSysStatus.正常状态 && tuple.runStatus.ToEnum() == EnumRunStatus.停梯) + { + Logger.Information($"disTask.require_id={disTask.require_id}"); + List disTaskIds = new() { disTask.id }; + var upInput = new { disTaskIds = disTask.id }; + TaskExecuteAfterUpInput teaUpInput = new() + { + disTaskIds = disTaskIds, + }; + await TaskExecuteAfter(teaUpInput); + TaskCompleUpInput tcUpInput = new() + { + disTaskIds = disTaskIds, + }; + await TaskComplate(tcUpInput); + + Logger.Information("电梯任务执行完成"); + } + + } + catch (Exception ex) + { + Logger.Error("执行到目标楼层电梯任务失败", ex); + throw; + } + } + /// + /// Agv调度 + /// + /// + /// + /// + private async Task AgvDispatch(List disTasks, CancellationToken token) + { + Logger.Information("【AgvDispatch】 Agv任务执行...."); + List kiva = new List(); + // 一楼中储仓 + kiva.Add("ZSSSXCTU02"); + kiva.Add("ZSSSXCTU01"); + List floor2 = new List(); + // 二楼暂存仓 + //floor2.Add("AS01"); + //floor2.Add("AS02"); + //floor2.Add("AX01"); + //floor2.Add("AX02"); + //调用AGV创建任务链接口 + try + { + AgvRequestConfig requestCfg = App.Configuration.Build(); + string url = requestCfg.AgvRequestUrls.CreateTaskChainUrl; + + Logger.Information($"【AgvDispatch】 Agv任务执行的disTasks:{JsonConvert.SerializeObject(disTasks)}"); + + var taskChainCodeDic = disTasks.Where(t => !t.groups.IsNullOrWhiteSpace()).GroupBy(g => g.groups!) + .ToDictionary(x => x.Key, x => x.Select(it => new + { + taskCode = it.bill_code, + sourceName = it.startpoint_code, + targetName = it.endpoint_code, + containerCode = it.carry_code, + shelfNumber = it.area_code == "E" ? it.carry_code : "" // 二楼暂存仓传料架 + })); + + Logger.Information($"【AgvDispatch】 Agv任务执行的taskChainCodeDic:{JsonConvert.SerializeObject(taskChainCodeDic)}"); + + foreach ((string k, object v) in taskChainCodeDic) + { + var typeflag = false; + var dis = disTasks.Where(p => p.groups == k).First(); + if (kiva.Contains(dis.startlocation_code) || kiva.Contains(dis.endlocation_code) + //|| floor2.Contains(dis.startlocation_code) || floor2.Contains(dis.endlocation_code) + ) + { + typeflag = true; + } + + // 如果管理区是E(二楼暂存仓和二楼缓存仓) 统一发KIVA + if (dis.area_code == "E") + { + typeflag = true; + } + + dynamic reqBody = new ExpandoObject(); + reqBody.taskChainCode = k; + reqBody.type = typeflag ? (int)EnumTaskChainType.KIVA : (int)EnumTaskChainType.AGV; + reqBody.sequential = false; + reqBody.taskChainPriority = 0; + reqBody.taskList = v; + reqBody.floor = dis.end_floor; + Logger.Information($"【AgvDispatch】 Agv任务执行 开始请求联核/task-chain/create接口 请求地址:{url} 请求参数:{JsonConvert.SerializeObject(reqBody)} "); + dynamic respBody = await HttpClientHelper.PostStreamAsync(url, reqBody, token); + Logger.Information($"【AgvDispatch】 Agv任务执行 接收到联核/task-chain/create接口信息:{respBody}"); + } + } + catch (Exception ex) + { + Logger.Information($"【AgvDispatch】 agv任务执行 请求联核/task-chain/create接口失败 异常信息:{ex}"); + throw; + } + } + + + + /// + /// 任务执行 + /// + /// + /// + [HttpPost] + public async Task TaskExecute(TaskExecuteUpInput input) + { + try + { + await _db.Ado.BeginTranAsync(); + + //更任务执行 + for (int i = 0, cnt = input.disTaskIds.Count; i < cnt; i++) + { + _ = input.EqpIds?.Count > 0 + ? await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID, device_id = input.EqpIds[i] }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync() + : await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); + //await _db.Updateable().SetColumns(it => setColVal).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); + } + List preTaskIds = await _db.Queryable().Where(it => input.disTaskIds.Contains(it.id)).Select(it => it.pretask_id).ToListAsync(); + if (preTaskIds.Count > 0) + { + //更预任务申请表状态 + _ = await _db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_START_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); + } + + await _db.Ado.CommitTranAsync(); + } + catch (Exception ex) + { + Logger.Error("任务执行失败", ex); + await _db.Ado.RollbackTranAsync(); + throw; + } + } + /// + /// 任务执行取操作返回(后续操作) + /// + /// + [HttpPost] + public async Task TaskExecuteAfter(TaskExecuteAfterUpInput input) + { + //更新任务执行表单据状态 + try + { + await _db.Ado.BeginTranAsync(); + + _ = await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_RUNING_ID, act_start_date = DateTime.Now }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); + //清空载具库位数据 + var carryAndLocIds = await _db.Queryable().Where(it => input.disTaskIds.Contains(it.id)).Select(it => new { it.carry_id, it.startlocation_id }).ToListAsync(); + if (carryAndLocIds?.Count > 0) + { + List carryIds = carryAndLocIds.Select(x => x.carry_id).ToList(); + _ = await _db.Updateable().SetColumns(it => new WmsCarryH { location_id = null, location_code = null }).Where(it => carryIds.Contains(it.id)).ExecuteCommandAsync(); + } + //更新起始库位,状态改为空闲、锁定状态,未锁定 + if (carryAndLocIds?.Count > 0) + { + List startLocationIds = carryAndLocIds.Select(x => x.startlocation_id).ToList(); + _ = await _db.Updateable().SetColumns(it => new BasLocation { is_use = ((int)EnumCarryStatus.空闲).ToString(), is_lock = 0 }).Where(it => startLocationIds.Contains(it.id)).ExecuteCommandAsync(); + } + + await _db.Ado.CommitTranAsync(); + + + } + catch (Exception ex) + { + Logger.Error("设备取返回操作失败", ex); + await _db.Ado.RollbackTranAsync(); + } + } + /// + /// 任务完成 + /// + /// + [HttpPost] + public async Task TaskComplate(TaskCompleUpInput input) + { + try + { + Logger.Information($"【TaskComplate】 开始执行TaskComplate"); + await _db.Ado.BeginTranAsync(); + + //更新任务执行表,单据状态为 完成 + _ = await _db.Updateable().SetColumns(it => new WmsDistaskH { status = WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID, act_end_date = DateTime.Now }).Where(it => input.disTaskIds.Contains(it.id)).ExecuteCommandAsync(); + List disTasks = await _db.Queryable().InnerJoin((a, b) => a.carry_id == b.id).Where(a => input.disTaskIds.Contains(a.id)).Select((a, b) => new WmsDistaskH { carry_status = b.carry_status }, true).ToListAsync(); + + Logger.Information($"【TaskComplate】 disTasks 值 {JsonConvert.SerializeObject(disTasks)}"); + if (disTasks?.Count > 0) + { + // 更新预任务申请表,单据状态为 已完成 + List preTaskIds = disTasks.Select(x => x.pretask_id).ToList(); + _ = await _db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); + + //更新电梯任务数量 + _ = await _db.Updateable().SetColumns(it => new WmsElevatorH { task_nums = it.task_nums - 1}).Where(it => disTasks.Select(x => x.area_code).Contains(it.area_code)).ExecuteCommandAsync(); + + // 更新任务数量 + _ = await _db.Updateable().SetColumns(it => new BasLocation { task_nums = it.task_nums - 1 }).Where(it => disTasks.Select(x => x.endlocation_code).Contains(it.location_code)).ExecuteCommandAsync(); + + + //更新载具,锁定状态为未锁定,更新载具的库位当前任务的目标库位 + + List<(string carry_id, string carry_status, string endlocation_id, string endlocation_code)> multiList = disTasks.Select(it => (it.carry_id, it.carry_status, it.endlocation_id, it.endlocation_code)).ToList(); + Dictionary locWhIdMap = await _db.Queryable().Where(it => multiList.Select(x => x.endlocation_id).Contains(it.id)).ToDictionaryAsync(it => it.id, it => it.wh_id); + Dictionary locTypeMap = await _db.Queryable().Where(it => multiList.Select(x => x.endlocation_id).Contains(it.id)).ToDictionaryAsync(it => it.id, it => it.is_type); + List carryIts = new(); + List carryCodeIts = new(); + List locIts = new(); + + Logger.Information($"【TaskComplate】 multiList 值 {JsonConvert.SerializeObject(multiList)}"); + for (int i = 0, cnt = multiList.Count; i < cnt; i++) + { + WmsCarryH carry = new() + { + id = multiList[i].carry_id, + is_lock = 0, + location_id = multiList[i].endlocation_id, + location_code = multiList[i].endlocation_code, + instock_time = DateTime.Now + }; + string endLocId = multiList[i].endlocation_id; + + WmsCarryH wmsCarryH = await _db.Queryable().Where(r => r.id == carry.id).FirstAsync(); + // 同步料架下的载具位置 + if (wmsCarryH != null && wmsCarryH.carrystd_id == WmsWareHouseConst.CARRY_LJSTD_ID) + { + List carrys = _db.Queryable() + .InnerJoin((a, b) => a.membercarry_id == b.id).Where((a, b) => a.carry_id == carry.id).Select((a, b) => b).ToList(); + carrys.ForEach(r => + { + r.location_id = carry.location_id; + r.location_code = carry.location_code; + carryIts.Add(r); + }); + } + + WmsCarryCode carryCode = new() + { + warehouse_id = locWhIdMap.ContainsKey(endLocId) ? locWhIdMap[endLocId].ToString() : "", + location_id = multiList[i].endlocation_id, + location_code = multiList[i].endlocation_code + }; + carryIts.Add(carry); + carryCodeIts.Add(carryCode); + + BasLocation loc = new() + { + id = multiList[i].endlocation_id, + is_lock = 0, + is_use = string.IsNullOrEmpty(multiList[i].carry_status) ? ((int)EnumCarryStatus.占用).ToString() : multiList[i].carry_status + }; + if (!string.IsNullOrEmpty(multiList[i].carry_status)) + { + loc.is_use = ((int)EnumCarryStatus.占用).ToString(); + } + + + + // 如果是出入库位 完成后解除占用 + string? is_type = locTypeMap.ContainsKey(endLocId) ? locTypeMap[endLocId].ToString() : ""; + if (is_type == ((int)EnumLocationType.出入库位).ToString()) + loc.is_use = ((int)EnumCarryStatus.空闲).ToString(); + + locIts.Add(loc); + } + + _ = await _db.Updateable(carryIts).UpdateColumns(it => new { it.is_lock, it.location_id, it.location_code, it.instock_time }).ExecuteCommandAsync(); + Logger.Information($"【TaskComplate】 更新载具 {JsonConvert.SerializeObject(carryIts)}"); + //更新条码的库位和仓库信息 + _ = await _db.Updateable(carryCodeIts).UpdateColumns(it => new { it.warehouse_id, it.location_id, it.location_code }).Where(it => multiList.Select(x => x.carry_id).Contains(it.carry_id)).ExecuteCommandAsync(); + //更新库位信息,使用状态为 使用,锁定状态为未锁定 + _ = await _db.Updateable(locIts).UpdateColumns(it => new { it.is_use, it.is_lock }).ExecuteCommandAsync(); + Logger.Information($"【TaskComplate】 更新库位 {JsonConvert.SerializeObject(locIts)}"); + /* var loginType= _userManager?.LoginType ?? "web"; + Log.Information($"_userManager.LoginType={loginType}"); + */ //更新业务主表的单据状态 + foreach (WmsDistaskH? dt in disTasks) + { + #region todo 移到service中 + // 销售出库 + if (dt.biz_type == WmsWareHouseConst.BIZTYPE_WMSSALERELEASE_ID) + { + // TODO 一楼工位放货完成后更新出库明细的实际出库数量 + if (dt.start_floor == 1 && dt.end_floor == 1) + { + WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == dt.carry_id).FirstAsync(); + await _db.Updateable().SetColumns(r => r.purchase_prqty == r.purchase_prqty + wmsCarryCode.codeqty).Where(r => r.id == dt.require_id).ExecuteCommandAsync(); + + CarryCodeUnbindInput carryCodeUnbindInput = new CarryCodeUnbindInput(); + carryCodeUnbindInput.carry_id = dt.carry_id; + await _wmsCarryUnbindService.CarryCodeUnbind(carryCodeUnbindInput, _db); + } + } + // 成品调拨入库 + else if (dt.biz_type == WmsWareHouseConst.BIZTYPE_WMSTRANSFERINSTOCK_ID) + { + if (dt.start_floor == 3 && dt.end_floor == 3) + { + WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == dt.carry_id).FirstAsync(); + await _db.Updateable().SetColumns(r => r.qty == r.qty + wmsCarryCode.codeqty).Where(r => r.id == dt.require_id).ExecuteCommandAsync(); + } + } + // 二楼物料呼叫任务结束后清空工位信息 + else if (dt.biz_type == "FloorCallMaterial") + { + await _db.Updateable().SetColumns(r => new WmsCarryH + { + work_station = "" + }).Where(r => r.id == dt.carry_id).ExecuteCommandAsync(); + + // require_code是任务单 + //string mo_task_code = dt.require_code; + } + else if (dt.biz_type == "erp_qtrk") + { + WmsMaterialTransfer wmsMaterialTransfer = await _db.Queryable().SingleAsync(x=>x.id==dt.source_id); + List wmsMaterialTransferDs = await _db.Queryable().Where(x=>x.bill_id==dt.source_id).ToListAsync(); + List materialIds = wmsMaterialTransferDs.Select(x=>x.material_id).Distinct().ToList(); + List unitCodes = wmsMaterialTransferDs.Select(x => x.unit_id).Distinct().ToList(); + List unitDatas = await _db.Queryable() + .LeftJoin((x, y) => x.Id == y.DictionaryTypeId) + .Where((x, y) => x.EnCode == DictConst.MeasurementUnit && unitCodes.Contains(y.EnCode)) + .Select((x,y)=>y) + .ToListAsync(); + + List ids = new List(); + ids.Add(wmsMaterialTransfer.create_id); + ids.Add(WmsWareHouseConst.AdministratorOrgId); + ids.Add(wmsMaterialTransfer.warehouse_instock); + ids.AddRange(materialIds); + ids.AddRange(unitDatas.Select(x=>x.Id).ToList()); + + List erpExtendFields = await _db.Queryable().Where(x=>ids.Contains(x.table_id)).ToListAsync(); + string erpCreateId = erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.create_id)?.user_id ?? ""; + ErpExtendField erpOrg = erpExtendFields.Find(x => x.table_id == (wmsMaterialTransfer.org_id ?? WmsWareHouseConst.AdministratorOrgId)); + string nowStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + + List> requestData = new List>(); + Dictionary erpRequestData = new Dictionary(); + erpRequestData.Add("approver",erpCreateId); + erpRequestData.Add("billmaker",erpCreateId); + erpRequestData.Add("corpoid",erpOrg.corpoid); + erpRequestData.Add("corpvid",erpOrg.corpvid); + erpRequestData.Add("creationtime",nowStr); + erpRequestData.Add("creator",erpCreateId); + erpRequestData.Add("ctrantypeid","0001H11000000000D30Z"); + erpRequestData.Add("cwarehouseid",erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.warehouse_instock)?.cotherwhid ?? ""); + erpRequestData.Add("cwhsmanagerid",""); + erpRequestData.Add("dbilldate",nowStr); + erpRequestData.Add("dmakedate",nowStr); + erpRequestData.Add("ntotalnum",wmsMaterialTransferDs.Sum(x=>x.qty)); + erpRequestData.Add("pk_group",erpOrg.pk_group); + erpRequestData.Add("pk_org",erpOrg.pk_org); + erpRequestData.Add("pk_org_v",erpOrg.pk_org_v); + erpRequestData.Add("vbillcode",wmsMaterialTransfer.bill_code); + erpRequestData.Add("vtrantypecode","4A-01"); + List> erpRequestDataDetails = new List>(); + foreach(WmsMaterialTransferD item in wmsMaterialTransferDs) + { + erpRequestDataDetails.Add(new Dictionary() + { + ["cbodytranstypecode"] = "4A-01", + ["cbodywarehouseid"] = erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.warehouse_instock)?.cotherwhid ?? "", + ["cgeneralbid"] = erpExtendFields.Find(x=>x.table_id==wmsMaterialTransfer.warehouse_instock)?.cotherwhid ?? "", + ["cgeneralbid"] = null, + ["cgeneralhid"] = null, + ["cmaterialoid"] = erpExtendFields.Find(x=>x.table_id==item.material_id)?.cmaterialoid ?? "", + ["cmaterialvid"] = erpExtendFields.Find(x=>x.table_id==item.material_id)?.cmaterialvid ?? "", + ["corpoid"] = erpOrg.corpoid, + ["corpvid"] = erpOrg.corpvid, + ["crowno"] = (wmsMaterialTransferDs.FindIndex(x=>x.id==item.id)+1) * 10, + ["cunitid"] = erpExtendFields.Find(x=>x.table_id==(unitDatas.Find(x=>x.EnCode==item.unit_id)?.Id ?? ""))?.cunitid ?? "", + ["cvendorid"] = "", + ["cvendorvid"] = "", + ["dbizdate"] = nowStr, + ["nnum"] = item.qty, + ["pk_group"] = erpOrg.pk_group, + ["pk_org"] = erpOrg.pk_org, + ["pk_org_v"] = erpOrg.pk_org_v, + ["csourcebillbid"] = item.erp_line_pk, + ["csourcebillhid"] = wmsMaterialTransfer.erp_pk, + ["vbatchcode"] = item.code_batch, + }); + } + erpRequestData.Add("dtls",erpRequestDataDetails); + requestData.Add(erpRequestData); + + ThirdWebapiRecord thirdWebapiRecord = new ThirdWebapiRecord(); + thirdWebapiRecord.id = SnowflakeIdHelper.NextId(); + thirdWebapiRecord.third_name = WmsWareHouseConst.BIP; + thirdWebapiRecord.name = "其它入库"; + thirdWebapiRecord.method = "POST"; + thirdWebapiRecord.url = WmsWareHouseConst.BIP_DOMAIN+"uapws/rest/generalin/save"; + thirdWebapiRecord.request_data = JsonConvert.SerializeObject(requestData); + thirdWebapiRecord.create_time = DateTime.Now; + + await _db.Insertable(thirdWebapiRecord).ExecuteCommandAsync(); + } + #endregion + + List disTaskCodes = await _db.Queryable().Where(it => it.bill_id == dt.id).ToListAsync(); + WareHouseUpInput upInput = new() { bizTypeId = dt.biz_type, requireId = dt.require_id!, require_code = dt.require_code!, source_id = dt.source_id! + , source_code = dt.source_code!, distaskCodes = disTaskCodes, carryIds = disTasks.Select(x => x.carry_id).ToList(), + bill_code = dt.bill_code!,area_code= dt.area_code!,wmsDistaskH = dt! + }; + + /*if (!_userManager?.LoginType.IsNullOrEmpty() ?? false) + { + upInput.loginType = "app"; + } + else + { + upInput.loginType = "web"; + }*/ + upInput.loginType = "web";//(!string.IsNullOrEmpty(_userManager?.LoginType) ? "app" : "web") ?? "web"; + if (dt.is_sign == 1 && dt.chain_type == "3") + { + await DoUpdate(upInput); + } + } + } + Logger.Information($"【TaskComplate】 任务操作完成提交事务 {string.Join(",", input.disTaskIds)}"); + await _db.Ado.CommitTranAsync(); + + Logger.Information($"【TaskComplate】 任务操作完成 {string.Join(",", input.disTaskIds)}"); + } + catch (Exception ex) + { + Logger.Error($"任务结束失败", ex); + Logger.Error($"任务结束失败堆栈异常", ex); + await _db.Ado.RollbackTranAsync(); + throw; + } + finally + { + _ = GenTaskExecute(); + } + } + /// + /// 出入库策略启用、禁用状态修改 + /// + /// + /// + [HttpPost] + public async Task ModifyPoliciesStatus(ModifyEnabledInput input) + { + async Task _updateStatus(ModifyEnabledInput input) where T : BaseEntity, IUpdatePoliciesStatus, new() + { + T obj = new() { status = input.status }; + _ = await _db.Updateable(obj).UpdateColumns(it => it.status).Where(it => input.ids.Contains(it.id)).ExecuteCommandAsync(); + } + + switch (input.strategyType) + { + case EnumInOutStockType.In: + await _updateStatus(input); + break; + case EnumInOutStockType.Out: + await _updateStatus(input); + break; + } + } + + /// + /// 生成预任务 + /// + /// 预任务集合 + /// 预任务编码集合 + /// + public async Task GenPreTask(List preTasks, List preTaskCodes, ISqlSugarClient dbConn = null) + { + try + { + await s_taskGenPreTask.WaitAsync(); + + var db = _db; + if (dbConn != null) + db = dbConn; + + //如果预任务出现起终库位相同,则删除对应预任务 + //modifiy by ly on 20230922 将当前预任务操作者设为四场管理员 + preTasks.ForEach(pt => + { + pt.org_id = WmsWareHouseConst.AdministratorOrgId; + pt.create_id = WmsWareHouseConst.AdministratorUserId; + }); + if (preTasks.FindAll(it => it.startlocation_id == it.endlocation_id)?.Count > 0) + { + _ = preTasks.RemoveAll(it => it.startlocation_id == it.endlocation_id); + } + List> grpList = preTasks.OrderBy(o => o.bill_code).GroupBy(g => g.carry_id).ToList(); + if (grpList?.Count > 0) + { + foreach (IGrouping? grp in grpList) + { + WmsPretaskH[] arr = grp.ToArray(); + if (arr.Length > 1) + { + WmsPretaskH[] subArr = arr[..^1]; + System.Array.ForEach(subArr, a => a.chain_type = "1"); + } + } + } + int row = await db.Insertable(preTasks).ExecuteCommandAsync(); + if (preTaskCodes?.Count > 0) + { + row = await db.Insertable(preTaskCodes).ExecuteCommandAsync(); + } + var eleP = preTasks.Find(x => x.area_code.Contains("ELE")); + if (eleP != null) + { + row = await db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(it => it.area_code == eleP.area_code).ExecuteCommandAsync(); + } + + // 累加终点库位任务数 + row = await db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1) + .Where(it => preTasks.Select(r => r.endlocation_id).Contains(it.id)).ExecuteCommandAsync(); + + return row > 0; + } + catch (Exception ex) + { + throw; + } + finally + { + s_taskGenPreTask.Release(); + } + } + + + /// + /// 生成预任务后续处理 + /// + /// + [NonAction] + public async Task GenInStockTaskHandleAfter(GenPreTaskUpInput input, Expression> setCarryColumnsExp, Expression> setLocaionColumbExp, ISqlSugarClient dbConn = null) + { + try + { + var db = _db; + if (dbConn != null) + db = dbConn; + + //根据生成的预任务,插入预任务操作记录 + if (input.PreTaskRecord != null) + { + _ = await db.Insertable(input.PreTaskRecord).ExecuteCommandAsync(); + } + if (input.PreTaskHandleCodes.Count > 0) + { + _ = await db.Insertable(input.PreTaskHandleCodes).ExecuteCommandAsync(); + } + //根据载具ID,更新是否锁定和赋值起始库位 + if (setCarryColumnsExp != null) + { + Expression> whereExp = input.CarryIds?.Count > 0 ? it => input.CarryIds.Contains(it.id) : it => it.id == input.CarryId; + _ = await db.Updateable().SetColumns(setCarryColumnsExp).Where(whereExp).ExecuteCommandAsync(); + } + if (input.CarryStartLocationId.IsNullOrWhiteSpace() == false) + { + _ = await db.Updateable().SetColumns(setLocaionColumbExp).Where(it => input.LocationIds.Contains(it.id)).ExecuteCommandAsync(); + } + //根据所有库位更新库位的锁定状态为“锁定” + if (setLocaionColumbExp != null && input.LocationIds?.Count > 0) + { + _ = await db.Updateable().SetColumns(setLocaionColumbExp).Where(it => input.LocationIds.Contains(it.id)).ExecuteCommandAsync(); + } + } + catch (Exception ex) + { + Logger.LogError("【GenInStockTaskHandleAfter】" + ex.Message); + Logger.LogError("【GenInStockTaskHandleAfter】" + ex.StackTrace); + throw; + } + } + + /// + /// 路径算法 + /// + /// + /// + /// + [NonAction] + public async Task> PathAlgorithms(string pStartId, string pEndId) + { + /* + var sp= await _db.Queryable().Where(it => it.id == pStartId).FirstAsync(); + var ep = await _db.Queryable().Where(it => it.id == pEndId).FirstAsync(); + + if (sp.area_code == "B" || ep.area_code == "B") + { + List Points = new List(); + var zp = await _db.Queryable().Where(it => it.point_code == "ZSCJZJD").FirstAsync(); + Points.Add(sp); + Points.Add(ep); + Points.Add(zp); + Points.ForEach(p => + { + p.area_code = zp.area_code; + p.area_id = zp.area_id; + }); + return Points; + }*/ + + + + List wmsPointHs = await _db.Queryable().Where(it => it.status == 1).ToListAsync(); + + List points = new List(); + + // 待验证 算法太慢 电梯不跑算法 电梯起终点仓库对应表 + BasLocation startlocation = await _db.Queryable().InnerJoin((a, b) => a.id == b.location_id).Where((a, b) => b.id == pStartId).FirstAsync(); + BasLocation endlocation = await _db.Queryable().InnerJoin((a, b) => a.id == b.location_id).Where((a, b) => b.id == pEndId).FirstAsync(); + + // 后续可整理成配置表 + // 3-1 + if (startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CP_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CPCRK_ID) + { + WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "2" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); + string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); + + points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-03-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-3-{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-1-{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-01-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); + } + //1-3 + else if (startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CPCRK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_CP_ID) + { + WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "2" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); + string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); + + points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-01-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-1-{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-3-{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-03-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); + } + // 2-4 + else if(startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_ZZXBK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_DMJC_ID) + { + WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "1" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); + string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); + + points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-02-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-02-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-04-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-04-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); + } + // 1-4 + else if(startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_F1BCK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_BCK_ID) + { + WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "1" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); + string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); + + points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-01-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-01-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-04-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-04-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); + } + // 4-2 + else if (startlocation.wh_id == WmsWareHouseConst.WAREHOUSE_BCK_ID && endlocation.wh_id == WmsWareHouseConst.WAREHOUSE_F2BCQ_ID) + { + WmsElevatorH wmsElevatorH = await _db.Queryable().Where(it => it.elevator_group == "1" && it.enabled == 1).OrderBy(r => r.task_nums).FirstAsync(); + string elevatorSno = wmsElevatorH.elevator_code.Replace("Elevator", ""); + + points.Add(wmsPointHs.Where(r => r.id == pStartId).First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-C-04-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-04-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-02-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.point_code == $"DT-R-02-0{elevatorSno}").First()); + points.Add(wmsPointHs.Where(r => r.id == pEndId).First()); + } + else + { + List roads = await _db.Queryable().Where(it => it.status == 1).ToListAsync(); + points = await LocPathCalcAlgorithms(pStartId, pEndId, roads); + } + + + Logger.Information($"起点{startlocation.location_code} 终点{endlocation.location_code} 获取到路径 {JsonConvert.SerializeObject(points)}"); + if (points.Count < 6) + { + throw new AppFriendlyException($"路径错误,需要检查路径配置{JsonConvert.SerializeObject(points)}", 500); + } + + //List wmsRoads = await _db.Queryable().Where(r => r.startpoint_id == pStartId).ToListAsync(); + //if (wmsRoads?.FindAll(x => x.endpoint_code != null && x.location_code.Contains("dt", StringComparison.OrdinalIgnoreCase))?.Count > 0) + //{ + + //} + + //List wmsRoads = await _db.Queryable().Where(r => r.startpoint_id == pStartId).ToListAsync(); + + + + + //try + //{ + // if (points?.FindAll(x => x.location_code != null && x.location_code.Contains("dt", StringComparison.OrdinalIgnoreCase))?.Count > 0) + // { + // //查询当前电梯点 + // List curEleDs = await _db.Queryable().InnerJoin((a, b) => a.bill_id == b.id).Where((a, b) => points.Select(x => x.id).Contains(a.point_id)).ToListAsync(); + // Logger.Information($"curEleDs==null :{curEleDs == null},curEleDs:{string.Join(",", curEleDs.Select(x => x.bill_id))}"); + // //如果有电梯点,则会进行电梯的均匀分配 + // if (curEleDs?.Count > 0) + // { + // //当前电梯 + // WmsElevatorH curEle = await _db.Queryable().SingleAsync(it => it.id == curEleDs.First().bill_id); + + // //同电梯组电梯 + // List sGpEle = await _db.Queryable().Where(it => it.elevator_group == curEle.elevator_group && it.id != curEle.id && it.enabled == 1).ToListAsync(); + // if (curEle.enabled == 0 && (sGpEle == null || sGpEle.Count < 1)) + // { + // throw new AppFriendlyException("电梯被禁用或未配置", 500); + // } + // if ((sGpEle == null || sGpEle.Count < 1) && curEle.enabled == 1) + // { + // return points; + // } + // if (sGpEle?.Count > 0 && curEle.enabled == 0) + // { + // return points; + // } + // //判断电梯组中各电梯任务数 + // if (sGpEle.FindAll(x => Math.Abs(x.task_nums - curEle.task_nums) % 2 == 1)?.Count > 0) + // { + // List sGpDs = await _db.Queryable().Where(it => it.bill_id == sGpEle.First().id).ToListAsync(); + // if (sGpDs?.Count > 0) + // { + // List sGpPoints = await _db.Queryable().Where(it => sGpDs.Select(x => x.point_id).Contains(it.id)).ToListAsync(); + // string sFEndId = sGpDs.Single(x => x.floor == curEleDs.First().floor).point_id; + // string eFStartId = sGpDs.Single(x => x.floor == curEleDs.Last().floor).point_id; + // List sFPoints = await LocPathCalcAlgorithms(pStartId, sFEndId, roads); + // List elePoints = new(); + // foreach (WmsElevatorD pt in curEleDs) + // { + // WmsPointH? elePoint = sGpPoints.Find(x => x.floor == pt.floor); + // if (elePoint != null) + // { + // elePoints.Add(elePoint); + // } + // } + // List eFPoints = await LocPathCalcAlgorithms(eFStartId, pEndId, roads); + // _ = elePoints.Remove(elePoints.First()); + // _ = elePoints.Remove(elePoints.Last()); + // points.Clear(); + // points.AddRange(sFPoints); + // points.AddRange(elePoints); + // points.AddRange(eFPoints); + // } + // } + + // } + // } + //} + //catch (Exception ex) + //{ + // Logger.Error("路径算法异常", ex); + // throw; + //} + + return points; + } + /// + /// 路径算法 当出现多个载具同时出库,可能需要进入电梯时 + /// + /// + /// + /// + /// + [NonAction] + public async Task> PathAlgorithmsEle(string pStartId, string pEndId, int ele) + { + List roads = await _db.Queryable().Where(it => it.status == 1).ToListAsync(); + List points = await LocPathCalcAlgorithms(pStartId, pEndId, roads); + try + { + if (points.FindAll(x => x.location_code != null && x.location_code.Contains("dt", StringComparison.OrdinalIgnoreCase))?.Count > 0) + { + //查询当前电梯点 + List curEleDs = await _db.Queryable().Where(it => points.Select(x => x.id).Contains(it.point_id)).ToListAsync(); + //如果有电梯点,则会进行电梯的均匀分配 + if (curEleDs?.Count > 0) + { + //当前电梯 + WmsElevatorH curEle = await _db.Queryable().SingleAsync(it => it.id == curEleDs.First().bill_id && it.enabled == 1); + + + //同电梯组电梯 + List sGpEle = await _db.Queryable().Where(it => it.elevator_group == curEle.elevator_group && it.id != curEle.id && it.enabled == 1).ToListAsync(); + + + if (curEle == null && sGpEle?.Count > 0) + { + throw new AppFriendlyException("电梯被禁用或未配置", 500); + } + if (ele % 2 == 1) + { + //判断电梯组中各电梯任务数 + if (curEle == null || sGpEle.FindAll(x => Math.Abs(x.task_nums - curEle.task_nums) % 2 == 1)?.Count > 0) + { + List sGpDs = await _db.Queryable().Where(it => it.bill_id == sGpEle.First().id).ToListAsync(); + if (sGpDs?.Count > 0) + { + List sGpPoints = await _db.Queryable().Where(it => sGpDs.Select(x => x.point_id).Contains(it.id)).ToListAsync(); + string sFEndId = sGpDs.Single(x => x.floor == curEleDs.First().floor).point_id; + string eFStartId = sGpDs.Single(x => x.floor == curEleDs.Last().floor).point_id; + List sFPoints = await LocPathCalcAlgorithms(pStartId, sFEndId, roads); + List elePoints = new(); + foreach (WmsElevatorD pt in curEleDs) + { + WmsPointH? elePoint = sGpPoints.Find(x => x.floor == pt.floor); + if (elePoint != null) + { + elePoints.Add(elePoint); + } + } + List eFPoints = await LocPathCalcAlgorithms(eFStartId, pEndId, roads); + _ = elePoints.Remove(elePoints.First()); + _ = elePoints.Remove(elePoints.Last()); + points.Clear(); + points.AddRange(sFPoints); + points.AddRange(elePoints); + points.AddRange(eFPoints); + } + } + } + + } + } + } + catch (Exception ex) + { + Logger.Error("路径算法异常", ex); + throw; + } + + return points; + } + #region PrivateMethods + + private async Task> LocPathCalcAlgorithms(string pStartId, string pEndId, List roads) + { + Logger.Information($"【LocPathCalcAlgorithms】开始执行 pStartId:{pStartId} pEndId:{pEndId}"); + Stopwatch stopwatch = Stopwatch.StartNew(); + #region dp + //List results = new(); + //var points = await _db.Queryable().ToListAsync(); + //Dictionary isVisited = roads.Select(x => x.startpoint_id).Distinct().ToDictionary(x => x, x => false); + + //List pointIds = new(); + //List codes = new(); + //Dp dp = new(); + //dynamic obj = new ExpandoObject(); + //obj.isArrivedEpoint = false; + //dp.DpFunc(roads, pointIds, isVisited, pStartId, pEndId, obj); + //foreach (var pid in pointIds) + //{ + // var point = points.Find(x => x.id == pid); + // if (point != null) + // { + // results.Add(point); + // } + //} + //return results; + #endregion + + #region dijkstra + List results = new(); + + try + { + 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]); + } + + 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) + { + WmsPointH? point = points?.Find(x => x.id == i); + if (point != null) + { + results.Add(point); + } + } + } + } + catch (Exception ex) + { + Logger.Error("路径算法错误", ex); + throw; + } + finally + { + stopwatch.Stop(); + Logger.Information($"【LocPathCalcAlgorithms】耗时{stopwatch.ElapsedMilliseconds}"); + } + + + return results; + #endregion + + } + /// + /// 获取匹配的最短路径节点 + /// + /// + /// + /// + /// + /// + /// + private void MatchPoint(List results, List roads, List shortestPathPoints, Dictionary isVisited, string pStartId, string pEndId) + { + List sRoads = roads.Where(x => x.startpoint_id == pStartId).ToList(); + for (int j = 0; j < sRoads.Count; j++) + { + WmsPointH? sPoint = shortestPathPoints.Find(x => x.id == sRoads[j].endpoint_id); + if (sPoint != null && isVisited.ContainsKey(sPoint.id) && !isVisited[sPoint.id] && sPoint.id != pEndId) + { + string code = sPoint.point_code; + results.Add(sPoint); + isVisited[sPoint.id] = true; + MatchPoint(results, roads, shortestPathPoints, isVisited, sPoint.id, pEndId); + } + } + } + /// + /// 根据终止节点获取最短路径顶点 + /// + /// + /// + /// + /// + private static void GetPoints(List pointIds, int[] prev, Stack result, int eIdx) + { + int index = eIdx; + while (index != 0) + { + result.Push(pointIds[index]); + index = prev[index]; + } + } + + private async Task Update(T1 entity, List entities) where T1 : BaseEntity, new() where T2 : BaseEntity, new() + { + bool isOk = false; + try + { + await _db.Ado.BeginTranAsync(); + isOk = await _db.Updateable(entity).ExecuteCommandHasChangeAsync(); + if (entities?.Count > 0) + { + int row = await _db.Storageable(entities).ExecuteCommandAsync(); + isOk = row > 0; + } + await _db.Ado.CommitTranAsync(); + } + catch (Exception) + { + await _db.Ado.RollbackTranAsync(); + } + return isOk; + } + + /// + /// 根据明细Id获取出入库明细信息 + /// + /// 出入库明细 + /// 明细输出类 + /// 出入库条码 + /// 明细Id + /// + private async Task FetchInOutStockCodesById(string billDId) + where TStockD : BaseEntity, new() + where TOutput : IInOutStockDetail, new() + where TStockCode : BaseEntity, IInOutStockCode, new() + { + Dictionary dic = await _dictionaryDataService.GetDictionaryByTypeId(WmsWareHouseConst.WMS_INSTOCK_D_BILL_STATUS_TYPEID); + List data = await _db.Queryable() + .Where(a => a.id == billDId) + .Select(a => new TOutput + { + CodeDetails = SqlFunc.Subqueryable().Where(it => it.bill_d_id == a.id).ToList(), + }, true) + .Mapper(it => + { + it.line_status = it.line_status != null && dic.ContainsKey(key: it.line_status) ? dic[it.line_status]?.ToString() : ""; + it.warehouse_id = _db.Queryable().Single(y => y.id == it.warehouse_id)?.whname ?? ""; + }) + .ToListAsync(); + + return data; + } + + + /// + /// 二楼kiva把料架送到下升降机后生成中储仓入库任务 + /// + /// 料架id + /// + + public async Task Floor2EmptyCarryCreateZZCPretask(string rackid) + { + try + { + List wmsCarryCodes = _db.Queryable().Where(r => r.carry_id == rackid).ToList(); int move_num = 6; string[] startlocations = new string[2] { WmsWareHouseConst.ZZCSSX111011, WmsWareHouseConst.ZZCSSX111012 }; BasLocation startLocation = null; - int index = 0; - foreach (WmsCarryD wmsCarryD in wmsCarryCodes) - { - await s_floor2CreatePretask.WaitAsync(); - - //入库取终点 //出库起点 - InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_ZC_ID, Size = 1 }; - List endLocations = await InStockStrategy(inStockStrategyInput); - if (endLocations.Count == 0) - { - Logger.LogWarning("没有可用的入库库位"); - continue; + int index = 0; + foreach (WmsCarryD wmsCarryD in wmsCarryCodes) + { + await s_floor2CreatePretask.WaitAsync(); + + //入库取终点 //出库起点 + InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_ZC_ID, Size = 1 }; + List endLocations = await InStockStrategy(inStockStrategyInput); + if (endLocations.Count == 0) + { + Logger.LogWarning("没有可用的入库库位"); + continue; } // 每6个重新获取一次起点 @@ -3142,277 +3145,277 @@ namespace Tnb.WarehouseMgr startLocation = await _db.Queryable().Where(r => startlocations.Contains(r.id)).OrderBy("is_lock, task_nums, location_code").FirstAsync(); } - BasLocation endLocation = endLocations[0]; - - WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.carry_code == wmsCarryD.membercarry_code); - await _db.Updateable().SetColumns(r => new WmsCarryH - { - location_id = startLocation.id, - location_code = startLocation.location_code, - }).Where(r => r.id == carry.id).ExecuteCommandAsync(); - - bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, endLocation); - if (!isMatch) - { - Logger.LogWarning("库位与载具规格不匹配"); - continue; - } - - CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput(); - commonCreatePretaskInput.startlocation_id = startLocation.id; - commonCreatePretaskInput.endlocation_id = endLocation.id; - commonCreatePretaskInput.carry_id = wmsCarryD.membercarry_id; - commonCreatePretaskInput.carry_code = wmsCarryD.membercarry_code; - commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID; - commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSEMPTYINSTOCK_ID; - commonCreatePretaskInput.isExcuteMission = false; - commonCreatePretaskInput.moduleConsts = ModuleConsts.MODULE_WMSEMPTYINSTOCK_ID; - - VisualDevModelDataCrInput visualDevInput = new VisualDevModelDataCrInput(); - visualDevInput.data = new Dictionary(); - visualDevInput.data.Add("bill_code", ""); - visualDevInput.data.Add("biz_type", WmsWareHouseConst.BIZTYPE_WMSEMPTYINSTOCK_ID); - visualDevInput.data.Add("carry_code", wmsCarryD.membercarry_code); - visualDevInput.data.Add("carry_id", wmsCarryD.membercarry_id); - //visualDevInput.data.Add("create_id", ""); - visualDevInput.data.Add("create_time", ""); - visualDevInput.data.Add("flowId", ""); - visualDevInput.data.Add("id", ""); - visualDevInput.data.Add("location_id", startLocation.id); - visualDevInput.data.Add("modify_id", ""); - visualDevInput.data.Add("modify_time", ""); - //visualDevInput.data.Add("org_id", ""); - visualDevInput.data.Add("status", WmsWareHouseConst.BILLSTATUS_ADD_ID); - visualDevInput.data.Add("warehouse_id", WmsWareHouseConst.WAREHOUSE_ZC_ID); - commonCreatePretaskInput.visualDevInput = visualDevInput; - - Logger.LogInformation($"【送满托到下升降区】 开始生成一楼CTU预任务 起点{startLocation.location_code} 终点{endLocation.location_code} 料箱 {wmsCarryD.membercarry_code}"); - - await _db.Updateable().SetColumns(it => it.is_lock == 1).Where(r => r.id == endLocations[0].id).ExecuteCommandAsync(); - await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(r => r.id == startLocation.id).ExecuteCommandAsync(); - - Entities.Dto.Outputs.Result res = await CommonCreatePretask(commonCreatePretaskInput); - if (res.code == JNPF.Common.Enums.HttpStatusCode.OK) - { - } - else - { - Logger.LogInformation($"【二楼kiva把料架送到下升降机后生成中储仓入库任务】 未成功生成预任务 起点{startLocation.location_code} 终点{endLocation.location_code} 料箱 {wmsCarryD.membercarry_code}"); + BasLocation endLocation = endLocations[0]; + + WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.carry_code == wmsCarryD.membercarry_code); + await _db.Updateable().SetColumns(r => new WmsCarryH + { + location_id = startLocation.id, + location_code = startLocation.location_code, + }).Where(r => r.id == carry.id).ExecuteCommandAsync(); + + bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, endLocation); + if (!isMatch) + { + Logger.LogWarning("库位与载具规格不匹配"); + continue; + } + + CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput(); + commonCreatePretaskInput.startlocation_id = startLocation.id; + commonCreatePretaskInput.endlocation_id = endLocation.id; + commonCreatePretaskInput.carry_id = wmsCarryD.membercarry_id; + commonCreatePretaskInput.carry_code = wmsCarryD.membercarry_code; + commonCreatePretaskInput.task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID; + commonCreatePretaskInput.biz_type = WmsWareHouseConst.BIZTYPE_WMSEMPTYINSTOCK_ID; + commonCreatePretaskInput.isExcuteMission = false; + commonCreatePretaskInput.moduleConsts = ModuleConsts.MODULE_WMSEMPTYINSTOCK_ID; + + VisualDevModelDataCrInput visualDevInput = new VisualDevModelDataCrInput(); + visualDevInput.data = new Dictionary(); + visualDevInput.data.Add("bill_code", ""); + visualDevInput.data.Add("biz_type", WmsWareHouseConst.BIZTYPE_WMSEMPTYINSTOCK_ID); + visualDevInput.data.Add("carry_code", wmsCarryD.membercarry_code); + visualDevInput.data.Add("carry_id", wmsCarryD.membercarry_id); + //visualDevInput.data.Add("create_id", ""); + visualDevInput.data.Add("create_time", ""); + visualDevInput.data.Add("flowId", ""); + visualDevInput.data.Add("id", ""); + visualDevInput.data.Add("location_id", startLocation.id); + visualDevInput.data.Add("modify_id", ""); + visualDevInput.data.Add("modify_time", ""); + //visualDevInput.data.Add("org_id", ""); + visualDevInput.data.Add("status", WmsWareHouseConst.BILLSTATUS_ADD_ID); + visualDevInput.data.Add("warehouse_id", WmsWareHouseConst.WAREHOUSE_ZC_ID); + commonCreatePretaskInput.visualDevInput = visualDevInput; + + Logger.LogInformation($"【送满托到下升降区】 开始生成一楼CTU预任务 起点{startLocation.location_code} 终点{endLocation.location_code} 料箱 {wmsCarryD.membercarry_code}"); + + await _db.Updateable().SetColumns(it => it.is_lock == 1).Where(r => r.id == endLocations[0].id).ExecuteCommandAsync(); + await _db.Updateable().SetColumns(it => it.task_nums == it.task_nums + 1).Where(r => r.id == startLocation.id).ExecuteCommandAsync(); + + Entities.Dto.Outputs.Result res = await CommonCreatePretask(commonCreatePretaskInput); + if (res.code == JNPF.Common.Enums.HttpStatusCode.OK) + { + } + else + { + Logger.LogInformation($"【二楼kiva把料架送到下升降机后生成中储仓入库任务】 未成功生成预任务 起点{startLocation.location_code} 终点{endLocation.location_code} 料箱 {wmsCarryD.membercarry_code}"); } index++; - + s_floor2CreatePretask.Release(); - } - return true; - } - catch(Exception ex) - { - Logger.LogInformation($"【二楼kiva把料架送到下升降机后生成中储仓入库任务】:{ex}"); - s_floor2CreatePretask.Release(); - return false; - } - finally - { - s_floor2CreatePretask.Release(); - } - } - #endregion - - - #region 通用接口 - - /// - /// 生成预任务接口 CTU需要传task_type - /// - /// - /// - [HttpPost, NonUnify, AllowAnonymous] - public async Task CommonCreatePretask(CommonCreatePretaskInput input, ISqlSugarClient dbConn = null) - { - var db = _db; - if (dbConn != null) - db = dbConn; - - - { - await s_taskCommonCreatePretask.WaitAsync(); - Logger.LogInformation($"【createPretask】 接收到请求 参数:{JsonConvert.SerializeObject(input)}"); - try - { - - WmsPointH? sPoint = null; - WmsPointH? ePoint = null; - - if (!string.IsNullOrEmpty(input.startlocation_id)) - { - sPoint = await db.Queryable().FirstAsync(it => it.location_id == input.startlocation_id); - } - if (!string.IsNullOrEmpty(input.endlocation_id)) - { - ePoint = await db.Queryable().FirstAsync(it => it.location_id == input.endlocation_id); - } - - if (sPoint == null) - { - throw new Exception($"库位{input.startlocation_id} 的起点点位未维护"); - } - if (ePoint == null) - { - throw new Exception($"库位{input.endlocation_id} 的终点点位未维护"); - } - - - List points = new List(); - if (sPoint.area_code != ePoint.area_code) - { - points = await PathAlgorithms(sPoint.id, ePoint.id); - if (points.Count <= 2) - { - throw new AppFriendlyException($"sPoint {sPoint.point_code} ePoint{ePoint.point_code}该路径不存在", 500); - } - } - else - { - points.Add(sPoint); - points.Add(ePoint); - } - - //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) - WmsPretaskH preTask = null; - string bill_code = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE); - - string carry_id = ""; - string carry_code = ""; - WmsCarryH wmsCarryH = null; - - - if (!string.IsNullOrEmpty(input.carry_id) && !string.IsNullOrEmpty(input.carry_code)) - { - carry_id = input.carry_id; - carry_code = input.carry_code; - } - // 如果指定了carry_id - else if (!string.IsNullOrEmpty(input.carry_id)) - { - wmsCarryH = db.Queryable().Where(r => r.id == input.carry_id).First(); - carry_id = wmsCarryH.id; - carry_code = wmsCarryH.carry_code; - } - // carry_code - else if (!string.IsNullOrEmpty(input.carry_code)) - { - wmsCarryH = db.Queryable().Where(r => r.carry_code == input.carry_code).First(); - carry_id = wmsCarryH.id; - carry_code = wmsCarryH.carry_code; - } - - - if (input.visualDevInput != null) - { - //在线开发moduleConsts - VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(input.moduleConsts, true); - await _runService.Create(templateEntity, input.visualDevInput); - input.require_id = input.visualDevInput.data["ReturnIdentity"].ToString() ?? ""; - input.require_code = input.visualDevInput.data["bill_code"].ToString() ?? ""; - } - - - List preTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it => - { - WmsPointH? sPoint = it.FirstOrDefault(); - WmsPointH? ePoint = it.LastOrDefault(); - - preTask = new() - { - org_id = _userManager.User?.OrganizeId, - startlocation_id = sPoint?.location_id!, - startlocation_code = sPoint?.location_code!, - endlocation_id = ePoint?.location_id!, - endlocation_code = ePoint?.location_code!, - start_floor = sPoint?.floor.ToString(), - end_floor = ePoint?.floor.ToString(), - startpoint_id = sPoint?.id!, - startpoint_code = sPoint?.point_code!, - endpoint_id = ePoint?.id!, - endpoint_code = ePoint?.point_code!, - bill_code = bill_code, - status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, - biz_type = !string.IsNullOrEmpty(input.biz_type) ? input.biz_type : "", - task_type = !string.IsNullOrEmpty(input.task_type) ? input.task_type : "", - carry_id = carry_id, - carry_code = carry_code, - area_id = sPoint?.area_id!, - area_code = it.Key, - source_id = input.source_id, - source_code = input.source_code, - require_id = input.require_id, - require_code = input.require_code, - create_id = _userManager.UserId, - create_time = DateTime.Now - }; - - return preTask; - }).ToList(); - //更新页面 - //赋值签收状态 - - Logger.LogInformation($"【CommonCreatePretask】 开始执行 GenPreTask {JsonConvert.SerializeObject(preTasks)}"); - - bool result = await GenPreTask(preTasks, null!, db); - Logger.LogInformation($"【CommonCreatePretask】 GenPreTask 结果 {result}"); - if (result) - { - GenPreTaskUpInput preTaskUpInput = new() - { - RquireId = input.require_id, - CarryId = carry_id, - CarryStartLocationId = points.FirstOrDefault()!.location_id!, - CarryStartLocationCode = points.FirstOrDefault()!.location_code!, - LocationIds = points.Select(x => x.location_id).ToList()! - }; - - //根据载具移入Id,回更单据状态 - _ = await db.Updateable().SetColumns(it => new WmsMoveInstock { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == preTaskUpInput.RquireId).ExecuteCommandAsync(); - - - Expression> wmsCarryHChangeExp = a => new WmsCarryH { is_lock = 1 }; - - if (input.isChangeCarryLoc2StartLoc) - { - wmsCarryHChangeExp = a => new WmsCarryH { is_lock = 1, location_id = preTaskUpInput.CarryStartLocationId, location_code = preTaskUpInput.CarryStartLocationCode }; - } - - await GenInStockTaskHandleAfter(preTaskUpInput, - wmsCarryHChangeExp, - it => new BasLocation { is_lock = 1 }, db); - Logger.LogInformation($"【CommonCreatePretask】 成功生成预任务:{preTasks.First().bill_code}"); - return await ToApiResult(JNPF.Common.Enums.HttpStatusCode.OK, "成功"); - } - else - { - throw new AppFriendlyException("生成预任务失败(可能是因为预任务起点与终点相同)", 500); - } - } - catch (Exception ex) - { - Logger.LogInformation($"【CommonCreatePretask】 {ex.Message}"); - Logger.LogInformation($"【CommonCreatePretask】 {ex.StackTrace}"); - if (!db.Ado.Transaction.IsNull()) - await db.Ado.CommitTranAsync(); - return await ToApiResult(JNPF.Common.Enums.HttpStatusCode.InternalServerError, ex.Message); - } - finally - { - s_taskCommonCreatePretask.Release(); - if (input.isExcuteMission) - { - GenTaskExecute(); - } - } - } - } - #endregion - - } -} + } + return true; + } + catch(Exception ex) + { + Logger.LogInformation($"【二楼kiva把料架送到下升降机后生成中储仓入库任务】:{ex}"); + s_floor2CreatePretask.Release(); + return false; + } + finally + { + s_floor2CreatePretask.Release(); + } + } + #endregion + + + #region 通用接口 + + /// + /// 生成预任务接口 CTU需要传task_type + /// + /// + /// + [HttpPost, NonUnify, AllowAnonymous] + public async Task CommonCreatePretask(CommonCreatePretaskInput input, ISqlSugarClient dbConn = null) + { + var db = _db; + if (dbConn != null) + db = dbConn; + + + { + await s_taskCommonCreatePretask.WaitAsync(); + Logger.LogInformation($"【createPretask】 接收到请求 参数:{JsonConvert.SerializeObject(input)}"); + try + { + + WmsPointH? sPoint = null; + WmsPointH? ePoint = null; + + if (!string.IsNullOrEmpty(input.startlocation_id)) + { + sPoint = await db.Queryable().FirstAsync(it => it.location_id == input.startlocation_id); + } + if (!string.IsNullOrEmpty(input.endlocation_id)) + { + ePoint = await db.Queryable().FirstAsync(it => it.location_id == input.endlocation_id); + } + + if (sPoint == null) + { + throw new Exception($"库位{input.startlocation_id} 的起点点位未维护"); + } + if (ePoint == null) + { + throw new Exception($"库位{input.endlocation_id} 的终点点位未维护"); + } + + + List points = new List(); + if (sPoint.area_code != ePoint.area_code) + { + points = await PathAlgorithms(sPoint.id, ePoint.id); + if (points.Count <= 2) + { + throw new AppFriendlyException($"sPoint {sPoint.point_code} ePoint{ePoint.point_code}该路径不存在", 500); + } + } + else + { + points.Add(sPoint); + points.Add(ePoint); + } + + //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) + WmsPretaskH preTask = null; + string bill_code = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE); + + string carry_id = ""; + string carry_code = ""; + WmsCarryH wmsCarryH = null; + + + if (!string.IsNullOrEmpty(input.carry_id) && !string.IsNullOrEmpty(input.carry_code)) + { + carry_id = input.carry_id; + carry_code = input.carry_code; + } + // 如果指定了carry_id + else if (!string.IsNullOrEmpty(input.carry_id)) + { + wmsCarryH = db.Queryable().Where(r => r.id == input.carry_id).First(); + carry_id = wmsCarryH.id; + carry_code = wmsCarryH.carry_code; + } + // carry_code + else if (!string.IsNullOrEmpty(input.carry_code)) + { + wmsCarryH = db.Queryable().Where(r => r.carry_code == input.carry_code).First(); + carry_id = wmsCarryH.id; + carry_code = wmsCarryH.carry_code; + } + + + if (input.visualDevInput != null) + { + //在线开发moduleConsts + VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(input.moduleConsts, true); + await _runService.Create(templateEntity, input.visualDevInput); + input.require_id = input.visualDevInput.data["ReturnIdentity"].ToString() ?? ""; + input.require_code = input.visualDevInput.data["bill_code"].ToString() ?? ""; + } + + + List preTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it => + { + WmsPointH? sPoint = it.FirstOrDefault(); + WmsPointH? ePoint = it.LastOrDefault(); + + preTask = new() + { + org_id = _userManager.User?.OrganizeId, + startlocation_id = sPoint?.location_id!, + startlocation_code = sPoint?.location_code!, + endlocation_id = ePoint?.location_id!, + endlocation_code = ePoint?.location_code!, + start_floor = sPoint?.floor.ToString(), + end_floor = ePoint?.floor.ToString(), + startpoint_id = sPoint?.id!, + startpoint_code = sPoint?.point_code!, + endpoint_id = ePoint?.id!, + endpoint_code = ePoint?.point_code!, + bill_code = bill_code, + status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, + biz_type = !string.IsNullOrEmpty(input.biz_type) ? input.biz_type : "", + task_type = !string.IsNullOrEmpty(input.task_type) ? input.task_type : "", + carry_id = carry_id, + carry_code = carry_code, + area_id = sPoint?.area_id!, + area_code = it.Key, + source_id = input.source_id, + source_code = input.source_code, + require_id = input.require_id, + require_code = input.require_code, + create_id = _userManager.UserId, + create_time = DateTime.Now + }; + + return preTask; + }).ToList(); + //更新页面 + //赋值签收状态 + + Logger.LogInformation($"【CommonCreatePretask】 开始执行 GenPreTask {JsonConvert.SerializeObject(preTasks)}"); + + bool result = await GenPreTask(preTasks, null!, db); + Logger.LogInformation($"【CommonCreatePretask】 GenPreTask 结果 {result}"); + if (result) + { + GenPreTaskUpInput preTaskUpInput = new() + { + RquireId = input.require_id, + CarryId = carry_id, + CarryStartLocationId = points.FirstOrDefault()!.location_id!, + CarryStartLocationCode = points.FirstOrDefault()!.location_code!, + LocationIds = points.Select(x => x.location_id).ToList()! + }; + + //根据载具移入Id,回更单据状态 + _ = await db.Updateable().SetColumns(it => new WmsMoveInstock { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == preTaskUpInput.RquireId).ExecuteCommandAsync(); + + + Expression> wmsCarryHChangeExp = a => new WmsCarryH { is_lock = 1 }; + + if (input.isChangeCarryLoc2StartLoc) + { + wmsCarryHChangeExp = a => new WmsCarryH { is_lock = 1, location_id = preTaskUpInput.CarryStartLocationId, location_code = preTaskUpInput.CarryStartLocationCode }; + } + + await GenInStockTaskHandleAfter(preTaskUpInput, + wmsCarryHChangeExp, + it => new BasLocation { is_lock = 1 }, db); + Logger.LogInformation($"【CommonCreatePretask】 成功生成预任务:{preTasks.First().bill_code}"); + return await ToApiResult(JNPF.Common.Enums.HttpStatusCode.OK, "成功"); + } + else + { + throw new AppFriendlyException("生成预任务失败(可能是因为预任务起点与终点相同)", 500); + } + } + catch (Exception ex) + { + Logger.LogInformation($"【CommonCreatePretask】 {ex.Message}"); + Logger.LogInformation($"【CommonCreatePretask】 {ex.StackTrace}"); + if (!db.Ado.Transaction.IsNull()) + await db.Ado.CommitTranAsync(); + return await ToApiResult(JNPF.Common.Enums.HttpStatusCode.InternalServerError, ex.Message); + } + finally + { + s_taskCommonCreatePretask.Release(); + if (input.isExcuteMission) + { + GenTaskExecute(); + } + } + } + } + #endregion + + } +} From 69b0d1e6eda5a60f16a13f3036672fd5c9fcbace Mon Sep 17 00:00:00 2001 From: zhou keda <1315948824@qq.com> Date: Mon, 22 Jul 2024 12:51:15 +0800 Subject: [PATCH 3/6] bug --- ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs index 87407b95..e149b0a6 100644 --- a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs @@ -778,7 +778,7 @@ namespace Tnb.ProductionMgr string[] tables = new[] { "base_dictionarydata", "bas_material" }; var erpdb = _db.AsTenant().GetConnection("erpdb"); List list = await erpdb.Queryable().ToListAsync(); - List bomList = await erpdb.Queryable().OrderBy(x=>x.BOMID).OrderBy(x=>x.ROWNO).ToListAsync(); + List bomList = await erpdb.Queryable().ToListAsync(); List erpExtendFields = await _db.Queryable() .Where(x => tables.Contains(x.table_name)).ToListAsync(); Dictionary unitDic = await _db.Queryable() From 46ef173bb585e2dfd3d3b05c2293c8ee6cfabeea Mon Sep 17 00:00:00 2001 From: zhou keda <1315948824@qq.com> Date: Mon, 22 Jul 2024 12:54:53 +0800 Subject: [PATCH 4/6] bug --- .../Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs index bbefd45c..3f2b56bf 100644 --- a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/ErpEntity/BomList.cs @@ -39,6 +39,6 @@ namespace Tnb.ProductionMgr.Entities.Entity.ErpEntity /// public string MODIFIEDTIME { get; set; } - public int ROWNO { get; set; } + // public int ROWNO { get; set; } } } \ No newline at end of file From ad604ac5ab01b8005c6e9dc1a33c29d1565164bc Mon Sep 17 00:00:00 2001 From: zhou keda <1315948824@qq.com> Date: Mon, 22 Jul 2024 17:04:38 +0800 Subject: [PATCH 5/6] bug --- .../Tnb.ProductionMgr/PrdMoTaskService.cs | 16 ++++++++-------- .../Tnb.ProductionMgr/TimeWorkService.cs | 7 ++++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs b/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs index c5a790c3..dde3c67c 100644 --- a/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs @@ -2150,14 +2150,14 @@ namespace Tnb.ProductionMgr List> erpRequestDataDetails = new List>(); erpRequestDataDetails.Add(new Dictionary() { - ["bbchkflag"] = "N", - ["bbhasbckfled"] = "N", - ["bbhaspicked"] = "N", - ["bbinstock"] = "N", - ["bbisempass"] = "N", - ["bbotherreject"] = "N", - ["bbsetmark"] = "N", - ["bbstockbycheck"] = "N", + ["bbchkflag"] = false, + ["bbhasbckfled"] = false, + ["bbhaspicked"] = false, + ["bbinstock"] = false, + ["bbisempass"] = false, + ["bbotherreject"] = false, + ["bbsetmark"] = false, + ["bbstockbycheck"] = false, ["cbastunitid"] = "", ["cbbomversionid"] = "", ["cbdeptid"] = "", diff --git a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs index e149b0a6..1bb08ab3 100644 --- a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs @@ -773,8 +773,10 @@ namespace Tnb.ProductionMgr [AllowAnonymous] public async Task SyncBaseData() { + string msg = ""; try { + int editCount = 0; string[] tables = new[] { "base_dictionarydata", "bas_material" }; var erpdb = _db.AsTenant().GetConnection("erpdb"); List list = await erpdb.Queryable().ToListAsync(); @@ -869,6 +871,7 @@ namespace Tnb.ProductionMgr .SetColumns(x => x.erp_modify_time == erpBdMaterial.MODIFIEDTIME) .Where(x => x.id == materialId) .ExecuteCommandAsync(); + editCount += updateRow; if (updateRow <= 0) { Log.Error($"未找到物料{erpBdMaterial.ID},跳过此条数据"); @@ -1019,6 +1022,8 @@ namespace Tnb.ProductionMgr await _db.Insertable(insertBasEbomDs).ExecuteCommandAsync(); await _db.Ado.CommitTranAsync(); + msg = $"新增物料${insertMaterial.Count}条,修改物料{editCount}条"; + Log.Information(msg); } catch (Exception e) { @@ -1027,7 +1032,7 @@ namespace Tnb.ProductionMgr throw Oops.Bah(e.Message); } - return "成功"; + return msg; } /// From 0a8cdfddbb8cb22f3a17784b2ff98da8e4796c20 Mon Sep 17 00:00:00 2001 From: zhou keda <1315948824@qq.com> Date: Mon, 22 Jul 2024 17:47:06 +0800 Subject: [PATCH 6/6] bug --- ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs | 2 +- ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs b/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs index aceff700..964e1722 100644 --- a/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs @@ -424,7 +424,7 @@ namespace Tnb.ProductionMgr .LeftJoin((a, b, c, d, e, f, g, h) => a.material_id == h.output_material_id && a.eqp_id == h.equip_id && a.mold_id == h.molds_id && h.enabled == 1) .LeftJoin((a, b, c, d, e, f, g, h, i) => a.process_id == i.process_id && i.enabled == 1 && a.schedule_type==1) .LeftJoin((a, b, c, d, e, f, g, h, i, j) => a.mo_id == j.id) - .LeftJoin((a, b, c, d, e, f, g, h, i, j, k) => a.material_id == k.material_id && k.auxiliary_unit_id == "kg") + .LeftJoin((a, b, c, d, e, f, g, h, i, j, k) => a.material_id == k.material_id && k.auxiliary_unit_id == "KGM") .LeftJoin((a, b, c, d, e, f, g, h, i, j, k, l) => a.eqp_id == l.equip_id && l.enabled == 1 && l.label_name.Contains("允许称重"))//注塑空满箱请求 // .Where((a, b) => a.workstation_id == input.stationId) .Where((a, b) => a.worker_id == _userManager.UserId && (a.schedule_type==1 || (a.schedule_type==2 && a.parent_id!=null))) diff --git a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs index 1bb08ab3..566f371c 100644 --- a/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/TimeWorkService.cs @@ -827,6 +827,7 @@ namespace Tnb.ProductionMgr material_standard = erpBdMaterial.MATERIALTYPE, category_id = "[\"CGJCJ\"]", unit_id = unitId, + state = "1", create_time = DateTime.Now }; insertMaterial.Add(basMaterial);