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.

170 lines
5.2 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.HikRoBotSdk;
using Sln.Wcs.HikRoBotSdk.Dto.GenAgvSchedulingTask;
using Sln.Wcs.HoistSdk;
using Sln.Wcs.HoistSdk.Dto.HoistTaskExecutor;
using Sln.Wcs.Model.Domain;
using Sln.Wcs.Repository.service;
namespace Sln.Wcs.Strategy;
/// <summary>
/// 任务执行策略 - 轮询数据库中待执行的任务,根据设备类型调用对应 SDK 下发
/// </summary>
public class TaskExecuteStrategy : ITaskExecuteStrategy
{
private readonly ILiveTaskQueueService _taskQueueService;
private readonly ILiveTaskDetailService _taskDetailService;
private readonly IHIKRoBotSdk _hikRobotSdk;
private readonly IHoistSdk _hoistSdk;
public TaskExecuteStrategy(
ILiveTaskQueueService taskQueueService,
ILiveTaskDetailService taskDetailService,
IHIKRoBotSdk hikRobotSdk,
IHoistSdk hoistSdk)
{
_taskQueueService = taskQueueService;
_taskDetailService = taskDetailService;
_hikRobotSdk = hikRobotSdk;
_hoistSdk = hoistSdk;
}
/// <summary>
/// 执行一轮任务调度:查询所有待执行任务,按设备类型下发
/// </summary>
public Task<int> ExecuteAsync()
{
return Task.Run(() =>
{
// 1. 查询所有待执行的任务队列task_status = 1
var pendingTasks = _taskQueueService.Query(x => x.taskStatus == 1);
if (pendingTasks.Count == 0)
return 0;
int dispatchedCount = 0;
foreach (var task in pendingTasks)
{
try
{
// 2. 查询任务明细
var details = _taskDetailService.Query(x => x.taskCode == task.taskCode);
if (details.Count == 0)
continue;
// 3. 取第一个未执行的明细步骤
var currentDetail = details
.Where(x => x.taskStatus == 1)
.OrderBy(x => x.objId)
.FirstOrDefault();
if (currentDetail == null)
continue;
// 4. 根据设备类型下发任务
var success = DispatchByDeviceType(currentDetail);
if (success)
{
// 5. 更新明细状态为执行中
currentDetail.taskStatus = 2;
_taskDetailService.Update(currentDetail);
// 6. 更新队列状态为执行中
task.taskStatus = 2;
_taskQueueService.Update(task);
dispatchedCount++;
}
}
catch (Exception ex)
{
Console.WriteLine($"任务 {task.taskCode} 下发失败: {ex.Message}");
}
}
return dispatchedCount;
});
}
/// <summary>
/// 根据设备类型分发到对应 SDK
/// </summary>
private bool DispatchByDeviceType(LiveTaskDetail detail)
{
return detail.deviceType switch
{
1 => DispatchToAgv(detail),
2 => DispatchToHoist(detail),
_ => throw new NotSupportedException($"不支持的设备类型: {detail.deviceType}")
};
}
/// <summary>
/// 下发 AGV 任务(海康机器人 SDK
/// </summary>
private bool DispatchToAgv(LiveTaskDetail detail)
{
var dto = new GenAgvSchedulingTaskDto
{
reqCode = detail.taskCode,
reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
clientCode = "WCS",
taskCode = detail.taskCode,
taskTyp = detail.taskType switch
{
1 => "1", // 入库
2 => "2", // 出库
_ => "0"
},
taskMode = detail.taskType switch
{
1 => "2", // 入库 move
2 => "1", // 出库 move
_ => "0"
},
wbCode = detail.startPoint,
ctnrCode = detail.palletBarcode,
materialLot = detail.materialBarcode,
positionCodePath = new List<Position>
{
new() { positionCode = detail.startPoint, type = "00" },
new() { positionCode = detail.endPoint, type = "00" }
}
};
var result = _hikRobotSdk.GenAgvSchedulingTask(dto);
return result.code == "0";
}
/// <summary>
/// 下发提升机任务Hoist SDK
/// </summary>
private bool DispatchToHoist(LiveTaskDetail detail)
{
var dto = new HoistTaskExeDto
{
hoistCode = detail.startPoint,
taskCode = detail.taskCode,
startPoint = ParseIntPoint(detail.startPoint),
endPoint = ParseIntPoint(detail.endPoint)
};
var result = _hoistSdk.HoistTaskExecutor(dto);
return result.code == "0";
}
/// <summary>
/// 将位置字符串转为整数楼层/层号
/// </summary>
private static int ParseIntPoint(string? point)
{
if (string.IsNullOrEmpty(point))
return 0;
return int.TryParse(point, out var val) ? val : 0;
}
}