刘磊
2024-12-26 d8f650de070335be494c33d0705e8105b7a215d6
Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
@@ -1,17 +1,15 @@
using Autofac.Core;
using HslCommunication;
using Newtonsoft.Json;
using Mapster;
using Quartz;
using System.Diagnostics.CodeAnalysis;
using WIDESEAWCS_BasicInfoRepository;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_Core.HttpContextUser;
using WIDESEAWCS_DTO.MOM;
using WIDESEAWCS_IProcessRepository;
using WIDESEAWCS_ITaskInfo_HtyRepository;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_QuartzJob.DeviceBase;
@@ -19,6 +17,7 @@
using WIDESEAWCS_QuartzJob.Service;
using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
using WIDESEAWCS_SignalR;
using WIDESEAWCS_Tasks.ConveyorLineJob;
using WIDESEAWCS_Tasks.StackerCraneJob;
namespace WIDESEAWCS_Tasks
@@ -33,8 +32,10 @@
        private readonly IProcessRepository _processRepository;
        private readonly ICacheService _cacheService;
        private readonly INoticeService _noticeService;
        private readonly IDt_StationManagerRepository _stationManagerRepository;
        private readonly ITask_HtyRepository _htyRepository;
        public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IProcessRepository processRepository, ICacheService cacheService, INoticeService noticeService)
        public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IProcessRepository processRepository, ICacheService cacheService, INoticeService noticeService, IDt_StationManagerRepository stationManagerRepository, ITask_HtyRepository htyRepository)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
@@ -43,6 +44,8 @@
            _processRepository = processRepository;
            _cacheService = cacheService;
            _noticeService = noticeService;
            _stationManagerRepository = stationManagerRepository;
            _htyRepository = htyRepository;
        }
        public Task Execute(IJobExecutionContext context)
@@ -89,27 +92,25 @@
                    #region 调用事件总线通知前端
                    var tokenInfos = _cacheService.Get<List<UserInfo>>("Cache_UserToken");
                    if (tokenInfos == null || !tokenInfos.Any())
                    if (tokenInfos != null && tokenInfos.Any())
                    {
                        throw new Exception(commonStackerCrane.DeviceName + "缓存中未找到Token缓存");
                    }
                    var userTokenIds = tokenInfos?.Select(x => x.Token_ID).ToList();
                    var userIds = tokenInfos?.Select(x => x.UserId).ToList();
                        var userTokenIds = tokenInfos?.Select(x => x.Token_ID).ToList();
                        var userIds = tokenInfos?.Select(x => x.UserId).ToList();
                    object obj = new
                    {
                        commonStackerCrane.StackerCraneStatusDes,
                        commonStackerCrane.StackerCraneAutoStatusDes,
                        commonStackerCrane.StackerCraneWorkStatusDes,
                        commonStackerCrane.DeviceCode,
                        commonStackerCrane.DeviceName,
                        commonStackerCrane.CurrentTaskNum,
                        commonStackerCrane.LastTaskNum,
                    };
                    _noticeService.StackerData(userIds?.FirstOrDefault(), userTokenIds, new { commonStackerCrane.DeviceName, data = obj });
                        object obj = new
                        {
                            commonStackerCrane.StackerCraneStatusDes,
                            commonStackerCrane.StackerCraneAutoStatusDes,
                            commonStackerCrane.StackerCraneWorkStatusDes,
                            commonStackerCrane.DeviceCode,
                            commonStackerCrane.DeviceName,
                            commonStackerCrane.CurrentTaskNum,
                            commonStackerCrane.LastTaskNum,
                        };
                        _noticeService.StackerData(userIds?.FirstOrDefault(), userTokenIds, new { commonStackerCrane.DeviceName, data = obj });
                    }
                    #endregion 调用事件总线通知前端
                }
            }
            catch (Exception ex)
@@ -132,11 +133,49 @@
            CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane;
            if (commonStackerCrane != null)
            {
                if (commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5)
                //var x = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType);
                //if (commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5)
                {
                    //Console.Out.WriteLine("TaskCompleted" + e.TaskNum);
                    ConsoleHelper.WriteColorLine($"【{commonStackerCrane.DeviceName}】任务完成,任务号:【{e.TaskNum}】", ConsoleColor.Blue);
                    var task = _taskRepository.QueryFirst(x => x.TaskNum == e.TaskNum);
                    if (task == null) commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5);
                    if (commonStackerCrane.DeviceCode.Contains("GW") && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
                    {
                        var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == task.TargetAddress);
                        IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == station.stationPLC);
                        if (device != null)
                        {
                            CommonConveyorLine_GW conveyorLine = (CommonConveyorLine_GW)device;
                            var isResult = conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineBarcode, task.PalletCode, task.TargetAddress);
                            if (!isResult)
                            {
                                var result = conveyorLine.GetValue<ConveyorLineDBName_After, string>(ConveyorLineDBName_After.ConveyorLineBarcode, task.TargetAddress);
                                if (result != task.PalletCode)
                                {
                                    conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineBarcode, task.PalletCode, task.TargetAddress);
                                }
                            }
                        }
                        else
                            return;
                    }
                    _taskService.StackCraneTaskCompleted(e.TaskNum);
                    if (commonStackerCrane.DeviceCode.Contains("CH") && task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
                    {
                        task = _taskRepository.QueryFirst(x => x.TaskNum == e.TaskNum);
                        Dt_Task? newTask = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress);
                    }
                    if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup && task.TargetAddress == "002-021-001")
                    {
                        var TASKHTY = task.Adapt<Dt_Task_Hty>();
                        _taskRepository.DeleteData(task);
                        _htyRepository.AddData(TASKHTY);
                    }
                    commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5);
                }
            }
@@ -150,15 +189,14 @@
        private Dt_Task? GetTask(CommonStackerCrane commonStackerCrane)
        {
            Dt_Task task;
            var taskRun = _taskRepository.QueryFirst(x => x.TaskState == (int)TaskOutStatusEnum.SC_OutExecuting || x.TaskState == (int)TaskInStatusEnum.SC_InExecuting);
            if (taskRun != null) { return null; }
            if (commonStackerCrane.LastTaskType == null)
            {
                task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode);
            }
            else
            {
                if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
                var lastTaskTypeGroup = commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup();
                if (lastTaskTypeGroup == TaskTypeGroup.OutbondGroup)
                {
                    task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
                    if (task == null)
@@ -174,23 +212,18 @@
            if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
            {
                if (OutTaskStationIsOccupied(task) != null)
                // 检查当前出库任务站台是否允许放货
                var occupiedStation = OutTaskStationIsOccupied(task);
                if (occupiedStation == null)
                {
                    // 如果当前出库任务站台不允许放货,排除当前任务,查找其他出库任务
                    ConsoleHelper.WriteErrorLine($"任务号:【{task.TaskNum}】出库地址:【{task.NextAddress}】不允许放货");
                    task = FindAnotherOutboundTask(commonStackerCrane.DeviceCode, task.TaskId);
                }
                else
                {
                    return task;
                }
                //else
                //{
                //    List<string> otherOutStaionCodes = _routerService.QueryNextRoutes(commonStackerCrane.DeviceCode, task.NextAddress).Select(x => x.ChildPosi).ToList();
                //    List<Dt_Task> tasks = _taskService.QueryStackerCraneOutTasks(commonStackerCrane.DeviceCode, otherOutStaionCodes);
                //    foreach (var item in tasks)
                //    {
                //        if (OutTaskStationIsOccupied(task) != null)
                //        {
                //            return task;
                //        }
                //    }
                //    task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
                //}
            }
            else if (task == null)
            {
@@ -212,34 +245,44 @@
            {
                if (router != null)
                {
                    IDevice? device = null;
                    if (task.Roadway.Contains("CW"))
                    {
                        device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
                    }
                    else
                    {
                        device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "1015");
                    }
                    if (device != null)
                    {
                        CommonConveyorLine_GW conveyorLine = (CommonConveyorLine_GW)device;
                        if (conveyorLine.IsOccupied(task.TargetAddress))//出库站台未被占用
                        if (device != null)
                        {
                            return task;
                            CommonConveyorLine_GW conveyorLine = (CommonConveyorLine_GW)device;
                            if (conveyorLine.IsOccupied(task.NextAddress))//出库站台未被占用
                            {
                                return task;
                            }
                        }
                    }
                    else
                    {
                        _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到出库站台【{task.TargetAddress}】对应的通讯对象,无法判断出库站台是否被占用");
                        else
                        {
                            _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到出库站台【{task.NextAddress}】对应的通讯对象,无法判断出库站台是否被占用");
                        }
                    }
                }
                else
                {
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法校验站台");
                    IDevice? device = null;
                    if (task.Roadway.Contains("GW"))
                    {
                        device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "1015");
                        if (device != null)
                        {
                            CommonConveyorLine_GW conveyorLine = (CommonConveyorLine_GW)device;
                            if (conveyorLine.IsOccupied(task.TargetAddress))//出库站台未被占用
                            {
                                return task;
                            }
                        }
                        else
                        {
                            _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到出库站台【{task.TargetAddress}】对应的通讯对象,无法判断出库站台是否被占用");
                        }
                    }
                    //_taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.TargetAddress}】信息,无法校验站台");
                }
            }
            else
@@ -251,7 +294,7 @@
                    if (device != null)
                    {
                        CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
                        if (conveyorLine.IsOccupied(router.ChildPosi))//出库站台未被占用
                        //if (conveyorLine.IsOccupied(router.ChildPosi))//出库站台未被占用
                        {
                            return task;
                        }
@@ -266,6 +309,37 @@
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法校验站台");
                }
            }
            return null;
        }
        /// <summary>
        /// 查找其他出库任务的辅助方法(排除指定任务ID的任务)
        /// </summary>
        /// <param name="deviceCode">设备代码</param>
        /// <param name="excludedTaskId">要排除的任务ID</param>
        /// <returns></returns>
        private Dt_Task? FindAnotherOutboundTask(string deviceCode, int excludedTaskId)
        {
            // 先获取所有符合条件(排除指定任务ID)的出库任务列表
            var allOutboundTasks = _taskService.QueryAllOutboundTasks(deviceCode);
            var availableTasks = allOutboundTasks?.Where(t => excludedTaskId != t.TaskId && t.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup).ToList();
            if (availableTasks == null || availableTasks.Count == 0)
            {
                return null;
            }
            // 遍历可用任务列表,检查任务站台是否允许放货,找到第一个允许放货的任务就返回
            foreach (var candidateTask in availableTasks)
            {
                var occupiedStation = OutTaskStationIsOccupied(candidateTask);
                if (occupiedStation != null)
                {
                    return candidateTask;
                }
                ConsoleHelper.WriteErrorLine($"任务号:【{candidateTask.TaskNum}】出库地址:【{candidateTask.NextAddress}】不允许放货");
            }
            return null;
        }
@@ -286,13 +360,21 @@
            stackerCraneTaskCommand.StartCommand = 1;
            if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)//判断是否是入库任务
            {
                List<Dt_Router> routers = _routerService.QueryNextRoutes(task.CurrentAddress, task.Roadway);
                if (routers.Count > 0)
                if (task.SourceAddress == "1359-4" && task.Roadway.Contains("JZ"))
                {
                    stackerCraneTaskCommand.StartRow = Convert.ToInt16(routers.FirstOrDefault().SrmRow);
                    stackerCraneTaskCommand.StartColumn = Convert.ToInt16(routers.FirstOrDefault().SrmColumn);
                    stackerCraneTaskCommand.StartLayer = Convert.ToInt16(routers.FirstOrDefault().SrmLayer);
                    string[] souredCodes = task.CurrentAddress.Split("-");
                    if (souredCodes.Length == 3)
                    {
                        stackerCraneTaskCommand.StartRow = Convert.ToInt16(souredCodes[0]);
                        stackerCraneTaskCommand.StartColumn = Convert.ToInt16(souredCodes[1]);
                        stackerCraneTaskCommand.StartLayer = Convert.ToInt16(souredCodes[2]);
                    }
                    else
                    {
                        //数据配置错误
                        _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库任务起点错误,起点:【{task.CurrentAddress}】");
                        return null;
                    }
                    string[] targetCodes = task.NextAddress.Split("-");
                    if (targetCodes.Length == 3)
                    {
@@ -309,8 +391,32 @@
                }
                else
                {
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法获取对应的堆垛机取货站台信息");
                    return null;
                    List<Dt_Router> routers = _routerService.QueryNextRoutes(task.CurrentAddress, task.Roadway);
                    if (routers.Count > 0)
                    {
                        stackerCraneTaskCommand.StartRow = Convert.ToInt16(routers.FirstOrDefault().SrmRow);
                        stackerCraneTaskCommand.StartColumn = Convert.ToInt16(routers.FirstOrDefault().SrmColumn);
                        stackerCraneTaskCommand.StartLayer = Convert.ToInt16(routers.FirstOrDefault().SrmLayer);
                        string[] targetCodes = task.NextAddress.Split("-");
                        if (targetCodes.Length == 3)
                        {
                            stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[0]) % 2 != 0 ? (short)1 : (short)2;
                            stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[1]);
                            stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[2]);
                        }
                        else
                        {
                            //数据配置错误
                            _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库任务终点错误,起点:【{task.NextAddress}】");
                            return null;
                        }
                    }
                    else
                    {
                        _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法获取对应的堆垛机取货站台信息");
                        return null;
                    }
                }
            }
            else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
@@ -328,31 +434,45 @@
                }
                else
                {
                    List<Dt_Router> routers = _routerService.QueryNextRoutes(task.Roadway, task.TargetAddress);
                    if (routers.Count > 0)
                    if (task.TargetAddress == "002-021-001" && task.Roadway.Contains("JZ") && task.TaskType == (int)TaskOutboundTypeEnum.OutTray)
                    {
                        stackerCraneTaskCommand.EndRow = Convert.ToInt16(routers.FirstOrDefault().SrmRow);
                        stackerCraneTaskCommand.EndColumn = Convert.ToInt16(routers.FirstOrDefault().SrmColumn);
                        stackerCraneTaskCommand.EndLayer = Convert.ToInt16(routers.FirstOrDefault().SrmLayer);
                        string[] sourceCodes = task.CurrentAddress.Split("-");
                        if (sourceCodes.Length == 3)
                        {
                            stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]) % 2 != 0 ? (short)1 : (short)2;
                            stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]);
                            stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]);
                        }
                        else
                        {
                            //数据配置错误
                            _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"出库任务起点错误,起点:【{task.CurrentAddress}】");
                            return null;
                        }
                        string[] endCodes = task.NextAddress.Split("-");
                        stackerCraneTaskCommand.EndRow = Convert.ToInt16(endCodes[0]);
                        stackerCraneTaskCommand.EndColumn = Convert.ToInt16(endCodes[1]);
                        stackerCraneTaskCommand.EndLayer = Convert.ToInt16(endCodes[2]);
                        string[] sourceCodes = task.SourceAddress.Split("-");
                        stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]) % 2 != 0 ? (short)1 : (short)2;
                        stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]);
                        stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]);
                    }
                    else
                    {
                        _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法获取对应的堆垛机放货站台信息");
                        return null;
                        List<Dt_Router> routers = _routerService.QueryNextRoutes(task.Roadway, task.TargetAddress);
                        if (routers.Count > 0)
                        {
                            stackerCraneTaskCommand.EndRow = Convert.ToInt16(routers.FirstOrDefault().SrmRow);
                            stackerCraneTaskCommand.EndColumn = Convert.ToInt16(routers.FirstOrDefault().SrmColumn);
                            stackerCraneTaskCommand.EndLayer = Convert.ToInt16(routers.FirstOrDefault().SrmLayer);
                            string[] sourceCodes = task.CurrentAddress.Split("-");
                            if (sourceCodes.Length == 3)
                            {
                                stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]) % 2 != 0 ? (short)1 : (short)2;
                                stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]);
                                stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]);
                            }
                            else
                            {
                                //数据配置错误
                                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"出库任务起点错误,起点:【{task.CurrentAddress}】");
                                return null;
                            }
                        }
                        else
                        {
                            _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法获取对应的堆垛机放货站台信息");
                            return null;
                        }
                    }
                }
            }
@@ -387,38 +507,5 @@
            }
            return stackerCraneTaskCommand;
        }
        /// <summary>
        /// 设备心跳
        /// </summary>
        /// <param name="commonStackerCrane"></param>
        //public async void EqptAlive(CommonStackerCrane commonStackerCrane)
        //{
        //    if (commonStackerCrane.StackerOnline)
        //    {
        //        BasicDto dto = new BasicDto
        //        {
        //            EmployeeNo = "T00001",
        //            EquipmentCode = commonStackerCrane.DeviceCode,
        //            RequestTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
        //            SessionId = Guid.NewGuid().ToString(),
        //            Software = commonStackerCrane.DeviceName,
        //        };
        //        var respone = await HttpHelper.PostAsync("http://ts-momapp01:12020/api/MachineIntegration/EqptAlive", dto.ToJsonString());
        //        if (respone != null)
        //        {
        //            var result = JsonConvert.DeserializeObject<ResponseEqptAliveDto>(respone);
        //            if (result != null && result.Success)
        //            {
        //                if (result.KeyFlag == "99")
        //                    commonStackerCrane.StackerOnline = true;
        //                else if (result.KeyFlag == "98")
        //                    commonStackerCrane.StackerOnline = false;
        //            }
        //        }
        //    }
        //}
    }
}