#region << 版 本 注 释 >>
|
/*----------------------------------------------------------------
|
* 命名空间:WIDESEAWCS_TaskInfoService
|
* 创建者:胡童庆
|
* 创建时间:2024/8/2 16:13:36
|
* 版本:V1.0.0
|
* 描述:
|
*
|
* ----------------------------------------------------------------
|
* 修改人:
|
* 修改时间:
|
* 版本:V1.0.1
|
* 修改说明:
|
*
|
*----------------------------------------------------------------*/
|
#endregion << 版 本 注 释 >>
|
using AutoMapper;
|
using Microsoft.AspNetCore.Mvc;
|
using Newtonsoft.Json;
|
using NPOI.SS.Formula.Functions;
|
using NPOI.SS.UserModel;
|
using NPOI.XSSF.UserModel;
|
using RYB_PTL_API;
|
using SqlSugar;
|
using System.Collections.Generic;
|
using System.Diagnostics;
|
using System.Diagnostics.CodeAnalysis;
|
using System.DirectoryServices.Protocols;
|
using System.Linq;
|
using System.Net.Http.Headers;
|
using System.Security.Policy;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEA_DTO.Agv;
|
using WIDESEA_External.Model;
|
using WIDESEAWCS_BasicInfoService;
|
using WIDESEAWCS_Common;
|
using WIDESEAWCS_Common.APIEnum;
|
using WIDESEAWCS_Common.Helper;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_Core.BaseRepository;
|
using WIDESEAWCS_Core.BaseServices;
|
using WIDESEAWCS_Core.Enums;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_Core.LogHelper;
|
using WIDESEAWCS_DTO;
|
using WIDESEAWCS_DTO.Agv;
|
using WIDESEAWCS_DTO.TaskInfo;
|
using WIDESEAWCS_IBasicInfoRepository;
|
using WIDESEAWCS_IBasicInfoService;
|
using WIDESEAWCS_ITaskInfoRepository;
|
using WIDESEAWCS_ITaskInfoService;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob.Models;
|
using WIDESEAWCS_QuartzJob.Repository;
|
using WIDESEAWCS_QuartzJob.Service;
|
using ICacheService = WIDESEAWCS_Core.Caches.ICacheService;
|
|
namespace WIDESEAWCS_TaskInfoService
|
{
|
public partial class TaskService : ServiceBase<Dt_Task, ITaskRepository>, ITaskService
|
{
|
private readonly IMapper _mapper;
|
private readonly IUnitOfWorkManage _unitOfWorkManage;
|
private readonly ICacheService _cacheService;
|
private readonly IRouterService _routerService;
|
private readonly ITaskExecuteDetailService _taskExecuteDetailService;
|
private readonly ITaskExecuteDetailRepository _taskExecuteDetailRepository;
|
private readonly IStationMangerRepository _stationMangerRepository;
|
private readonly IRouterRepository _routerRepository;
|
private readonly IApiInfoRepository _apiInfoRepository;
|
private readonly ILocationInfoRepository _locationInfoRepository;
|
private readonly ILocationInfoService _locationInfoService;
|
private readonly ILocationStatusChangeRecordService _locationStatusChangeRecordService;
|
private readonly IErrorInfoRepository _errorInfoRepository;
|
|
private Dictionary<string, OrderByType> _taskOrderBy = new()
|
{
|
{nameof(Dt_Task.Grade),OrderByType.Desc },
|
{nameof(Dt_Task.TaskNum),OrderByType.Asc},
|
{nameof(Dt_Task.CreateDate),OrderByType.Asc},
|
};
|
|
|
public Dictionary<string, OrderByType> TaskOrderBy { get { return _taskOrderBy; } set { _taskOrderBy = value; } }
|
|
public List<int> TaskInboundTypes => typeof(TaskTypeEnum).GetEnumIndexList().Where(x => x >= 500 && x < 900).ToList();
|
|
public List<int> TaskOutboundTypes => typeof(TaskTypeEnum).GetEnumIndexList().Where(x => x >= 100 && x < 500).ToList();
|
|
public List<int> TaskRelocationTypes => typeof(TaskTypeEnum).GetEnumIndexList().Where(x => x >= 900 && x < 1000).ToList();
|
|
public TaskService(ITaskRepository BaseDal, IMapper mapper, ICacheService cacheService, IRouterService routerService, ITaskExecuteDetailService taskExecuteDetailService, ITaskExecuteDetailRepository taskExecuteDetailRepository, IStationMangerRepository stationMangerRepository, IRouterRepository routerRepository, IApiInfoRepository apiInfoRepository, ILocationInfoRepository locationInfoRepository, IUnitOfWorkManage unitOfWorkManage, ILocationInfoService locationInfoService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IErrorInfoRepository errorInfoRepository) : base(BaseDal)
|
{
|
_mapper = mapper;
|
_cacheService = cacheService;
|
_routerService = routerService;
|
_taskExecuteDetailService = taskExecuteDetailService;
|
_taskExecuteDetailRepository = taskExecuteDetailRepository;
|
_stationMangerRepository = stationMangerRepository;
|
_routerRepository = routerRepository;
|
_apiInfoRepository = apiInfoRepository;
|
_locationInfoRepository = locationInfoRepository;
|
_unitOfWorkManage = unitOfWorkManage;
|
_locationInfoService = locationInfoService;
|
_locationStatusChangeRecordService = locationStatusChangeRecordService;
|
_errorInfoRepository = errorInfoRepository;
|
}
|
static object lock_taskReceive = new object();
|
/// <summary>
|
/// 接收WMS任务信息
|
/// </summary>
|
/// <param name="taskDTOs">WMS任务对象集合</param>
|
/// <returns>返回处理结果</returns>
|
public WMSReceiveTaskContent ReceiveWMSTask([NotNull] WMSTaskDTO taskDTO)
|
{
|
WMSReceiveTaskContent content = new WMSReceiveTaskContent();
|
string errorMsg = "";
|
try
|
{
|
lock (lock_taskReceive)
|
{
|
WriteLog.Write_Log("入库任务下发", "WMS入库任务接收参数", "接收参数", $"参数:{taskDTO.ToJson()}");
|
List<Dt_Task> tasks = new List<Dt_Task>();
|
List<Dt_Task> taskOlds = BaseDal.QueryData(x => taskDTO.Tasks.Select(x => x.TaskDescribe.ContainerCode).Contains(x.PalletCode));
|
List<Dt_LocationInfo> locationInfos = _locationInfoRepository.GetCanOut(taskDTO.Tasks.Select(x => x.TaskDescribe.ContainerCode).ToList());
|
List<Dt_StationManger> stationMangers = _stationMangerRepository.QueryData();
|
////下发任务组
|
//string taskGroup= taskDTO.TaskGroupCode.IsNullOrEmpty() ? Guid.NewGuid().ToString().Replace("-","") : taskDTO.TaskGroupCode;
|
foreach (var item in taskDTO.Tasks.OrderBy(x => x.TaskDescribe.ToStationCode))
|
{
|
if (item.TaskDescribe.ToStationCode.IsNullOrEmpty()) throw new Exception($"任务{item.TaskCode}出库目标操作台不能为空");
|
//获取操作台
|
Dt_StationManger? stationManger = stationMangers.FirstOrDefault(x => x.PickStationCode == item.TaskDescribe.ToStationCode);
|
if (stationManger == null) throw new Exception($"任务{item.TaskCode}出库目标操作台{item.TaskDescribe.ToStationCode}不存在");
|
Dt_Task? taskOld = taskOlds.FirstOrDefault(x => x.PalletCode == item.TaskDescribe.ContainerCode);
|
if (taskOld != null)
|
{
|
errorMsg += $"料箱{taskOld.PalletCode}" + (taskOld.TaskType == TaskTypeEnum.Inbound.ObjToInt() ? "入库任务已存在;" : "出库任务已存在;");
|
content.FailData.Add(new BinCodeObj() { Bincode = item.TaskDescribe.ContainerCode });
|
continue;
|
}
|
Dt_LocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.PalletCode == item.TaskDescribe.ContainerCode);
|
if (locationInfo == null)
|
{
|
errorMsg += $"料箱{item.TaskDescribe.ContainerCode}不存在;";
|
content.FailData.Add(new BinCodeObj() { Bincode = item.TaskDescribe.ContainerCode });
|
continue;
|
}
|
Dt_LocationInfo? noOutLocation = locationInfos.FirstOrDefault(x => (x.LocationStatus != LocationStatusEnum.InStock.ObjToInt() || x.EnableStatus != EnableStatusEnum.Normal.ObjToInt()) && x.PalletCode == item.TaskDescribe.ContainerCode);
|
if (noOutLocation != null)
|
{
|
errorMsg += $"料箱{noOutLocation.PalletCode}货位{noOutLocation.LocationCode}状态不可出库";
|
content.FailData.Add(new BinCodeObj() { Bincode = noOutLocation.PalletCode });
|
continue;
|
}
|
Dt_Task task = _mapper.Map<Dt_Task>(item);
|
task.SourceAddress = locationInfo.LocationCode;
|
task.CurrentAddress = locationInfo.LocationCode;
|
task.NextAddress = stationManger.PickStationCode;
|
task.TargetAddress = stationManger.PickStationCode;
|
//task.GroupId = taskGroup;
|
task.TaskType = TaskTypeEnum.Outbound.ObjToInt();
|
task.Roadway = locationInfo.RoadwayNo;
|
task.DeviceCode = stationManger.CraneCode;
|
task.TaskState = TaskStatusEnum.AGV_Execute.ObjToInt();
|
tasks.Add(task);
|
content.SucessData.Add(new BinCodeObj() { Bincode = item.TaskDescribe.ContainerCode });
|
}
|
|
locationInfos.ForEach(x =>
|
{
|
x.LocationStatus = LocationStatusEnum.Lock.ObjToInt();
|
});
|
//添加任务更新货位数据
|
_unitOfWorkManage.BeginTran();
|
BaseDal.AddData(tasks);
|
_locationInfoRepository.UpdateData(locationInfos);
|
_unitOfWorkManage.CommitTran();
|
_taskExecuteDetailService.AddTaskExecuteDetail(tasks.Select(x => x.TaskNum).ToList(), "接收WMS任务");
|
if (tasks.Count > 0)
|
{
|
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfos, LocationStatusEnum.InStock, LocationStatusEnum.Lock, LocationChangeType.OutboundAssignLocation, tasks);
|
}
|
content.OK(errorMsg.IsNullOrEmpty() ? "成功" : errorMsg);
|
}
|
}
|
catch (Exception ex)
|
{
|
content.Error($"任务接收错误,错误信息:{ex.Message}");
|
}
|
return content;
|
}
|
|
/// <summary>
|
/// 容器入库创建任务
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent ContainerFlow(ContainerFlowDTO containerFlowDTO, string deviceCode, string stationCode, int type = 0)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
List<Dt_LocationInfo> locationInfos = _locationInfoRepository.QueryData();
|
Dt_LocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.PalletCode == containerFlowDTO.ContainerCode);
|
if (locationInfo != null) throw new Exception($"库位料箱号{containerFlowDTO.ContainerCode}已存在");
|
Dt_Task taskOld = BaseDal.QueryFirst(x => x.PalletCode == containerFlowDTO.ContainerCode);
|
if (taskOld != null && taskOld.PalletCode == containerFlowDTO.ContainerCode && taskOld.TaskType == TaskTypeEnum.Inbound.ObjToInt() && taskOld.TaskState == TaskStatusEnum.CL_Executing.ObjToInt() && taskOld.DeviceCode == deviceCode)
|
{
|
Thread.Sleep(500);
|
return content.OK();
|
}
|
if (taskOld != null && taskOld.PalletCode == containerFlowDTO.ContainerCode && taskOld.TaskType == TaskTypeEnum.Inbound.ObjToInt() && taskOld.TaskState == TaskStatusEnum.CL_Executing.ObjToInt() && taskOld.DeviceCode != deviceCode)
|
{
|
Dt_StationManger stationOld = _stationMangerRepository.QueryFirst(x => x.StationType == StationTypeEnum.StationType_OnlyInbound.ObjToInt() && x.StationDeviceCode == deviceCode);
|
string oldSlotCode = taskOld.SourceAddress;
|
taskOld.SourceAddress = containerFlowDTO.SlotCode;
|
taskOld.CurrentAddress = containerFlowDTO.SlotCode;
|
taskOld.NextAddress = stationOld.StationCode;
|
taskOld.DeviceCode = stationOld.StationDeviceCode;
|
//更新任务
|
BaseDal.UpdateData(taskOld);
|
_taskExecuteDetailService.AddTaskExecuteDetail(new List<int>() { taskOld.TaskNum }, $"{oldSlotCode}换至{containerFlowDTO.SlotCode}入库");
|
return content.OK();
|
}
|
else if (taskOld != null)
|
{
|
throw new Exception($"料箱号{containerFlowDTO.ContainerCode}" + (taskOld.TaskType == TaskTypeEnum.Inbound.ObjToInt() ? "入库AGV执行中" : "出库AGV执行中"));
|
}
|
Dt_LocationInfo? noInLocation = locationInfos.FirstOrDefault(x => x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.EnableStatus == EnableStatusEnum.Normal.ObjToInt());
|
if (noInLocation == null) throw new Exception($"可用货位不足!");
|
Dt_StationManger stationManger = _stationMangerRepository.QueryFirst(x => x.StationType == StationTypeEnum.StationType_OnlyInbound.ObjToInt() && x.StationDeviceCode == deviceCode);
|
//创建任务
|
Dt_Task task = new Dt_Task();
|
task.PalletCode = containerFlowDTO.ContainerCode;
|
task.SourceAddress = containerFlowDTO.SlotCode;
|
task.CurrentAddress = containerFlowDTO.SlotCode;
|
task.NextAddress = stationManger.StationCode;
|
task.TargetAddress = "";
|
task.WMSId = "";
|
task.TaskType = TaskTypeEnum.Inbound.ObjToInt();
|
task.Roadway = noInLocation.RoadwayNo;
|
task.DeviceCode = stationManger.StationDeviceCode;
|
task.TaskState = TaskStatusEnum.CL_Executing.ObjToInt();
|
|
//添加任务
|
int taskId = BaseDal.AddData(task);
|
if (type > 0)
|
{
|
_taskExecuteDetailService.AddTaskExecuteDetail(new List<int>() { task.TaskNum }, "手动按钮入库");
|
}
|
else
|
{
|
_taskExecuteDetailService.AddTaskExecuteDetail(new List<int>() { task.TaskNum }, "创建入库任务");
|
}
|
WriteLog.Write_Log("入库任务下发", "容器入库任务添加任务", "添加任务", $"任务:{task.ToJson()}");
|
content.OK("成功");
|
}
|
catch (Exception ex)
|
{
|
content.Error($"错误信息:{ex.Message}");
|
}
|
return content;
|
}
|
/// <summary>
|
/// 播种墙初始化
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent InitLight()
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
EPLightContent lightContent = INITIALIZATION();
|
if (lightContent.Result != "0") throw new Exception($"{lightContent.Msg}");
|
content.OK();
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 结束作业
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent EndLight()
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
EPLightContent lightContent = ENDWORK();
|
if (lightContent.Result != "0") throw new Exception($"{lightContent.Msg}");
|
content.OK();
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 一期播种墙下发
|
/// </summary>
|
/// <returns></returns>
|
public EPLightContent Phase1PickOrderInfoRequest(List<EPLightSendDTO> lightSendDTOs)
|
{
|
EPLightContent content = new EPLightContent();
|
|
try
|
{
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.Phase1PickOrderInfoRequest.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url))
|
{
|
return content.Error("未找到播种墙下发接口,请检查接口配置");
|
}
|
|
bool allSuccess = true;
|
StringBuilder errorMessages = new StringBuilder();
|
|
foreach (EPLightSendDTO lightSendDTO in lightSendDTOs)
|
{
|
try
|
{
|
bool operationResult;
|
|
// 处理灯光类型转换
|
if (!int.TryParse(lightSendDTO.LIGHTTYPE, out int lightType))
|
{
|
allSuccess = false;
|
errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} 错误: 无效的灯光类型 '{lightSendDTO.LIGHTTYPE}'");
|
continue;
|
}
|
|
// 处理关闭灯光请求
|
if (lightType == 2)
|
{
|
operationResult = RYB_PTL.RYB_PTL_CloseDigit5(url, lightSendDTO.LOCATION);
|
// TODO: 关闭灯光回调处理
|
//List<EPLightBackDTO> lightBackDTOs = new List<EPLightBackDTO>();
|
//List<TaskBackLight> taskBackLights = lightSendDTOs.Select(x => new TaskBackLight()
|
//{
|
// TagNo = "B1",
|
// TagCode = x.LOCATION,
|
//}).ToList();
|
//content = WMSLightBack(taskBackLights);
|
}
|
// 处理显示灯光请求
|
else
|
{
|
// 处理灯光颜色转换
|
if (!int.TryParse(lightSendDTO.LIGHTCOLOR, out int lightColor))
|
{
|
allSuccess = false;
|
errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} 错误: 无效的灯光颜色 '{lightSendDTO.LIGHTCOLOR}'");
|
continue;
|
}
|
|
operationResult = RYB_PTL.RYB_PTL_DspDigit5(
|
url,
|
|
lightSendDTO.LOCATION,
|
lightSendDTO.QUANTITY,
|
lightType,
|
lightColor);
|
}
|
if (!operationResult)
|
{
|
allSuccess = false;
|
errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} 操作失败");
|
}
|
}
|
|
catch (Exception ex)
|
{
|
allSuccess = false;
|
errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} 处理异常: {ex.Message}");
|
}
|
}
|
|
return allSuccess
|
? content.OK("所有播种墙下发操作成功")
|
: content.Error(errorMessages.ToString());
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 播种墙亮灯
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent SendLight(TaskSendLight taskSendLight)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
if (taskSendLight.TagNo == "B1")
|
{
|
List<EPLightSendDTO> lightSendDTOs = new List<EPLightSendDTO>()
|
{
|
new EPLightSendDTO
|
{
|
DOCNO = taskSendLight.DocNo,
|
TASKNO= taskSendLight.TaskNo,
|
LOCATION=taskSendLight.TagCode,
|
QUANTITY=taskSendLight.TagQunity,
|
LIGHTCOLOR=taskSendLight.Color switch
|
{
|
"Blue" => "4",
|
"Green" => "2",
|
"Red" => "1",
|
_ => throw new Exception($"未找到颜色定义")
|
},
|
ORDERTYPE="1",
|
LIGHTTYPE=taskSendLight.Mode.ToString(),
|
}
|
};
|
EPLightContent pLightContent = Phase1PickOrderInfoRequest(lightSendDTOs);
|
if (pLightContent.Result != "0") throw new Exception($"{pLightContent.Msg}");
|
content.OK();
|
}
|
else if (taskSendLight.TagNo == "B2")
|
{
|
List<EPLightSendDTO> lightSendDTOs = new List<EPLightSendDTO>()
|
{
|
new EPLightSendDTO
|
{
|
DOCNO = taskSendLight.DocNo,
|
TASKNO= taskSendLight.TaskNo,
|
LOCATION=taskSendLight.TagCode,
|
QUANTITY=taskSendLight.TagQunity,
|
LIGHTCOLOR=taskSendLight.Color switch
|
{
|
"Blue" => "1",
|
"Green" => "2",
|
"Red" => "4",
|
_ => throw new Exception($"未找到颜色定义")
|
},
|
ORDERTYPE="1",
|
LIGHTTYPE=taskSendLight.Mode.ToString(),
|
}
|
};
|
EPLightContent pLightContent = PickOrderInfoRequest(lightSendDTOs);
|
if (pLightContent.Result != "0") throw new Exception($"{pLightContent.Msg}");
|
content.OK();
|
}
|
else
|
{
|
content.OK();
|
}
|
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
static object lock_requestInTask = new object();
|
/// <summary>
|
/// 申请入库
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent RequestInTask(string stationCode, string barCode)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
lock (lock_requestInTask)
|
{
|
Dt_Task task = BaseDal.QueryFirst(x => x.PalletCode == barCode && x.TaskType == TaskTypeEnum.Inbound.ObjToInt() && x.NextAddress == stationCode && x.TaskState == TaskStatusEnum.CL_Executing.ObjToInt());
|
if (task == null) throw new Exception($"{barCode}料箱未找到任务!");
|
Dt_LocationInfo? locationInfo = _locationInfoService.AssignLocation();
|
if (locationInfo == null) throw new Exception($"可用货位不足!");
|
task.NextAddress = locationInfo.LocationCode;
|
task.TargetAddress = locationInfo.LocationCode;
|
task.CurrentAddress = stationCode;
|
task.DeviceCode = "AGV";
|
task.TaskState = TaskStatusEnum.AGV_Execute.ObjToInt();
|
locationInfo.LocationStatus = LocationStatusEnum.Lock.ObjToInt();
|
//更新任务和货位数据
|
_unitOfWorkManage.BeginTran();
|
BaseDal.UpdateData(task);
|
_locationInfoRepository.UpdateData(locationInfo);
|
_unitOfWorkManage.CommitTran();
|
_taskExecuteDetailService.AddTaskExecuteDetail(new List<int>() { task.TaskNum }, $"分配货位{locationInfo.LocationCode}");
|
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, LocationStatusEnum.Free, LocationStatusEnum.Lock, LocationChangeType.InboundAssignLocation, task.TaskNum);
|
WriteLog.Write_Log("入库任务下发", "申请入库接口", "更新任务", $"任务:{task.ToJson()}");
|
content.OK("成功");
|
}
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
content.Error($"错误信息:{ex.Message}");
|
}
|
return content;
|
}
|
|
public static string Post(string serviceAddress, string requestJson = "", string contentType = "application/json", Dictionary<string, string>? headers = null)
|
{
|
string result = string.Empty;
|
DateTime beginDate = DateTime.Now;
|
try
|
{
|
using (HttpContent httpContent = new StringContent(string.Empty))
|
{
|
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
using HttpClient httpClient = new HttpClient();
|
httpClient.Timeout = new TimeSpan(0, 0, 30);
|
HttpResponseMessage responseMessage = httpClient.PostAsync(serviceAddress, httpContent).Result;
|
result = responseMessage.Content.ReadAsStringAsync().Result;
|
}
|
return result;
|
}
|
catch (Exception e)
|
{
|
throw new Exception(e.Message);
|
}
|
finally
|
{
|
Logger.Add(serviceAddress, requestJson == null ? "" : requestJson, result, beginDate);
|
}
|
}
|
|
/// <summary>
|
/// 更新任务异常信息显示
|
/// </summary>
|
/// <param name="taskNum">任务号</param>
|
/// <param name="message">异常信息</param>
|
public WebResponseContent UpdateTaskExceptionMessage(int taskNum, string message)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】");
|
task.TaskState = (int)TaskStatusEnum.Pending;
|
task.ExceptionMessage = message;
|
task.ModifyDate = DateTime.Now;
|
BaseDal.UpdateData(task);
|
|
_taskExecuteDetailService.AddTaskExecuteDetail(task, task.ExceptionMessage);
|
WriteLog.Write_Log("更新任务异常信息", "更新任务接口", "更新任务", $"任务:{task.ToJson()}");
|
content = WebResponseContent.Instance.OK();
|
}
|
catch (Exception ex)
|
{
|
content = WebResponseContent.Instance.Error(ex.Message);
|
}
|
return content;
|
}
|
|
/// <summary>
|
/// 恢复挂起任务
|
/// </summary>
|
/// <param name="taskNum">任务号</param>
|
/// <returns>返回处理结果</returns>
|
public WebResponseContent TaskStatusRecovery(int taskNum)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】");
|
if (task.TaskState != (int)TaskStatusEnum.Pending)
|
{
|
return content = WebResponseContent.Instance.Error($"该任务状态不可恢复,任务号:【{taskNum}】,任务状态:【{task.TaskState}】");
|
}
|
|
Dt_TaskExecuteDetail taskExecuteDetail = _taskExecuteDetailRepository.QueryFirst(x => x.TaskId == task.TaskId && x.IsNormal, new Dictionary<string, OrderByType> { { nameof(Dt_TaskExecuteDetail.TaskDetailId), OrderByType.Desc } });
|
if (taskExecuteDetail != null)
|
{
|
task.TaskState = taskExecuteDetail.TaskState;
|
}
|
else
|
{
|
task.TaskState = (int)TaskStatusEnum.New;
|
}
|
|
task.ExceptionMessage = string.Empty;
|
|
BaseDal.UpdateData(task);
|
|
_taskExecuteDetailService.AddTaskExecuteDetail(task, $"人工恢复挂起任务,恢复挂起时任务状态【{task.TaskState}】");
|
|
content = WebResponseContent.Instance.OK();
|
}
|
catch (Exception ex)
|
{
|
content = WebResponseContent.Instance.Error(ex.Message);
|
}
|
return content;
|
}
|
|
/// <summary>
|
/// 回滚任务状态
|
/// </summary>
|
/// <param name="taskNum">任务号</param>
|
/// <returns>返回处理结果</returns>
|
public WebResponseContent RollbackTaskStatusToLast(int taskNum)
|
{
|
WebResponseContent content = new();
|
try
|
{
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】");
|
|
int oldState = task.TaskState;
|
Dt_TaskExecuteDetail taskExecuteDetail = _taskExecuteDetailRepository.QueryFirst(x => x.TaskId == task.TaskId && x.TaskState < task.TaskState && x.TaskState > 0, new Dictionary<string, OrderByType> { { nameof(Dt_TaskExecuteDetail.TaskDetailId), OrderByType.Desc } });
|
if (taskExecuteDetail != null)
|
{
|
task.TaskState = taskExecuteDetail.TaskState;
|
task.CurrentAddress = taskExecuteDetail.CurrentAddress;
|
task.NextAddress = taskExecuteDetail.NextAddress;
|
}
|
else
|
{
|
return content = WebResponseContent.Instance.Error($"未找到任务明细信息,该任务状态不可回滚到上一步,任务号:【{taskNum}】,任务状态:【{task.TaskState}】");
|
}
|
|
task.ExceptionMessage = string.Empty;
|
|
BaseDal.UpdateData(task);
|
|
_taskExecuteDetailService.AddTaskExecuteDetail(task, $"人工将任务状态从【{oldState}】回滚到【{task.TaskState}】");
|
|
content = WebResponseContent.Instance.OK();
|
}
|
catch (Exception ex)
|
{
|
content = WebResponseContent.Instance.Error(ex.Message);
|
}
|
return content;
|
}
|
|
|
/// <summary>
|
/// 接受WMS手动完成任务
|
/// </summary>
|
/// <param name="taskNum"></param>
|
/// <returns></returns>
|
public WebResponseContent RecWMSTaskCompleted(int taskNum)
|
{
|
try
|
{
|
WriteLog.Write_Log("接受WMS手动完成任务", "接受WMS手动完成任务接口", "任务号", $"任务号:{taskNum}");
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task != null)
|
{
|
task.TaskState = TaskStatusEnum.Finish.ObjToInt();
|
BaseDal.DeleteAndMoveIntoHty(task, OperateTypeEnum.人工完成);
|
}
|
return WebResponseContent.Instance.OK();
|
}
|
catch (Exception ex)
|
{
|
return WebResponseContent.Instance.Error(ex.Message);
|
}
|
}
|
/// <summary>
|
/// AGV任务放行
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent AgvTaskFlow(string code)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
WriteLog.Write_Log("AGV任务放行", "AGV任务放行接口", "料箱号", $"料箱:{code}");
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.AgvTaskFlow.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url)) throw new Exception($"{code},未找到AGV任务放行接口,请检查接口配置");
|
AgvTaskFlowDTO agvTaskFlowDTO = new AgvTaskFlowDTO()
|
{
|
RequestId = Guid.NewGuid().ToString().Replace("-", ""),
|
MissionCode = code
|
};
|
string request = JsonConvert.SerializeObject(agvTaskFlowDTO, settings);
|
string response = HttpHelper.Post(url, request);
|
WriteLog.Write_Log("AGV任务放行接口请求AGV", "AGV任务放行接口", $"请求:{request},回传:{response}");
|
AgvResponseContent agvResponse = JsonConvert.DeserializeObject<AgvResponseContent>(response) ?? throw new Exception($"{code},未接收到AGV任务放行返回值");
|
if (!agvResponse.Success) throw new Exception($"料箱{code},AGV任务放行错误,信息:{agvResponse.Message}");
|
content.OK();
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// WMS料箱到达拣选位上报
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent WMSPickUp(string stationCode, string pickCode)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
WriteLog.Write_Log("WMS料箱到达拣选位上报", "WMS料箱到达拣选位上报成接口", "信息", $"拣选位:{stationCode},料箱:{pickCode}");
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.WMSPickArrivedUp.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url)) throw new Exception($"未找到WMS料箱到达拣选位上报接口,请检查接口配置");
|
ContainerArriveDTO containerArriveDTO = new ContainerArriveDTO()
|
{
|
SlotCode = stationCode,
|
ContainerCode = pickCode
|
};
|
string request = JsonConvert.SerializeObject(containerArriveDTO, settings);
|
string response = HttpHelper.Post(url, request);
|
WriteLog.Write_Log("上报WMS料箱到达", "上报WMS料箱到达", "信息", $"请求:{request},回传:{response}");
|
WMSResponseContent wMSResponse = JsonConvert.DeserializeObject<WMSResponseContent>(response) ?? throw new Exception($"{pickCode},未接收到WMS料箱到达拣选位上报返回值");
|
if (wMSResponse.Code != "0") throw new Exception($"料箱{pickCode}WMS料箱到达拣选位上报错误,信息:{wMSResponse.Msg}");
|
content.OK();
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 任务完成
|
/// </summary>
|
/// <param name="taskNum"></param>
|
/// <returns></returns>
|
public WebResponseContent TaskCompleted(int taskNum)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
WriteLog.Write_Log("任务完成", "任务完成接口", "任务号", $"任务:{taskNum}");
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)//出库任务完成逻辑
|
{
|
Dt_LocationInfo locationInfo = _locationInfoRepository.QueryFirst(x => x.PalletCode == task.PalletCode);
|
if (locationInfo.LocationStatus != LocationStatusEnum.Lock.ObjToInt())
|
{
|
return content.Error($"{locationInfo.LocationCode}货位状态不正确");
|
}
|
task.TaskState = TaskStatusEnum.Finish.ObjToInt();
|
locationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt();
|
locationInfo.PalletCode = "";
|
//料箱出库完成上报给WMS
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.WMSInOutBoundBack.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url))
|
{
|
_taskExecuteDetailService.AddTaskExecuteDetail(task, $"未找到WMS出库上报接口,请检查接口配置");
|
UpdateTaskExceptionMessage(taskNum, $"未找到WMS出库上报接口,请检查接口配置");
|
return content.Error($"{taskNum},未找到WMS出库上报接口,请检查接口配置");
|
}
|
ContainerInFinishDTO containerInFinishDTO = new ContainerInFinishDTO()
|
{
|
TaskCode = task.TaskNum.ToString(),
|
ContainerCode = task.PalletCode,
|
StationCode = task.TargetAddress,
|
LocationCode = task.SourceAddress,
|
CompleteType = 1
|
};
|
string request = JsonConvert.SerializeObject(containerInFinishDTO, settings);
|
|
_unitOfWorkManage.BeginTran();
|
_locationInfoRepository.UpdateData(locationInfo);
|
BaseDal.DeleteAndMoveIntoHty(task, App.User?.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
|
_unitOfWorkManage.CommitTran();
|
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, LocationStatusEnum.Lock, LocationStatusEnum.Free, LocationChangeType.OutboundCompleted, task.TaskNum);
|
//调用接口
|
string response = HttpHelper.Post(url, request);
|
WriteLog.Write_Log("WMS出库任务完成回传", "任务完成接口", "任务信息", $"请求:{request},回传:{response}");
|
WMSResponseContent wMSResponse = JsonConvert.DeserializeObject<WMSResponseContent>(response) ?? throw new Exception($"{taskNum},未接收到WMS出库上报返回值");
|
if (wMSResponse.Code != "0") content.Message = $"出库任务{task.TaskNum}WMS出库上报错误,信息:{wMSResponse.Msg}";
|
}
|
else if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)//入库任务完成逻辑
|
{
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.WMSInOutBoundBack.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url))
|
{
|
_taskExecuteDetailService.AddTaskExecuteDetail(task, $"未找到WMS入库上报接口,请检查接口配置");
|
UpdateTaskExceptionMessage(taskNum, $"未找到WMS入库上报接口,请检查接口配置");
|
return content.Error($"{taskNum},未找到WMS入库上报接口,请检查接口配置");
|
}
|
ContainerInFinishDTO containerInFinishDTO = new ContainerInFinishDTO()
|
{
|
TaskCode = task.TaskNum.ToString(),
|
ContainerCode = task.PalletCode,
|
StationCode = task.SourceAddress,
|
LocationCode = task.TargetAddress,
|
CompleteType = 2
|
};
|
string request = JsonConvert.SerializeObject(containerInFinishDTO, settings);
|
|
Dt_LocationInfo locationInfo = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress);
|
if (locationInfo.LocationStatus != LocationStatusEnum.Lock.ObjToInt())
|
{
|
return content.Error($"{locationInfo.LocationCode}货位状态不正确");
|
}
|
task.TaskState = TaskStatusEnum.Finish.ObjToInt();
|
locationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
|
locationInfo.PalletCode = task.PalletCode;
|
_unitOfWorkManage.BeginTran();
|
_locationInfoRepository.UpdateData(locationInfo);
|
BaseDal.DeleteAndMoveIntoHty(task, App.User?.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
|
_unitOfWorkManage.CommitTran();
|
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, LocationStatusEnum.Lock, LocationStatusEnum.InStock, LocationChangeType.InboundCompleted, task.TaskNum);
|
//调用接口
|
string response = HttpHelper.Post(url, request);
|
WriteLog.Write_Log("WMS入库任务完成回传", "任务完成接口", "任务信息", $"请求:{request},回传:{response}");
|
WMSResponseContent wMSResponse = JsonConvert.DeserializeObject<WMSResponseContent>(response) ?? throw new Exception($"{taskNum},未接收到WMS入库上报返回值");
|
if (wMSResponse.Code != "0") content.Message = $"入库任务{task.TaskNum}WMS入库上报错误,信息:{wMSResponse.Msg}";
|
}
|
content.OK("任务完成");
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 人工手动取消指定任务
|
/// </summary>
|
/// <param name="taskNum">任务编号</param>
|
/// <returns>操作结果</returns>
|
public WebResponseContent ManualTaskCancellation(int taskNum)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
WriteLog.Write_Log("任务取消接收", "人工手动取消指定任务", "任务号", $"任务:{taskNum}");
|
// 1. 获取任务信息
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task == null) return content.Error($"任务{taskNum}不存在");
|
|
TaskTypeGroup group = task.TaskType.GetTaskTypeGroup();
|
if (group == TaskTypeGroup.InboundGroup)// 入库任务取消
|
{
|
// 获取目标货位
|
Dt_LocationInfo locationInfo = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress);
|
if (locationInfo == null) return content.Error($"目标货位{task.TargetAddress}不存在");
|
// 验证货位状态
|
if (locationInfo.LocationStatus != LocationStatusEnum.Lock.ObjToInt())
|
return content.Error($"{task.TargetAddress}货位状态异常,无法取消");
|
|
// 恢复货位状态
|
locationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt(); // 恢复为空闲状态
|
locationInfo.PalletCode = ""; // 清空托盘号
|
// 更新数据库
|
_unitOfWorkManage.BeginTran();
|
_locationInfoRepository.UpdateData(locationInfo);
|
BaseDal.DeleteAndMoveIntoHty(task, OperateTypeEnum.人工删除);
|
_unitOfWorkManage.CommitTran();
|
// 记录状态变更
|
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(
|
locationInfo,
|
LocationStatusEnum.Lock,
|
LocationStatusEnum.Free,
|
LocationChangeType.InboundCancelled,
|
task.TaskNum
|
);
|
content.OK("任务取消成功");
|
}
|
else
|
{
|
content.Error("只能入库任务取消!");
|
}
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
content.Error($"取消失败: {ex.Message}");
|
// 记录详细错误
|
_taskExecuteDetailService.AddTaskExecuteDetail(
|
new Dt_Task { TaskNum = taskNum },
|
$"任务取消异常: {ex.Message}"
|
);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 任务取消
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent TaskCancelCompleted(int taskNum)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
WriteLog.Write_Log("任务取消接收", "任务取消接口", "任务号", $"任务:{taskNum}");
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)//出库任务完成逻辑
|
{
|
Dt_LocationInfo locationInfo = _locationInfoRepository.QueryFirst(x => x.PalletCode == task.PalletCode);
|
if (locationInfo.LocationStatus != LocationStatusEnum.Lock.ObjToInt())
|
{
|
return content.Error($"{locationInfo.LocationCode}货位状态不正确");
|
}
|
task.TaskState = TaskStatusEnum.Cancel.ObjToInt();
|
locationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
|
_unitOfWorkManage.BeginTran();
|
_locationInfoRepository.UpdateData(locationInfo);
|
BaseDal.DeleteAndMoveIntoHty(task, App.User?.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
|
_unitOfWorkManage.CommitTran();
|
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, LocationStatusEnum.Lock, LocationStatusEnum.InStock, LocationChangeType.InboundCompleted, task.TaskNum);
|
content.OK();
|
}
|
else
|
{
|
content.Error($"未找到出库任务{taskNum}");
|
}
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 任务取消
|
/// </summary>
|
/// <returns></returns>
|
public WebResponseContent TaskCancel(List<TaskCancel> taskCancels)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
// 参数验证
|
if (taskCancels == null || taskCancels.Count == 0)
|
{
|
return content.Error("传入参数不能为空");
|
}
|
|
WriteLog.Write_Log("任务取消接收", "任务取消接口", "任务取消", $"任务:{taskCancels.ToJson()}");
|
|
// 获取所有出库任务(只查询一次)
|
List<Dt_Task> outTasks = BaseDal.QueryData(x =>
|
x.TaskType == TaskTypeEnum.Outbound.ObjToInt());
|
|
if (outTasks.Count == 0)
|
{
|
return content.Error("未找到对应的任务");
|
}
|
|
// 按GroupId分组处理
|
var tasksByGroup = outTasks.GroupBy(x => x.GroupId)
|
.Where(g => !string.IsNullOrEmpty(g.Key))
|
.ToDictionary(g => g.Key, g => g.ToList());
|
|
List<Dt_Task> cancelTasks = new List<Dt_Task>();
|
List<Dt_Task> cancelTasksCompleted = new List<Dt_Task>();
|
// 收集所有需要检查的任务组
|
var groupsToCheck = new List<List<Dt_Task>>();
|
|
foreach (var taskCancel in taskCancels)
|
{
|
// 找到该任务所在的组
|
var group = tasksByGroup.Values.FirstOrDefault(g =>
|
g.Any(t => t.PalletCode == taskCancel.ContainerCode));
|
|
if (group != null && !groupsToCheck.Contains(group))
|
{
|
groupsToCheck.Add(group);
|
}
|
}
|
// 验证任务状态
|
foreach (var group in groupsToCheck)
|
{
|
var firstTask = group.FirstOrDefault();
|
if (firstTask == null) continue;
|
|
// 检查组内所有任务状态
|
foreach (var task in group)
|
{
|
if (task.TaskState == TaskStatusEnum.AGV_TakeFinish.ObjToInt())
|
{
|
task.IsCancel = 1;
|
cancelTasks.Add(task);
|
}
|
else if (task.TaskState == TaskStatusEnum.AGV_Executing.ObjToInt())
|
{
|
cancelTasksCompleted.Add(task);
|
}
|
else
|
{
|
return content.Error($"任务取消失败{task.PalletCode}任务状态不可取消!");
|
}
|
}
|
}
|
//WriteLog.Write_Log("任务取消接收", "任务取消接口", "任务取消", $"任务:{taskCancels.ToJson()}");
|
//if (taskCancels==null || taskCancels.Count<=0)
|
//{
|
// return content.Error("传入不能为空");
|
//}
|
////获取所有料箱
|
//List<Dt_Task> outTasks = BaseDal.QueryData(x=>x.TaskType==TaskTypeEnum.Outbound.ObjToInt());
|
//List<Dt_Task> cancelTasks = new List<Dt_Task>();
|
//List<Dt_Task> cancelTasksCompleted = new List<Dt_Task>();
|
//HashSet<string> processedGroups = new HashSet<string>();
|
////判断是否有任务存在
|
//foreach (var item in taskCancels)
|
//{
|
// Dt_Task? taskExist = outTasks.FirstOrDefault(x=>x.PalletCode == item.ContainerCode);
|
// if (taskExist==null)
|
// {
|
// content.Message += $"{item.ContainerCode}任务不存在";
|
// WriteLog.Write_Log("任务取消接收", "任务取消接口", "任务不存在", $"任务:{item.ContainerCode}");
|
// continue;
|
// }
|
// if (string.IsNullOrEmpty(taskExist.GroupId))
|
// {
|
// continue;
|
// }
|
// processedGroups.Add(taskExist.GroupId);
|
// //if (taskExist.TaskState == TaskStatusEnum.AGV_TakeFinish.ObjToInt())
|
// //{
|
// // taskExist.IsCancel = 1;
|
// // cancelTasks.Add(taskExist);
|
// //}
|
// //else if(taskExist.TaskState == TaskStatusEnum.AGV_Executing.ObjToInt())
|
// //{
|
// // cancelTasksCompleted.Add(taskExist);
|
// //}
|
// //else
|
// //{
|
// // return content.Error($"任务取消失败{item.TaskCode}任务状态不可取消!");
|
// //}
|
//}
|
//// 取消整个组
|
//foreach(var processed in processedGroups)
|
//{
|
// List<Dt_Task> groupTask = BaseDal.QueryData(x => x.TaskType == TaskTypeEnum.Outbound.ObjToInt() && x.GroupId == processed);
|
// foreach (var group in groupTask)
|
// {
|
// if (group.TaskState == TaskStatusEnum.AGV_TakeFinish.ObjToInt())
|
// {
|
// group.IsCancel = 1;
|
// cancelTasks.Add(group);
|
// }
|
// else if (group.TaskState == TaskStatusEnum.AGV_Executing.ObjToInt())
|
// {
|
// cancelTasksCompleted.Add(group);
|
// }
|
// else
|
// {
|
// return content.Error($"任务取消失败{group.PalletCode}任务状态不可取消!");
|
// }
|
// }
|
//}
|
|
_unitOfWorkManage.BeginTran();
|
BaseDal.UpdateData(cancelTasks);
|
foreach (var item in cancelTasksCompleted)
|
{
|
WebResponseContent responseContent = TaskCancelCompleted(item.TaskNum);
|
if (!responseContent.Status)
|
{
|
throw new Exception(responseContent.Message);
|
}
|
}
|
_unitOfWorkManage.CommitTran();
|
cancelTasks.AddRange(cancelTasksCompleted);
|
foreach (var item in cancelTasks)
|
{
|
AgvTaskCancelDTO agvTaskCancel = new AgvTaskCancelDTO()
|
{
|
RequestId = DateTime.Now.ToString("yyMMddHHmmssfff"),
|
MissionCode = item.GroupId,
|
ContainerCode = item.PalletCode,
|
Position = "",
|
CancelMode = "CTU_REDIRECT_START",
|
Reason = ""
|
};
|
AgvCancelTask(agvTaskCancel);
|
}
|
content.OK();
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 二期播种墙回传
|
/// </summary>
|
/// <returns></returns>
|
public EPLightContent WMSLightBack(List<TaskBackLight> taskBackLights)
|
{
|
EPLightContent content = new EPLightContent();
|
try
|
{
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.WMSLightBack.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url))
|
{
|
return content.Error($"未找到播种墙上报,请检查接口配置");
|
}
|
string request = JsonConvert.SerializeObject(taskBackLights, settings);
|
string response = HttpHelper.Post(url, request);
|
WMSResponseContent wMSResponse = JsonConvert.DeserializeObject<WMSResponseContent>(response) ?? throw new Exception($"未接收到播种墙上报返回值");
|
if (wMSResponse.Code != "0") throw new Exception($"播种墙上报错误,信息:{wMSResponse.Msg}");
|
content.OK();
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 二期播种墙下发
|
/// </summary>
|
/// <returns></returns>
|
public EPLightContent PickOrderInfoRequest(List<EPLightSendDTO> lightSendDTOs)
|
{
|
EPLightContent content = new EPLightContent();
|
try
|
{
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.PickOrderInfoRequest.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url))
|
{
|
return content.Error($"未找到播种墙下发接口,请检查接口配置");
|
}
|
string request = JsonConvert.SerializeObject(lightSendDTOs, settings).ToUpper();
|
// 调用接口
|
string response = HttpHelper.Post(url, request);
|
EPLightContent lightContent = JsonConvert.DeserializeObject<EPLightContent>(response) ?? throw new Exception($"未接收到播种墙下发上报返回值");
|
if (lightContent.Result != "0") throw new Exception($"播种墙下发错误,信息:{lightContent.Msg}");
|
content.OK("成功");
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 二期播种墙初始化
|
/// </summary>
|
/// <param name="taskNum"></param>
|
/// <returns></returns>
|
public EPLightContent INITIALIZATION()
|
{
|
EPLightContent content = new EPLightContent();
|
try
|
{
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.INITIALIZATION.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url))
|
{
|
return content.Error($"未找到播种墙初始化接口,请检查接口配置");
|
}
|
//调用接口
|
string response = Post(url);
|
EPLightContent lightContent = JsonConvert.DeserializeObject<EPLightContent>(response) ?? throw new Exception($"未接收到播种墙初始化上报返回值");
|
if (lightContent.Result != "0") throw new Exception($"播种墙初始化错误,信息:{lightContent.Msg}");
|
content.OK("成功");
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 二期播种墙结束作业
|
/// </summary>
|
/// <param name="taskNum"></param>
|
/// <returns></returns>
|
public EPLightContent ENDWORK()
|
{
|
EPLightContent content = new EPLightContent();
|
try
|
{
|
string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.ENDWORK.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(url))
|
{
|
return content.Error($"未找到播种墙结束作业接口,请检查接口配置");
|
}
|
//调用接口
|
string response = Post(url);
|
EPLightContent lightContent = JsonConvert.DeserializeObject<EPLightContent>(response) ?? throw new Exception($"未接收到播种墙结束作业上报返回值");
|
if (lightContent.Result != "0") throw new Exception($"播种墙结束作业错误,信息:{lightContent.Msg}");
|
content.OK("成功");
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
public override WebResponseContent Export(PageDataOptions options)
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
string savePath = AppDomain.CurrentDomain.BaseDirectory + "ExcelExport";
|
|
// 确保目录存在
|
if (!Directory.Exists(savePath))
|
Directory.CreateDirectory(savePath);
|
|
// 获取数据
|
ISugarQueryable<Dt_Task> query = BaseDal.Db.Queryable<Dt_Task>();
|
var dataList = query.ToList();
|
var properties = typeof(Dt_Task).GetProperties();
|
|
string filePath = TExportHelper.GetExport(savePath, properties, dataList);
|
return WebResponseContent.Instance.OK(data: filePath);
|
}
|
catch (Exception ex)
|
{
|
content = WebResponseContent.Instance.Error(ex.Message);
|
}
|
return content;
|
}
|
/// <summary>
|
/// 重置所有异常任务
|
/// </summary>
|
public WebResponseContent ResetAllExceptionTask(int taskNum)
|
{
|
// 获取异常任务990修改为AGV待执行300
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
|
if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】");
|
if (task.TaskState != (int)TaskStatusEnum.Exception)
|
{
|
return content = WebResponseContent.Instance.Error($"该任务状态不可重置,任务号:【{taskNum}】,任务状态:【{task.TaskState}】");
|
}
|
task.TaskState = (int)TaskStatusEnum.AGV_Execute;
|
BaseDal.UpdateData(task);
|
//_taskExecuteDetailService.AddTaskExecuteDetail(task, $"人工重置异常任务,重置后任务状态【{task.TaskState}】");
|
content = WebResponseContent.Instance.OK();
|
}
|
catch (Exception ex)
|
{
|
content.Error(ex.Message);
|
}
|
return content;
|
}
|
|
public WebResponseContent WmsRecovery()
|
{
|
WebResponseContent content = new WebResponseContent();
|
try
|
{
|
// 删除第一个异常
|
// 按创建时间升序获取第一条记录
|
var orderBy = new Dictionary<string, OrderByType>
|
{
|
{ "CreateDate", OrderByType.Asc }
|
};
|
Dt_ErrorInfo errorInfo = _errorInfoRepository.QueryFirst(x => true, orderBy);
|
if (errorInfo == null)
|
{
|
return content.Error("当前没有异常任务");
|
}
|
// 获取第一个异常(按创建时间排序)
|
_unitOfWorkManage.BeginTran();
|
_errorInfoRepository.DeleteData(errorInfo);
|
_unitOfWorkManage.CommitTran();
|
// 上报恢复
|
string? apiErrorBack = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.WMSErrorBack.ToString())?.ApiAddress;
|
if (string.IsNullOrEmpty(apiErrorBack)) throw new Exception($"未找到WMS故障上报,请检查接口配置");
|
TaskError taskError = new TaskError()
|
{
|
MsgID = errorInfo.Id,
|
StationCode = errorInfo.StationCode,
|
MsgCode = 0,
|
Msg = "恢复"
|
};
|
string reqErrorBack = JsonConvert.SerializeObject(taskError, settings);
|
HttpHelper.Post(apiErrorBack, reqErrorBack);
|
return content.OK();
|
}
|
catch (Exception ex)
|
{
|
_unitOfWorkManage.RollbackTran();
|
return content.Error(ex.Message);
|
throw new Exception(ex.Message);
|
}
|
}
|
}
|
}
|