using Microsoft.AspNetCore.Components.Routing; 
 | 
using Newtonsoft.Json; 
 | 
using Quartz; 
 | 
using System; 
 | 
using System.Collections.Generic; 
 | 
using System.Diagnostics.CodeAnalysis; 
 | 
using System.Linq; 
 | 
using System.Text; 
 | 
using System.Threading.Tasks; 
 | 
using WIDESEAWCS_Common.APIEnum; 
 | 
using WIDESEAWCS_Common.TaskEnum; 
 | 
using WIDESEAWCS_Core; 
 | 
using WIDESEAWCS_Core.Enums; 
 | 
using WIDESEAWCS_Core.Helper; 
 | 
using WIDESEAWCS_IBasicInfoRepository; 
 | 
using WIDESEAWCS_ITaskInfoRepository; 
 | 
using WIDESEAWCS_ITaskInfoService; 
 | 
using WIDESEAWCS_Model.Models; 
 | 
using WIDESEAWCS_QuartzJob; 
 | 
using WIDESEAWCS_QuartzJob.DeviceBase; 
 | 
using WIDESEAWCS_QuartzJob.Models; 
 | 
using WIDESEAWCS_QuartzJob.Service; 
 | 
using WIDESEAWCS_QuartzJob.StackerCrane.Enum; 
 | 
using WIDESEAWCS_Tasks.HoisterJob; 
 | 
using WIDESEAWCS_Tasks.StackerCraneJob; 
 | 
using WIDESEAWCS_Core.Caches; 
 | 
using WIDESEAWCS_Tasks.ConveyorLineJob; 
 | 
using WIDESEAWCS_QuartzJob.Repository; 
 | 
  
 | 
namespace WIDESEAWCS_Tasks 
 | 
{ 
 | 
    [DisallowConcurrentExecution] 
 | 
    public class StackerCraneJob_GM : JobBase, IJob 
 | 
    { 
 | 
        private readonly ICacheService _cacheService; 
 | 
        private readonly ITaskService _taskService; 
 | 
        private readonly ITaskExecuteDetailService _taskExecuteDetailService; 
 | 
        private readonly ITaskRepository _taskRepository; 
 | 
        private readonly IRouterService _routerService; 
 | 
        private readonly IStationMangerRepository _stationMangerRepository; 
 | 
        private readonly IRouterRepository _routerRepository; 
 | 
        private List<Dt_ApiInfo> apiInfos; 
 | 
  
 | 
        public StackerCraneJob_GM(ITaskService taskService, ICacheService cacheService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository, IRouterRepository routerRepository) 
 | 
        { 
 | 
            _taskService = taskService; 
 | 
            _taskExecuteDetailService = taskExecuteDetailService; 
 | 
            _taskRepository = taskRepository; 
 | 
            _routerService = routerService; 
 | 
            _stationMangerRepository = stationMangerRepository; 
 | 
            _cacheService = cacheService; 
 | 
            _routerRepository = routerRepository; 
 | 
  
 | 
            string? apiInfoStr = _cacheService.Get("apiInfos"); 
 | 
            if (!string.IsNullOrEmpty(apiInfoStr)) 
 | 
            { 
 | 
                List<Dt_ApiInfo>? infos = JsonConvert.DeserializeObject<List<Dt_ApiInfo>>(apiInfoStr); 
 | 
                if (infos == null || infos.Count == 0) 
 | 
                { 
 | 
                    apiInfos = new List<Dt_ApiInfo>(); 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    apiInfos = infos; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        public Task Execute(IJobExecutionContext context) 
 | 
        { 
 | 
            try 
 | 
            { 
 | 
                CommonStackerCrane commonStackerCrane = (CommonStackerCrane)context.JobDetail.JobDataMap.Get("JobParams"); 
 | 
                if (commonStackerCrane != null) 
 | 
                { 
 | 
                    if (!commonStackerCrane.IsEventSubscribed) 
 | 
                    { 
 | 
                        commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件 
 | 
                    } 
 | 
                    commonStackerCrane.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次 
 | 
                    if (commonStackerCrane.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && commonStackerCrane.StackerCraneStatusValue == StackerCraneStatus.Normal && commonStackerCrane.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby) 
 | 
                    { 
 | 
                        Dt_Task? task = GetTask(commonStackerCrane); 
 | 
                        if (task != null) 
 | 
                        { 
 | 
                            StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task); 
 | 
                            if (stackerCraneTaskCommand != null) 
 | 
                            { 
 | 
                                bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand); 
 | 
                                if (sendFlag) 
 | 
                                { 
 | 
                                    commonStackerCrane.LastTaskType = task.TaskType; 
 | 
                                    task.Dispatchertime = DateTime.Now; 
 | 
                                    task.ExceptionMessage = ""; 
 | 
                                    _taskService.UpdateTask(task, TaskStatusEnum.SC_Executing); 
 | 
  
 | 
                                    commonStackerCrane.Communicator.Write("DB105.54", (short)1); 
 | 
                                } 
 | 
                            } 
 | 
                        } 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
            catch (Exception ex) 
 | 
            { 
 | 
                WriteError(nameof(CommonStackerCraneJob), ex.Message, ex); 
 | 
            } 
 | 
            return Task.CompletedTask; 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 任务完成事件订阅的方法 
 | 
        /// </summary> 
 | 
        /// <param name="sender"></param> 
 | 
        /// <param name="e"></param> 
 | 
        private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, WIDESEAWCS_QuartzJob.StackerCrane.StackerCraneTaskCompletedEventArgs e) 
 | 
        { 
 | 
            CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane; 
 | 
            if (commonStackerCrane != null) 
 | 
            { 
 | 
                if (commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5) 
 | 
                { 
 | 
                    StackerCraneTaskCompleted(e.TaskNum, commonStackerCrane.DeviceCode); 
 | 
                    commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        public WebResponseContent StackerCraneTaskCompleted(int taskNum, string deviceCode) 
 | 
        { 
 | 
            try 
 | 
            { 
 | 
                Dt_Task task = _taskRepository.QueryFirst(x => x.TaskNum == taskNum); 
 | 
                if (task != null) 
 | 
                { 
 | 
                    if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) 
 | 
                    { 
 | 
                        Dt_StationManger stationManger = _stationMangerRepository.QueryFirst(x => x.StackerCraneStationCode == task.NextAddress); 
 | 
                        if (stationManger == null) 
 | 
                        { 
 | 
                            _taskExecuteDetailService.AddTaskExecuteDetail(taskNum, $"输送线出库站点未配置,{task.NextAddress}"); 
 | 
                            _taskService.UpdateTaskExceptionMessage(taskNum, $"输送线出库站点未配置,{task.NextAddress}"); 
 | 
                            return WebResponseContent.Instance.Error($"输送线出库站点未配置,{task.NextAddress}"); 
 | 
                        } 
 | 
  
 | 
                        int oldStatus = task.TaskState; 
 | 
                        task.DeviceCode = stationManger.StationDeviceCode; 
 | 
                        task.TaskState = TaskStatusEnum.Line_Execute.ObjToInt(); 
 | 
                        task.CurrentAddress = stationManger.StationCode; 
 | 
                        _taskRepository.UpdateData(task); 
 | 
                        _taskExecuteDetailService.AddTaskExecuteDetail(taskNum, $"系统自动流程,,任务状态从【{oldStatus}】转到【{task.TaskState}】"); 
 | 
                        //todo 完成 
 | 
                    } 
 | 
                    else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup || task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup) 
 | 
                    { 
 | 
                        _taskService.TaskCompleted(taskNum); 
 | 
                    } 
 | 
                    else 
 | 
                    { 
 | 
                        WriteInfo(deviceCode, $"未找到该任务类型回调WMS任务完成接口,{task.TaskType}"); 
 | 
                        _taskExecuteDetailService.AddTaskExecuteDetail(taskNum, $"未找到该任务类型回调WMS任务完成接口,{task.TaskType}"); 
 | 
                        _taskService.UpdateTaskExceptionMessage(taskNum, $"未找到该任务类型回调WMS任务完成接口,{task.TaskType}"); 
 | 
                    } 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    WriteInfo(deviceCode, $"未找到任务信息,任务号:{taskNum}"); 
 | 
                    return WebResponseContent.Instance.Error($"未找到任务信息,任务号:{taskNum}"); 
 | 
                } 
 | 
  
 | 
                return WebResponseContent.Instance.OK(); 
 | 
            } 
 | 
            catch (Exception ex) 
 | 
            { 
 | 
                WriteError(deviceCode, $"任务完成错误", ex); 
 | 
                return WebResponseContent.Instance.Error(ex.Message); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 获取任务 
 | 
        /// </summary> 
 | 
        /// <param name="commonStackerCrane">堆垛机对象</param> 
 | 
        /// <returns></returns> 
 | 
        private Dt_Task? GetTask(CommonStackerCrane commonStackerCrane) 
 | 
        { 
 | 
            Dt_Task task; 
 | 
            if (commonStackerCrane.LastTaskType == null) 
 | 
            { 
 | 
                task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode); 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) 
 | 
                { 
 | 
                    task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode); 
 | 
                    if (task == null) 
 | 
                    { 
 | 
                        task = _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode); 
 | 
                    } 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    task = _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode); 
 | 
                    if (task == null) 
 | 
                    { 
 | 
                        task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode); 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
  
 | 
            if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) 
 | 
            { 
 | 
                if (OutTaskStationIsOccupied(task) == null) 
 | 
                { 
 | 
                    bool flag = false; 
 | 
                    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) 
 | 
                        { 
 | 
                            flag = true; 
 | 
                            break; 
 | 
                        } 
 | 
                    } 
 | 
                    if (!flag) 
 | 
                    { 
 | 
                        task = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode); 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
  
 | 
            if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) 
 | 
            { 
 | 
                string? url = apiInfos.FirstOrDefault(x => x.ApiCode == APIEnum.FeedBackWMSTaskCompleted.ToString())?.ApiAddress; 
 | 
                if (string.IsNullOrEmpty(url)) 
 | 
                { 
 | 
                    _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskNum, $"未找到WMS移库判断接口"); 
 | 
                    WriteInfo(commonStackerCrane.DeviceCode, $"未找到WMS移库判断接口"); 
 | 
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到WMS移库判断接口"); 
 | 
                    return null; 
 | 
                } 
 | 
                HttpHelper.Post($"{url}?taskNum={task.TaskNum}&locationCode={task.NextAddress}", "");//todo 调用WMS任务完成方法 
 | 
            } 
 | 
  
 | 
            return task; 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 出库任务判断出库站台是否被占用 
 | 
        /// </summary> 
 | 
        /// <param name="task">任务实体</param> 
 | 
        /// <returns>如果未被占用,返回传入的任务信息,否则,返回null</returns> 
 | 
        private Dt_Task? OutTaskStationIsOccupied([NotNull] Dt_Task task) 
 | 
        { 
 | 
            Dt_StationManger? stationManger = _stationMangerRepository.QueryFirst(x => x.StationCode == task.NextAddress && x.StackerCraneCode == task.DeviceCode); 
 | 
            if (stationManger != null) 
 | 
            { 
 | 
                IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == stationManger.StationDeviceCode); 
 | 
                if (device != null) 
 | 
                { 
 | 
                    OtherDevice client = (OtherDevice)device; 
 | 
                    if (!client.GetValue<R_ConveyorLineDB, bool>(R_ConveyorLineDB.Goods, stationManger.StationCode))//出库站台未被占用 
 | 
                    { 
 | 
                        task.NextAddress = stationManger.StackerCraneStationCode; 
 | 
                        _taskRepository.UpdateData(task); 
 | 
                        return task; 
 | 
                    } 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    WriteInfo(task.DeviceCode, $"未找到出库站台【{stationManger.StationDeviceCode}】对应的通讯对象,无法判断出库站台是否被占用"); 
 | 
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到出库站台【{stationManger.StationDeviceCode}】对应的通讯对象,无法判断出库站台是否被占用"); 
 | 
                } 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                WriteInfo(task.DeviceCode, $"未找到站台【{task.NextAddress}】信息,无法校验站台"); 
 | 
                _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法校验站台"); 
 | 
            } 
 | 
            return null; 
 | 
        } 
 | 
  
 | 
        /// <summary> 
 | 
        /// 任务实体转换成命令Model 
 | 
        /// </summary> 
 | 
        /// <param name="task">任务实体</param> 
 | 
        /// <returns></returns> 
 | 
        /// <exception cref="Exception"></exception> 
 | 
        public StackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task) 
 | 
        { 
 | 
            StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand(); 
 | 
  
 | 
            stackerCraneTaskCommand.Barcode = task.PalletCode; 
 | 
            stackerCraneTaskCommand.TaskNum = task.TaskNum; 
 | 
            stackerCraneTaskCommand.WorkType = 1; 
 | 
            stackerCraneTaskCommand.TrayType = (Int16)task.PalletType; 
 | 
            if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)//判断是否是入库任务 
 | 
            { 
 | 
                string[] startCodes = task.CurrentAddress.Split("-"); 
 | 
                if (startCodes.Length == 3) 
 | 
                { 
 | 
                    stackerCraneTaskCommand.StartRow = Convert.ToInt16(startCodes[0]); 
 | 
                    stackerCraneTaskCommand.StartColumn = Convert.ToInt16(startCodes[1]); 
 | 
                    stackerCraneTaskCommand.StartLayer = Convert.ToInt16(startCodes[2]); 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库任务起点错误,起点:【{task.CurrentAddress}】"); 
 | 
                    WriteInfo(task.DeviceCode, $"入库任务起点错误,起点:【{task.CurrentAddress}】"); 
 | 
                    return null; 
 | 
                } 
 | 
  
 | 
                string[] targetCodes = task.NextAddress.Split("-"); 
 | 
                if (targetCodes.Length == 5) 
 | 
                { 
 | 
                    stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[1]); 
 | 
                    stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[2]); 
 | 
                    stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[3]); 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    //数据配置错误 
 | 
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"入库任务终点错误,终点:【{task.NextAddress}】"); 
 | 
                    WriteInfo(task.DeviceCode, $"入库任务终点错误,终点:【{task.NextAddress}】"); 
 | 
                    return null; 
 | 
                } 
 | 
            } 
 | 
            else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) 
 | 
            { 
 | 
                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}】"); 
 | 
                    WriteInfo(task.DeviceCode, $"出库任务终点错误,终点:【{task.NextAddress}】"); 
 | 
                    return null; 
 | 
                } 
 | 
  
 | 
                string[] sourceCodes = task.CurrentAddress.Split("-"); 
 | 
                if (sourceCodes.Length == 5) 
 | 
                { 
 | 
                    stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[1]); 
 | 
                    stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[2]); 
 | 
                    stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[3]); 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    //数据配置错误 
 | 
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"出库任务起点错误,起点:【{task.CurrentAddress}】"); 
 | 
                    WriteInfo(task.DeviceCode, $"出库任务起点错误,起点:【{task.CurrentAddress}】"); 
 | 
                    return null; 
 | 
                } 
 | 
            } 
 | 
            else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup) 
 | 
            { 
 | 
                string[] targetCodes = task.NextAddress.Split("-"); 
 | 
                if (targetCodes.Length == 5) 
 | 
                { 
 | 
                    stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[1]); 
 | 
                    stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[2]); 
 | 
                    stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[3]); 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    //数据配置错误 
 | 
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"移库任务终点错误,终点:【{task.NextAddress}】"); 
 | 
                    WriteInfo(task.DeviceCode, $"移库任务终点错误,终点:【{task.NextAddress}】"); 
 | 
                    return null; 
 | 
                } 
 | 
                string[] sourceCodes = task.CurrentAddress.Split("-"); 
 | 
                if (sourceCodes.Length == 5) 
 | 
                { 
 | 
                    stackerCraneTaskCommand.StartRow = Convert.ToInt16(sourceCodes[1]); 
 | 
                    stackerCraneTaskCommand.StartColumn = Convert.ToInt16(sourceCodes[2]); 
 | 
                    stackerCraneTaskCommand.StartLayer = Convert.ToInt16(sourceCodes[3]); 
 | 
                } 
 | 
                else 
 | 
                { 
 | 
                    //数据配置错误 
 | 
                    _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"移库任务起点错误,起点:【{task.CurrentAddress}】"); 
 | 
                    WriteInfo(task.DeviceCode, $"移库任务起点错误,起点:【{task.CurrentAddress}】"); 
 | 
                    return null; 
 | 
                } 
 | 
            } 
 | 
            return stackerCraneTaskCommand; 
 | 
        } 
 | 
    } 
 | 
} 
 |