肖洋
2025-01-15 ef7ff6f2da6051b0a0db3babd61a29ed69e3e228
Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerStationJob/CommonStackerStationCraneJob.cs
@@ -2,10 +2,13 @@
using Newtonsoft.Json;
using Quartz;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Threading.Tasks;
using WIDESEAWCS_BasicInfoRepository;
using WIDESEAWCS_BasicInfoService;
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_ITaskInfoRepository;
@@ -17,6 +20,7 @@
using WIDESEAWCS_QuartzJob.Models;
using WIDESEAWCS_QuartzJob.Service;
using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
using WIDESEAWCS_SignalR;
using WIDESEAWCS_Tasks.StackerCraneJob;
namespace WIDESEAWCS_Tasks
@@ -29,17 +33,18 @@
        private readonly ITaskRepository _taskRepository;
        private readonly IProcessRepository _processRepository;
        private readonly IDt_StationManagerRepository _stationManagerRepository;
        private readonly IRouterService _routerService;
        private readonly ICacheService _cacheService;
        private readonly INoticeService _noticeService;
        public CommonStackerStationCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IProcessRepository processRepository, IDt_StationManagerRepository stationManagerRepository)
        public CommonStackerStationCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IProcessRepository processRepository, IDt_StationManagerRepository stationManagerRepository, ICacheService cacheService, INoticeService noticeService)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
            _taskRepository = taskRepository;
            _processRepository = processRepository;
            _stationManagerRepository = stationManagerRepository;
            _routerService = routerService;
            _cacheService = cacheService;
            _noticeService = noticeService;
        }
        public Task Execute(IJobExecutionContext context)
@@ -72,9 +77,21 @@
                                StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task);
                                if (stackerCraneTaskCommand != null)
                                {
                                    Thread.Sleep(1000);
                                    bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand);
                                    if (sendFlag)
                                    {
                                        //commonStackerCrane.LastTaskType = task.TaskType;
                                        //_taskService.UpdateTaskStatusToNext(task.TaskNum);
                                        StringBuilder builder = new StringBuilder();
                                        builder.AppendLine();
                                        builder.AppendLine($"【{commonStackerCrane.DeviceName}】堆垛机状态:【{commonStackerCrane.StackerCraneStatusDes}】,时间:【{DateTime.Now}】");
                                        builder.AppendLine($"【{commonStackerCrane.DeviceName}】手自动状态:【{commonStackerCrane.StackerCraneAutoStatusDes}】,时间:【{DateTime.Now}】");
                                        builder.AppendLine($"【{commonStackerCrane.DeviceName}】作业状态:【{commonStackerCrane.StackerCraneWorkStatusDes}】,时间:【{DateTime.Now}】");
                                        builder.AppendLine($"【{commonStackerCrane.DeviceName}】下发任务成功,【{JsonConvert.SerializeObject(stackerCraneTaskCommand, Formatting.Indented)}】");
                                        builder.AppendLine($"时间:【{DateTime.Now}】");
                                        builder.AppendLine();
                                        ConsoleHelper.WriteColorLine(builder, ConsoleColor.Blue);
                                        commonStackerCrane.LastTaskType = task.TaskType;
                                        _taskService.UpdateTaskStatusToNext(task.TaskNum);
                                    }
@@ -82,6 +99,31 @@
                            }
                        }
                    }
                    #region 调用事件总线通知前端
                    var tokenInfos = _cacheService.Get<List<UserInfo>>("Cache_UserToken");
                    if (tokenInfos == null || !tokenInfos.Any())
                    {
                        //throw new Exception(commonStackerCrane.DeviceName + "缓存中未找到Token缓存");
                        return Task.CompletedTask;
                    }
                    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 });
                    #endregion 调用事件总线通知前端
                }
            }
            catch (Exception ex)
@@ -105,9 +147,19 @@
            {
                if (commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5)
                {
                    Console.Out.WriteLine("TaskCompleted" + e.TaskNum);
                    _taskService.StackCraneTaskCompleted(e.TaskNum);
                    ConsoleHelper.WriteColorLine($"【{commonStackerCrane.DeviceName}】堆垛机作业状态:【{(int)commonStackerCrane.StackerCraneWorkStatusValue}】时间【{DateTime.Now}】", ConsoleColor.Magenta);
                    string str = $"【{commonStackerCrane.DeviceName}】任务完成,任务号:【{e.TaskNum}】时间【{DateTime.Now}】";
                    WriteInfo(commonStackerCrane.DeviceName, str);
                    ConsoleHelper.WriteColorLine(str, ConsoleColor.Blue);
                    var content = _taskService.StackCraneTaskCompletedByStation(e.TaskNum);
                    commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5);
                    var isWorkType = commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5);
                    str = $"{commonStackerCrane.DeviceName}】WMS|WCS任务完成:【{content.Status}】,堆垛机完成信号写入:【{isWorkType}】,任务号:【{e.TaskNum}】时间【{DateTime.Now}】";
                    WriteInfo(commonStackerCrane.DeviceName, str);
                    ConsoleHelper.WriteColorLine(str, ConsoleColor.Blue);
                }
            }
        }
@@ -120,6 +172,13 @@
        private Dt_Task? GetTask(CommonStackerStationCrane commonStackerCrane)
        {
            Dt_Task task;
            task = _taskService.QueryRelocationTask(commonStackerCrane.DeviceCode);
            if (task != null)
            {
                return task;
            }
            if (commonStackerCrane.LastTaskType == null)
            {
                task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode);
@@ -142,21 +201,21 @@
            if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
            {
                if (OutTaskStationIsOccupied(task) != null)
                // 检查当前出库任务站台是否允许放货
                var occupiedStation = OutTaskStationIsOccupied(task);
                if (occupiedStation == null)
                {
                    return task;
                    // 如果当前出库任务站台不允许放货,排除当前任务,查找其他出库任务
                    ConsoleHelper.WriteErrorLine($"任务号:【{task.TaskNum}】出库地址:【{task.NextAddress}】不允许放货");
                    task = FindAnotherOutboundTask(commonStackerCrane.DeviceCode, 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;
                    //    }
                    //}
                    return task;
                }
                if (task == null)
                {
                    task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
                }
            }
@@ -193,6 +252,40 @@
        }
        /// <summary>
        /// 查找其他出库任务的辅助方法(排除不可出的出库口任务)
        /// </summary>
        /// <param name="deviceCode">设备代码</param>
        /// <param name="excludedTaskId">要排除的任务ID</param>
        /// <returns></returns>
        private Dt_Task? FindAnotherOutboundTask(string deviceCode, Dt_Task task)
        {
            // 先获取所有符合条件(排除不可出的)的出库任务列表
            var allOutboundTasks = _taskService.QueryAllOutboundTasks(deviceCode);
            Console.WriteLine(allOutboundTasks.Count);
            var availableTasks = allOutboundTasks?.Where(t => t.TargetAddress != task.TargetAddress && t.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup).ToList();
            Console.WriteLine("其他出库口任务:" + availableTasks?.Count);
            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;
        }
        /// <summary>
        /// 任务实体转换成命令Model
        /// </summary>
        /// <param name="task">任务实体</param>
@@ -207,127 +300,35 @@
            stackerCraneTaskCommand.WorkType = 1;
            stackerCraneTaskCommand.TrayType = 0;
            stackerCraneTaskCommand.StartCommand = 1;
            if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)//判断是否是入库任务
            {
                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]);
                        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)
            string[] sourceCodes = task.SourceAddress.Split("-");
            if (sourceCodes.Length == 3)
            {
                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);
                stackerCraneTaskCommand.StartRow = (short)(Convert.ToInt16(sourceCodes[0]) % 2 == 0 ? 2 : 1);
                stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]);
                stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]);
            }
            else
            {
                //数据配置错误
                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"移库任务起点错误,起点:【{task.CurrentAddress}】");
                return null;
            }
            string[] targetCodes = task.TargetAddress.Split("-");
            if (targetCodes.Length == 3)
            {
                stackerCraneTaskCommand.EndRow = (short)(Convert.ToInt16(targetCodes[0]) % 2 == 0 ? 2 : 1);
                stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[1]);
                stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[2]);
            }
            else
            {
                //数据配置错误
                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"任务终点错误,起点:【{task.NextAddress}】");
                return null;
            }
                    string[] sourceCodes = task.CurrentAddress.Split("-");
                    if (sourceCodes.Length == 3)
                    {
                        stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]);
                        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;
                }
            }
            else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup)
            {
                string[] targetCodes = task.NextAddress.Split("-");
                if (targetCodes.Length == 3)
                {
                    stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[0]);
                    stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[1]);
                    stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[2]);
                }
                else
                {
                    //数据配置错误
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"移库任务终点错误,起点:【{task.NextAddress}】");
                    return null;
                }
                string[] sourceCodes = task.CurrentAddress.Split("-");
                if (sourceCodes.Length == 3)
                {
                    stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[0]);
                    stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[1]);
                    stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[2]);
                }
                else
                {
                    //数据配置错误
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"移库任务起点错误,起点:【{task.CurrentAddress}】");
                    return null;
                }
            }
            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;
                    }
                }
            }
        }
    }
}