You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
4.8 KiB
C#

using Sln.Wcs.Model.Domain;
using Sln.Wcs.Repository.service;
using Sln.Wcs.Serilog;
namespace Sln.Wcs.Strategy;
public class MaterialStrategy
{
private readonly SerilogHelper _logger;
private readonly ILiveTaskQueueService _taskQueueService;
private readonly ILiveTaskDetailService _taskDetailService;
private CancellationTokenSource? _cts;
private bool _isRunning;
public MaterialStrategy(
SerilogHelper logger,
ILiveTaskQueueService taskQueueService,
ILiveTaskDetailService taskDetailService)
{
_logger = logger;
_taskQueueService = taskQueueService;
_taskDetailService = taskDetailService;
}
public void Run()
{
_logger.Info("包材任务调度就绪,输入 start 启动stop 停止quit 退出");
while (true)
{
var input = Console.ReadLine()?.Trim().ToLower();
switch (input)
{
case "start":
Start();
break;
case "stop":
Stop();
break;
case "quit":
Stop();
return;
default:
_logger.Info("未知指令,可用: start | stop | quit");
break;
}
}
}
private void Start()
{
if (_isRunning)
{
_logger.Info("调度已在运行中");
return;
}
_cts = new CancellationTokenSource();
_isRunning = true;
Task.Run(() => SchedulingLoop(_cts.Token));
_logger.Info("调度已启动");
}
private void Stop()
{
if (!_isRunning)
{
_logger.Info("调度未在运行");
return;
}
_cts?.Cancel();
_isRunning = false;
_logger.Info("调度已停止");
}
private void SchedulingLoop(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
var taskQueues = _taskQueueService.getLiveTaskQueues(x =>
x.taskCategory == 1 && x.taskStatus == 1);
_logger.Info($"查询待执行包材任务,共 {taskQueues.Count} 条");
if (taskQueues.Count > 0)
{
Parallel.ForEach(taskQueues, task =>
{
ProcessTask(task, ct);
});
}
Thread.Sleep(1000);
}
_logger.Info("调度循环已退出");
}
private void ProcessTask(LiveTaskQueue task, CancellationToken ct)
{
if (ct.IsCancellationRequested) return;
_logger.Info($"开始执行任务 {task.taskCode},子任务数 {task.taskDetails.Count}");
task.taskStatus = 2;
_taskQueueService.Update(task);
foreach (var detail in task.taskDetails.OrderBy(x => x.objId))
{
if (ct.IsCancellationRequested)
{
_logger.Info($"任务 {task.taskCode} 被中断,当前步骤 {detail.objId} 未执行");
return;
}
_logger.Info($"子任务 {task.taskCode}-{detail.objId},设备类型 {detail.deviceType}");
if (detail.taskStatus == 2 || detail.taskStatus == 3)
{
_logger.Info($"子任务 {task.taskCode}-{detail.objId},已下发,不再重复下发");
continue;
}
var success = detail.deviceType switch
{
1 => DispatchToAgv(detail),
2 => DispatchToHoist(detail),
_ => true
};
if (success)
{
detail.taskStatus = 2;
_taskDetailService.Update(detail);
_logger.Info($"子任务 {task.taskCode}-{detail.objId} 下发成功");
}
else
{
_logger.Error($"子任务 {task.taskCode}-{detail.objId} 下发失败,中断后续步骤");
break;
}
}
if (ct.IsCancellationRequested) return;
task.taskStatus = 3;
_taskQueueService.Update(task);
_logger.Info($"任务 {task.taskCode} 执行完成");
}
private bool DispatchToAgv(LiveTaskDetail detail)
{
if (detail.taskCode == "2026051816004580")
{
Task.Delay(1000 * 3).Wait();
}
_logger.Info($"AGV 下发: {detail.taskCode}-{detail.objId},起点 {detail.startPoint} → 终点 {detail.endPoint}");
return true;
}
private bool DispatchToHoist(LiveTaskDetail detail)
{
if (detail.taskCode == "2026050700001")
{
Task.Delay(1000 * 3).Wait();
}
_logger.Info($"提升机下发: {detail.taskCode}-{detail.objId},起点 {detail.startPoint} → 终点 {detail.endPoint}");
return true;
}
}