using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.Extensions.Caching.Memory;
|
using Newtonsoft.Json;
|
using System.DirectoryServices.Protocols;
|
using System.Threading.Tasks;
|
using WIDESEA_Common.StockEnum;
|
using WIDESEA_Common.WareHouseEnum;
|
using WIDESEA_Core;
|
using WIDESEA_Core.BaseRepository;
|
using WIDESEA_Core.Filter;
|
using WIDESEA_Core.LogHelper;
|
using WIDESEA_DTO.Basic;
|
using WIDESEA_ITaskInfoService;
|
using WIDESEA_Model.Models;
|
|
namespace WIDESEA_WMSServer.Controllers
|
{
|
|
[Route("api/ESS")]
|
[ApiController]
|
[AllowAnonymous]
|
public class ESSController : Controller
|
{
|
|
public readonly ITaskService _taskService;
|
private readonly ILogger<ESSController> _logger;
|
private readonly IMemoryCache _memoryCache;
|
private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
|
public ESSController(ITaskService taskService, ILogger<ESSController> logger, IMemoryCache memoryCache)
|
{
|
_taskService = taskService;
|
_logger = logger;
|
_memoryCache = memoryCache;
|
}
|
|
/// <summary>
|
/// 容器到达上报
|
/// </summary>
|
/// <param name="request"></param>
|
/// <returns></returns>
|
[HttpPost("ContainerArrivalReport"), AllowAnonymous]
|
public async Task<IActionResult> ContainerArrivalReport([FromBody] ContainerArrivalRequest request)
|
{
|
//这里要判断出库的时候,料箱会到扫码处。也会请求这个接口。
|
_logger.LogInformation(" ESSController ContainerArrivalReport : CallId={CallId},ContainerCode={ContainerCode},SlotCode={SlotCode}", request.CallId, request.ContainerCode, request.SlotCode);
|
var response = new ApiResponse<ContainerArrivalResponseData>
|
{
|
Code = 1
|
|
};
|
|
// 生成请求的唯一标识(基于callId + 时间戳)
|
var requestKey = $"callback_{request.CallId}-{request.ContainerCode}_{DateTime.UtcNow:yyyyMMddHH}";
|
|
// 检查是否已经处理过相同的请求
|
if (_memoryCache.TryGetValue(requestKey, out bool _))
|
{
|
_logger.LogWarning("检测到重复请求,已忽略: CallId={CallId}", request.CallId);
|
response.Code = 1;
|
response.Msg = null;
|
response.Data = null;
|
return Ok(response);
|
}
|
|
|
await _semaphore.WaitAsync();
|
try
|
{
|
if (_memoryCache.TryGetValue(requestKey, out bool _))
|
{
|
_logger.LogWarning("双重检查检测到重复请求,已忽略: CallId={CallId}", request.CallId);
|
response.Code = 1;
|
response.Msg = null;
|
response.Data = null;
|
return Ok(response);
|
}
|
|
WebResponseContent result = await _taskService.RequestInboundTask(request.ContainerCode, request.SlotCode);
|
|
var cacheOptions = new MemoryCacheEntryOptions
|
{
|
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20)
|
};
|
_memoryCache.Set(requestKey, true, cacheOptions);
|
response = new ApiResponse<ContainerArrivalResponseData>
|
{
|
Code = 0,
|
Msg = "",
|
Data = new ContainerArrivalResponseData
|
{
|
direction = "100"
|
}
|
};
|
if (result != null && !string.IsNullOrEmpty( result.Message ) && result.Message.Contains("该托盘已生成任务"))
|
{
|
return Ok(response);
|
}
|
if (result != null && result.Status)
|
{
|
return Ok(response);
|
}
|
else
|
{
|
response.Code = 1;
|
response.Msg = null;
|
response.Data = null;
|
_logger.LogError(" ESSController ContainerArrivalReport Error: Message={Message}", result.Message);
|
|
return Ok(response);
|
}
|
}
|
catch (Exception ex)
|
{
|
_logger.LogError(ex, "处理任务状态回调时发生异常: CallId={CallId}", request.CallId);
|
return Ok($"处理回调时发生异常: {ex.Message}");
|
}
|
finally
|
{
|
_semaphore.Release();
|
}
|
|
}
|
|
/// <summary>
|
/// 异常上报
|
/// </summary>
|
/// <param name="request"></param>
|
/// <returns></returns>
|
[HttpPost("ExceptionReporting"), AllowAnonymous]
|
|
public async Task<ActionResult<StatusCallbackResponse>> ExceptionReporting(
|
[FromBody] RobotAbnormalEventRequest request)
|
{
|
_logger.LogInformation("异常上报接口request: " + JsonConvert.SerializeObject(request));
|
|
|
return StatusCallbackResponse.Success();
|
|
}
|
//任务状态上报接口
|
[HttpPost("TaskStatusCcallback"), AllowAnonymous]
|
|
public async Task<ActionResult<StatusCallbackResponse>> TaskStatusCallback(
|
[FromBody] StatusCallbackRequest request)
|
{
|
_logger.LogInformation("任务状态上报接口request: " + JsonConvert.SerializeObject(request));
|
try
|
{
|
|
_logger.LogInformation("收到任务状态回调: CallId={CallId}, EventType={EventType}, Status={Status}",
|
request.CallId, request.EventType, request.Status);
|
|
// 根据事件类型和状态进行不同的业务处理
|
switch (request.EventType)
|
{
|
case EventType.tote_load:
|
await HandleToteLoad(request);
|
break;
|
case EventType.tote_unload:
|
await HandleToteUnload(request);
|
break;
|
case EventType.robot_reach:
|
await HandleRobotReach(request);
|
break;
|
case EventType.task:
|
await HandleTaskStatusChange(request);
|
break;
|
case EventType.task_allocated:
|
await HandleTaskAllocated(request);
|
break;
|
|
default:
|
_logger.LogWarning("未知的事件类型: {EventType}", request.EventType);
|
break;
|
}
|
|
_logger.LogInformation("任务状态回调处理完成: CallId={CallId}", request.CallId);
|
|
return StatusCallbackResponse.Success();
|
}
|
catch (Exception ex)
|
{
|
_logger.LogError(ex, "处理任务状态回调时发生异常: CallId={CallId}", request?.CallId);
|
return StatusCallbackResponse.Error($"处理回调时发生异常: {ex.Message}");
|
}
|
}
|
|
/// <summary>
|
/// 处理任务状态变化
|
/// </summary>
|
private async Task HandleTaskStatusChange(StatusCallbackRequest request)
|
{
|
// 根据任务状态进行不同的处理
|
switch (request.Status)
|
{
|
case WIDESEA_DTO.Basic.TaskStatus.success:
|
await HandleTaskCompleted(request);
|
break;
|
case WIDESEA_DTO.Basic.TaskStatus.fail:
|
await HandleTaskFailed(request);
|
break;
|
case WIDESEA_DTO.Basic.TaskStatus.cancel:
|
await HandleTaskCancelled(request);
|
break;
|
case WIDESEA_DTO.Basic.TaskStatus.suspend:
|
await HandleTaskSuspended(request);
|
break;
|
}
|
}
|
|
/// <summary>
|
/// 处理任务完成
|
/// </summary>
|
private async Task HandleTaskCompleted(StatusCallbackRequest request)
|
{
|
_logger.LogInformation("任务完成: TaskCode={TaskCode}, Container={Container}, Robot={Robot}",
|
request.TaskCode, request.ContainerCode, request.RobotCode);
|
|
_taskService.TaskCompleted(request.TaskCode);
|
// 根据不同的任务类型进行特殊处理
|
if (request.Weight.HasValue)
|
{
|
// 称重任务完成
|
_logger.LogInformation("称重任务完成: 重量={Weight}g, 托盘层={TrayLevel}",
|
request.Weight, request.TrayLevel);
|
}
|
else if (request.Rfids != null && request.Rfids.Count > 0)
|
{
|
// RFID任务完成
|
_logger.LogInformation("RFID任务完成: RFID数量={RfidCount}, 托盘层={TrayLevel}",
|
request.Rfids.Count, request.TrayLevel);
|
}
|
else if (request.IsLocationHasContainer.HasValue)
|
{
|
// 扫描任务完成
|
_logger.LogInformation("扫描任务完成: 库位有容器={HasContainer}",
|
request.IsLocationHasContainer);
|
}
|
else
|
{
|
// 普通任务完成
|
_logger.LogInformation("普通任务完成");
|
}
|
|
// 这里添加您的业务逻辑
|
await Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 处理任务失败
|
/// </summary>
|
private async Task HandleTaskFailed(StatusCallbackRequest request)
|
{
|
_logger.LogWarning("任务失败: TaskCode={TaskCode}, 原因={Message}",
|
request.TaskCode, request.Message);
|
|
// 这里添加您的失败处理逻辑
|
await Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 处理任务取消
|
/// </summary>
|
private async Task HandleTaskCancelled(StatusCallbackRequest request)
|
{
|
_logger.LogInformation("任务取消: TaskCode={TaskCode}", request.TaskCode);
|
|
// 这里添加您的取消处理逻辑
|
await Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 处理任务挂起
|
/// </summary>
|
private async Task HandleTaskSuspended(StatusCallbackRequest request)
|
{
|
_logger.LogWarning("任务挂起: TaskCode={TaskCode}, 系统任务码={SysTaskCode}, 原因={Message}",
|
request.TaskCode, request.SysTaskCode, request.Message);
|
|
// 这里添加您的挂起处理逻辑
|
await Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 处理任务分配
|
/// </summary>
|
private async Task HandleTaskAllocated(StatusCallbackRequest request)
|
{
|
_logger.LogInformation("任务分配: TaskCode={TaskCode}, Robot={Robot}",
|
request.TaskCode, request.RobotCode);
|
|
// 这里添加您的任务分配处理逻辑
|
await Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 处理取箱操作
|
/// </summary>
|
private async Task HandleToteLoad(StatusCallbackRequest request)
|
{
|
if (request.Status == WIDESEA_DTO.Basic.TaskStatus.success)
|
{
|
_logger.LogInformation("取箱完成: Container={Container}, Location={Location}",
|
request.ContainerCode, request.LocationCode);
|
}
|
else
|
{
|
_logger.LogWarning("取箱失败: Container={Container}, Location={Location}",
|
request.ContainerCode, request.LocationCode);
|
}
|
|
// 这里添加您的取箱处理逻辑
|
await Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 处理放箱操作
|
/// </summary>
|
private async Task HandleToteUnload(StatusCallbackRequest request)
|
{
|
if (request.Status == WIDESEA_DTO.Basic.TaskStatus.success)
|
{
|
_logger.LogInformation("放箱完成: Container={Container}, Location={Location}",
|
request.ContainerCode, request.LocationCode);
|
}
|
else
|
{
|
_logger.LogWarning("放箱失败: Container={Container}, Location={Location}",
|
request.ContainerCode, request.LocationCode);
|
}
|
|
// 这里添加您的放箱处理逻辑
|
await Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 处理机器人到达工作站
|
/// </summary>
|
private async Task HandleRobotReach(StatusCallbackRequest request)
|
{
|
_logger.LogInformation("机器人到达工作站: Robot={Robot}, Station={Station}, Location={Location}",
|
request.RobotCode, request.StationCode, request.LocationCode);
|
|
if (request.Trays != null && request.Trays.Count > 0)
|
{
|
_logger.LogInformation("机器人携带托盘信息: 托盘数量={TrayCount}", request.Trays.Count);
|
foreach (var tray in request.Trays)
|
{
|
_logger.LogInformation("托盘: Container={Container}, Level={Level}, Position={Position}, Face={Face}",
|
tray.ContainerCode, tray.TrayLevel, tray.PositionCode, tray.ContainerFace);
|
}
|
}
|
|
// 这里添加您的机器人到达处理逻辑
|
await Task.CompletedTask;
|
}
|
}
|
}
|