1、更新AGV接口

This commit is contained in:
葛林强 2024-11-14 23:06:18 +08:00
parent 2010caa685
commit 610de3343b
9 changed files with 414 additions and 8 deletions

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace WcsMain.ApiClient.DataEntity.AGVEntity;
@ -13,12 +14,14 @@ public class AGVResponseLayout<T> where T : class, new()
/// 头部
/// </summary>
[JsonProperty("header")]
[JsonPropertyName("header")]
public AGVResponseHeader? Header { get; set; }
/// <summary>
/// 数据
/// </summary>
[JsonProperty("body")]
[JsonPropertyName("body")]
public AGVResponseBody<T>? Body { get; set; }
@ -34,19 +37,22 @@ public class AGVResponseHeader
/// 请求ID
/// </summary>
[JsonProperty("requestId")]
[JsonPropertyName("requestId")]
public string? RequestId { get; set; }
/// <summary>
/// 时间戳
/// </summary>
[JsonProperty("timestamp")]
[JsonPropertyName("timestamp")]
public string? TimeStamp { get; set; }
/// <summary>
/// 版本号
/// </summary>
[JsonProperty("version")]
public string? version { get; set; }
[JsonPropertyName("version")]
public string? Version { get; set; }
@ -62,24 +68,28 @@ public class AGVResponseBody<T> where T : class, new()
/// 是否成功
/// </summary>
[JsonProperty("success")]
[JsonPropertyName("success")]
public bool? Success { get; set; }
/// <summary>
/// 条码
/// </summary>
[JsonProperty("code")]
[JsonPropertyName("code")]
public string? Code { get; set; }
/// <summary>
/// 响应信息
/// </summary>
[JsonProperty("message")]
[JsonPropertyName("message")]
public string? Message { get; set; }
/// <summary>
/// 响应数据
/// </summary>
[JsonProperty("data")]
[JsonPropertyName ("data")]
public T? Data { get; set; }

View File

@ -1,5 +1,8 @@
using Microsoft.AspNetCore.Mvc;
using WcsMain.ApiClient.DataEntity.AGVEntity;
using WcsMain.ApiServe.ControllerFilter;
using WcsMain.ApiServe.Controllers.Dto.AGV;
using WcsMain.ApiServe.Service.AGVService;
namespace WcsMain.ApiServe.Controllers.AGVController;
@ -9,9 +12,15 @@ namespace WcsMain.ApiServe.Controllers.AGVController;
[Route("api/agv")]
[ApiController]
[ServiceFilter<ResponseFilterAttribute>]
public class AGVController : ControllerBase
public class AGVController(AGVService agvService) : ControllerBase
{
/// <summary>
/// AGV 任务的回告
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("taskCallBack")]
public AGVResponseLayout<AGVResponseLayout<object>> TaskCallBack(Dto.AGV.AGVRequestLayout<AGVRequestBodyLayout<AGVNoVeBuckMoveRequest>> request) => agvService.TaskCallBack(request);

View File

@ -0,0 +1,63 @@
using System.Text.Json.Serialization;
namespace WcsMain.ApiServe.Controllers.Dto.AGV;
public class AGVNoVeBuckMoveRequest
{
/// <summary>
/// 机器人编号
/// </summary>
[JsonPropertyName("agvCode")]
public string? AGVCode { get; set; }
/// <summary>
/// 起始点
/// </summary>
[JsonPropertyName("startPoint")]
public string? StartPoint { get; set; }
/// <summary>
/// 起始点简码
/// </summary>
[JsonPropertyName("startPointName")]
public string? StartPointName { get; set; }
/// <summary>
/// 目标区域
/// </summary>
[JsonPropertyName("endArea")]
public string? EndArea { get; set; }
/// <summary>
/// 目标点位
/// </summary>
[JsonPropertyName("endPoint")]
public string? EndPoint { get; set; }
/// <summary>
/// 目标点简码
/// </summary>
[JsonPropertyName("endPointName")]
public string? EndPointName { get; set;}
/// <summary>
/// 货架作业面
/// </summary>
[JsonPropertyName("workFaces")]
public string? WorkFaces { get; set; }
/// <summary>
/// 货架编码
/// </summary>
[JsonPropertyName("bucketCode")]
public string? BucketCode { get; set; }
/// <summary>
/// 货架简码
/// </summary>
[JsonPropertyName("alias")]
public string? Alias { get; set; }
}

View File

@ -0,0 +1,49 @@
using System.Text.Json.Serialization;
namespace WcsMain.ApiServe.Controllers.Dto.AGV;
/// <summary>
/// AGV 回告任务状态的模板
/// </summary>
public class AGVRequestBodyLayout<T>
{
/// <summary>
/// 上游任务号
/// </summary>
[JsonPropertyName("robotJobId")]
public string? RobotJobId { get; set; }
/// <summary>
/// 仓库编号
/// </summary>
[JsonPropertyName("warehouseId")]
public string? WarehouseId { get; set; }
/// <summary>
/// 快仓系统内部任务号
/// </summary>
[JsonPropertyName("jobId")]
public string? JobId { get; set; }
/// <summary>
/// 任务状态
/// </summary>
[JsonPropertyName("state")]
public string? State { get; set; }
/// <summary>
/// 内部任务类型
/// </summary>
[JsonPropertyName("jobType")]
public string? JobType { get; set; }
/// <summary>
/// 数据
/// </summary>
[JsonPropertyName("jobData")]
public T? JobData { get; set; }
}

View File

@ -0,0 +1,63 @@
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace WcsMain.ApiServe.Controllers.Dto.AGV;
/// <summary>
/// 接收AGV请求的实体
/// </summary>
public class AGVRequestLayout<T>
{
/// <summary>
/// 头部
/// </summary>
[JsonPropertyName("header")]
public AGVRequestHeader? Header { get; set; }
/// <summary>
/// 数据
/// </summary>
[JsonPropertyName("body")]
public T? Body { get; set; }
}
/// <summary>
/// AGV 报文请求头
/// </summary>
public class AGVRequestHeader
{
/// <summary>
/// 快仓唯一标识
/// </summary>
[JsonPropertyName("appKey")]
public string? AppKey { get; set; }
/// <summary>
/// 应用密钥
/// </summary>
[JsonPropertyName("appSecret")]
public string? AppSecret { get; set; }
/// <summary>
/// 请求ID
/// </summary>
[JsonPropertyName("requestId")]
public string? RequestId { get; set; }
/// <summary>
/// 时间戳
/// </summary>
[JsonPropertyName("timestamp")]
public string? TimeStamp { get; set; }
/// <summary>
/// 版本号
/// </summary>
[JsonPropertyName("version")]
public string? version { get; set; }
}

View File

@ -0,0 +1,149 @@
using Humanizer;
using WcsMain.ApiClient.DataEntity.AGVEntity;
using WcsMain.ApiServe.Controllers.Dto.AGV;
using WcsMain.Business.CommonAction;
using WcsMain.DataBase.Dao;
using WcsMain.DataBase.TableEntity;
using WcsMain.Enum.Stacker;
using WcsMain.WcsAttribute.AutoFacAttribute;
namespace WcsMain.ApiServe.Service.AGVService;
[Service]
public class AGVService(AppWmsTaskDao wmsTaskDao, WCSTaskExecuteEvent taskExecuteEvent)
{
/// <summary>
/// AGV 任务回告
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public AGVResponseLayout<AGVResponseLayout<object>> TaskCallBack(Controllers.Dto.AGV.AGVRequestLayout<AGVRequestBodyLayout<AGVNoVeBuckMoveRequest>> request)
{
var bodyData = request.Body;
if(bodyData == default)
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = "Body 未能正确解析" }
};
}
string? wmsTaskId = bodyData.RobotJobId; // 任务号
string? status = bodyData.State; // 状态
if(status == default || wmsTaskId == default)
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = "任务号和状态未能正确解析" }
};
}
/* 实际业务处理 */
// 找到此任务
List<AppWmsTask>? wmsTasks = wmsTaskDao.Select(new() { TaskId = wmsTaskId });
if(wmsTasks == default)
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = "数据连接异常" }
};
}
if (wmsTasks.Count < 1)
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = "该任务号不存在任务" }
};
}
AppWmsTask wmsTask = wmsTasks.First();
// 若是入库任务或者移库任务则在开始移动时上报WMS货物离开起始位置
if (status == "MOVE_BEGIN" && (wmsTask.TaskType == (int)WmsTaskTypeEnum.inTask || wmsTask.TaskType == (int)WmsTaskTypeEnum.agv))
{
// 上报WMS任务已经开始
string? errText = taskExecuteEvent.LeaveStart(wmsTask);
if (string.IsNullOrEmpty(errText))
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "SUCCESS", Success = true, Message = "操作成功" }
};
}
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = $"操作异常:{errText}" }
};
}
// 若是出库位置则在上报任务完成时上报WMS任务完成
if (status == "DONE" || status == "ABNORMAL_COMPLETED")
{
if(wmsTask.TaskType == (int)WmsTaskTypeEnum.outTask || wmsTask.TaskType == (int)WmsTaskTypeEnum.agv)
{
string? errText = taskExecuteEvent.CompleteTaskEvent(wmsTask, "AGV上报完成", wmsTask.Destination);
if (string.IsNullOrEmpty(errText))
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "SUCCESS", Success = true, Message = "操作成功" }
};
}
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = $"操作异常:{errText}" }
};
}
if(wmsTask.TaskType == (int)WmsTaskTypeEnum.inTask)
{
var updateResult = wmsTaskDao.Update(new() { TaskId = wmsTask.TaskId, TaskStatus = (int)WmsTaskStatusEnum.arriveMid, ModifyTime = DateTime.Now });
if(updateResult > 0)
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "SUCCESS", Success = true, Message = "操作成功" }
};
}
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = $"操作异常,数据更新失败" }
};
}
}
if(status == "CANCEL" || status == "ABNORMAL_CANCEL")
{
var updateResult = wmsTaskDao.Update(new() { TaskId = wmsTask.TaskId, TaskStatus = (int)WmsTaskStatusEnum.err, TaskMsg = status, ModifyTime = DateTime.Now });
if (updateResult > 0)
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "SUCCESS", Success = true, Message = "操作成功" }
};
}
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = $"操作异常数据更新失败" }
};
}
var updateAllResult = wmsTaskDao.Update(new() { TaskId = wmsTask.TaskId, TaskMsg = status, ModifyTime = DateTime.Now });
if (updateAllResult > 0)
{
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "SUCCESS", Success = true, Message = "操作成功" }
};
}
return new()
{
Header = new() { RequestId = request.Header?.RequestId, Version = request.Header?.version, TimeStamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") },
Body = new() { Code = "ERROR", Success = false, Message = $"操作异常数据更新失败" }
};
}
}

View File

@ -308,4 +308,44 @@ public class SendWmsTaskStatus(AppWmsTaskDao wmsTaskDao, WmsWebApiPost wmsWebApi
}
});
}
/// <summary>
/// 发送任务离开起始位置
/// </summary>
/// <param name="wmsTask"></param>
/// <param name="count"></param>
public void SendTaskLeaveStart(AppWmsTask wmsTask, int count = 5)
{
Task.Factory.StartNew(() => {
if (wmsTask == default) { return; }
SendWmsTaskStatusRequest request = new()
{
TaskId = wmsTask.TaskId,
TaskStatus = (int)SendWmsTaskStatusEnum.leaveOrigin,
VehicleNo = wmsTask.VehicleNo,
Message = "任务离开起始位置"
};
for (int i = 1; i <= count; i++)
{
var response = wmsWebApiPost.HttpPost<SendWmsTaskStatusRequest, WmsResponse>(request, CommonData.AppApiBaseInfos.GetAddress("SendWmsTaskStatusApiAddress") ?? "");
if (!response.IsSend)
{
ConsoleLog.Error($"【异常】发送WMS[任务离开起始位置]失败,发送次数:{i},任务号:{wmsTask.TaskId},参考信息:{response.RequestException?.Message}");
continue;
}
var responseObj = response.ResponseEntity;
if (responseObj == default)
{
ConsoleLog.Error($"【异常】发送WMS[任务离开起始位置]失败解析WMS返回数据失败发送次数{i},任务号:{wmsTask.TaskId}");
return;
}
if (responseObj.Code == 0)
{
ConsoleLog.Tip($"发送WMS[任务离开起始位置]成功任务号:{wmsTask.TaskId},载具号:{wmsTask.VehicleNo}{wmsTask.Origin} => {wmsTask.Destination}");
return;
}
ConsoleLog.Error($"【异常】发送WMS[任务离开起始位置]失败WMS返回异常任务号{wmsTask.TaskId},载具号:{wmsTask.VehicleNo},参考信息:{responseObj.Message}");
}
});
}
}

View File

@ -5,6 +5,7 @@ using WcsMain.DataBase.MixDao;
using WcsMain.Enum.TaskEnum;
using WcsMain.WcsAttribute.AutoFacAttribute;
using WcsMain.StaticData;
using WcsMain.Enum.Stacker;
namespace WcsMain.Business.CommonAction;
@ -12,7 +13,7 @@ namespace WcsMain.Business.CommonAction;
/// WCS 任务 触发的事件
/// </summary>
[Component]
public class WCSTaskExecuteEvent(TaskDao taskDao, SendWmsTaskStatus sendWmsTaskStatus, AppLocationDao locationDao)
public class WCSTaskExecuteEvent(TaskDao taskDao, SendWmsTaskStatus sendWmsTaskStatus, AppLocationDao locationDao, AppWmsTaskDao wmsTaskDao)
{
/// <summary>
/// 任务执行异常触发事件
@ -162,11 +163,34 @@ public class WCSTaskExecuteEvent(TaskDao taskDao, SendWmsTaskStatus sendWmsTaskS
{
ConsoleLog.Warning($"【异常】任务完成更新WMS任务状态失败异常信息{errText}");
}
if(task.CreatePerson == StaticData.StaticString.WMS)
{
/* 上报WMS */
sendWmsTaskStatus.SendTaskComplete(task.TaskId, destination: destination);
}
return errText;
}
/// <summary>
/// 发送任务离开起始位置
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public string? LeaveStart(AppWmsTask task)
{
int updateResult = wmsTaskDao.Update(new() { TaskId = task.TaskId, TaskStatus = task.TaskType == (int)WmsTaskTypeEnum.moveTask ? (int)WmsTaskStatusEnum.toDestination : (int)WmsTaskStatusEnum.toMid, ModifyTime = DateTime.Now });
if (updateResult < 1)
{
ConsoleLog.Warning($"【异常】任务完成更新WMS任务状态失败");
}
if (task.CreatePerson == StaticData.StaticString.WMS)
{
/* 上报WMS */
sendWmsTaskStatus.SendTaskLeaveStart(task);
}
return "更新信息失败";
}
#endregion

View File

@ -38,7 +38,6 @@
<ItemGroup>
<Folder Include="ApiServe\Controllers\Dto\CommonEntity\" />
<Folder Include="ApiServe\Controllers\AGVController\" />
<Folder Include="ApiServe\Service\TestService\" />
<Folder Include="Business\CirculationTask\Container\" />
<Folder Include="Business\CirculationTask\Shuttle\" />