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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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