using Mapster;
using MapsterMapper;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using System.DirectoryServices.Protocols;
using System.Text.Json;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_Core.Core;
using WIDESEA_Core.Enums;
using WIDESEA_Core.Helper;
using WIDESEA_DTO.GradingMachine;
using WIDESEA_DTO.MES;
using WIDESEA_DTO.Stock;
using WIDESEA_DTO.Task;
using WIDESEA_IBasicService;
using WIDESEA_IStockService;
using WIDESEA_ITaskInfoService;
using WIDESEA_Model.Models;
namespace WIDESEA_TaskInfoService
{
public partial class TaskService
{
#region 极卷库任务模块
public string AGV_OutTaskComplete = WIDESEA_Core.Helper.AppSettings.Configuration["AGV_OutTaskComplete"]; // 上报AGV出库输送线完成
public string WCS_ReceiveTask = WIDESEA_Core.Helper.AppSettings.Configuration["WCS_ReceiveTask"]; // WMS输送线任务下发
///
/// 出入库申请
///
/// 请求参数
///
public async Task ApplyInOutAsync(ApplyInOutDto applyInOutDto)
{
AGVResponse aGVResponse = new AGVResponse();
try
{
// 参数验证
if (applyInOutDto == null) return aGVResponse.Error("请求参数不能为空");
if (string.IsNullOrWhiteSpace(applyInOutDto.TrayNumber)) return aGVResponse.Error("托盘号不能为空");
if (string.IsNullOrWhiteSpace(applyInOutDto.TaskId)) return aGVResponse.Error("任务号不能为空");
if (string.IsNullOrWhiteSpace(applyInOutDto.MaterialType)) return aGVResponse.Error("物料类型不能为空");
if (string.IsNullOrWhiteSpace(applyInOutDto.MaterialName)) return aGVResponse.Error("物料描述不能为空");
if (string.IsNullOrWhiteSpace(applyInOutDto.ReqTime)) return aGVResponse.Error("请求时间不能为空");
if (applyInOutDto.Floor != 1 && applyInOutDto.Floor != 2) return aGVResponse.Error($"楼层段错误,必须为1(模切段)或2(卷绕段),当前值:{applyInOutDto.Floor}");
if (applyInOutDto.YinYang != 1 && applyInOutDto.YinYang != 2) return aGVResponse.Error($"阴阳极错误,必须为1(阴极)或2(阳极),当前值:{applyInOutDto.YinYang}");
if (applyInOutDto.InOut != 1 && applyInOutDto.InOut != 2) return aGVResponse.Error($"出入库类型错误,必须为1(入库)或2(出库),当前值:{applyInOutDto.InOut}");
if (applyInOutDto.InOut == 1) // 入库
{
if (applyInOutDto.Width == null || applyInOutDto.Width <= 0) return aGVResponse.Error("入库时宽度不能为空且必须大于0");
if (string.IsNullOrWhiteSpace(applyInOutDto.Group)) return aGVResponse.Error("入库时整托组别不能为空");
}
// 检查任务是否已存在
var existingTask = await BaseDal.QueryFirstAsync(x => x.PalletCode == applyInOutDto.TrayNumber);
if (existingTask != null) return aGVResponse.Error($"WMS已有当前任务,不可重复下发,任务号:{applyInOutDto.TaskId}");
// 创建任务
Dt_Task task = new Dt_Task
{
OrderNo = applyInOutDto.TaskId, // 使用AGV的任务号
PalletCode = applyInOutDto.TrayNumber,
PalletType = applyInOutDto.Floor,
//WarehouseId = applyInOutDto.YinYang,
Grade = 1,
Creater = "AGV",
CreateDate = DateTime.Now,
Remark = $"物料类型:{applyInOutDto.MaterialType},物料描述:{applyInOutDto.MaterialName}"
};
// 根据阴极/阳极设置巷道和站台
if (applyInOutDto.YinYang == 1) // 阴极
{
// 货物到达后分配货物位
task.Roadway = WarehouseEnum.FJ1.ToString();
task.WarehouseId = (int)WarehouseEnum.FJ1;
task.SourceAddress = applyInOutDto.InOut == 1 ? "D10010" : "D10020"; // 入库口/出库口
task.NextAddress = "D10080"; // 阴极公共出库口
task.TargetAddress = "阴极卷库";
}
else if (applyInOutDto.YinYang == 2) // 阳极
{
task.Roadway = WarehouseEnum.ZJ1.ToString();
task.WarehouseId = (int)WarehouseEnum.ZJ1;
task.SourceAddress = applyInOutDto.InOut == 1 ? "D10100" : "D10090"; // 入库口/出库口
task.NextAddress = "D10160"; // 阳极公共出库口
task.TargetAddress = "正极卷库";
}
// 根据出入库类型设置目标地址
if (applyInOutDto.InOut == 1) // 入库
{
var stockInfo = await _stockInfoService.GetStockInfoAsync(applyInOutDto.TrayNumber);
if (stockInfo != null) return aGVResponse.Error($"当前托盘{applyInOutDto.TrayNumber}已经入库了");
task.TaskType = (int)TaskInboundTypeEnum.Inbound;
task.TaskStatus = (int)TaskInStatusEnum.InNew;
task.CurrentAddress = task.SourceAddress; // 当前在入库口
// 保存任务
var result = await BaseDal.AddDataAsync(task);
}
else // 出库
{
// 判断是否移库
task.TaskType = (int)TaskOutboundTypeEnum.Outbound;
task.TaskStatus = (int)TaskOutStatusEnum.OutNew;
task.CurrentAddress = task.SourceAddress; // 当前在入库口
// 查找库存
var stockInfo = await _stockInfoService.GetStockInfoAsync(applyInOutDto.TrayNumber);
if (stockInfo == null) return aGVResponse.Error($"未找到托盘{applyInOutDto.TrayNumber}的库存信息");
// 验证库存所属是否正确
if (stockInfo.WarehouseId != applyInOutDto.YinYang) return aGVResponse.Error($"托盘{applyInOutDto.TrayNumber}不属于当前{(applyInOutDto.YinYang == 1 ? "阴极" : "阳极")}");
if (stockInfo.StockStatus != (int)StockStatusEmun.入库完成) return aGVResponse.Error($"托盘{applyInOutDto.TrayNumber}正在移动中,请稍后!");
task.SourceAddress = stockInfo.LocationCode; // 源地址为货位
task.CurrentAddress = stockInfo.LocationCode; // 当前位置在货位
task.TargetAddress = applyInOutDto.YinYang == 1 ? "D10020" : "D10090"; // 目标地址为出库口
// 保存任务
var result = await BaseDal.AddDataAsync(task);
// 判断是否移库
//var transferTask = await _locationInfoService.TransferCheckAsync(result);
}
// 构建响应数据
AGVDataDto aGVDataDto = new AGVDataDto
{
DevId = applyInOutDto.InOut == 1 ? task.SourceAddress : task.TargetAddress,
TrayNumber = task.PalletCode,
Group = applyInOutDto.Group,
Width = applyInOutDto.Width ?? 0,
LabelNumber = applyInOutDto.LabelNumber,
ProductNo = applyInOutDto.ProductNo,
ProductName = applyInOutDto.ProductName,
Quantity = applyInOutDto.Quantity,
UomCode = applyInOutDto.UomCode,
ProductType = applyInOutDto.ProductType,
Equipment = applyInOutDto.Equipment,
ProductionDate = applyInOutDto.ProductionDate,
LowerLimitTime = applyInOutDto.LowerLimitTime,
WarningTime = applyInOutDto.WarningTime,
OverdueTime = applyInOutDto.OverdueTime
};
return aGVResponse.OK(aGVDataDto);
}
catch (Exception ex)
{
return aGVResponse.Error($"WMS任务创建接口错误: {ex.Message}");
}
}
///
/// 手动出库完成反馈给AGV
///
/// 请求参数
///
public async Task OutTaskComplete(OutTaskCompleteDto outTaskCompleteDto)
{
WebResponseContent webResponse = new WebResponseContent();
try
{
if (outTaskCompleteDto == null) return webResponse.Error("请求参数不能为空");
if (string.IsNullOrWhiteSpace(outTaskCompleteDto.TaskId)) return webResponse.Error("任务号不能为空");
if (string.IsNullOrWhiteSpace(outTaskCompleteDto.DevId)) return webResponse.Error("出库口编号不能为空");
var task = await BaseDal.QueryFirstAsync(x => x.OrderNo == outTaskCompleteDto.TaskId);
if (task == null) return webResponse.Error("未找到任务信息");
outTaskCompleteDto.ReqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var httpResponse = _httpClientHelper.Post(AGV_OutTaskComplete, outTaskCompleteDto.ToJson()).Data;
// 判断远程接口返回是否成功
if (httpResponse != null && httpResponse.Data != null)
{
AGVResponse agvResponse = httpResponse;
// 根据code字段判断,code为true表示成功
if (agvResponse.Code == true)
{
var stockInfo = await _stockInfoService.GetStockInfoAsync(task.PalletCode);
if (stockInfo == null) return webResponse.Error($"未找到托盘{task.PalletCode}的库存信息");
var locationInfo = await _locationInfoService.GetLocationInfoAsync(stockInfo.LocationCode);
if (locationInfo == null) return webResponse.Error($"未找到托盘{stockInfo.LocationCode}的货位信息");
if (stockInfo.StockStatus != (int)StockStatusEmun.出库锁定 || locationInfo.LocationStatus != (int)LocationStatusEnum.InStockLock)
{
return webResponse.Error($"当前库存{stockInfo.StockStatus}或者货位{locationInfo.LocationStatus}状态信息错误");
}
locationInfo.LocationStatus = (int)LocationStatusEnum.Free;
_unitOfWorkManage.BeginTran();
BaseDal.DeleteData(task);
_locationInfoService.UpdateData(locationInfo);
_stockInfoService.DeleteData(stockInfo);
_unitOfWorkManage.CommitTran();
return webResponse.OK(agvResponse.Msg);
}
else
{
// 失败:返回AGV返回的错误信息
return webResponse.Error(string.IsNullOrWhiteSpace(agvResponse.Msg)
? "AGV接口调用失败"
: agvResponse.Msg);
}
}
else
{
// HTTP请求本身失败
return webResponse.Error(httpResponse?.Msg ?? "AGV接口调用异常");
}
}
catch (Exception ex)
{
_unitOfWorkManage.RollbackTran();
return webResponse.Error($"WMS任务完成接口错误:{ex.Message}");
}
}
/////
///// 任务完成接口
/////
/////
/////
//public async Task TaskCompleted(WCSTaskDTO wCSTask)
//{
// WebResponseContent webResponse = new WebResponseContent();
// try
// {
// Dt_Task task = await BaseDal.QueryFirstAsync(x => x.TaskId == wCSTask.TaskNum && x.PalletCode == wCSTask.PalletCode);
// if (task == null) return webResponse.Error("未找到任务信息");
// // 出库完成反馈
// OutTaskCompleteDto outTaskCompleteDto = new OutTaskCompleteDto()
// {
// TaskId = task.OrderNo,
// DevId = task.TargetAddress,
// ReqTime = DateTime.Now.ToString()
// };
// return await OutTaskComplete(outTaskCompleteDto);
// }
// catch (Exception ex)
// {
// return webResponse.Error($"WMS任务完成接口错误:{ex.Message}");
// }
//}
///
/// 输送线申请进入
///
/// 请求参数
///
public async Task ApplyEnterAsync(ApplyEnterDto applyEnterDto)
{
AGVResponse aGVResponse = new AGVResponse();
try
{
// 参数验证
if (applyEnterDto == null) return aGVResponse.Error("请求参数不能为空");
if (string.IsNullOrWhiteSpace(applyEnterDto.DevId)) return aGVResponse.Error("设备编号不能为空");
if (string.IsNullOrWhiteSpace(applyEnterDto.TaskId)) return aGVResponse.Error("任务号不能为空");
if (applyEnterDto.InOut != 1 && applyEnterDto.InOut != 2) return aGVResponse.Error($"出入库类型错误,必须为1(入库)或2(出库),当前值:{applyEnterDto.InOut}");
// 查询任务是否存在
var task = await BaseDal.QueryFirstAsync(x => x.OrderNo == applyEnterDto.TaskId);
if (task == null) return aGVResponse.Error($"未找到任务信息,任务号:{applyEnterDto.TaskId}");
if (applyEnterDto.InOut == 1 && task.TaskType == (int)TaskInboundTypeEnum.Inbound && task.TaskStatus == (int)TaskInStatusEnum.InNew)
{
aGVResponse.OK();
}
else if (applyEnterDto.InOut == 2 && task.TaskType == (int)TaskOutboundTypeEnum.Outbound && task.TaskStatus == (int)TaskStatusEnum.Line_Finish)
{
aGVResponse.OK();
}
return aGVResponse.Error($"输送线{applyEnterDto.DevId}当前繁忙,请稍后重试");
// Dt_Task.SourceAddress询问wcs站台1-阴极入口叫D10010和D10020;2-阳极D10090和D10100是否有货物
//var httpResponse = _httpClientHelper.Post("http://127.0.0.1:9999/api/Task/ApplyInOut", JsonSerializer.Serialize(task)).Data;
//if (httpResponse != null && httpResponse.Status == true)
//{
// _unitOfWorkManage.BeginTran();
// task.TaskStatus = (int)TaskStatusEnum.AGV_Executing;
// await BaseDal.UpdateDataAsync(task);
// _unitOfWorkManage.CommitTran();
// return aGVResponse.OK();
//}
//else
//{
// return aGVResponse.Error($"站台{task.SourceAddress}已经载货");
//}
}
catch (Exception ex)
{
//_unitOfWorkManage.RollbackTran();
return aGVResponse.Error($"WMS输送线申请接口错误:{ex.Message}");
}
}
///
/// 取放货完成
///
/// 请求参数
///
public async Task TaskCompleteAsync(TaskCompleteDto taskCompleteDto)
{
AGVResponse aGVResponse = new AGVResponse();
try
{
if (taskCompleteDto == null) return aGVResponse.Error("请求参数不能为空");
if (string.IsNullOrWhiteSpace(taskCompleteDto.TaskId)) return aGVResponse.Error("任务号不能为空");
if (string.IsNullOrWhiteSpace(taskCompleteDto.DevId)) return aGVResponse.Error("设备编号不能为空");
if (taskCompleteDto.InOut != 1 && taskCompleteDto.InOut != 2) return aGVResponse.Error($"出入库类型错误,必须为1(入库)或2(出库),当前值:{taskCompleteDto.InOut}");
var task = await BaseDal.QueryFirstAsync(x => x.OrderNo == taskCompleteDto.TaskId);
if (task == null) return aGVResponse.Error($"未找到任务信息,任务号:{taskCompleteDto.TaskId}");
if (taskCompleteDto.InOut == 2)
{
var stockInfo = await _stockInfoService.GetStockInfoAsync(task.PalletCode);
if (stockInfo == null) return aGVResponse.Error($"未找到托盘{task.PalletCode}的库存信息");
var locationInfo = await _locationInfoService.GetLocationInfoAsync(stockInfo.LocationCode);
if (locationInfo == null) return aGVResponse.Error($"未找到托盘{stockInfo.LocationCode}的货位信息");
if (stockInfo.StockStatus != (int)StockStatusEmun.出库锁定 || locationInfo.LocationStatus != (int)LocationStatusEnum.InStockLock)
{
return aGVResponse.Error($"当前库存{stockInfo.StockStatus}或者货位{locationInfo.LocationStatus}状态信息错误");
}
locationInfo.LocationStatus = (int)LocationStatusEnum.Free;
task.TaskStatus = (int)TaskOutStatusEnum.OutFinish;
_unitOfWorkManage.BeginTran();
_stockInfoService.DeleteData(stockInfo);
await _locationInfoService.UpdateLocationInfoAsync(locationInfo);
BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
_unitOfWorkManage.CommitTran();
}
else
{
//查找可用货位
var availableLocation = await _locationInfoService.GetLocationInfo(task.Roadway);
if (availableLocation == null) return aGVResponse.Error("无可用的入库货位");
task.TargetAddress = availableLocation.LocationCode;
// 通知WCS入库
var wcsTaskDto = _mapper.Map(task);
var httpResponse = _httpClientHelper.Post(WCS_ReceiveTask, JsonSerializer.Serialize(wcsTaskDto));
if (httpResponse == null) return aGVResponse.Error("下发WCS失败");
task.TaskStatus = (int)TaskStatusEnum.Line_Executing;
task.Dispatchertime = DateTime.Now;
var locationInfo = await _locationInfoService.GetLocationInfoAsync(task.TargetAddress);
if (locationInfo == null) return aGVResponse.Error($"未找到托盘{task.TargetAddress}的货位信息");
if (locationInfo.LocationStatus != (int)LocationStatusEnum.InStock)
{
return aGVResponse.Error($"当前货位{locationInfo.LocationStatus}状态信息错误");
}
Dt_StockInfo dt_Stock = new Dt_StockInfo()
{
PalletCode = task.PalletCode,
StockStatus = (int)StockStatusEmun.入库确认,
LocationCode = locationInfo.LocationCode,
WarehouseId = task.WarehouseId,
Creater = "AGV",
CreateDate = DateTime.Now
};
locationInfo.LocationStatus = (int)LocationStatusEnum.FreeLock;
_unitOfWorkManage.BeginTran();
BaseDal.UpdateData(task);
_locationInfoService.UpdateData(locationInfo);
_stockInfoService.AddData(dt_Stock);
_unitOfWorkManage.CommitTran();
}
return aGVResponse.OK();
}
catch (Exception ex)
{
_unitOfWorkManage.RollbackTran();
return aGVResponse.Error($"WMS取放货完成接口错误:{ex.Message}");
}
}
///
/// 任务取消
///
/// 请求参数
///
public async Task TaskCancelAsync(TaskCancelDto taskCancelDto)
{
AGVResponse aGVResponse = new AGVResponse();
try
{
if (taskCancelDto == null) return aGVResponse.Error("请求参数不能为空");
if (string.IsNullOrWhiteSpace(taskCancelDto.TaskId)) return aGVResponse.Error("任务号不能为空");
var task = await BaseDal.QueryFirstAsync(x => x.OrderNo == taskCancelDto.TaskId);
// 没有任务强制取消
if (task == null) return aGVResponse.OK();
if (task.TaskStatus == (int)TaskInStatusEnum.InNew)
{
task.TaskStatus = (int)TaskInStatusEnum.InCancel;
// 入库任务直接删除
_unitOfWorkManage.BeginTran();
BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
_unitOfWorkManage.CommitTran();
return aGVResponse.OK();
}
else if (task.TaskStatus == (int)TaskOutStatusEnum.OutNew)
{
// 出库任务恢复库存
var stockInfo = await _stockInfoService.GetStockInfoAsync(task.PalletCode);
if (stockInfo == null) return aGVResponse.Error($"未找到托盘{task.PalletCode}的库存信息");
var locationInfo = await _locationInfoService.GetLocationInfoAsync(stockInfo.LocationCode);
if (locationInfo == null) return aGVResponse.Error($"未找到托盘{stockInfo.LocationCode}的货位信息");
if (stockInfo.StockStatus != (int)StockStatusEmun.出库锁定 || locationInfo.LocationStatus != (int)LocationStatusEnum.InStockLock)
{
return aGVResponse.Error($"当前库存{stockInfo.StockStatus}或者货位{locationInfo.LocationStatus}状态信息错误");
}
stockInfo.StockStatus = (int)StockStatusEmun.入库完成;
locationInfo.LocationStatus = (int)LocationStatusEnum.InStock;
task.TaskStatus = (int)TaskOutStatusEnum.OutCancel;
_unitOfWorkManage.BeginTran();
_locationInfoService.UpdateData(locationInfo);
_stockInfoService.UpdateData(stockInfo);
BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
_unitOfWorkManage.CommitTran();
return aGVResponse.OK();
}
return aGVResponse.Error("任务已经在执行中,不可取消");
}
catch (Exception ex)
{
_unitOfWorkManage.RollbackTran();
return aGVResponse.Error($"WMS任务取消接口错误:{ex.Message}");
}
}
#endregion 极卷库任务模块
}
}