#region << 版 本 注 释 >>
|
|
/*----------------------------------------------------------------
|
* 命名空间:WIDESEAWCS_TaskInfoService
|
* 创建者:胡童庆
|
* 创建时间:2024/8/2 16:13:36
|
* 版本:V1.0.0
|
* 描述:
|
*
|
* ----------------------------------------------------------------
|
* 修改人:
|
* 修改时间:
|
* 版本:V1.0.1
|
* 修改说明:
|
*
|
*----------------------------------------------------------------*/
|
|
#endregion << 版 本 注 释 >>
|
|
using MapsterMapper;
|
using Microsoft.Extensions.Configuration;
|
using Newtonsoft.Json;
|
using SqlSugar;
|
using System.Diagnostics.CodeAnalysis;
|
using WIDESEA_Core;
|
using WIDESEAWCS_Common.HttpEnum;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_Core.BaseServices;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_DTO.Stock;
|
using WIDESEAWCS_DTO.TaskInfo;
|
using WIDESEAWCS_ITaskInfoRepository;
|
using WIDESEAWCS_ITaskInfoService;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob;
|
using WIDESEAWCS_QuartzJob.DTO;
|
|
namespace WIDESEAWCS_TaskInfoService
|
{
|
public class RobotTaskService : ServiceBase<Dt_RobotTask, IRobotTaskRepository>, IRobotTaskService
|
{
|
private readonly IMapper _mapper;
|
private readonly HttpClientHelper _httpClientHelper;
|
private readonly ITaskExecuteDetailService _taskExecuteDetailService;
|
|
private Dictionary<string, OrderByType> _taskOrderBy = new()
|
{
|
{nameof(Dt_RobotTask.RobotGrade),OrderByType.Desc },
|
{nameof(Dt_RobotTask.CreateDate),OrderByType.Asc},
|
};
|
|
public Dictionary<string, OrderByType> TaskOrderBy
|
{ get { return _taskOrderBy; } set { _taskOrderBy = value; } }
|
|
public List<int> TaskInboundTypes => typeof(TaskInboundTypeEnum).GetEnumIndexList();
|
|
public List<int> TaskOutboundTypes => typeof(TaskOutboundTypeEnum).GetEnumIndexList();
|
|
public List<int> TaskRobotTypes => typeof(TaskOtherTypeEnum).GetEnumIndexList();
|
|
public RobotTaskService(IRobotTaskRepository BaseDal, IMapper mapper, HttpClientHelper httpClientHelper, ITaskExecuteDetailService taskExecuteDetailService) : base(BaseDal)
|
{
|
_mapper = mapper;
|
_httpClientHelper = httpClientHelper;
|
_taskExecuteDetailService = taskExecuteDetailService;
|
}
|
|
public WebResponseContent ReceiveWMSTask([NotNull] WMSTaskDTO taskDTO, StockDTO stockDTO)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
if (BaseDal.QueryFirst(x => x.RobotTaskNum == taskDTO.TaskNum || x.RobotSourceAddressPalletCode == taskDTO.PalletCode) != null)
|
{
|
return content.Error("任务已存在");
|
}
|
|
Dt_RobotTask task = new Dt_RobotTask
|
{
|
RobotTaskNum = taskDTO.TaskNum,
|
RobotSourceAddressLineCode = stockDTO.SourceLineNo,
|
RobotTargetAddressLineCode = stockDTO.TargetLineNo,
|
RobotRoadway = stockDTO.Roadway,
|
RobotSourceAddress = stockDTO.SourceLineNo,
|
RobotTargetAddress = stockDTO.TargetLineNo,
|
RobotSourceAddressPalletCode = stockDTO.SourcePalletNo,
|
RobotTargetAddressPalletCode = stockDTO.TargetPalletNo,
|
RobotTaskType = taskDTO.TaskType,
|
RobotTaskState = taskDTO.TaskStatus,
|
RobotGrade = taskDTO.Grade,
|
Creater = "WMS",
|
RobotTaskTotalNum = 0,
|
};
|
|
BaseDal.AddData(task);
|
|
_taskExecuteDetailService.AddTaskExecuteDetail(new List<int> { task.RobotTaskNum }, "接收WMS任务");
|
|
content = WebResponseContent.Instance.OK("成功", task);
|
}
|
catch (Exception ex)
|
{
|
content = WebResponseContent.Instance.Error($"任务接收错误,错误信息:{ex.Message}");
|
}
|
return content;
|
}
|
|
public Dt_RobotTask? QueryRobotCraneTask(string deviceCode)
|
{
|
return BaseDal.QueryFirst(x => x.RobotRoadway == deviceCode && x.RobotTaskState != (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy);
|
}
|
|
public async Task<bool> UpdateRobotTaskAsync(Dt_RobotTask robotTask)
|
{
|
return await BaseDal.UpdateDataAsync(robotTask);
|
}
|
|
/// <summary>
|
/// 获取WMS系统机械手任务
|
/// </summary>
|
/// <param name="task"></param>
|
/// <returns></returns>
|
public WebResponseContent GetWMSRobotTask(Dt_Task task)
|
{
|
string configKey = ResolveRobotTaskConfigKey(task.TargetAddress);
|
StockDTO stock = BuildRobotTaskStock(task, configKey);
|
|
var result = _httpClientHelper.Post<WebResponseContent>(configKey, stock.ToJson());
|
|
if (!result.IsSuccess || !result.Data.Status)
|
return WebResponseContent.Instance.Error($"获取WMS系统机械手任务失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,目标地址:【{task.TargetAddress}】,接口:【{configKey}】,错误信息:【{result.Data?.Message}】");
|
|
var wMSTask = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data?.ToString() ?? string.Empty);
|
if (wMSTask == null)
|
return WebResponseContent.Instance.Error($"获取WMS系统机械手任务失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【WMS未返回有效任务数据】");
|
|
return ReceiveWMSTask(wMSTask, stock);
|
}
|
|
/// <summary>
|
/// 根据输送线目标地址解析机械手任务接口。
|
/// 规则:
|
/// 1. 从配置读取精确地址映射(AddressMap)
|
/// 2. 未命中时默认换盘
|
/// </summary>
|
public string ResolveRobotTaskConfigKey(string? targetAddress)
|
{
|
string address = (targetAddress ?? string.Empty).Trim();
|
if (string.IsNullOrWhiteSpace(address))
|
return nameof(ConfigKey.CreateRobotChangePalletTask);
|
|
var section = App.Configuration.GetSection("RobotTaskAddressRules");
|
var addressMap = ReadRobotRuleMap(section.GetSection("AddressMap"));
|
if (addressMap.TryGetValue(address, out string? exactTaskType))
|
return MapRobotTaskTypeToConfigKey(exactTaskType);
|
|
return nameof(ConfigKey.CreateRobotChangePalletTask);
|
}
|
|
public int MapWarehouseIdConfigKey(string? targetAddress)
|
{
|
return targetAddress switch
|
{
|
"11068" => 1,
|
"11001" => 3,
|
"11010" => 3,
|
"10010" => 1,
|
"10030" => 1,
|
_ => 1
|
};
|
}
|
|
/// <summary>
|
/// 将配置任务类型转换为接口配置键。
|
/// 支持值:Split/Group/Change(大小写不敏感)
|
/// </summary>
|
public string MapRobotTaskTypeToConfigKey(string? taskType)
|
{
|
string type = (taskType ?? string.Empty).Trim().ToLowerInvariant();
|
return type switch
|
{
|
"split" => nameof(ConfigKey.CreateRobotSplitPalletTask),
|
"group" => nameof(ConfigKey.CreateRobotGroupPalletTask),
|
_ => nameof(ConfigKey.CreateRobotChangePalletTask)
|
};
|
}
|
|
/// <summary>
|
/// 根据接口类型构建机械手任务入参。
|
/// </summary>
|
public StockDTO BuildRobotTaskStock(Dt_Task task, string configKey)
|
{
|
string targetAddress = task.TargetAddress ?? string.Empty;
|
string roadway = ResolveRobotRuleValue(targetAddress, "AddressRoadwayMap", task.Roadway);
|
string sourceLineNo = ResolveRobotRuleValue(targetAddress, "AddressSourceLineNoMap", task.SourceAddress);
|
|
var stock = new StockDTO
|
{
|
Roadway = roadway,
|
SourceLineNo = sourceLineNo,
|
TargetLineNo = task.TargetAddress,
|
SourcePalletNo = task.PalletCode,
|
TargetPalletNo = task.PalletCode
|
};
|
|
if (configKey == nameof(ConfigKey.CreateRobotSplitPalletTask))
|
{
|
stock.TargetPalletNo = string.Empty;
|
}
|
else if (configKey == nameof(ConfigKey.CreateRobotGroupPalletTask))
|
{
|
stock.SourcePalletNo = string.Empty;
|
}
|
else if (configKey == nameof(ConfigKey.CreateRobotChangePalletTask))
|
{
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceLineNo));
|
if (device != null)
|
{
|
CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
|
|
DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(ConveyorLineDBNameNew.Barcode) && x.DeviceChildCode == sourceLineNo);
|
ConveyorLineTaskCommandNew command = conveyorLine.ReadCustomer<ConveyorLineTaskCommandNew>(sourceLineNo); // 测试用
|
//var barcode = conveyorLine.GetValue<ConveyorLineDBNameNew, string>(ConveyorLineDBNameNew.Barcode, sourceLineNo);
|
stock.SourcePalletNo = string.IsNullOrEmpty(command.Barcode.Replace("\0", "").ToString()) ? string.Empty : command.Barcode.Replace("\0", "").ToString();
|
}
|
}
|
|
return stock;
|
}
|
|
/// <summary>
|
/// 根据目标地址按「精确 > 回退值」解析规则值。
|
/// </summary>
|
public string ResolveRobotRuleValue(string? targetAddress, string addressSectionName, string? fallback)
|
{
|
string address = (targetAddress ?? string.Empty).Trim();
|
string defaultValue = fallback ?? string.Empty;
|
if (string.IsNullOrWhiteSpace(address))
|
return defaultValue;
|
|
var section = App.Configuration.GetSection("RobotTaskAddressRules");
|
var addressMap = ReadRobotRuleMap(section.GetSection(addressSectionName));
|
if (addressMap.TryGetValue(address, out string? value))
|
return value;
|
|
return defaultValue;
|
}
|
|
/// <summary>
|
/// 读取规则映射段。
|
/// </summary>
|
private Dictionary<string, string> ReadRobotRuleMap(IConfigurationSection section)
|
{
|
return section
|
.GetChildren()
|
.Where(x => !string.IsNullOrWhiteSpace(x.Key) && !string.IsNullOrWhiteSpace(x.Value))
|
.ToDictionary(x => x.Key.Trim(), x => x.Value!.Trim());
|
}
|
}
|
}
|