1
xiazhengtongxue
2026-02-07 4f2fb79143f0545e96f114c92e1da733b2d9716a
ÏîÄ¿´úÂë/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WMSCruJob.cs
@@ -40,6 +40,7 @@
    {
        private readonly ILogger<WMSCruJob> _logger;
        private Timer _timer;
        private Timer _timer2;
        private readonly ITaskService _taskService;
        private readonly ILocationInfoService _locationInfoService;
        private readonly IStockInfoService _stockInfoService;
@@ -56,113 +57,74 @@
            _taskService=taskService;
        }
        private static readonly object _taskProcessLock = new object();
        private const int TASK_PROCESS_TIMEOUT = 3000; // 3秒超时
        private const int TASK_PROCESS_TIMEOUT = 1000; // 2秒超时
        private readonly Queue<int> _deviceQueueSC = new Queue<int>();
        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWorkWheel, null, TimeSpan.Zero, TimeSpan.FromSeconds(3));
            // åˆå§‹åŒ–设备队列(1-5)
            for (int i = 1; i <= 5; i++)
            {
                _deviceQueueSC.Enqueue(i);
            }
            _timer = new Timer(SCProcessNextDevice, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
            //_timer2 = new Timer(PLCDoDeciceWork, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
            return Task.CompletedTask;
        }
        public static List<string> InStationareaList = new List<string>() { "1113", "1114", "1115", "1116", "1117", "1118", "1119", "1120", "1121", "1122" };
        private void DoWorkWheel(object state)
        //堆垛机队列
        private void SCProcessNextDevice(object state)
        {
            if (!Monitor.TryEnter(_taskProcessLock, TASK_PROCESS_TIMEOUT))
            {
                return;
            }
            if (!Monitor.TryEnter(_taskProcessLock, TASK_PROCESS_TIMEOUT)) return;
            try
            {
                // å®šä¹‰çŠ¶æ€å¸¸é‡ï¼Œé¿å…é­”æ³•æ•°å­—
                const int PLC_IN_FINISH = (int)InTaskStatusEnum.PLC_InFinish;
                const int PLC_IN_InNew = (int)InTaskStatusEnum.InNew;
                const int OUT_NEW = (int)OutTaskStatusEnum.OutNew;
                const int SC_OUT_FINISH = (int)OutTaskStatusEnum.SC_OutFinish;
                const int SC_IN_EXECUTING = (int)InTaskStatusEnum.SC_IntExecuting;
                const int SC_OUT_EXECUTING = (int)OutTaskStatusEnum.SC_OutExecuting;
                const int RELOCATION_EXECUTING = (int)RelocationTaskStatusEnum.RelocationExecuting;
                const int PLC_OUT_EXECUTING = (int)OutTaskStatusEnum.PLC_OutExecuting;
                if (_deviceQueueSC.Count == 0)
                    return;
                // èŽ·å–å½“å‰ä»»åŠ¡æ•°æ®
                List<Dt_Task> allTasks = _taskService.Repository.QueryData();
                int deviceId = _deviceQueueSC.Dequeue();
                // èŽ·å–å··é“è¶…è¿‡3个任务的路段
                HashSet<string> excludedRoadways = allTasks
                    .Where(x => x.NumberSsuances > 3)
                    .Select(x => x.Roadway)
                    .Distinct()
                    .ToHashSet();
                // è¿‡æ»¤éœ€è¦å¤„理的任务
                List<Dt_Task> tasksToProcess = allTasks
                    .Where(x =>
                        (x.TaskStatus == PLC_IN_FINISH ||
                         x.TaskStatus == OUT_NEW ||
                         x.TaskStatus == SC_OUT_FINISH || (x.TaskStatus == PLC_IN_InNew && InStationareaList.Contains(x.SourceAddress))) &&
                        !excludedRoadways.Contains(x.Roadway))
                    .ToList();
                // æŒ‰çŠ¶æ€åˆ†ç»„å¤„ç†ï¼Œå‡å°‘é‡å¤æŸ¥è¯¢
                ProcessInAndNewTasks(tasksToProcess, allTasks, excludedRoadways);   //下发堆垛机
                ProcessOutFinishTasks(tasksToProcess, allTasks);    //下发输送线任务
                ProcessInPalltask(tasksToProcess, allTasks);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"任务处理异常:{ex.Message}");
                try
                {
                    SCDoDeviceWork(deviceId);
                    _deviceQueueSC.Enqueue(deviceId);
                    PLCDoDeciceWork();
                }
                catch (Exception ex)
                {
                    _deviceQueueSC.Enqueue(deviceId);
                    Console.WriteLine($"设备 {deviceId} æ‰§è¡Œå¤±è´¥: {ex.Message}");
                }
            }
            finally
            {
                // å¿…须释放锁,否则会导致死锁
                Monitor.Exit(_taskProcessLock);
            }
        }
        private void ProcessInAndNewTasks(List<Dt_Task> tasksToProcess, List<Dt_Task> allTasks, HashSet<string> excludedRoadways)
        //执行方法
        private void SCDoDeviceWork(int deviceId)
        {
            const int PLC_IN_FINISH = (int)InTaskStatusEnum.PLC_InFinish;
            const int OUT_NEW = (int)OutTaskStatusEnum.OutNew;
            const int SC_IN_EXECUTING = (int)InTaskStatusEnum.SC_IntExecuting;
            const int SC_OUT_EXECUTING = (int)OutTaskStatusEnum.SC_OutExecuting;
            const int RELOCATION_EXECUTING = (int)RelocationTaskStatusEnum.RelocationExecuting;
            const int RELOCCATION_NEW = (int)RelocationTaskStatusEnum.RelocationNew;
            var inAndNewTasks = tasksToProcess
                .Where(x => x.TaskStatus == PLC_IN_FINISH || x.TaskStatus == OUT_NEW).OrderBy(x=>x.CreateDate)
                .ToList();
            if(inAndNewTasks.Count > 0)
            try
            {
                foreach (var task in inAndNewTasks)
                //判断当前堆垛机是否有执行任务
                if (_taskService.CurrentTaskProgress(deviceId.ToString())) return;
                // èŽ·å–å½“å‰å †åž›æœºä»»åŠ¡
                List<Dt_Task> taskList = _taskService.GetaskQueue(deviceId.ToString());
                if (taskList.Count == 0) return;
                foreach (Dt_Task task in taskList)
                {
                    // æ£€æŸ¥åŒä¸€å··é“是否有正在执行的任务
                    bool hasExecutingTask = allTasks.Any(x =>
                        x.TaskId != task.TaskId &&
                        x.Roadway == task.Roadway &&
                        (x.TaskStatus == SC_IN_EXECUTING ||
                         x.TaskStatus == SC_OUT_EXECUTING ||
                         x.TaskStatus == RELOCATION_EXECUTING || x.TaskStatus == RELOCCATION_NEW));
                    if (hasExecutingTask)
                        continue;
                    if (task.TaskStatus == OUT_NEW)
                    WebResponseContent webResponse = JudgmentIsRelocations(task);
                    if (!webResponse.Status)
                    {
                        bool SCNewTasks = allTasks.Any(x => x.TaskStatus != OUT_NEW && x.TargetAddress == task.TargetAddress);
                        if (SCNewTasks)
                            continue;
                        WriteLog.Write_Log("WMS_移库故障", $"移库返回失败内容", "失败", $"移库失败,原因:{webResponse.Message}");
                        return;
                    }
                    //判断是否需要移库
                    WebResponseContent webResponse = JudgmentIsRelocations(task);
                    if (!webResponse.Status) continue;
                    // ä¸‹å‘堆垛机任务
                    WCSginseng result = _taskService.SC_IssueTasks(
                        task.TaskId,
                        int.Parse(task.Roadway),
@@ -175,78 +137,38 @@
                    UpdateTaskStatus(task, result,
                        successStatus: task.TaskStatus == PLC_IN_FINISH ? SC_IN_EXECUTING : SC_OUT_EXECUTING, 1);
                    return;
                }
            }
        }
        private void ProcessOutFinishTasks(List<Dt_Task> tasksToProcess, List<Dt_Task> allTasks)
        {
            const int SC_OUT_FINISH = (int)OutTaskStatusEnum.SC_OutFinish;
            const int PLC_OUT_EXECUTING = (int)OutTaskStatusEnum.PLC_OutExecuting;
            var outFinishTasks = tasksToProcess
                .Where(x => x.TaskStatus == SC_OUT_FINISH)
                .ToList();
            if(outFinishTasks.Count > 0)
            catch (Exception ex)
            {
                foreach (var task in outFinishTasks)
                {
                    // æ£€æŸ¥åŒä¸€å··é“是否有其他已完成的任务
                    bool hasOtherFinishTask = allTasks.Any(x =>
                        x.Roadway == task.Roadway &&
                        x.TaskStatus == SC_OUT_FINISH &&
                        x.TaskId != task.TaskId);
                    if (hasOtherFinishTask)
                        continue;
                    // ä¸‹å‘PLC任务
                    WCSginseng result = _taskService.PLC_IssueTasks(
                        task.TaskId,
                        int.Parse(task.Roadway),
                        task.TaskNum,
                        task.PalletCode,
                        int.Parse(task.PalletType),
                        task.CurrentAddress,
                        task.NextAddress,
                        "");
                    UpdateTaskStatus(task, result, PLC_OUT_EXECUTING, 2);
                }
                Console.WriteLine($"任务处理异常:{ex.Message}");
            }
        }
        private void ProcessInPalltask(List<Dt_Task> tasksToProcess, List<Dt_Task> allTasks)
        private void PLCDoDeciceWork()
        {
            const int PLC_IN_InNew = (int)InTaskStatusEnum.InNew;
            const int PLC_PLC_INEXECUTING = (int)InTaskStatusEnum.PLC_InExecuting;
            var outFinishTasks = tasksToProcess
                .Where(x => x.TaskStatus == PLC_IN_InNew && InStationareaList.Contains(x.SourceAddress))
                .ToList();
            if(outFinishTasks.Count > 0)
            try
            {
                foreach (var task in outFinishTasks)
                // èŽ·å–å½“å‰ä»»åŠ¡æ•°æ®
                List<Dt_Task> allTasks = _taskService.GetaskQueuePLC();
                if (allTasks.Count == 0) return;
                foreach (var task in allTasks)
                {
                    // ä¸‹å‘PLC任务
                    WCSginseng result = _taskService.PLC_IssueTasks(
                        task.TaskId,
                        int.Parse(task.Roadway),
                        task.TaskNum,
                        task.PalletCode,
                        int.Parse(task.PalletType),
                        task.CurrentAddress,
                        task.NextAddress,
                        "");
                    UpdateTaskStatus(task, result, PLC_PLC_INEXECUTING, 2);
                    WCSginseng result = _taskService.PLC_IssueTasks(task.TaskId, task.WarehouseId, task.TaskNum, task.PalletCode, int.Parse(task.PalletType), task.CurrentAddress, task.NextAddress, "");
                    UpdateTaskStatus(task, result, (int)OutTaskStatusEnum.PLC_OutExecuting, 2);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"堆垛机完成,下发输送线执行任务失败! åŽŸå› : {ex.Message}");
            }
        }
        //修改状态
        private void UpdateTaskStatus(Dt_Task task, WCSginseng result, int successStatus,int statype)
        {
            if (result.IsSuccess)
@@ -255,25 +177,22 @@
                task.TaskStatus = successStatus;
                if(task.TaskStatus== (int)OutTaskStatusEnum.SC_OutExecuting)
                {
                    string Result = MesOutTaskStatusEnum.出库开始.GetDescription();
                    string Result = MesOutTaskStatusEnum.Start.GetDescription();
                    //调取上游系统反馈开始任务
                    _taskService.OutStoreDocCallback(task.TaskNum,Result, "操作成功");
                }else if(task.TaskStatus == (int)InTaskStatusEnum.PLC_InExecuting)
                {
                    string Result = MesInTaskStatusEnum.入库开始.GetDescription();
                    //调取上游系统反馈开始任务
                    _taskService.InStoreDocCallback(task.TaskNum, Result, "操作成功",task.PalletCode,"");
                }
            }
            else
            {
                task.Remark = result.Message;
                task.NumberSsuances++;
                //task.NumberSsuances++;
            }
            _taskService.Repository.UpdateData(task);
        }
        public Task StopAsync(CancellationToken cancellationToken)
        {
@@ -284,164 +203,6 @@
        public void Dispose()
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// åˆ¤æ–­å··é“内移库
        /// </summary>
        /// <param name="TaskNum"></param>
        /// <param name="SourceAddress"></param>
        /// <returns></returns>
        public WebResponseContent JudgmentIsRelocations(Dt_Task dt_Task)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                string Locationcodeadd = dt_Task.TaskType == (int)TaskTypeEnum.Inbound ? dt_Task.NextAddress:  dt_Task.CurrentAddress ;
                Dt_LocationInfo dt_Location = _locationInfoService.Repository.QueryData(x => x.LocationCode == Locationcodeadd).FirstOrDefault();
                if (dt_Location.Depth == 1 || dt_Location.RoadwayNo == "5") return content.OK();
                int locrow = judgmentRow(dt_Location.RoadwayNo, dt_Location.Row);
                Dt_LocationInfo shallowLocation = _locationInfoService.Repository.QueryData(x => x.RoadwayNo == dt_Location.RoadwayNo && x.Row == locrow && x.Layer == dt_Location.Layer && x.Column == dt_Location.Column).FirstOrDefault();
                if (shallowLocation.LocationStatus == (int)LocationStatusEnum.Free) return content.OK();
                if (shallowLocation.LocationStatus != (int)(int)LocationStatusEnum.InStock) return content.Error();
                //判断是否有移库任务
                var TransferTask = _taskService.Repository.QueryData(x=>x.TaskStatus== (int)RelocationTaskStatusEnum.RelocationNew && x.CurrentAddress== shallowLocation.LocationCode).FirstOrDefault();
                if(TransferTask != null)
                {
                    //进行下发给堆垛机任务
                    WCSginseng result = _taskService.SC_IssueTasks(
                        TransferTask.TaskId,
                        int.Parse(TransferTask.Roadway),
                        TransferTask.TaskNum,
                        TransferTask.PalletCode,
                        int.Parse(TransferTask.PalletType),
                        TransferTask.CurrentAddress,
                        TransferTask.NextAddress,
                        TransferTask.TargetAddress);
                    if (result.IsSuccess)
                    {
                        return content.OK();
                    }
                    else
                    {
                        WriteLog.GetLog("判断巷道内移库").Write($"下发堆垛机任务失败,原因:{result.Message}", $"生成移库任务:GenerateTransferTask");
                        return content.Error();
                    }
                }
                //生成移库任务,进行下发
                return content =GenerateTransferTask(shallowLocation.LocationCode);
            }
            catch (Exception ex)
            {
                WriteLog.GetLog("判断巷道内移库").Write($"判断移库失败,原因:{ex.Message}", $"判断巷道内移库方法:JudgmentIsRelocations");
                return content.Error();
            }
        }
        private int judgmentRow(string RoadwayNo,int locrow)
        {
            if (RoadwayNo == "1" || RoadwayNo == "3")
            {
                return locrow == 1 ? 2 : 3;
            }
            else if (RoadwayNo == "2" || RoadwayNo == "4")
            {
                return locrow == 5 ? 6 : 7;
            }
            else
            {
                return 0;
            }
        }
        public WebResponseContent GenerateTransferTask(string shallowLocation)
        {
            WebResponseContent webResponse=new WebResponseContent();
            try
            {
                Dt_LocationInfo OriginalLocation = _locationInfoService.Repository.QueryData(x => x.LocationCode == shallowLocation).FirstOrDefault();
                Dt_StockInfo dt_StockInfo = _stockInfoService.Repository.QueryData(x => x.LocationCode == shallowLocation).FirstOrDefault();
                Dt_LocationInfo newLocation = _locationInfoService.GetLocation(OriginalLocation.RoadwayNo, OriginalLocation.LocationType);
                List<Dt_LocationInfo> dt_Locations = new List<Dt_LocationInfo>();
                MES_parameter mES_Parame = _taskService.ApplicationChangeStorageLocation(dt_StockInfo.PalletCode, OriginalLocation.LocationCode, newLocation.LocationCode);
                if (mES_Parame != null)
                {
                    if (mES_Parame.Result == "Y")
                    {
                        //进行生成任务,下发任务至MES
                        Dt_Task task = new Dt_Task();
                        task.TaskNum = "0";
                        task.PalletCode = dt_StockInfo.PalletCode;
                        task.PalletType = dt_StockInfo.PalletType;
                        task.Roadway = OriginalLocation.RoadwayNo;
                        task.TaskType = (int)TaskTypeEnum.Relocation;
                        task.TaskStatus = (int)RelocationTaskStatusEnum.RelocationNew;
                        task.SourceAddress = OriginalLocation.LocationCode;
                        task.TargetAddress = newLocation.LocationCode;
                        task.CurrentAddress = OriginalLocation.LocationCode;
                        task.NextAddress = newLocation.LocationCode;
                        task.WarehouseId = OriginalLocation.WarehouseId;
                        task.OrderNo = "";
                        task.Grade = 1;
                        task.Creater = "MES";
                        task.CreateDate = DateTime.Now;
                        OriginalLocation.LocationStatus = (int)LocationStatusEnum.Lock;
                        newLocation.LocationStatus = (int)LocationStatusEnum.Lock;
                        dt_StockInfo.StockStatus = (int)StockStatusEmun.移库锁定;
                        dt_Locations.Add(OriginalLocation);
                        dt_Locations.Add(newLocation);
                        _unitOfWorkManage.BeginTran();
                        _taskService.AddData(task);
                        _locationInfoService.UpdateData(dt_Locations);
                        _stockInfoService.UpdateData(dt_StockInfo);
                        _unitOfWorkManage.CommitTran();
                        //进行下发给堆垛机任务
                        WCSginseng result = _taskService.SC_IssueTasks(
                            task.TaskId,
                            int.Parse(task.Roadway),
                            task.TaskNum,
                            task.PalletCode,
                            int.Parse(task.PalletType),
                            task.CurrentAddress,
                            task.NextAddress,
                            task.TargetAddress);
                        if (result.IsSuccess)
                        {
                            return webResponse.OK();
                        }
                        else
                        {
                            WriteLog.GetLog("判断巷道内移库").Write($"下发堆垛机任务失败,原因:{result.Message}", $"生成移库任务:GenerateTransferTask");
                            return webResponse.Error();
                        }
                    }
                    else
                    {
                        WriteLog.GetLog("判断巷道内移库").Write($"申请储位异动,MES不允许移动", $"生成移库任务:GenerateTransferTask");
                        return webResponse.Error();
                    }
                }
                else
                {
                    WriteLog.GetLog("判断巷道内移库").Write($"申请储位异动,MES返回为空", $"生成移库任务:GenerateTransferTask");
                    return webResponse.Error();
                }
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                WriteLog.GetLog("判断巷道内移库").Write($"生成移库任务失败:{ex.Message}", $"生成移库任务:GenerateTransferTask");
                return webResponse.Error();
            }
        }
    }
}