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> /// </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; }
} }
} }

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> /// </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);
} }
} }

View File

@@ -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)
{ {

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 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>

View File

@@ -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();
} }
} }