WMS新增,自定义定时任务

This commit is contained in:
alex
2023-08-02 17:50:51 +08:00
parent 9b4e76192a
commit e685faca9e
7 changed files with 143 additions and 50 deletions

View File

@@ -11,15 +11,9 @@ namespace Tnb.WarehouseMgr.Entities.Dto.Inputs
/// </summary>
public class TaskCompleUpInput
{
/// <summary>
/// 区分pda与pc端调用默认pc端忽略大小写
/// </summary>
public string prefix { get; set; }
/// <summary>
/// 任务执行Ids
/// </summary>
public List<string> disTaskIds { get; set; }
}
}

View File

@@ -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
{
/// <summary>
/// 任务Ids
/// </summary>
public List<string> disTaskIds { get; set; }
/// <summary>
/// 设备Ids
/// </summary>
public List<string> EqpIds { get; set; }
}
}

View File

@@ -41,13 +41,18 @@ namespace Tnb.WarehouseMgr.Interfaces
/// </summary>
/// <param name="preTasks"></param>
/// <returns></returns>
Task<bool> GenPreTask(List<WmsPretaskH> preTasks,List<WmsPretaskCode> preTaskCodes);
Task<bool> GenPreTask(List<WmsPretaskH> preTasks, List<WmsPretaskCode> preTaskCodes);
/// <summary>
/// 生成预任务成功后操作
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task GenInStockTaskHandleAfter(GenPreTaskUpInput input,Expression<Func<WmsCarryH,WmsCarryH>> setCarryColumnsExp,Expression<Func<BasLocation,BasLocation>> setLocaionColumbExp);
Task GenInStockTaskHandleAfter(GenPreTaskUpInput input, Expression<Func<WmsCarryH, WmsCarryH>> setCarryColumnsExp, Expression<Func<BasLocation, BasLocation>> setLocaionColumbExp);
/// <summary>
/// 生成任务执行
/// </summary>
/// <returns></returns>
Task GenTaskExecute(CancellationTokenSource? cts = default);
/// <summary>
/// 任务完成
/// </summary>
@@ -66,6 +71,6 @@ namespace Tnb.WarehouseMgr.Interfaces
/// /// <param name="input"></param>
/// <returns></returns>
Task TaskExecuteAfter(TaskExecuteAfterUpInput input);
}
}

View File

@@ -29,6 +29,7 @@ namespace Tnb.WarehouseMgr
{
private readonly ISqlSugarClient _db;
private readonly IWareHouseService _wareHouseService;
public DeviceProviderService(ISqlSugarRepository<WmsInstockH> repository, IWareHouseService wareHouseService)
{

View File

@@ -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
{
/// <summary>
/// 定时任务
/// added by ly on 20230802
/// </summary>
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<IWareHouseService>();
TimedTask(withOutParamAction: (cts) => Task.Run(async () =>
{
while (!token.IsCancellationRequested)
{
await wareHouseService.GenTaskExecute(tokenSource);
await Task.Delay(1000);
}
}, token));
});
}
private Task? TimedTask(Func<CancellationTokenSource?, Task>? withOutParamAction = null, Func<TimedtaskInput, Task>? withParemAction = null, CancellationTokenSource? cts = default, TimedtaskInput? parameter = null)
{
return parameter != null ? withParemAction?.Invoke(parameter) : withOutParamAction?.Invoke(cts);
}
}
}

View File

@@ -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
/// </summary>
/// <returns></returns>
[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<WmsPretaskH>().InnerJoin<WmsCarryH>((a, b) => a.startlocation_id == b.location_id && a.carry_id == b.id)
var preTasks = await db.Queryable<WmsPretaskH>().InnerJoin<WmsCarryH>((a, b) => a.startlocation_id == b.location_id && a.carry_id == b.id)
.InnerJoin<WmsAreaH>((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<WmsPretaskCode>().Where(it => ids.Contains(it.bill_id)).ToListAsync();
var preTaskCodes = await db.Queryable<WmsPretaskCode>().Where(it => ids.Contains(it.bill_id)).ToListAsync();
if (preTasks.Count > 0)
{
//根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链通过管理区ID
@@ -237,55 +250,60 @@ namespace Tnb.WarehouseMgr
List<WmsDistaskCode> distaskCodes = new();
foreach (var itGroup in preTaskGroups)
{
var moveNum = itGroup.First().move_num;
var items = itGroup.Adapt<List<WmsDistaskH>>();
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<int, WmsDistaskH[]>();
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<WmsDistaskH[]>(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<WmsPretaskH>().SetColumns(it => new WmsPretaskH { status = WmsWareHouseConst.PRETASK_BILL_STATUS_YXF_ID }).Where(it => preTaskIds.Contains(it.id)).ExecuteCommandAsync();
row = await db.Updateable<WmsPretaskH>().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
}
}
/// <summary>
/// 生成预任务
/// </summary>

View File

@@ -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<TimedTaskBackgroundService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
@@ -110,7 +115,7 @@ public class Startup : AppStartup
SnowflakeIdHelper.InitYitIdWorker();
bool isStartTimeJob = App.GetConfig<bool>("IsStartTimeJob");
if(isStartTimeJob)
if (isStartTimeJob)
serviceProvider.GetRequiredService<ITimeTaskService>().StartTimerJob();
}
}