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<WMSCruJob> _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<WMSCruJob> 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<int> _deviceQueueSC = new Queue<int>();
|
|
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<Dt_Task> 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<Dt_Task> 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)
|
{
|
task.Dispatchertime = DateTime.Now;
|
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();
|
}
|
}
|
}
|