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#

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