wanshenmean
5 小时以前 e4921e003cc293fea714bdaf74dc6a6b6b750295
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -1,5 +1,5 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Serilog;
using WIDESEA_Core;
using WIDESEAWCS_Common;
using WIDESEAWCS_Common.HttpEnum;
@@ -79,7 +79,7 @@
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger _logger;
        private readonly ILogger _logger;
        /// <summary>
        /// 构造函数
@@ -146,7 +146,7 @@
        /// <returns>删除是否成功</returns>
        public bool? DeleteTask(int ID)
        {
            return _robotTaskService.Repository.DeleteDataById(ID);
            return _robotTaskService.DeleteRobotTask(ID);
        }
        /// <summary>
@@ -170,38 +170,35 @@
            // 构建取货指令,格式:Pickbattery,{源地址}
            string taskString = $"Pickbattery,{task.RobotSourceAddress}";
            // 通过 Socket 网关发送指令到机器人客户端
            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
            // 更新任务状态为"机器人执行中"
            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
            if (result)
            // 将任务关联到状态对象
            state.CurrentTask = task;
            if (isScanNG)
            {
                // 发送成功,记录 Info 日志
                _logger.LogInformation("下发取货指令成功,指令: {TaskString},设备: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Info($"下发取货指令成功,指令: {taskString}", state.RobotCrane?.DeviceName);
                // 更新任务状态为"机器人执行中"
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                // 将任务关联到状态对象
                state.CurrentTask = task;
                if (isScanNG)
                {
                    state.IsScanNG = true;
                }
                // 保持原语义:仅在状态安全写入成功后再更新任务状态
                // 这样可以确保状态和任务记录的一致性
                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
                {
                    await _robotTaskService.UpdateRobotTaskAsync(task);
                }
                state.IsScanNG = true;
            }
            else
            // 保持原语义:仅在状态安全写入成功后再更新任务状态
            // 这样可以确保状态和任务记录的一致性
            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
            {
                // 发送失败,记录 Error 日志
                _logger.LogError("下发取货指令失败,指令: {TaskString},设备: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Error($"下发取货指令失败,指令: {taskString}", state.RobotCrane?.DeviceName);
                QuartzLogHelper.LogInfo(_logger, $"状态更新成功,设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                // 通过 Socket 网关发送指令到机器人客户端
                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
                if (result)
                {
                    // 发送成功,记录 Info 日志
                    QuartzLogHelper.LogInfo(_logger, $"下发取货指令成功,指令: {taskString},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                    //await _robotTaskService.UpdateRobotTaskAsync(task);
                }
                else
                {
                    // 发送失败,记录 Error 日志
                    QuartzLogHelper.LogError(_logger, $"下发取货指令失败,指令: {taskString},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                }
            }
        }
@@ -224,7 +221,7 @@
        {
            if (positions == null || positions.Count == 0)
            {
                _logger.LogWarning("SendSocketRobotFakeBatteryPickAsync:平面点位列表为空,任务号: {TaskNum}", task.RobotTaskNum);
                QuartzLogHelper.LogWarn(_logger, $"SendSocketRobotFakeBatteryPickAsync:平面点位列表为空,任务号: {task.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
                return;
            }
@@ -236,30 +233,26 @@
            // 标记点位为已使用
            _fakeBatteryPositionService.MarkAsUsed(positions);
            // 通过 Socket 网关发送指令到机器人客户端
            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
            // 更新任务状态为"机器人执行中"
            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
            if (result)
            // 将任务关联到状态对象
            state.CurrentTask = task;
            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
            {
                _logger.LogInformation("下发假电芯取货指令成功,指令: {TaskString},点位: {Positions},设备: {DeviceName}",
                    taskString, string.Join(",", positions), state.RobotCrane?.DeviceName);
                QuartzLogger.Info($"下发假电芯取货指令成功,指令: {taskString}", state.RobotCrane?.DeviceName);
                // 通过 Socket 网关发送指令到机器人客户端
                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
                // 更新任务状态为"机器人执行中"
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                // 将任务关联到状态对象
                state.CurrentTask = task;
                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
                if (result)
                {
                    await _robotTaskService.UpdateRobotTaskAsync(task);
                    QuartzLogHelper.LogInfo(_logger, $"下发假电芯取货指令成功,指令: {taskString},点位: {string.Join(",", positions)},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                    //await _robotTaskService.UpdateRobotTaskAsync(task);
                }
            }
            else
            {
                _logger.LogError("下发假电芯取货指令失败,指令: {TaskString},设备: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Error($"下发假电芯取货指令失败,指令: {taskString}", state.RobotCrane?.DeviceName);
                else
                {
                    QuartzLogHelper.LogError(_logger, $"下发假电芯取货指令失败,指令: {taskString},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                }
            }
        }
@@ -312,34 +305,31 @@
        /// <param name="batchEnd">批次结束编号</param>
        public async Task SendPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
        {
            // 先发送总数指令
            string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
            await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
            // 再发送批次取货指令
            string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
            string taskString = $"Pickbattery,{position},{range}";
            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
            state.CurrentTask = task;
            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
            if (result)
            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
            {
                _logger.LogInformation("下发批次取货指令成功,指令: {TaskString},批次: {Range},设备: {DeviceName}",
                    taskString, range, state.RobotCrane?.DeviceName);
                QuartzLogger.Info($"下发批次取货指令成功,指令: {taskString},批次: {range}", state.RobotCrane?.DeviceName);
                // 先发送总数指令
                string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
                await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                state.CurrentTask = task;
                // 再发送批次取货指令
                string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
                string taskString = $"Pickbattery,{position},{range}";
                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
                if (result)
                {
                    await _robotTaskService.UpdateRobotTaskAsync(task);
                    QuartzLogHelper.LogInfo(_logger, $"下发批次取货指令成功,指令: {taskString},批次: {range},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                    //await _robotTaskService.UpdateRobotTaskAsync(task);
                }
            }
            else
            {
                _logger.LogError("下发批次取货指令失败,指令: {TaskString},设备: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Error($"下发批次取货指令失败,指令: {taskString}", state.RobotCrane?.DeviceName);
                else
                {
                    QuartzLogHelper.LogError(_logger, $"下发批次取货指令失败,指令: {taskString},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                }
            }
        }
@@ -359,34 +349,31 @@
        /// <param name="batchEnd">批次结束编号</param>
        public async Task SendFakeBatteryPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, int batchStart, int batchEnd)
        {
            // 先发送总数指令
            string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
            await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
            state.CurrentTask = task;
            // 再发送批次取货指令(假电芯固定从5号位取)
            string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
            string taskString = $"Pickbattery,5,{range}";
            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
            if (result)
            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
            {
                _logger.LogInformation("下发假电芯批次取货指令成功,指令: {TaskString},批次: {Range},设备: {DeviceName}",
                    taskString, range, state.RobotCrane?.DeviceName);
                QuartzLogger.Info($"下发假电芯批次取货指令成功,指令: {taskString},批次: {range}", state.RobotCrane?.DeviceName);
                // 先发送总数指令
                string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
                await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                state.CurrentTask = task;
                // 再发送批次取货指令(假电芯固定从5号位取)
                string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
                string taskString = $"Pickbattery,5,{range}";
                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
                if (result)
                {
                    await _robotTaskService.UpdateRobotTaskAsync(task);
                    QuartzLogHelper.LogInfo(_logger, $"下发假电芯批次取货指令成功,指令: {taskString},批次: {range},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                    //await _robotTaskService.UpdateRobotTaskAsync(task);
                }
            }
            else
            {
                _logger.LogError("下发假电芯批次取货指令失败,指令: {TaskString},设备: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Error($"下发假电芯批次取货指令失败,指令: {taskString}", state.RobotCrane?.DeviceName);
                else
                {
                    QuartzLogHelper.LogError(_logger, $"下发假电芯批次取货指令失败,指令: {taskString},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                }
            }
        }
@@ -407,35 +394,31 @@
        /// <param name="batchEnd">批次结束编号</param>
        public async Task SendPutWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
        {
            // 先发送总数指令
            string totalNumCmd = $"PutTotalNum,{task.RobotTaskTotalNum}";
            await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
            state.CurrentTask = task;
            // 再发送批次放货指令
            string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
            string taskString = $"Putbattery,{position},{range}";
            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
            if (result)
            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
            {
                _logger.LogInformation("下发放货指令成功,指令: {TaskString},批次: {Range},设备: {DeviceName}",
                    taskString, range, state.RobotCrane?.DeviceName);
                QuartzLogger.Info($"下发放货指令成功,指令: {taskString},批次: {range}", state.RobotCrane?.DeviceName);
                // 先发送总数指令
                string totalNumCmd = $"PutTotalNum,{task.RobotTaskTotalNum}";
                await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                state.CurrentTask = task;
                // 再发送批次放货指令
                string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
                string taskString = $"Putbattery,{position},{range}";
                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
                if (result)
                {
                    await _robotTaskService.UpdateRobotTaskAsync(task);
                    QuartzLogHelper.LogInfo(_logger, $"下发放货指令成功,指令: {taskString},批次: {range},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                    //await _robotTaskService.UpdateRobotTaskAsync(task);
                }
            }
            else
            {
                _logger.LogError("下发放货指令失败,指令: {TaskString},设备: {DeviceName}",
                    taskString, state.RobotCrane?.DeviceName);
                QuartzLogger.Error($"下发放货指令失败,指令: {taskString}", state.RobotCrane?.DeviceName);
                else
                {
                    QuartzLogHelper.LogError(_logger, $"下发放货指令失败,指令: {taskString},设备: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
                }
            }
        }
@@ -462,8 +445,7 @@
            var currentTask = state.CurrentTask;
            if (currentTask == null)
            {
                _logger.LogDebug("HandleInboundTaskAsync:当前任务为空");
                QuartzLogger.Debug($"HandleInboundTaskAsync:当前任务为空", state.RobotCrane?.DeviceName ?? "Unknown");
                QuartzLogHelper.LogDebug(_logger, $"HandleInboundTaskAsync:当前任务为空", state.RobotCrane?.DeviceName ?? "Unknown");
                return false;
            }
@@ -573,17 +555,27 @@
            };
            // 记录日志:开始调用 WMS 创建入库任务
            _logger.LogInformation("HandleInboundTaskAsync:调用WMS创建入库任务,托盘码: {PalletCode},任务类型: {TaskType}", PalletCode, taskType);
            QuartzLogger.Info($"调用WMS创建入库任务,托盘码: {PalletCode},任务类型: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
            QuartzLogHelper.LogInfo(_logger, $"HandleInboundTaskAsync:调用WMS创建入库任务,托盘码: {PalletCode},任务类型: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
            // 调用 WMS 接口创建入库任务
            var result = _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.CreateTaskInboundAsync), taskDto.ToJson());
            string configKey = nameof(ConfigKey.CreateTaskInboundAsync);
            string requestParam = taskDto.ToJson();
            DateTime startTime = DateTime.Now;
            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
            if (!result.IsSuccess || !result.Data.Status)
            {
                QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{configKey}】,请求参数:【{requestParam}】,错误信息:【{result.Data?.Message}】", state.RobotCrane?.DeviceName ?? "Unknown");
                return false;
            }
            QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{configKey}】,响应数据:【{result.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", state.RobotCrane?.DeviceName ?? "Unknown");
            // 如果调用失败或返回错误状态
            if (!result.Data.Status && result.IsSuccess)
            {
                _logger.LogError("HandleInboundTaskAsync:WMS返回错误状态,Status: {Status}", result.Data.Status);
                QuartzLogger.Error($"HandleInboundTaskAsync:WMS返回错误状态", state.RobotCrane?.DeviceName ?? "Unknown");
                QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync:WMS返回错误状态,Status: {result.Data.Status}", state.RobotCrane?.DeviceName ?? "Unknown");
                return false;
            }
@@ -594,8 +586,7 @@
            var content = _taskService.ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO });
            if (!content.Status)
            {
                _logger.LogError("HandleInboundTaskAsync:接收WMS任务失败");
                QuartzLogger.Error($"HandleInboundTaskAsync:接收WMS任务失败", state.RobotCrane?.DeviceName ?? "Unknown");
                QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync:接收WMS任务失败", state.RobotCrane?.DeviceName ?? "Unknown");
                return false;
            }
@@ -632,7 +623,7 @@
            //    }
            //}
            return false;
            return true;
        }
        /// <summary>
@@ -698,7 +689,18 @@
        /// <returns>HTTP 响应结果</returns>
        public HttpResponseResult<WebResponseContent> PostSplitPalletAsync(StockDTO stockDTO)
        {
            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.SplitPalletAsync), stockDTO.ToJson());
            string configKey = nameof(ConfigKey.SplitPalletAsync);
            string requestParam = stockDTO.ToJson();
            DateTime startTime = DateTime.Now;
            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
            if (!result.IsSuccess || !result.Data.Status)
                QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{configKey}】,请求参数:【{requestParam}】,错误信息:【{result.Data?.Message}】", "RobotTaskProcessor");
            else
                QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{configKey}】,响应数据:【{result.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
            return result;
        }
        /// <summary>
@@ -717,7 +719,17 @@
        /// <returns>HTTP 响应结果</returns>
        public HttpResponseResult<WebResponseContent> PostGroupPalletAsync(string configKey, StockDTO stockDTO)
        {
            return _httpClientHelper.Post<WebResponseContent>(configKey, stockDTO.ToJson());
            string requestParam = stockDTO.ToJson();
            DateTime startTime = DateTime.Now;
            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
            if (!result.IsSuccess || !result.Data.Status)
                QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{configKey}】,请求参数:【{requestParam}】,错误信息:【{result.Data?.Message}】", "RobotTaskProcessor");
            else
                QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{configKey}】,响应数据:【{result.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
            return result;
        }
        /// <summary>
@@ -731,8 +743,19 @@
        /// <returns>HTTP 响应结果</returns>
        public HttpResponseResult<WebResponseContent> PostSplitPalletConfirmAsync(string palletCode, string deviceName)
        {
            string configKey = nameof(ConfigKey.SplitPalletConfirm);
            var request = new { PalletCode = palletCode, DeviceName = deviceName };
            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.SplitPalletConfirm), request.ToJson());
            string requestParam = request.ToJson();
            DateTime startTime = DateTime.Now;
            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
            if (!result.IsSuccess || !result.Data.Status)
                QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{configKey}】,请求参数:【{requestParam}】,错误信息:【{result.Data?.Message}】", "RobotTaskProcessor");
            else
                QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{configKey}】,响应数据:【{result.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
            return result;
        }
        /// <summary>
@@ -746,8 +769,25 @@
        /// <returns>HTTP 响应结果</returns>
        public HttpResponseResult<WebResponseContent> PostGroupPalletConfirmAsync(string palletCode, string deviceName)
        {
            string configKey = nameof(ConfigKey.GroupPalletConfirm);
            var request = new { PalletCode = palletCode, DeviceName = deviceName };
            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.GroupPalletConfirm), request.ToJson());
            string requestParam = request.ToJson();
            DateTime startTime = DateTime.Now;
            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
            if (!result.IsSuccess || !result.Data.Status)
                QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{configKey}】,请求参数:【{requestParam}】,错误信息:【{result.Data?.Message}】", "RobotTaskProcessor");
            else
                QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{configKey}】,响应数据:【{result.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
            return result;
        }
        public bool UpdateRobotTask(Dt_RobotTask task)
        {
            WebResponseContent content = _robotTaskService.UpdateData(task);
            return content.Status;
        }
    }
}