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; /// /// 任务执行策略 - 轮询数据库中待执行的任务,根据设备类型调用对应 SDK 下发 /// 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; } /// /// 执行一轮任务调度:查询所有待执行任务,按设备类型下发 /// public Task 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; }); } /// /// 根据设备类型分发到对应 SDK /// private bool DispatchByDeviceType(LiveTaskDetail detail) { return detail.deviceType switch { 1 => DispatchToAgv(detail), 2 => DispatchToHoist(detail), _ => throw new NotSupportedException($"不支持的设备类型: {detail.deviceType}") }; } /// /// 下发 AGV 任务(海康机器人 SDK) /// 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 { new() { positionCode = detail.startPoint, type = "00" }, new() { positionCode = detail.endPoint, type = "00" } } }; var result = _hikRobotSdk.GenAgvSchedulingTask(dto); return result.code == "0"; } /// /// 下发提升机任务(Hoist SDK) /// 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"; } /// /// 将位置字符串转为整数楼层/层号 /// private static int ParseIntPoint(string? point) { if (string.IsNullOrEmpty(point)) return 0; return int.TryParse(point, out var val) ? val : 0; } }