diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TaskCompleUpInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TaskCompleUpInput.cs index 8e1a68b1..b312aaeb 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TaskCompleUpInput.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TaskCompleUpInput.cs @@ -11,15 +11,9 @@ namespace Tnb.WarehouseMgr.Entities.Dto.Inputs /// public class TaskCompleUpInput { - /// - /// 区分pda与pc端调用,默认pc端,忽略大小写 - /// - public string prefix { get; set; } /// /// 任务执行Ids /// public List disTaskIds { get; set; } - - } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TimedtaskInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TimedtaskInput.cs new file mode 100644 index 00000000..398d08b8 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/TimedtaskInput.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tnb.WarehouseMgr.Entities.Dto.Inputs +{ + public class TimedtaskInput + { + /// + /// 任务Ids + /// + public List disTaskIds { get; set; } + /// + /// 设备Ids + /// + public List EqpIds { get; set; } + + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs index 93adbc1c..ed3c0953 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Interfaces/IWareHouseService.cs @@ -41,13 +41,18 @@ namespace Tnb.WarehouseMgr.Interfaces /// /// /// - Task GenPreTask(List preTasks,List preTaskCodes); + Task GenPreTask(List preTasks, List preTaskCodes); /// /// 生成预任务成功后操作 /// /// /// - Task GenInStockTaskHandleAfter(GenPreTaskUpInput input,Expression> setCarryColumnsExp,Expression> setLocaionColumbExp); + Task GenInStockTaskHandleAfter(GenPreTaskUpInput input, Expression> setCarryColumnsExp, Expression> setLocaionColumbExp); + /// + /// 生成任务执行 + /// + /// + Task GenTaskExecute(CancellationTokenSource? cts = default); /// /// 任务完成 /// @@ -66,6 +71,6 @@ namespace Tnb.WarehouseMgr.Interfaces /// /// /// Task TaskExecuteAfter(TaskExecuteAfterUpInput input); - + } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs b/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs index 97600ffe..1bc4c98c 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/DeviceProviderService.cs @@ -29,6 +29,7 @@ namespace Tnb.WarehouseMgr { private readonly ISqlSugarClient _db; private readonly IWareHouseService _wareHouseService; + public DeviceProviderService(ISqlSugarRepository repository, IWareHouseService wareHouseService) { diff --git a/WarehouseMgr/Tnb.WarehouseMgr/TimedTaskBackgroundService.cs b/WarehouseMgr/Tnb.WarehouseMgr/TimedTaskBackgroundService.cs new file mode 100644 index 00000000..2cbddff8 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr/TimedTaskBackgroundService.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using JNPF; +using JNPF.Common.Extension; +using JNPF.Logging; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.Extensions.Hosting; +using Tnb.WarehouseMgr.Entities.Dto.Inputs; +using Tnb.WarehouseMgr.Interfaces; + +namespace Tnb.WarehouseMgr +{ + /// + /// 定时任务 + /// added by ly on 20230802 + /// + public class TimedTaskBackgroundService : BackgroundService + { + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + + await Task.Run(() => + { + CancellationTokenSource tokenSource = new(); + CancellationToken token = tokenSource.Token; + var wareHouseService = App.GetRequiredService(); + TimedTask(withOutParamAction: (cts) => Task.Run(async () => + { + while (!token.IsCancellationRequested) + { + await wareHouseService.GenTaskExecute(tokenSource); + await Task.Delay(1000); + } + }, token)); + }); + } + + private Task? TimedTask(Func? withOutParamAction = null, Func? withParemAction = null, CancellationTokenSource? cts = default, TimedtaskInput? parameter = null) + { + return parameter != null ? withParemAction?.Invoke(parameter) : withOutParamAction?.Invoke(cts); + } + + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs index 1f6da2b4..e0d69443 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WareHouseService.cs @@ -29,6 +29,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.CodeAnalysis; using NPOI.HPSF; using NPOI.OpenXmlFormats.Wordprocessing; +using NPOI.SS.Formula.Functions; using Polly.Timeout; using Senparc.NeuChar.Helpers; using Senparc.Weixin.Work.AdvancedAPIs.OaDataOpen; @@ -214,11 +215,23 @@ namespace Tnb.WarehouseMgr /// /// [HttpPost] - public async Task GenTaskExecute() + public async Task GenTaskExecute(CancellationTokenSource? cts = default) { + //test + //CancellationTokenSource curCts = new(); + + //curCts?.Cancel(); + //if (cts != null) + //{ + // cts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, curCts.Token); + //} + //cts?.Cancel(); + //await Task.CompletedTask; + Stopwatch sw = Stopwatch.StartNew(); + var db = _db.CopyNew(); //获取所有未下发的预任务申请 - var preTasks = await _db.Queryable().InnerJoin((a, b) => a.startlocation_id == b.location_id && a.carry_id == b.id) + var preTasks = await db.Queryable().InnerJoin((a, b) => a.startlocation_id == b.location_id && a.carry_id == b.id) .InnerJoin((a, b, c) => a.area_id == c.id) .Where(a => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID) .OrderBy(a => new { priority = SqlFunc.Desc(a.priority), a.bill_code }) @@ -228,7 +241,7 @@ namespace Tnb.WarehouseMgr }, true) .ToListAsync(); var ids = preTasks.Select(x => x.id).Distinct().ToList(); - var preTaskCodes = await _db.Queryable().Where(it => ids.Contains(it.bill_id)).ToListAsync(); + var preTaskCodes = await db.Queryable().Where(it => ids.Contains(it.bill_id)).ToListAsync(); if (preTasks.Count > 0) { //根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链,通过管理区ID @@ -237,55 +250,60 @@ namespace Tnb.WarehouseMgr List distaskCodes = new(); foreach (var itGroup in preTaskGroups) { - var moveNum = itGroup.First().move_num; var items = itGroup.Adapt>(); for (int i = 0, cnt = items.Count; i < cnt; i++) { items[i].id = SnowflakeIdHelper.NextId(); items[i].status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID; } - if (moveNum >= 1) + var moveNum = itGroup.First().move_num; + var itemsCount = items.Count; + var mod = itemsCount % moveNum > 0 ? itemsCount / moveNum + 1 : itemsCount / moveNum; + var arrary = items.ToArray(); + for (int i = 1; i <= mod; i++) { - var areaPreTasks = itGroup.ToList(); var groupCode = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_TASK_EXECUTE_ENCODE); - if (moveNum == 1 || (moveNum > areaPreTasks.Count && areaPreTasks.Count == 1)) + if (moveNum >= 1) { - items.ForEach(x => + var areaPreTasks = itGroup.ToList(); + + if (moveNum == 1 || (moveNum > areaPreTasks.Count && areaPreTasks.Count == 1)) { - x.is_chain = 0; - }); - items[0].groups = groupCode; - items[0].bill_code = $"{groupCode}-1"; - } - else if ((moveNum >= areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum < areaPreTasks.Count) - { - items.ForEach(x => x.is_chain = 1); - var itemsCount = items.Count; - var start = 0; - var end = Math.Min(itemsCount, moveNum); - var arrary = items.ToArray(); - var dic = new Dictionary(); - var mod = itemsCount % moveNum > 0 ? itemsCount / moveNum + 1 : itemsCount / moveNum; - for (int i = 1; i <= mod; i++) + items.ForEach(x => + { + x.is_chain = 0; + }); + items[0].groups = groupCode; + items[0].bill_code = $"{groupCode}-1"; + } + else if ((moveNum >= areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum < areaPreTasks.Count) { + items.ForEach(x => x.is_chain = 1); + + var start = 0; + var end = Math.Min(itemsCount, moveNum); + var arrList = new List(mod); + while (start < itemsCount) { var subArray = arrary[start..end]; - dic[i] = subArray; + arrList.Add(subArray); start = end; end = Math.Min((end + moveNum), arrary.Length); } - } - foreach (var (i, v) in dic) - { - foreach (var it in v) + + foreach (var arr in arrList) { - it.groups = groupCode; - it.bill_code = $"{groupCode}-{i}"; + for (int j = 1, len = arr.Length; j <= len; j++) + { + arr[j - 1].groups = groupCode; + arr[j - 1].bill_code = $"{groupCode}-{j}"; + } } } } } + if (preTaskCodes?.Count > 0) { foreach (var disTask in items) @@ -306,18 +324,18 @@ namespace Tnb.WarehouseMgr } try { - await _db.Ado.BeginTranAsync(); + await db.Ado.BeginTranAsync(); //disTasks.ForEach(x => x.id = SnowflakeIdHelper.NextId()); - var row = await _db.Insertable(disTasks).ExecuteCommandAsync(); + var row = await db.Insertable(disTasks).ExecuteCommandAsync(); if (preTaskCodes?.Count > 0) { - row = await _db.Insertable(distaskCodes).ExecuteCommandAsync(); + row = await db.Insertable(distaskCodes).ExecuteCommandAsync(); } if (row > 0) { var preTaskIds = preTasks.Select(x => x.id).ToList(); - row = await _db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); + row = await db.Updateable().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync(); } //调用AGV创建任务链接口 @@ -332,12 +350,17 @@ namespace Tnb.WarehouseMgr dynamic reqBody = new ExpandoObject(); sw.Stop(); - Log.Information($"程序运行耗时{sw.ElapsedMilliseconds}ms"); - await _db.Ado.CommitTranAsync(); + JNPF.Logging.Log.Information($"程序运行耗时{sw.ElapsedMilliseconds}ms"); + await db.Ado.CommitTranAsync(); } catch (Exception) { - await _db.Ado.RollbackTranAsync(); + await db.Ado.RollbackTranAsync(); + cts?.Cancel(); + } + finally + { + cts?.Dispose(); } } } @@ -513,9 +536,6 @@ namespace Tnb.WarehouseMgr } } - - - /// /// 生成预任务 /// diff --git a/apihost/Tnb.API.Entry/Startup.cs b/apihost/Tnb.API.Entry/Startup.cs index da09f6a4..dd5e6ed7 100644 --- a/apihost/Tnb.API.Entry/Startup.cs +++ b/apihost/Tnb.API.Entry/Startup.cs @@ -22,6 +22,7 @@ using Senparc.Weixin; using Senparc.Weixin.Entities; using Senparc.Weixin.RegisterServices; using SqlSugar; +using Tnb.WarehouseMgr; namespace JNPF.API.Entry; @@ -61,6 +62,10 @@ public class Startup : AppStartup .AddSenparcWeixinServices(App.Configuration); // Senparc.Weixin 注册(如果使用Senparc.Weixin SDK则添加) services.AddOverideVisualDev(); + + //定时任务 + services.AddHostedService(); + } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IOptions senparcSetting, IOptions senparcWeixinSetting) @@ -110,7 +115,7 @@ public class Startup : AppStartup SnowflakeIdHelper.InitYitIdWorker(); bool isStartTimeJob = App.GetConfig("IsStartTimeJob"); - if(isStartTimeJob) + if (isStartTimeJob) serviceProvider.GetRequiredService().StartTimerJob(); } } \ No newline at end of file