using System.ComponentModel;
using System.Reflection;
using Newtonsoft.Json;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEA_Core.Helper;
using WIDESEA_DTO.Task;
using WIDESEA_Model.Models;
namespace WIDESEA_TaskInfoService
{
public partial class TaskService
{
#region 手动任务
///
/// 手动创建任务
///
/// 手动创建任务参数
///
public async Task CreateManualTaskAsync(CreateManualTaskDto dto)
{
try
{
int taskType;
int taskStatus;
switch (dto.TaskType)
{
case "入库":
taskType = TaskInboundTypeEnum.Inbound.GetHashCode();
taskStatus = TaskInStatusEnum.InNew.GetHashCode();
break;
case "出库":
taskType = TaskOutboundTypeEnum.Outbound.GetHashCode();
taskStatus = TaskOutStatusEnum.OutNew.GetHashCode();
break;
case "移库":
taskType = TaskRelocationTypeEnum.Relocation.GetHashCode();
taskStatus = TaskRelocationStatusEnum.RelocationNew.GetHashCode();
break;
default:
return WebResponseContent.Instance.Error($"不支持的任务类型: {dto.TaskType}");
}
int taskNum = await BaseDal.GetTaskNo();
var task = new Dt_Task
{
TaskNum = taskNum,
PalletCode = dto.Barcode,
SourceAddress = dto.SourceAddress,
TargetAddress = dto.TargetAddress,
TaskType = taskType,
TaskStatus = taskStatus,
Grade = dto.Grade,
Roadway = dto.TargetAddress,
WarehouseId = dto.WarehouseId,
CurrentAddress = dto.SourceAddress,
NextAddress = dto.TargetAddress,
Creater = "manual",
CreateDate = DateTime.Now,
ModifyDate = DateTime.Now
};
var wmsTaskDtos = new List()
{
new()
{
TaskNum = task.TaskNum,
PalletCode = task.PalletCode,
SourceAddress = task.SourceAddress,
TargetAddress = task.TargetAddress,
TaskType = task.TaskType,
Roadway = task.Roadway,
TaskStatus = task.TaskStatus,
WarehouseId = task.WarehouseId
}
};
return await _unitOfWorkManage.BeginTranAsync(async () =>
{
// 保存到数据库并同步发送给WCS
var result = await BaseDal.AddDataAsync(task) > 0;
if (!result)
return WebResponseContent.Instance.Error("创建任务失败");
var wcsResult = _httpClientHelper.Post(
"http://localhost:9292/api/Task/ReceiveManualTask",
wmsTaskDtos.ToJson());
if (!wcsResult.IsSuccess || !wcsResult.Data.Status)
return WebResponseContent.Instance.Error($"任务已创建但发送给WCS失败: {wcsResult.Data?.Message}");
return WebResponseContent.Instance.OK($"手动创建任务成功,任务号: {taskNum}");
});
}
catch (Exception ex)
{
return WebResponseContent.Instance.Error($"手动创建任务异常: {ex.Message}");
}
}
///
/// 手动下发任务到WCS(批量处理)
///
/// 下发任务参数列表
/// 批量下发结果
public async Task DispatchTasksToWCSAsync(List dtos)
{
try
{
if (dtos == null || !dtos.Any())
return WebResponseContent.Instance.Error("请选择要下发的任务");
var resultDto = new DispatchResultDto
{
SuccessCount = 0,
FailCount = 0,
FailResults = new List()
};
// 第一步:查询并校验所有任务状态,收集有效任务
var validTasks = new List<(DispatchTaskDto Dto, Dt_Task Task)>();
foreach (var dto in dtos)
{
var task = await BaseDal.QueryFirstAsync(t => t.TaskId == dto.TaskId);
if (task == null)
{
resultDto.FailResults.Add(new DispatchTaskResultDto
{
TaskId = dto.TaskId,
TaskNum = 0,
Success = false,
ErrorMessage = "任务不存在"
});
resultDto.FailCount++;
continue;
}
// 校验任务状态:仅入库新单/出库新单/移库新单可下发
bool canDispatch = false;
if (task.TaskType == TaskInboundTypeEnum.Inbound.GetHashCode()
&& task.TaskStatus == TaskInStatusEnum.InNew.GetHashCode())
canDispatch = true;
else if (task.TaskType == TaskOutboundTypeEnum.Outbound.GetHashCode()
&& task.TaskStatus == TaskOutStatusEnum.OutNew.GetHashCode())
canDispatch = true;
else if (task.TaskType == TaskRelocationTypeEnum.Relocation.GetHashCode()
&& task.TaskStatus == TaskRelocationStatusEnum.RelocationNew.GetHashCode())
canDispatch = true;
if (!canDispatch)
{
var statusName = GetTaskStatusName(task.TaskType, task.TaskStatus);
resultDto.FailResults.Add(new DispatchTaskResultDto
{
TaskId = dto.TaskId,
TaskNum = task.TaskNum,
Success = false,
ErrorMessage = $"任务状态[{statusName}]不允许下发"
});
resultDto.FailCount++;
continue;
}
validTasks.Add((dto, task));
}
// 如果全部校验失败,直接返回
if (validTasks.Count == 0)
return WebResponseContent.Instance.Error($"下发失败,共{resultDto.FailCount}个任务");
// 第二步:构造所有WMSTaskDTO,一次性调用WCS
var wmsTaskDtos = validTasks.Select(vt => new WMSTaskDTO
{
Id = vt.Task.TaskId,
TaskNum = vt.Task.TaskNum,
PalletCode = vt.Dto.PalletCode,
SourceAddress = vt.Dto.SourceAddress,
TargetAddress = vt.Dto.TargetAddress,
CurrentAddress = vt.Dto.SourceAddress,
NextAddress = vt.Dto.TargetAddress,
TaskType = vt.Task.TaskType,
TaskStatus = vt.Task.TaskStatus,
Roadway = vt.Task.Roadway,
Grade = vt.Dto.Grade,
WarehouseId = vt.Task.WarehouseId,
PalletType = vt.Task.PalletType
}).ToList();
// 一次性调用WCS批量接口
var wcsResult = _httpClientHelper.Post(
"http://localhost:9292/api/Task/ReceiveManualTask",
wmsTaskDtos.ToJson());
if (wcsResult == null || !wcsResult.IsSuccess)
{
// WCS调用失败,所有任务都算失败
// 尝试从WCS响应中解析错误详情
string errorDetail = "";
if (wcsResult?.Data != null)
{
// 尝试将Data转换为错误信息
try
{
var errorData = wcsResult.Data.ToString();
errorDetail = $"WCS错误: {errorData}";
}
catch
{
errorDetail = wcsResult?.ErrorMessage ?? "WCS响应异常";
}
}
else
{
errorDetail = wcsResult?.ErrorMessage ?? "WCS响应异常";
}
foreach (var vt in validTasks)
{
resultDto.FailResults.Add(new DispatchTaskResultDto
{
TaskId = vt.Dto.TaskId,
TaskNum = vt.Task.TaskNum,
Success = false,
ErrorMessage = $"{errorDetail} (任务号:{vt.Task.TaskNum}, 托盘:{vt.Dto.PalletCode})"
});
resultDto.FailCount++;
}
resultDto.SuccessCount = 0;
return WebResponseContent.Instance.Error($"WCS批量下发失败,共{resultDto.FailCount}个任务");
}
// WCS调用成功,解析返回的结构化数据
ReceiveTaskResultDto wcsResultData = null;
try
{
if (wcsResult.Data?.Data != null)
{
var jsonStr = wcsResult.Data.Data.ToString();
if (!string.IsNullOrEmpty(jsonStr) && jsonStr.Contains("duplicateTasks"))
{
wcsResultData = JsonConvert.DeserializeObject(jsonStr);
}
}
}
catch (Exception ex)
{
// 解析WCS返回数据失败,记录日志但继续处理
Console.WriteLine($"解析WCS返回数据异常: {ex.Message}");
}
// 如果有重复任务,记录到失败结果中
if (wcsResultData?.DuplicateTasks != null && wcsResultData.DuplicateTasks.Count > 0)
{
foreach (var dup in wcsResultData.DuplicateTasks)
{
var statusName = GetTaskStatusName(dup.TaskType, dup.TaskStatus);
resultDto.FailResults.Add(new DispatchTaskResultDto
{
TaskId = 0, // 重复任务可能没有WMS的TaskId
TaskNum = dup.TaskNum,
Success = false,
ErrorMessage = $"WCS中已存在该任务(托盘:{dup.PalletCode}, 状态:{statusName})"
});
resultDto.FailCount++;
}
}
// 第三步:WCS调用成功后,批量更新DB
foreach (var vt in validTasks)
{
vt.Task.PalletCode = vt.Dto.PalletCode;
vt.Task.SourceAddress = vt.Dto.SourceAddress;
vt.Task.TargetAddress = vt.Dto.TargetAddress;
vt.Task.CurrentAddress = vt.Dto.SourceAddress;
vt.Task.NextAddress = vt.Dto.TargetAddress;
vt.Task.Grade = vt.Dto.Grade;
vt.Task.Dispatchertime = DateTime.Now;
}
// 批量更新DB
var tasksToUpdate = validTasks.Select(vt => vt.Task).ToList();
await BaseDal.UpdateDataAsync(tasksToUpdate);
resultDto.SuccessCount = validTasks.Count - (wcsResultData?.DuplicateTasks?.Count ?? 0);
if (resultDto.FailCount == 0)
return WebResponseContent.Instance.OK($"成功下发{resultDto.SuccessCount}个任务", resultDto);
var errorResponse = WebResponseContent.Instance.Error($"部分下发成功{resultDto.SuccessCount}个,失败{resultDto.FailCount}个");
errorResponse.Data = resultDto;
return errorResponse;
}
catch (Exception ex)
{
return WebResponseContent.Instance.Error($"下发任务异常: {ex.Message}");
}
}
///
/// 获取任务状态名称
///
/// 任务类型
/// 任务状态
/// 状态的中文描述
private string GetTaskStatusName(int taskType, int taskStatus)
{
FieldInfo? fieldInfo = taskType switch
{
_ when taskType == TaskInboundTypeEnum.Inbound.GetHashCode() => typeof(TaskInStatusEnum).GetField(((TaskInStatusEnum)taskStatus).ToString()),
_ when taskType == TaskOutboundTypeEnum.Outbound.GetHashCode() => typeof(TaskOutStatusEnum).GetField(((TaskOutStatusEnum)taskStatus).ToString()),
_ when taskType == TaskRelocationTypeEnum.Relocation.GetHashCode() => typeof(TaskRelocationStatusEnum).GetField(((TaskRelocationStatusEnum)taskStatus).ToString()),
_ => null
};
var descAttr = fieldInfo?.GetCustomAttributes(typeof(DescriptionAttribute), false)
.FirstOrDefault() as DescriptionAttribute;
return descAttr?.Description ?? taskStatus.ToString();
}
#endregion 手动任务
}
}