using AutoMapper; using MailKit.Search; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using System.Reflection.Metadata; using System.Security.Policy; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.LocationEnum; using WIDESEA_Common.Log; using WIDESEA_Common.OtherEnum; using WIDESEA_Common.StockEnum; using WIDESEA_Common.TaskEnum; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Enums; using WIDESEA_Core.Helper; using WIDESEA_DTO.Inbound; using WIDESEA_DTO.Stock; using WIDESEA_DTO.Task; using WIDESEA_IBasicService; using WIDESEA_IStockService; using WIDESEA_ITaskInfoService; using WIDESEA_Model.Models; using static WIDESEA_ITaskInfoService.ITaskService; namespace WIDESEA_TaskInfoService { public partial class WMSCruJob : IHostedService, IDisposable { private readonly ILogger _logger; private Timer _timer; private Timer _timer2; private readonly ITaskService _taskService; private readonly ILocationInfoService _locationInfoService; private readonly IStockInfoService _stockInfoService; private readonly IUnitOfWorkManage _unitOfWorkManage; public WMSCruJob(ILogger logger, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, ILocationInfoService locationInfoService, ITaskService taskService) { _logger = logger; _unitOfWorkManage = unitOfWorkManage; _stockInfoService = stockInfoService; _locationInfoService = locationInfoService; _taskService=taskService; } private static readonly object _taskProcessLock = new object(); private const int TASK_PROCESS_TIMEOUT = 1000; // 2秒超时 private readonly Queue _deviceQueueSC = new Queue(); public Task StartAsync(CancellationToken cancellationToken) { // 初始化设备队列(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; } //堆垛机队列 private void SCProcessNextDevice(object state) { if (!Monitor.TryEnter(_taskProcessLock, TASK_PROCESS_TIMEOUT)) return; try { if (_deviceQueueSC.Count == 0) return; int deviceId = _deviceQueueSC.Dequeue(); try { SCDoDeviceWork(deviceId); _deviceQueueSC.Enqueue(deviceId); PLCDoDeciceWork(); } catch (Exception ex) { _deviceQueueSC.Enqueue(deviceId); Console.WriteLine($"设备 {deviceId} 执行失败: {ex.Message}"); } } finally { Monitor.Exit(_taskProcessLock); } } //执行方法 private void SCDoDeviceWork(int deviceId) { const int PLC_IN_FINISH = (int)InTaskStatusEnum.PLC_InFinish; const int SC_IN_EXECUTING = (int)InTaskStatusEnum.SC_IntExecuting; const int SC_OUT_EXECUTING = (int)OutTaskStatusEnum.SC_OutExecuting; try { //判断当前堆垛机是否有执行任务 if (_taskService.CurrentTaskProgress(deviceId.ToString())) return; // 获取当前堆垛机任务 List taskList = _taskService.GetaskQueue(deviceId.ToString()); if (taskList.Count == 0) return; foreach (Dt_Task task in taskList) { WebResponseContent webResponse = JudgmentIsRelocations(task); if (!webResponse.Status) { WriteLog.Write_Log("WMS_移库故障", $"移库返回失败内容", "失败", $"移库失败,原因:{webResponse.Message}"); return; } 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); UpdateTaskStatus(task, result, successStatus: task.TaskStatus == PLC_IN_FINISH ? SC_IN_EXECUTING : SC_OUT_EXECUTING, 1); return; } } catch (Exception ex) { Console.WriteLine($"任务处理异常:{ex.Message}"); } } private void PLCDoDeciceWork() { try { // 获取当前任务数据 List allTasks = _taskService.GetaskQueuePLC(); if (allTasks.Count == 0) return; foreach (var task in allTasks) { // 下发PLC任务 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) { task.TaskStatus = successStatus; if(task.TaskStatus== (int)OutTaskStatusEnum.SC_OutExecuting) { string Result = MesOutTaskStatusEnum.Start.GetDescription(); //调取上游系统反馈开始任务 _taskService.OutStoreDocCallback(task.TaskNum,Result, "操作成功"); } } else { task.Remark = result.Message; //task.NumberSsuances++; } _taskService.Repository.UpdateData(task); } public Task StopAsync(CancellationToken cancellationToken) { _timer?.Dispose(); return Task.CompletedTask; } public void Dispose() { throw new NotImplementedException(); } } }