diff --git a/Sln.Wcs.Strategy/ITaskExecuteStrategy.cs b/Sln.Wcs.Strategy/ITaskExecuteStrategy.cs
new file mode 100644
index 0000000..2a0e0bb
--- /dev/null
+++ b/Sln.Wcs.Strategy/ITaskExecuteStrategy.cs
@@ -0,0 +1,13 @@
+namespace Sln.Wcs.Strategy;
+
+///
+/// 任务执行策略接口 - 从任务队列中取出待执行任务,根据设备类型下发到对应 SDK
+///
+public interface ITaskExecuteStrategy
+{
+ ///
+ /// 执行一轮任务调度:查询待执行任务,按设备类型下发
+ ///
+ /// 本次下发的任务数量
+ Task ExecuteAsync();
+}
diff --git a/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj b/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj
index 3a63532..428753c 100644
--- a/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj
+++ b/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj
@@ -1,4 +1,4 @@
-
+
net8.0
@@ -6,4 +6,11 @@
enable
+
+
+
+
+
+
+
diff --git a/Sln.Wcs.Strategy/TaskExecuteStrategy.cs b/Sln.Wcs.Strategy/TaskExecuteStrategy.cs
new file mode 100644
index 0000000..61f559f
--- /dev/null
+++ b/Sln.Wcs.Strategy/TaskExecuteStrategy.cs
@@ -0,0 +1,169 @@
+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;
+ }
+}