wanshenmean
8 天以前 fd18eaba5e1c086a588509371f91310e7aafff9c
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -1,3 +1,4 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using WIDESEA_Core;
using WIDESEAWCS_Common;
@@ -68,6 +69,11 @@
        private readonly HttpClientHelper _httpClientHelper;
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger _logger;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="socketClientGateway">Socket 网关</param>
@@ -75,18 +81,21 @@
        /// <param name="robotTaskService">机器人任务服务</param>
        /// <param name="taskService">通用任务服务</param>
        /// <param name="httpClientHelper">HTTP 客户端帮助类</param>
        /// <param name="logger">日志记录器</param>
        public RobotTaskProcessor(
            ISocketClientGateway socketClientGateway,
            RobotStateManager stateManager,
            IRobotTaskService robotTaskService,
            ITaskService taskService,
            HttpClientHelper httpClientHelper)
            HttpClientHelper httpClientHelper,
            ILogger logger)
        {
            _socketClientGateway = socketClientGateway;
            _stateManager = stateManager;
            _robotTaskService = robotTaskService;
            _taskService = taskService;
            _httpClientHelper = httpClientHelper;
            _logger = logger;
        }
        /// <summary>
@@ -101,6 +110,20 @@
        public Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
        {
            return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
        }
        /// <summary>
        /// 按设备编码获取当前机器人的执行中任务
        /// </summary>
        /// <remarks>
        /// 从数据库中查询指定设备编码的执行中机器人任务。
        /// 当RobotArmObject为1(有物料)且没有待处理任务时调用。
        /// </remarks>
        /// <param name="robotCrane">机器人设备信息,包含设备编码</param>
        /// <returns>执行中的任务对象,如果没有则返回 null</returns>
        public Dt_RobotTask? GetExecutingTask(RobotCraneDevice robotCrane)
        {
            return _robotTaskService.QueryRobotCraneExecutingTask(robotCrane.DeviceCode);
        }
        /// <summary>
@@ -141,8 +164,9 @@
            if (result)
            {
                // 发送成功,记录日志
                QuartzLogger.Error($"下发取货指令,指令: {taskString}", state.RobotCrane.DeviceName);
                // 发送成功,记录 Info 日志
                _logger.LogInformation("下发取货指令成功,指令: {TaskString},设备: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Info($"下发取货指令成功,指令: {taskString}", state.RobotCrane?.DeviceName);
                // 更新任务状态为"机器人执行中"
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
@@ -156,6 +180,12 @@
                {
                    await _robotTaskService.UpdateRobotTaskAsync(task);
                }
            }
            else
            {
                // 发送失败,记录 Error 日志
                _logger.LogError("下发取货指令失败,指令: {TaskString},设备: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Error($"下发取货指令失败,指令: {taskString}", state.RobotCrane?.DeviceName);
            }
        }
@@ -182,6 +212,8 @@
            var currentTask = state.CurrentTask;
            if (currentTask == null)
            {
                _logger.LogDebug("HandleInboundTaskAsync:当前任务为空");
                QuartzLogger.Debug($"HandleInboundTaskAsync:当前任务为空", state.RobotCrane?.DeviceName ?? "Unknown");
                return false;
            }
@@ -190,7 +222,7 @@
            // 根据巷道名称判断仓库 ID
            // ZYRB1 -> 1, HPRB001 -> 2, 其他 -> 3
            int warehouseId = currentTask.RobotRoadway == "ZYRB1" ? 1 : currentTask.RobotRoadway == "HPRB001" ? 2 : 3;
            int warehouseId = currentTask.RobotRoadway == "注液组盘机械手" ? 1 : currentTask.RobotRoadway == "HPRB001" ? 2 : 3;
            // 任务类型(0 表示未定义,稍后根据任务类型设置)
            int taskType = 0;
@@ -213,6 +245,8 @@
                {
                    case RobotTaskTypeEnum.GroupPallet:
                        // 组盘任务不使用源地址,直接返回 false
                        _logger.LogDebug("HandleInboundTaskAsync:组盘任务不使用源地址");
                        QuartzLogger.Debug($"HandleInboundTaskAsync:组盘任务不使用源地址", state.RobotCrane?.DeviceName ?? "Unknown");
                        return false;
                    case RobotTaskTypeEnum.ChangePallet:
@@ -237,6 +271,8 @@
                    case RobotTaskTypeEnum.SplitPallet:
                        // 拆盘任务不使用目标地址
                        _logger.LogDebug("HandleInboundTaskAsync:拆盘任务不使用目标地址");
                        QuartzLogger.Debug($"HandleInboundTaskAsync:拆盘任务不使用目标地址", state.RobotCrane?.DeviceName ?? "Unknown");
                        return true;
                }
            }
@@ -253,12 +289,18 @@
                TaskType = taskType                         // 任务类型(入库/空托盘入库)
            };
            // 记录日志:开始调用 WMS 创建入库任务
            _logger.LogInformation("HandleInboundTaskAsync:调用WMS创建入库任务,托盘码: {PalletCode},任务类型: {TaskType}", PalletCode, taskType);
            QuartzLogger.Info($"调用WMS创建入库任务,托盘码: {PalletCode},任务类型: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
            // 调用 WMS 接口创建入库任务
            var result = _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.CreateTaskInboundAsync), taskDto.ToJson());
            // 如果调用失败或返回错误状态
            if (!result.Data.Status && result.IsSuccess)
            {
                _logger.LogError("HandleInboundTaskAsync:WMS返回错误状态,Status: {Status}", result.Data.Status);
                QuartzLogger.Error($"HandleInboundTaskAsync:WMS返回错误状态", state.RobotCrane?.DeviceName ?? "Unknown");
                return false;
            }
@@ -269,11 +311,14 @@
            var content = _taskService.ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO });
            if (!content.Status)
            {
                _logger.LogError("HandleInboundTaskAsync:接收WMS任务失败");
                QuartzLogger.Error($"HandleInboundTaskAsync:接收WMS任务失败", state.RobotCrane?.DeviceName ?? "Unknown");
                return false;
            }
            // 解析返回的任务信息
            var taskInfo = JsonConvert.DeserializeObject<Dt_Task>(content.Data.ToJson() ?? string.Empty) ?? new Dt_Task();
            var taskInfos = JsonConvert.DeserializeObject<List<Dt_Task>>(content.Data.ToJson() ?? string.Empty) ?? new List<Dt_Task>();
            var taskInfo = taskInfos.FirstOrDefault();
            // 获取源地址
            string sourceAddress = taskDTO.SourceAddress;
@@ -298,6 +343,8 @@
                // 更新任务状态到下一阶段
                if (_taskService.UpdateTaskStatusToNext(taskInfo).Status)
                {
                    _logger.LogInformation("HandleInboundTaskAsync:入库任务处理成功,任务号: {TaskNum}", taskInfo.TaskNum);
                    QuartzLogger.Info($"HandleInboundTaskAsync:入库任务处理成功,任务号: {taskInfo.TaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
                    return true;
                }
            }
@@ -331,6 +378,9 @@
                // 目标输送线编号
                TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
                // 巷道编号(机器人名称)
                Roadway = state.CurrentTask.RobotRoadway,
                // 电池位置详情列表
                // 过滤掉位置为 0 或负数的无效数据
                // 按位置编号排序
@@ -341,7 +391,7 @@
                    .Select((x, idx) => new StockDetailDTO
                    {
                        // 数量:如果已有任务总数,使用任务总数+当前位置数;否则只使用当前位置数
                        Quantity = state.RobotTaskTotalNum > 0 ? state.RobotTaskTotalNum + positions.Length : positions.Length,
                        Quantity = 1,
                        // 通道/位置编号
                        Channel = x,