using Newtonsoft.Json;
using WIDESEA_Core;
using WIDESEAWCS_Common;
using WIDESEAWCS_Common.HttpEnum;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_DTO.Stock;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_Tasks.Workflow.Abstractions;
namespace WIDESEAWCS_Tasks
{
///
/// 机器人任务处理器:负责任务获取、下发、入库任务回传及库存 DTO 构建。
///
public class RobotTaskProcessor
{
// 通过网关访问 Socket,避免业务层直接依赖 TcpSocketServer。
private readonly ISocketClientGateway _socketClientGateway;
private readonly RobotStateManager _stateManager;
private readonly IRobotTaskService _robotTaskService;
private readonly ITaskService _taskService;
private readonly HttpClientHelper _httpClientHelper;
public RobotTaskProcessor(
ISocketClientGateway socketClientGateway,
RobotStateManager stateManager,
IRobotTaskService robotTaskService,
ITaskService taskService,
HttpClientHelper httpClientHelper)
{
_socketClientGateway = socketClientGateway;
_stateManager = stateManager;
_robotTaskService = robotTaskService;
_taskService = taskService;
_httpClientHelper = httpClientHelper;
}
///
/// 按设备编码获取当前机器人任务。
///
public Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
{
return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
}
///
/// 删除机器人任务。
///
public bool? DeleteTask(int ID)
{
return _robotTaskService.Repository.DeleteDataById(ID);
}
///
/// 下发取货指令(Pickbattery)到机器人客户端。
///
public async Task SendSocketRobotPickAsync(Dt_RobotTask task, RobotSocketState state)
{
string taskString = $"Pickbattery,{task.RobotSourceAddress}";
bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
if (result)
{
task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
state.CurrentTask = task;
// 保持原语义:仅在状态安全写入成功后再更新任务状态。
if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
{
await _robotTaskService.UpdateRobotTaskAsync(task);
}
}
}
///
/// 处理入库任务回传(拆盘/组盘/换盘场景)。
///
public async Task HandleInboundTaskAsync(RobotSocketState state, bool useSourceAddress)
{
var currentTask = state.CurrentTask;
if (currentTask == null)
{
return false;
}
string roadway = currentTask.RobotSourceAddressLineCode;
int warehouseId = currentTask.RobotRoadway == "ZYRB1" ? 1 : currentTask.RobotRoadway == "HPRB001" ? 2 : 3;
int taskType = 0;
string SourceAddress = currentTask.RobotTargetAddressLineCode;
string TargetAddress = currentTask.RobotSourceAddressLineCode;
string PalletCode = string.Empty;
var robotTaskType = (RobotTaskTypeEnum)currentTask.RobotTaskType;
if (useSourceAddress)
{
switch (robotTaskType)
{
case RobotTaskTypeEnum.GroupPallet:
return false;
case RobotTaskTypeEnum.ChangePallet:
case RobotTaskTypeEnum.SplitPallet:
taskType = TaskTypeEnum.InEmpty.GetHashCode();
PalletCode = currentTask.RobotSourceAddressPalletCode;
break;
}
}
else
{
switch (robotTaskType)
{
case RobotTaskTypeEnum.ChangePallet:
case RobotTaskTypeEnum.GroupPallet:
taskType = TaskTypeEnum.Inbound.GetHashCode();
PalletCode = currentTask.RobotTargetAddressPalletCode;
break;
case RobotTaskTypeEnum.SplitPallet:
return true;
}
}
CreateTaskDto taskDto = new CreateTaskDto
{
PalletCode = PalletCode,
SourceAddress = SourceAddress ?? string.Empty,
TargetAddress = TargetAddress ?? string.Empty,
Roadway = roadway,
WarehouseId = warehouseId,
PalletType = 1,
TaskType = taskType
};
var result = _httpClientHelper.Post(nameof(ConfigKey.CreateTaskInboundAsync), taskDto.ToJson());
if (!result.Data.Status && result.IsSuccess)
{
return false;
}
WMSTaskDTO taskDTO = JsonConvert.DeserializeObject(result.Data.Data.ToJson() ?? string.Empty) ?? new WMSTaskDTO();
var content = _taskService.ReceiveWMSTask(new List { taskDTO });
if (!content.Status)
{
return false;
}
var taskInfo = JsonConvert.DeserializeObject(content.Data.ToJson() ?? string.Empty) ?? new Dt_Task();
string sourceAddress = taskDTO.SourceAddress;
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceAddress));
if (device != null)
{
CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
conveyorLine.SetValue(ConveyorLineDBNameNew.Target, taskInfo.NextAddress, sourceAddress);
conveyorLine.SetValue(ConveyorLineDBNameNew.TaskNo, taskInfo.TaskNum, sourceAddress);
conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_STB, 1, sourceAddress);
if (_taskService.UpdateTaskStatusToNext(taskInfo).Status)
{
return true;
}
}
return false;
}
///
/// 构建库存回传 DTO。
///
public static StockDTO BuildStockDTO(RobotSocketState state, int[] positions)
{
return new StockDTO
{
SourceLineNo = state.CurrentTask.RobotSourceAddressLineCode,
SourcePalletNo = state.CurrentTask.RobotSourceAddressPalletCode,
TargetPalletNo = state.CurrentTask.RobotTargetAddressPalletCode,
TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
Details = positions
.Where(x => x > 0)
.OrderBy(x => x)
.Select((x, idx) => new StockDetailDTO
{
Quantity = state.RobotTaskTotalNum > 0 ? state.RobotTaskTotalNum + positions.Length : positions.Length,
Channel = x,
CellBarcode = state.CellBarcode?.Count > 0 ? state.CellBarcode[x - 1] : ""
})
.ToList()
};
}
///
/// 调用拆盘 API。
///
public HttpResponseResult PostSplitPalletAsync(StockDTO stockDTO)
{
return _httpClientHelper.Post(nameof(ConfigKey.SplitPalletAsync), stockDTO.ToJson());
}
///
/// 调用组盘/换盘 API。
///
public HttpResponseResult PostGroupPalletAsync(string configKey, StockDTO stockDTO)
{
return _httpClientHelper.Post(configKey, stockDTO.ToJson());
}
}
}