wanshenmean
6 天以前 fe2a1e74780259605cd230e6f9c629c3dd7fdf15
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
@@ -1,12 +1,14 @@
using MapsterMapper;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Quartz;
using SqlSugar;
using System.Text.Json;
using WIDESEA_Core;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_Core.LogHelper;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
@@ -70,6 +72,18 @@
        private readonly HttpClientHelper _httpClientHelper;
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<CommonConveyorLineNewJob> _logger;
        /// <summary>
        /// 目标地址到设备类型的映射
        /// </summary>
        /// <remarks>
        /// </remarks>
        private static List<string> AddressToDeviceType = new List<string> { "11020", "11028" };
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="taskService">任务服务</param>
@@ -77,16 +91,18 @@
        /// <param name="routerService">路由服务</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="httpClientHelper">HTTP 客户端帮助类</param>
        public CommonConveyorLineNewJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, HttpClientHelper httpClientHelper)
        /// <param name="logger">日志记录器</param>
        public CommonConveyorLineNewJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, HttpClientHelper httpClientHelper, ILogger<CommonConveyorLineNewJob> logger)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
            _routerService = routerService;
            _mapper = mapper;
            _httpClientHelper = httpClientHelper;
            _logger = logger;
            // 初始化调度处理器
            _conveyorLineDispatch = new ConveyorLineDispatchHandler(_taskService, _taskExecuteDetailService, _routerService, _mapper);
            _conveyorLineDispatch = new ConveyorLineDispatchHandler(_taskService, _taskExecuteDetailService, _routerService, _mapper, _logger);
        }
        /// <summary>
@@ -116,21 +132,26 @@
                    if (childDeviceCodes == null || childDeviceCodes.Count == 0)
                    {
                        // 没有子设备,直接返回
                        Console.WriteLine($"输送线 {conveyorLine.DeviceCode} 没有子设备");
                        _logger.LogInformation("输送线 {DeviceCode} 没有子设备", conveyorLine.DeviceCode);
                        QuartzLogger.Info($"输送线 {conveyorLine.DeviceCode} 没有子设备", conveyorLine.DeviceCode);
                        return Task.CompletedTask;
                    }
                    // 创建并行选项,限制最大并发数
                    var parallelOptions = new ParallelOptions
                    {
                        // 限制并发数:子设备数量和 CPU 核心数*2 的较小值
                        MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2),
                    };
                    //var parallelOptions = new ParallelOptions
                    //{
                    //    // 限制并发数:子设备数量和 CPU 核心数*2 的较小值
                    //    MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2),
                    //};
                    //_logger.LogDebug("Execute:开始并行处理输送线 {DeviceCode},子设备数量: {Count}", conveyorLine.DeviceCode, childDeviceCodes.Count);
                    //QuartzLogger.Debug($"开始并行处理输送线,子设备数量: {childDeviceCodes.Count}", conveyorLine.DeviceCode);
                    // 并行处理每个子设备
                    Parallel.For(0, childDeviceCodes.Count, parallelOptions, i =>
                    //Parallel.For(0, childDeviceCodes.Count, parallelOptions, i =>
                    foreach (var childDeviceCode in childDeviceCodes)
                    {
                        string childDeviceCode = childDeviceCodes[i];
                        //string childDeviceCode = childDeviceCodes[i];
                        var correlationId = Guid.NewGuid().ToString("N");
                        try
                        {
@@ -140,12 +161,11 @@
                            // 如果命令为空,跳过
                            if (command == null)
                            {
                                return;
                                _logger.LogDebug("Execute:子设备 {ChildDeviceCode} 命令为空,跳过", childDeviceCode);
                                QuartzLogger.Debug($"子设备 {childDeviceCode} 命令为空,跳过", conveyorLine.DeviceCode);
                                continue;
                            }
                            // 如果 WCS_ACK 为 1,先清除(表示处理过上一次请求)
                            if (command.WCS_ACK == 1)
                                conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 0, childDeviceCode);
                            // ========== 检查特定位置是否有托盘 ==========
                            // 从配置中读取需要检查托盘的位置列表
@@ -156,14 +176,17 @@
                            if (checkPalletPositions.Any(x => x.Code == childDeviceCode))
                            {
                                // 检查输送线状态(是否有托盘)
                                if (command.CV_State.ObjToBool())
                                if (command.CV_State == 2)
                                {
                                    // 检查该位置是否已有任务
                                    var existingTask = _taskService.Repository.QueryFirst(x => x.TargetAddress == childDeviceCode);
                                    var existingTask = _taskService.Db.Queryable<Dt_Task>().First(x => x.TargetAddress == childDeviceCode);
                                    if (existingTask.IsNullOrEmpty())
                                    {
                                        // 没有任务,向 WMS 请求出库托盘任务
                                        var position = checkPalletPositions.FirstOrDefault(x => x.Code == childDeviceCode);
                                        _logger.LogInformation("Execute:检查托盘位置 {ChildDeviceCode},请求WMS出库托盘任务", childDeviceCode);
                                        QuartzLogger.Info($"检查托盘位置 {childDeviceCode},请求WMS出库托盘任务", conveyorLine.DeviceCode);
                                        var responseResult = _httpClientHelper.Post<WebResponseContent>("GetOutBoundTrayTaskAsync", new CreateTaskDto()
                                        {
                                            WarehouseId = position.WarehouseId,
@@ -173,9 +196,10 @@
                                        // 如果请求成功,接收 WMS 返回的任务
                                        if (responseResult.IsSuccess && responseResult.Data.Status)
                                        {
                                            var wmsTask = JsonSerializer.Deserialize<List<WMSTaskDTO>>(responseResult.Data.Data.Serialize());
                                            var wmsTask = JsonConvert.DeserializeObject<WMSTaskDTO>(responseResult.Data.Data.ToString());
                                            List<WMSTaskDTO> taskDTOs = new List<WMSTaskDTO> { wmsTask };
                                            if (wmsTask != null)
                                                _taskService.ReceiveWMSTask(wmsTask);
                                                _taskService.ReceiveWMSTask(taskDTOs);
                                        }
                                    }
                                }
@@ -183,41 +207,53 @@
                            // ========== 检查 PLC_STB 标志 ==========
                            // 只有当 PLC_STB 为 1 时才处理任务
                            if (command.PLC_STB != 1) return;
                            if (command.PLC_STB != 1)
                            {
                                // 如果 WCS_ACK 为 1,先清除(表示处理过上一次请求)
                                if (command.WCS_ACK == 1)
                                    conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 0, childDeviceCode);
                                continue;
                            }
                            // ========== 处理无托盘条码的情况 ==========
                            // 无托盘条码时,请求出库任务
                            if (command.Barcode.IsNullOrEmpty() || command.Barcode.Replace("\0", "") == "")
                            {
                                _logger.LogDebug("Execute:子设备 {ChildDeviceCode} 无托盘条码,请求出库任务", childDeviceCode);
                                QuartzLogger.Debug($"子设备 {childDeviceCode} 无托盘条码,请求出库任务", conveyorLine.DeviceCode);
                                _conveyorLineDispatch.RequestOutbound(conveyorLine, command, childDeviceCode);
                                return;
                                continue;
                            }
                            // ========== 处理已有任务号的情况 ==========
                            if (command.TaskNo > 0)
                            if (command.TaskNo > 0 && !command.Barcode.IsNullOrEmpty())
                            {
                                // 查询正在执行的任务
                                Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.TaskNo, childDeviceCode);
                                if (!task.IsNullOrEmpty())
                                {
                                    _logger.LogInformation("Execute:子设备 {ChildDeviceCode} 处理任务 {TaskNum},状态: {Status}", childDeviceCode, task.TaskNum, task.TaskStatus);
                                    QuartzLogger.Info($"处理任务 {task.TaskNum},状态: {task.TaskStatus}", conveyorLine.DeviceCode);
                                    // 处理任务状态(根据状态分发到不同方法)
                                    ProcessTaskState(conveyorLine, command, task, childDeviceCode);
                                    return;
                                    return Task.CompletedTask;
                                }
                            }
                        }
                        catch (Exception innerEx)
                        {
                            // 记录异常,但不影响其他子设备的处理
                            Console.Error.WriteLine($"{DateTime.UtcNow:O} [{childDeviceCode}] CorrelationId={correlationId} {innerEx}");
                            _logger.LogError(innerEx, "Execute:子设备 {ChildDeviceCode} 处理异常,CorrelationId: {CorrelationId}", childDeviceCode, correlationId);
                            QuartzLogger.Error($"子设备处理异常: {innerEx.Message}", conveyorLine.DeviceCode, innerEx);
                        }
                    });
                    }
                }
            }
            catch (Exception ex)
            {
                // 记录整体异常
                Console.Error.WriteLine(ex);
                _logger.LogError(ex, "Execute:输送线 {DeviceCode} 执行异常", ex.Message);
                QuartzLogger.Error($"输送线执行异常: {ex.Message}", "CommonConveyorLineNewJob", ex);
            }
            return Task.CompletedTask;
        }
@@ -255,7 +291,13 @@
            {
                case InExecuting:
                    // 入库执行中,调用下一地址处理
                    _conveyorLineDispatch.RequestInNextAddress(conveyorLine, command, childDeviceCode);
                    if (AddressToDeviceType.Contains(childDeviceCode))
                        // 到达目标地址,调用入库完成
                        _conveyorLineDispatch.ConveyorLineInFinish(conveyorLine, command, childDeviceCode);
                    else
                        // 未到达目标地址,调用入库下一地址处理
                        _conveyorLineDispatch.RequestInNextAddress(conveyorLine, command, childDeviceCode);
                    break;
                case OutExecuting:
@@ -280,4 +322,4 @@
            }
        }
    }
}
}