WMS新增,自定义定时任务
This commit is contained in:
@@ -11,15 +11,9 @@ namespace Tnb.WarehouseMgr.Entities.Dto.Inputs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class TaskCompleUpInput
|
public class TaskCompleUpInput
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 区分pda与pc端调用,默认pc端,忽略大小写
|
|
||||||
/// </summary>
|
|
||||||
public string prefix { get; set; }
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 任务执行Ids
|
/// 任务执行Ids
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> disTaskIds { get; set; }
|
public List<string> disTaskIds { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,13 +41,18 @@ namespace Tnb.WarehouseMgr.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="preTasks"></param>
|
/// <param name="preTasks"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<bool> GenPreTask(List<WmsPretaskH> preTasks,List<WmsPretaskCode> preTaskCodes);
|
Task<bool> GenPreTask(List<WmsPretaskH> preTasks, List<WmsPretaskCode> preTaskCodes);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成预任务成功后操作
|
/// 生成预任务成功后操作
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input"></param>
|
/// <param name="input"></param>
|
||||||
/// <returns></returns>
|
/// <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>
|
||||||
/// 任务完成
|
/// 任务完成
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -66,6 +71,6 @@ namespace Tnb.WarehouseMgr.Interfaces
|
|||||||
/// /// <param name="input"></param>
|
/// /// <param name="input"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task TaskExecuteAfter(TaskExecuteAfterUpInput input);
|
Task TaskExecuteAfter(TaskExecuteAfterUpInput input);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace Tnb.WarehouseMgr
|
|||||||
{
|
{
|
||||||
private readonly ISqlSugarClient _db;
|
private readonly ISqlSugarClient _db;
|
||||||
private readonly IWareHouseService _wareHouseService;
|
private readonly IWareHouseService _wareHouseService;
|
||||||
|
|
||||||
|
|
||||||
public DeviceProviderService(ISqlSugarRepository<WmsInstockH> repository, IWareHouseService wareHouseService)
|
public DeviceProviderService(ISqlSugarRepository<WmsInstockH> repository, IWareHouseService wareHouseService)
|
||||||
{
|
{
|
||||||
|
|||||||
47
WarehouseMgr/Tnb.WarehouseMgr/TimedTaskBackgroundService.cs
Normal file
47
WarehouseMgr/Tnb.WarehouseMgr/TimedTaskBackgroundService.cs
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using NPOI.HPSF;
|
using NPOI.HPSF;
|
||||||
using NPOI.OpenXmlFormats.Wordprocessing;
|
using NPOI.OpenXmlFormats.Wordprocessing;
|
||||||
|
using NPOI.SS.Formula.Functions;
|
||||||
using Polly.Timeout;
|
using Polly.Timeout;
|
||||||
using Senparc.NeuChar.Helpers;
|
using Senparc.NeuChar.Helpers;
|
||||||
using Senparc.Weixin.Work.AdvancedAPIs.OaDataOpen;
|
using Senparc.Weixin.Work.AdvancedAPIs.OaDataOpen;
|
||||||
@@ -214,11 +215,23 @@ namespace Tnb.WarehouseMgr
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[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();
|
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)
|
.InnerJoin<WmsAreaH>((a, b, c) => a.area_id == c.id)
|
||||||
.Where(a => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID)
|
.Where(a => a.status == WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID)
|
||||||
.OrderBy(a => new { priority = SqlFunc.Desc(a.priority), a.bill_code })
|
.OrderBy(a => new { priority = SqlFunc.Desc(a.priority), a.bill_code })
|
||||||
@@ -228,7 +241,7 @@ namespace Tnb.WarehouseMgr
|
|||||||
}, true)
|
}, true)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var ids = preTasks.Select(x => x.id).Distinct().ToList();
|
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)
|
if (preTasks.Count > 0)
|
||||||
{
|
{
|
||||||
//根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链,通过管理区ID
|
//根据预任务管理区分组,获取到所有分组后的预任务,遍历每个预任务 是否为任务链,通过管理区ID
|
||||||
@@ -237,55 +250,60 @@ namespace Tnb.WarehouseMgr
|
|||||||
List<WmsDistaskCode> distaskCodes = new();
|
List<WmsDistaskCode> distaskCodes = new();
|
||||||
foreach (var itGroup in preTaskGroups)
|
foreach (var itGroup in preTaskGroups)
|
||||||
{
|
{
|
||||||
var moveNum = itGroup.First().move_num;
|
|
||||||
var items = itGroup.Adapt<List<WmsDistaskH>>();
|
var items = itGroup.Adapt<List<WmsDistaskH>>();
|
||||||
for (int i = 0, cnt = items.Count; i < cnt; i++)
|
for (int i = 0, cnt = items.Count; i < cnt; i++)
|
||||||
{
|
{
|
||||||
items[i].id = SnowflakeIdHelper.NextId();
|
items[i].id = SnowflakeIdHelper.NextId();
|
||||||
items[i].status = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID;
|
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);
|
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.ForEach(x =>
|
||||||
});
|
{
|
||||||
items[0].groups = groupCode;
|
x.is_chain = 0;
|
||||||
items[0].bill_code = $"{groupCode}-1";
|
});
|
||||||
}
|
items[0].groups = groupCode;
|
||||||
else if ((moveNum >= areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum < areaPreTasks.Count)
|
items[0].bill_code = $"{groupCode}-1";
|
||||||
{
|
}
|
||||||
items.ForEach(x => x.is_chain = 1);
|
else if ((moveNum >= areaPreTasks.Count && areaPreTasks.Count > 1) || moveNum < areaPreTasks.Count)
|
||||||
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 = 1);
|
||||||
|
|
||||||
|
var start = 0;
|
||||||
|
var end = Math.Min(itemsCount, moveNum);
|
||||||
|
var arrList = new List<WmsDistaskH[]>(mod);
|
||||||
|
|
||||||
while (start < itemsCount)
|
while (start < itemsCount)
|
||||||
{
|
{
|
||||||
var subArray = arrary[start..end];
|
var subArray = arrary[start..end];
|
||||||
dic[i] = subArray;
|
arrList.Add(subArray);
|
||||||
start = end;
|
start = end;
|
||||||
end = Math.Min((end + moveNum), arrary.Length);
|
end = Math.Min((end + moveNum), arrary.Length);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
foreach (var (i, v) in dic)
|
foreach (var arr in arrList)
|
||||||
{
|
|
||||||
foreach (var it in v)
|
|
||||||
{
|
{
|
||||||
it.groups = groupCode;
|
for (int j = 1, len = arr.Length; j <= len; j++)
|
||||||
it.bill_code = $"{groupCode}-{i}";
|
{
|
||||||
|
arr[j - 1].groups = groupCode;
|
||||||
|
arr[j - 1].bill_code = $"{groupCode}-{j}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preTaskCodes?.Count > 0)
|
if (preTaskCodes?.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var disTask in items)
|
foreach (var disTask in items)
|
||||||
@@ -306,18 +324,18 @@ namespace Tnb.WarehouseMgr
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _db.Ado.BeginTranAsync();
|
await db.Ado.BeginTranAsync();
|
||||||
|
|
||||||
//disTasks.ForEach(x => x.id = SnowflakeIdHelper.NextId());
|
//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)
|
if (preTaskCodes?.Count > 0)
|
||||||
{
|
{
|
||||||
row = await _db.Insertable(distaskCodes).ExecuteCommandAsync();
|
row = await db.Insertable(distaskCodes).ExecuteCommandAsync();
|
||||||
}
|
}
|
||||||
if (row > 0)
|
if (row > 0)
|
||||||
{
|
{
|
||||||
var preTaskIds = preTasks.Select(x => x.id).ToList();
|
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创建任务链接口
|
//调用AGV创建任务链接口
|
||||||
@@ -332,12 +350,17 @@ namespace Tnb.WarehouseMgr
|
|||||||
dynamic reqBody = new ExpandoObject();
|
dynamic reqBody = new ExpandoObject();
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
Log.Information($"程序运行耗时{sw.ElapsedMilliseconds}ms");
|
JNPF.Logging.Log.Information($"程序运行耗时{sw.ElapsedMilliseconds}ms");
|
||||||
await _db.Ado.CommitTranAsync();
|
await db.Ado.CommitTranAsync();
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
await _db.Ado.RollbackTranAsync();
|
await db.Ado.RollbackTranAsync();
|
||||||
|
cts?.Cancel();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
cts?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,9 +536,6 @@ namespace Tnb.WarehouseMgr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成预任务
|
/// 生成预任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ using Senparc.Weixin;
|
|||||||
using Senparc.Weixin.Entities;
|
using Senparc.Weixin.Entities;
|
||||||
using Senparc.Weixin.RegisterServices;
|
using Senparc.Weixin.RegisterServices;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using Tnb.WarehouseMgr;
|
||||||
|
|
||||||
namespace JNPF.API.Entry;
|
namespace JNPF.API.Entry;
|
||||||
|
|
||||||
@@ -61,6 +62,10 @@ public class Startup : AppStartup
|
|||||||
.AddSenparcWeixinServices(App.Configuration); // Senparc.Weixin 注册(如果使用Senparc.Weixin SDK则添加)
|
.AddSenparcWeixinServices(App.Configuration); // Senparc.Weixin 注册(如果使用Senparc.Weixin SDK则添加)
|
||||||
|
|
||||||
services.AddOverideVisualDev();
|
services.AddOverideVisualDev();
|
||||||
|
|
||||||
|
//定时任务
|
||||||
|
services.AddHostedService<TimedTaskBackgroundService>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
|
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();
|
SnowflakeIdHelper.InitYitIdWorker();
|
||||||
|
|
||||||
bool isStartTimeJob = App.GetConfig<bool>("IsStartTimeJob");
|
bool isStartTimeJob = App.GetConfig<bool>("IsStartTimeJob");
|
||||||
if(isStartTimeJob)
|
if (isStartTimeJob)
|
||||||
serviceProvider.GetRequiredService<ITimeTaskService>().StartTimerJob();
|
serviceProvider.GetRequiredService<ITimeTaskService>().StartTimerJob();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user