using AngleSharp.Dom; using log4net.Core; using Mapster; using Masuit.Tools; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; using NewLife; using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; using OfficeOpenXml.Table.PivotTable; using SixLabors.Fonts.Tables.AdvancedTypographic; using SqlSugar; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Metadata; using System.Security.Policy; using System.Text.RegularExpressions; using System.Threading.Tasks; using WIDESEA_Cache; using WIDESEA_Common; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.Const; using WIDESEA_Core.Enums; using WIDESEA_DTO.Basic; using WIDESEA_DTO.ERP; using WIDESEA_DTO.Location; using WIDESEA_DTO.Stock; using WIDESEA_DTO.WMS; using WIDESEA_IOrderRepository; using WIDESEA_IServices; using WIDESEA_Model.Models; using WIDESEA_Model.Models.Basic; using WIDESEA_Model.Models.ERP; using WIDESEA_Model.Models.Order; using WIDESEA_OrderRepository; using WIDESEA_StorageTaskRepository; using WIDESEAWCS_BasicInfoRepository; using WIDESEAWCS_QuartzJob.Models; using static System.Collections.Specialized.BitVector32; namespace WIDESEA_StorageTaskServices; public partial class Dt_TaskService : ServiceBase, IDt_TaskService { private readonly LogFactory LogFactory = new LogFactory(); private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IStockInfoRepository _stockInfoRepository; private readonly IStockInfoDetailRepository _stockInfoDetailRepository; private readonly IDt_Task_HtyRepository _task_HtyRepository; private readonly IMapper _mapper; private readonly ILocationInfoRepository _locationRepository; private readonly ITaskExecuteDetailRepository _taskExecuteDetailRepository; private readonly ILocationStatusChangeRecordRepository _locationStatusChangeRecordRepository; private readonly IBoxingInfoRepository _boxingInfoRepository; //组盘 private readonly IDt_AreaInfoRepository _areaInfoRepository; //区域 private readonly IDt_StationManagerRepository _stationManagerRepository; private readonly ISys_ConfigService _configService; private readonly IDt_OrderOutDetailsRepository _orderOutDetailsRepository; private readonly IDt_WareAreaInfoRepository _wareAreaInfoRepository; private readonly IDt_InventoryRecordRepository _inventoryRecordRepository; public Dt_TaskService(IDt_TaskRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoRepository stockInfoRepository, IDt_Task_HtyRepository task_HtyRepository, IMapper mapper, ILocationInfoRepository locationRepository, ITaskExecuteDetailRepository taskExecuteDetailRepository, ILocationStatusChangeRecordRepository locationStatusChangeRecordRepository, IBoxingInfoRepository boxingInfoRepository, IDt_AreaInfoRepository areaInfoRepository, IStockInfoDetailRepository stockInfoDetailRepository, IDt_StationManagerRepository stationManagerRepository, ISys_ConfigService configService, IDt_OrderOutDetailsRepository orderOutDetailsRepository, IDt_WareAreaInfoRepository wareAreaInfoRepository, IDt_InventoryRecordRepository inventoryRecordRepository) : base(BaseDal) { _unitOfWorkManage = unitOfWorkManage; _stockInfoRepository = stockInfoRepository; _task_HtyRepository = task_HtyRepository; _mapper = mapper; _locationRepository = locationRepository; _taskExecuteDetailRepository = taskExecuteDetailRepository; _locationStatusChangeRecordRepository = locationStatusChangeRecordRepository; _boxingInfoRepository = boxingInfoRepository; _areaInfoRepository = areaInfoRepository; _stockInfoDetailRepository = stockInfoDetailRepository; _stationManagerRepository = stationManagerRepository; _configService = configService; _orderOutDetailsRepository = orderOutDetailsRepository; _wareAreaInfoRepository = wareAreaInfoRepository; _inventoryRecordRepository = inventoryRecordRepository; } #region 外部接口方法 #region 出库任务完成 public async Task CompleteOutboundTaskAsync(Dt_Task task, DtStockInfo stock) { WebResponseContent content = new WebResponseContent(); try { if (task.TaskState.GetTaskStateGroup() == TaskStateGroup.CarryGroup) { var result1 = UpdateLocationStatus(task.SourceAddress, LocationEnum.Free, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticOutbound); await _locationStatusChangeRecordRepository.AddDataAsync(result1.Item1); await _locationRepository.UpdateDataAsync(result1.Item2); } task.TaskState = (int)TaskOutStatusEnum.OutFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; stock.ModifyDate = DateTime.Now; stock.LocationCode = task.TargetAddress; var result2 = UpdateLocationStatus(task.TargetAddress, LocationEnum.InStock, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticOutbound); DtStockInfo_Hty stockInfo_Hty = stock.Adapt(); var orderDetails = _orderOutDetailsRepository.QueryData(x => x.PalletCode == task.PalletCode); List orderdetailshtys = new List(); orderDetails.ForEach(item => { orderdetailshtys.Add(item.Adapt()); }); await ERPAllocateOut(stock); //调拨出库 if (task.TaskType == (int)TaskOutboundTypeEnum.OutAllocate) { if (orderDetails.Count > 0) await ERPAllocate(orderDetails.Where(x => x.OrderType == (int)OrderTypeEmun.调拨出库单).ToList()); } //其他出库 else if (task.TaskType == (int)TaskOutboundTypeEnum.OutOther) { if (orderDetails.Count > 0) { await ERPMixedSend(orderDetails.Where(x => x.OrderType == (int)OrderTypeEmun.其他出库单).ToList()); } } //生产领料出库 else if (task.TaskType == (int)TaskOutboundTypeEnum.MaterialRequisition) { if (orderDetails.Count > 0) { content = await ERPProduction(orderDetails.Where(x => x.OrderType == (int)OrderTypeEmun.生产领料单).ToList()); } } var boxingInfo = await _boxingInfoRepository.QueryFirstNavAsync(x => x.PalletCode == stock.PalletCode); if (boxingInfo != null) { var mergedDetails = boxingInfo.BoxingInfoDetails .GroupBy(x => new { x.MaterielCode, x.MaterielName }) .Select(g => new DtBoxingInfoDetail { MaterielCode = g.Key.MaterielCode, MaterielName = g.Key.MaterielName, DemandClassification = g.FirstOrDefault().DemandClassification, Warehouse = "WMS出库缓存区", WareHouseId = "205", OrderNo = g.FirstOrDefault().OrderNo, Unit = g.FirstOrDefault().Unit, Specs = g.FirstOrDefault().Specs, Weight = g.FirstOrDefault().Weight, DrawingNumber = g.FirstOrDefault().DrawingNumber, Date = g.FirstOrDefault().Date, Remark = g.FirstOrDefault().Remark, Quantity = g.Sum(item => item.Quantity), }) .ToList(); boxingInfo.BoxingInfoDetails = mergedDetails; } //await _unitOfWorkManage.UseTranAsync(async () => //{ _unitOfWorkManage.BeginTran(); await DeleteStockInfoAsync(stock.Id); _boxingInfoRepository.UpdateDataNav(boxingInfo); await DeleteStockInfoDetailsAsync(stock.StockInfoDetails); await AddStockInfoHtyAsync(stockInfo_Hty); await _locationStatusChangeRecordRepository.AddDataAsync(result2.Item1); await _locationRepository.UpdateDataAsync(result2.Item2); await _orderOutDetailsRepository.DeleteDataAsync(orderDetails); await SqlSugarHelper.DbWMS.Insertable(orderdetailshtys).ExecuteCommandAsync(); await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); _unitOfWorkManage.CommitTran(); //}); content.OK("出库完成"); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); task.ErrorMessage = ex.Message; await BaseDal.UpdateDataAsync(task); return content.Error(ex.Message); } return content; } #endregion 出库任务完成 #region 移库任务完成 /// /// 移库任务完成 /// /// 任务数据合集 /// 返回结果集 public async Task CompleteTransferTaskAsync(Dt_Task task, DtStockInfo stock) { WebResponseContent content = new WebResponseContent(); try { var locationStart = await _locationRepository.QueryFirstAsync(x => x.LocationCode == task.SourceAddress); var locationEnd = await _locationRepository.QueryFirstAsync(x => x.LocationCode == task.TargetAddress); task.TaskState = (int)TaskRelocationStatusEnum.AGV_RelocationFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; if (stock != null) { stock.ModifyDate = DateTime.Now; stock.LocationCode = task.TargetAddress; } var result1 = UpdateLocationStatus(locationStart.LocationCode, LocationEnum.Free, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticRelocation); var result2 = UpdateLocationStatus(locationEnd.LocationCode, LocationEnum.InStock, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticRelocation); await _unitOfWorkManage.UseTranAsync(async () => { await _locationStatusChangeRecordRepository.AddDataAsync(result1.Item1); await _locationRepository.UpdateDataAsync(result1.Item2); await _locationStatusChangeRecordRepository.AddDataAsync(result2.Item1); await _locationRepository.UpdateDataAsync(result2.Item2); if (stock != null) _stockInfoRepository.UpdateData(stock); await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); }); content.OK("移库完成"); } catch (Exception err) { Console.WriteLine(err.Message.ToString()); } return content; } #endregion 移库任务完成 #region 入库任务完成 /// /// 完成入库任务 /// /// 任务数据合集 /// 返回结果集 public async Task CompleteInboundTaskAsync(Dt_Task task) { WebResponseContent content = new WebResponseContent(); try { var boxinfo = await _boxingInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode); if (boxinfo == null) { return content.Error("未找到组盘数据"); } if (task.TaskState.GetTaskStateGroup() == TaskStateGroup.CarryGroup) { var result1 = UpdateLocationStatus(task.SourceAddress, LocationEnum.Free, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticInbound); await _locationStatusChangeRecordRepository.AddDataAsync(result1.Item1); await _locationRepository.UpdateDataAsync(result1.Item2); } var stock = CreateStock(boxinfo, task); task.TaskState = (int)TaskInStatusEnum.InFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; var result2 = UpdateLocationStatus(task.TargetAddress, LocationEnum.InStock, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticInbound); //await _unitOfWorkManage.UseTranAsync(async () => //{ _unitOfWorkManage.BeginTran(); await _stockInfoRepository.AddDataNavAsync(stock); await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); await _locationStatusChangeRecordRepository.AddDataAsync(result2.Item1); await _locationRepository.UpdateDataAsync(result2.Item2); _unitOfWorkManage.CommitTran(); //}); await ERPAllocate(boxinfo); content.OK("入库完成"); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); task.ErrorMessage = ex.Message; await BaseDal.UpdateDataAsync(task); return content.Error(ex.Message); } return content; } public DtStockInfo CreateStock(DtBoxingInfo boxingInfo,Dt_Task task) { var boxDetail = boxingInfo.BoxingInfoDetails.Adapt>(); boxDetail.ForEach(x => { x.Status = (int)StockStateEmun.已入库; }); var mergedDetails = boxDetail .GroupBy(x => new { x.MaterielCode, x.MaterielName }) .Select(g => new DtStockInfoDetail { MaterielCode = g.Key.MaterielCode, MaterielName = g.Key.MaterielName, DemandClassification = g.FirstOrDefault().DemandClassification, Warehouse = "智能立库", WareHouseId = "107", OrderNo = g.FirstOrDefault().OrderNo, Unit = g.FirstOrDefault().Unit, Specs = g.FirstOrDefault().Specs, Weight = g.FirstOrDefault().Weight, OutboundQuantity = g.FirstOrDefault().OutboundQuantity, DrawingNumber = g.FirstOrDefault().DrawingNumber, Date = g.FirstOrDefault().Date, AllocateWarehouse = g.FirstOrDefault().AllocateWarehouse, Remark = g.FirstOrDefault().Remark, Quantity = g.Sum(item => item.Quantity), }) .ToList(); return new DtStockInfo() { PalletCode = task.PalletCode, LocationCode = task.TargetAddress, CreateDate = DateTime.Now, Creater = "system", IsFullExit = boxingInfo.IsFullExit, StockInfoDetails = mergedDetails, StockStatus = (int)StockStateEmun.已入库 }; } #endregion 入库任务完成 #region 任务完成 /// /// 完成任务 /// /// 任务编号 /// 返回结果集 public async Task CompleteAsync(int taskNum) { // 初始化响应内容 WebResponseContent content = new WebResponseContent(); // 提取任务数据 LogFactory.GetLog("任务完成").InfoFormat(true, "提取任务数据", $"任务号:{taskNum}"); // 验证任务是否存在 var task = await GetByTaskNum(taskNum); if (task == null) { return content.Error("任务不存在"); } LogFactory.GetLog("任务完成").InfoFormat(true, "验证任务是否存在", JsonConvert.SerializeObject(task)); // 验证库存是否存在 var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode); if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { return await CompleteOutboundTaskAsync(task, stock); } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) { return await CompleteInboundTaskAsync(task); } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup) { return await CompleteTransferTaskAsync(task, stock); } else { return content.Error("未找到任务类型"); } } #endregion 任务完成 #region 取消任务 public WebResponseContent TaskCancel(int taskNum) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) { return content = WebResponseContent.Instance.Error("未找到任务信息"); } _unitOfWorkManage.BeginTran(); MethodInfo? methodInfo = GetType().GetMethod(((TaskTypeEnum)task.TaskType) + "TaskCancel"); if (methodInfo != null) { WebResponseContent? responseContent = (WebResponseContent?)methodInfo.Invoke(this, new object[] { task }); if (responseContent != null) { if (responseContent != null) { } } } return content = WebResponseContent.Instance.Error("未找到任务类型对应业务处理逻辑"); } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); return content = WebResponseContent.Instance.Error(ex.Message); } } #endregion #region 请求任务入库 public async Task RequestInboundTaskAsync(RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); try { var task = BaseDal.QueryFirst(x => x.PalletCode == taskDto.PalletCode); if (task != null) { return content.Error("该托盘已经存在任务,请勿重复下发"); } var boxingInfo = await _boxingInfoRepository.QueryFirstNavAsync(x => x.PalletCode == taskDto.PalletCode && x.StockStatus == (int)StockStateEmun.组盘暂存); if (boxingInfo == null) { return content.Error("托盘信息不存在,请确认托盘已组盘成功"); } //foreach (var item in boxingInfo.BoxingInfoDetails) //{ // var ERPStock = SqlSugarHelper.DBERP.Queryable<用友即时库存_ST>().Where(x => x.存储地点名称 == item.Warehouse && x.料号 == item.MaterielCode && x.品名 == item.MaterielName && x.库存数量 >= item.Quantity).ToList().FirstOrDefault(); // if (ERPStock == null) // { // return content.Error($"组盘数据未在ERP库存数据中,请人工确认数据是否正确"); // } //} var StartAddress = await _locationRepository.QueryFirstAsync(x => x.LocationCode == taskDto.Position); if (StartAddress == null) { return content.Error("起点库位未找到"); } if (!LocationIsOutBound(StartAddress)) { return content.Error($"起点库位{StartAddress.LocationCode}搬运路径被占用,请人工确认再下发任务"); } Dt_Task taskNew = new Dt_Task(); var area = _areaInfoRepository.QueryFirst(x => x.AreaID == taskDto.AreaId); if (area == null) { return content.Error("请选择入库区域"); } var locationInfo = await _locationRepository.QueryDataAsync(x => x.AreaId == area.AreaID && x.EnalbeStatus == 1 && x.LocationStatus == (int)LocationEnum.Free); var taskArea = BaseDal.QueryData(x => x.TargetAddress == area.AreaName && x.TaskType == (int)TaskInboundTypeEnum.Inbound); if (locationInfo.Count - taskArea.Count <= 0) { return content.Error("该区域无可用库位,请选择其他区域"); } switch (taskDto.AreaId) { case 1: taskNew = InboundStakerArea(taskDto, StartAddress, area); break; case 2: case 3: case 4: case 5: case 6: taskNew = InboundAGVCacheArea(taskDto, StartAddress, area); break; default: return content.Error("请选择正确的区域信息"); } var taskDTO = CreateListTaskDTO(taskNew); var result = UpdateLocationStatus(StartAddress.LocationCode, LocationEnum.InStockDisable, taskNew.TaskNum.Value, (int)StatusChangeTypeEnum.AutomaticInbound); await _unitOfWorkManage.UseTranAsync(async () => { await _locationStatusChangeRecordRepository.AddDataAsync(result.Item1); await _locationRepository.UpdateDataAsync(result.Item2); BaseDal.AddData(taskNew); }); return content = await SendWCSTask(taskDTO); } catch (Exception err) { return content.Error(err.Message); } } public Dt_Task InboundStakerArea(RequestTaskDto taskDto, DtLocationInfo StartAddress,Dt_AreaInfo area) { var station = _stationManagerRepository.QueryFirst(x => x.stationType == 1 && x.Roadway == "SC1"); return new Dt_Task { Grade = 1, Roadway = "SC1", TargetAddress = area.AreaName, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = station.stationChildCode, OrderNo = null, PalletCode = taskDto.PalletCode, SourceAddress = taskDto.Position, CurrentAddress = taskDto.Position, TaskState = (int)TaskInStatusEnum.InNew, TaskType = (int)TaskInboundTypeEnum.Inbound, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = "1F", }; } public Dt_Task InboundAGVCacheArea(RequestTaskDto taskDto, DtLocationInfo StartAddress, Dt_AreaInfo area) { WebResponseContent content = new WebResponseContent(); Dt_Task taskNew = new Dt_Task(); if (StartAddress.Floor != area.Spare1) { taskNew = RequestAcrossFloorTask(StartAddress, area, (int)TaskInboundTypeEnum.Inbound, taskDto); } else { taskNew = RequestAGVCarryTask(StartAddress, GetAGVEmptyCacheLocation(area.AreaID, StartAddress).Result, (int)TaskInboundTypeEnum.Inbound, taskDto); } return taskNew; } #endregion 请求任务入库 #region 更新任务状态 /// /// 更新任务货位 /// /// /// public async Task UpdateTaskStatus(int taskNum, int taskState) { WebResponseContent content = new WebResponseContent(); try { var task = await BaseDal.QueryFirstAsync(x => x.TaskNum == taskNum); if (task == null) return content.Error("未找到任务"); task.TaskState = taskState; var asb = await BaseDal.UpdateDataAsync(task); if (asb) content.OK(); else content.Error(); } catch (Exception ex) { content.Error(ex.Message); } return content; } #endregion #region 请求出库 /// /// 手动出库至缓存区域 /// /// /// public async Task OutBoundTaskAsync(string palletCode,string remark,int doubleTray) { WebResponseContent content = new WebResponseContent(); try { DtStockInfo stcok = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == palletCode); if (stcok == null) { return content.Error("托盘信息不存在,请确认托盘已入库成功"); } if (stcok.LocationInfo.LocationStatus != (int)LocationEnum.InStock) { return content.Error("请确认库存货位状态是否为有货"); } var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == palletCode); if (task != null) { return content.Error("该托盘已存在任务"); } var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == stcok.LocationCode); if (location.AreaId == 2) { return content.Error("该托盘库存已在出库缓存区"); } Dt_Task taskNew = await RequestOutboundTaskAsync(new RequestTaskDto { PalletCode = palletCode, AreaId = 2, Position = stcok.LocationCode, TaskType = (int)TaskOutboundTypeEnum.Outbound, DoubleTray= doubleTray }); List records = new List(); stcok.StockInfoDetails.ForEach(x => { records.Add(new Dt_InventoryRecord() { PalletCode = stcok.PalletCode, MaterielCode = x.MaterielCode, MaterielName = x.MaterielName, Quantity = x.Quantity, Status = (int)InventoryStatus.Normal, Remark = remark, }); }); var taskDto = CreateListTaskDTO(taskNew); var result = GetlcoationState(taskNew, StatusChangeTypeEnum.AutomaticOutbound); await _unitOfWorkManage.UseTranAsync(async () => { await BaseDal.AddDataAsync(taskNew); await _inventoryRecordRepository.AddDataAsync(records); await _stockInfoRepository.UpdateDataAsync(stcok); await _locationStatusChangeRecordRepository.AddDataAsync(result.Item1); await _locationRepository.UpdateDataAsync(result.Item2); }); return content = await SendWCSTask(taskDto); } catch (Exception ex) { return content.Error(ex.Message); } } /// /// 其他出库 /// /// /// public async Task OtherOutBoundTaskAsync(List details) { WebResponseContent content = new WebResponseContent(); try { var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.Id == details[0].StockId); if (stock == null) { return content.Error("未找到库存表头信息"); } if (stock.LocationInfo.LocationStatus != (int)LocationEnum.InStock) { return content.Error("请确认库存货位状态是否为有货"); } var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == stock.PalletCode); if (task != null) { return content.Error("该托盘已存在任务"); } if (stock.LocationInfo.AreaId == 2) { return content.Error("该托盘库存已在出库缓存区"); } Dt_Task taskNew = await RequestOutboundTaskAsync(new RequestTaskDto { PalletCode = stock.PalletCode, AreaId = 2, Position = stock.LocationCode, TaskType = (int)TaskOutboundTypeEnum.OutOther }); List outDetails = new List(); details.Where(x => x.OutboundQuantity > 0).ForEach(x => { if (x.Quantity < x.OutboundQuantity) { throw new Exception($"{x.MaterielName}{x.MaterielCode}出库数量不可大于库存数量"); } outDetails.Add(new Dt_OrderOutDetails() { OrderNo = "", PalletCode = stock.PalletCode, OrderType = (int)OrderTypeEmun.其他出库单, ERPOrderId = "", MaterielCode = x.MaterielCode, MaterielName = x.MaterielName, AllocateWarehouse = "", Warehouse = "智能立库", WareHouseId = "107", AllocateWarehouseId = "", OutboundQuantity = x.OutboundQuantity, }); }); stock.StockInfoDetails = details; var taskDto = CreateListTaskDTO(taskNew); var result = GetlcoationState(taskNew, StatusChangeTypeEnum.AutomaticOutbound); await _unitOfWorkManage.UseTranAsync(async () => { await BaseDal.AddDataAsync(taskNew); await _stockInfoRepository.UpdateDataNavAsync(stock); await _locationStatusChangeRecordRepository.AddDataAsync(result.Item1); await _locationRepository.UpdateDataAsync(result.Item2); await _orderOutDetailsRepository.AddDataAsync(outDetails); }); return content = await SendWCSTask(taskDto); } catch (Exception ex) { return content.Error(ex.Message); } } /// /// 手动调拨 /// /// /// public async Task HandAllocateOutBoundTaskAsync(List details) { WebResponseContent content = new WebResponseContent(); try { var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.Id == details[0].StockId); if (stock == null) { return content.Error("未找到库存表头信息"); } if (stock.LocationInfo.LocationStatus != (int)LocationEnum.InStock) { return content.Error("请确认库存货位状态是否为有货"); } var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == stock.PalletCode); if (task != null) { return content.Error("该托盘已存在任务"); } if (stock.LocationInfo.AreaId == 2) { return content.Error("该托盘库存已在出库缓存区"); } Dt_Task taskNew = await RequestOutboundTaskAsync(new RequestTaskDto { PalletCode = stock.PalletCode, AreaId = 2, Position = stock.LocationCode, TaskType = (int)TaskOutboundTypeEnum.OutAllocate }); List outDetails = new List(); details.Where(x=>x.OutboundQuantity>0).ForEach(x => { if (x.Quantity < x.OutboundQuantity) { throw new Exception($"{x.MaterielName}{x.MaterielCode}出库数量不可大于库存数量"); } var wareinfo = _wareAreaInfoRepository.QueryFirst(y => y.WareAreaCode ==x.AllocateWarehouse); if (wareinfo == null) { throw new Exception($"未找到调拨仓库{x.AllocateWarehouse}数据"); } if (wareinfo.WareAreaCode == "205") { throw new Exception($"不可调拨至WMS出库缓存区{x.AllocateWarehouse}数据"); } outDetails.Add(new Dt_OrderOutDetails() { OrderNo = "", PalletCode = stock.PalletCode, OrderType = (int)OrderTypeEmun.调拨出库单, ERPOrderId = "", MaterielCode = x.MaterielCode, MaterielName = x.MaterielName, AllocateWarehouse = wareinfo.WareAreaName, Warehouse = "智能立库", WareHouseId = "107", AllocateWarehouseId = wareinfo.WareAreaCode , OutboundQuantity = x.OutboundQuantity, }); }); stock.StockInfoDetails = details; var taskDto = CreateListTaskDTO(taskNew); var result = GetlcoationState(taskNew, StatusChangeTypeEnum.AutomaticOutbound); await _unitOfWorkManage.UseTranAsync(async () => { await BaseDal.AddDataAsync(taskNew); await _stockInfoRepository.UpdateDataNavAsync(stock); await _locationStatusChangeRecordRepository.AddDataAsync(result.Item1); await _locationRepository.UpdateDataAsync(result.Item2); await _orderOutDetailsRepository.AddDataAsync(outDetails); }); return content = await SendWCSTask(taskDto); } catch (Exception ex) { return content.Error(ex.Message); } } public (List,List) GetlcoationState(Dt_Task task, StatusChangeTypeEnum StatusChangeTypeEnum) { List locationStatusChangeRecords = new List(); List locations = new List(); var result = UpdateLocationStatus(task.SourceAddress, LocationEnum.InStockDisable, task.TaskNum.Value, (int)StatusChangeTypeEnum); locationStatusChangeRecords.AddRange(result.Item1); locations.AddRange(result.Item2); return (locationStatusChangeRecords,locations); } /// /// 请求出库任务 /// /// /// public async Task RequestOutboundTaskAsync(RequestTaskDto taskDto) { DtStockInfo stcok = await _stockInfoRepository.QueryFirstAsync(x => x.PalletCode == taskDto.PalletCode); if (stcok == null) { throw new Exception("托盘信息不存在,请确认托盘已入库成功"); } var StartAddress = await _locationRepository.QueryFirstAsync(x => x.LocationCode == taskDto.Position); if (StartAddress == null) { throw new Exception("起点库位未找到"); } if (!LocationIsOutBound(StartAddress)) { throw new Exception($"起点库位{StartAddress.LocationCode}出库路径被占用,请稍后重试"); } var area = _areaInfoRepository.QueryFirst(x => x.AreaID == 2); var locationInfo = await _locationRepository.QueryDataAsync(x => x.AreaId == area.AreaID && x.EnalbeStatus == 1 && x.LocationStatus == (int)LocationEnum.Free); var taskArea = BaseDal.QueryData(x => x.TargetAddress == area.AreaName && x.TaskType == (int)TaskInboundTypeEnum.Inbound); if (locationInfo.Count - taskArea.Count <= 0) { throw new Exception($"出库缓存区无可用库位,请清理库位后再试"); } switch (StartAddress.AreaId) { case 1: return OutboundStakerArea(taskDto, StartAddress, area); case 2: case 3: case 4: case 5: case 6: return OutboundAGVCacheArea(taskDto, StartAddress, area); default: throw new Exception("请选择正确的区域信息"); } } public Dt_Task OutboundStakerArea(RequestTaskDto taskDto, DtLocationInfo StartAddress, Dt_AreaInfo area) { var station = _stationManagerRepository.QueryFirst(x => x.stationType == 1 && x.Roadway == "SC1"); return new Dt_Task { Grade = Convert.ToInt32(StartAddress.Remark), Roadway = "SC1", TargetAddress = area.AreaName, Dispatchertime = DateTime.Now, MaterialNo = taskDto.MaterielCode, NextAddress = station.stationChildCode, OrderNo = taskDto.OrderNo, PalletCode = taskDto.PalletCode, SourceAddress = taskDto.Position, CurrentAddress = taskDto.Position, TaskState = (int)TaskOutStatusEnum.OutNew, TaskType = taskDto.TaskType, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = "1F", }; } public Dt_Task OutboundAGVCacheArea(RequestTaskDto taskDto, DtLocationInfo StartAddress, Dt_AreaInfo area) { Dt_Task taskNew = new Dt_Task(); if (StartAddress.Floor != area.Spare1) { taskNew = RequestAcrossFloorTask(StartAddress, area, taskDto.TaskType, taskDto); } else { taskNew = RequestAGVCarryTask(StartAddress, GetAGVEmptyCacheLocation(taskDto.AreaId, StartAddress).Result, taskDto.TaskType, taskDto); } return taskNew; } #endregion 请求出库(实盘&空盘) #region 请求移库任务 public async Task RequestRelocationTaskAsync(string SourceAddress,string TargetAddress) { WebResponseContent content = new WebResponseContent(); try { var startLocation = await _locationRepository.QueryFirstAsync(x => x.LocationCode == SourceAddress); var endLocation = await _locationRepository.QueryFirstAsync(x => x.LocationCode == TargetAddress); if (!startLocation.IsNotEmptyOrNull() || !endLocation.IsNotEmptyOrNull()) { return content.Error("库位信息不存在"); } if (endLocation.LocationStatus != (int)LocationEnum.Free) { return content.Error($"终点库位{endLocation.LocationCode}未处于空闲状态,请人工确认库位状态"); } if ((startLocation.AreaId == 1 || endLocation.AreaId == 1) && startLocation.AreaId != endLocation.AreaId) { return content.Error("移库起点库位与终点库位不在同一区域"); } if (startLocation.Floor != endLocation.Floor) { return content.Error("移库起点库位与终点库位不在同一楼层"); } var stock = await _stockInfoRepository.QueryFirstAsync(x => x.LocationCode == startLocation.LocationCode); var taskNew = new Dt_Task { Grade = startLocation.Floor == "1F" ? 10 : 1, Roadway = endLocation.RoadwayNo, TargetAddress = endLocation.LocationCode, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = endLocation.LocationCode, OrderNo = null, PalletCode = stock == null ? "M" + DateTime.Now.ToString("MMddHHmmss") + "-" + new Random().Next(100, 1000) : stock.PalletCode, SourceAddress = startLocation.LocationCode, CurrentAddress = startLocation.LocationCode, TaskState = startLocation.AreaId == 1 ? (int)TaskRelocationStatusEnum.RelocationNew : (int)TaskRelocationStatusEnum.RelocationNewAGV, TaskType = (int)TaskRelocationTypeEnum.Relocation, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = startLocation.Floor, }; var result = AddTaskAsync(new List() { taskNew }); await _unitOfWorkManage.UseTranAsync(async () => { await _locationStatusChangeRecordRepository.AddDataAsync(result.Item2); await _locationRepository.UpdateDataAsync(result.Item1); await BaseDal.AddDataAsync(taskNew); }); await SendWCSTask(CreateListTaskDTO(taskNew)); return content.OK("成功"); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 请求跨楼层2任务 /// /// 请求跨楼层2任务 /// /// /// public async Task AcrossFloorTaskAsync(RequestAcrossFloorTaskDto taskDto) { WebResponseContent content=new WebResponseContent(); try { var task = BaseDal.QueryFirst(x => x.TaskNum == Convert.ToInt32(taskDto.TaskNum) && x.PalletCode == taskDto.PalletCode); if(task == null) return content.Error("未找到任务"); Dt_StationManager stationManager = new Dt_StationManager(); if (task.Floor == "1F") { stationManager = _stationManagerRepository.QueryFirst(x => x.stationType == 5 && x.stationFloor == "2F"); } else { stationManager = _stationManagerRepository.QueryFirst(x => x.stationType == 5 && x.stationFloor == "1F"); } content = await RequestLocation(taskDto.PalletCode); Dt_Task taskNew = new Dt_Task { Grade = 1, Roadway = "AGV", TargetAddress = content.Data.ToString(), Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = content.Data.ToString(), OrderNo = null, PalletCode = task.PalletCode, SourceAddress = task.SourceAddress, CurrentAddress = stationManager.stationChildCode, TaskState = (int)TaskAcrossFloorStatusEnum.SecondCarry, TaskType = task.TaskType, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = stationManager.stationFloor, }; var taskDTO = CreateTaskDTO(taskNew); task.TaskState = (int)TaskAcrossFloorStatusEnum.FirstCarryFinish; var taskHty = task.Adapt(); taskHty.FinishTime = DateTime.Now; taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; await UpdateStartLocationInfo(taskNew); await _unitOfWorkManage.UseTranAsync(async () => { await DeleteTaskAsync(task.TaskId); await AddTaskHtyAsync(taskHty); BaseDal.AddData(taskNew); }); return content.OK(data: taskDTO); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 请求跨楼层任务 public Dt_Task RequestAcrossFloorTask(DtLocationInfo StartAddress, Dt_AreaInfo area, int TaskType, RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); var next = _stationManagerRepository.QueryFirst(x => x.stationType == 5 && x.stationFloor == StartAddress.Floor); return new Dt_Task { Grade = StartAddress.Column, Roadway = "AGV", TargetAddress = area.AreaName, Dispatchertime = DateTime.Now, MaterialNo = taskDto.MaterielCode, NextAddress = next.stationChildCode, OrderNo = taskDto.OrderNo, PalletCode = taskDto.PalletCode, SourceAddress = StartAddress.LocationCode, CurrentAddress = StartAddress.LocationCode, TaskState = (int)TaskAcrossFloorStatusEnum.CarryNew, TaskType = TaskType, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, Remark = StartAddress.AreaId.ToString(), AGVTaskNum = GenerateUniqueId(), Floor = StartAddress.Floor, DoubleTray = taskDto.DoubleTray, }; } #endregion #region 请求AGV搬运任务 public Dt_Task RequestAGVCarryTask(DtLocationInfo StartAddress, DtLocationInfo EndAddress, int TaskType, RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); return new Dt_Task { Grade = StartAddress.Column, Roadway = "AGV", TargetAddress = EndAddress.LocationCode, Dispatchertime = DateTime.Now, MaterialNo = taskDto.MaterielCode, NextAddress = EndAddress.LocationCode, OrderNo = taskDto.OrderNo, PalletCode = taskDto.PalletCode, SourceAddress = StartAddress.LocationCode, CurrentAddress = StartAddress.LocationCode, TaskState = (int)TaskAGVCarryStatusEnum.CarryNew, TaskType = TaskType, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, Remark = StartAddress.AreaId.ToString(), AGVTaskNum = GenerateUniqueId(), Floor = StartAddress.Floor, }; } #endregion #region 判断是否需要移库 /// /// 判断堆垛机出库是否需要移库 /// /// /// public async Task StackerIsNeedRelocationAsync(RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); try { var task = BaseDal.QueryFirst(x => x.PalletCode == taskDto.PalletCode && x.TaskNum == taskDto.TaskNum); if (task == null) { return content.Error("未找到任务"); } var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == taskDto.Position); if (location == null || location.Depth != 2) { return content.OK(data: _mapper.Map(task)); } var locationLateral = _locationRepository.QueryFirst(x => x.RoadwayNo == location.RoadwayNo && x.Row == 1 && x.Layer == location.Layer && x.Column == location.Column); if (locationLateral != null && (locationLateral.LocationStatus == (int)LocationEnum.FreeDisable || locationLateral.LocationStatus == (int)LocationEnum.Free) && locationLateral.EnalbeStatus == 1) { return content.OK(data: _mapper.Map(task)); } else if (locationLateral != null && locationLateral.LocationStatus == 1 && locationLateral.EnalbeStatus == 1) { return content.Error($"一深位异常锁定暂不可出库"); } else if (locationLateral != null && (locationLateral.LocationStatus == (int)LocationEnum.InStockDisable|| locationLateral.LocationStatus == (int)LocationEnum.InStock) && locationLateral.EnalbeStatus == 1) { var taskLateral = BaseDal.QueryFirst(x => x.SourceAddress == locationLateral.LocationCode); if (taskLateral != null) { return content.OK(data: _mapper.Map(taskLateral)); } var TargetAddress = await GetEmptyLocation("SC1"); if (TargetAddress == null) { return content.Error($"未找到可分配货位,请查看是否还有空闲可使用货位"); } var stock = await _stockInfoRepository.QueryFirstAsync(x => x.LocationCode == locationLateral.LocationCode); Dt_Task taskNew = new Dt_Task { Grade = 1, Roadway = "SC1", TargetAddress = TargetAddress.LocationCode, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = TargetAddress.LocationCode, OrderNo = null, PalletCode = stock == null ? "M" + DateTime.Now.ToString("MMddHHmmss") + "-" + new Random().Next(100, 1000) : stock.PalletCode, SourceAddress = locationLateral.LocationCode, CurrentAddress = locationLateral.LocationCode, TaskState = (int)TaskRelocationStatusEnum.RelocationNew, TaskType = (int)TaskRelocationTypeEnum.Relocation, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, Floor = "1F", }; var taskDTO = CreateListTaskDTO(taskNew); var isResult = await AddTaskAsync(taskNew, locationLateral, TargetAddress); if (!isResult) { _unitOfWorkManage.RollbackTran(); return content.Error("新增任务失败"); } return content.OK(data: taskDTO); } else { return content.Error("货位异常需人工确认才可出库"); } } catch (Exception ex) { return content.Error(ex.Message); } } public async Task AGVIsNeedRelocationAsync(RequestTaskDto taskDto) { WebResponseContent content = new WebResponseContent(); try { var task = BaseDal.QueryFirst(x => x.PalletCode == taskDto.PalletCode && x.TaskNum == taskDto.TaskNum); if (task == null) { return content.Error("未找到任务"); } var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == taskDto.Position); if (location == null) { return content.Error($"未找到货位信息{taskDto.Position}"); } List locationInfos = new List(); switch (location.AreaId) { case 2: locationInfos = _locationRepository.QueryData(x => x.Row == location.Row && x.Column > location.Column && x.Remark == location.Remark && x.AreaId == location.AreaId); break; case 5: case 6: locationInfos = _locationRepository.QueryData(x => x.Row == location.Row && x.Column < location.Column && x.Remark == location.Remark && x.AreaId == location.AreaId); break; default: break; } if (locationInfos.Count == 0) { return content.OK(data: new List { _mapper.Map(task) }); } List taskDTO = new List(); List taskNew = new List(); foreach (var item in locationInfos) { if(item.LocationStatus == (int)LocationEnum.Lock) { return content.Error($"{item.LocationCode}路径被占用,请稍后再试"); } if ((item.LocationStatus == (int)LocationEnum.InStockDisable || item.LocationStatus == (int)LocationEnum.InStock) && item.EnalbeStatus == 1) { DtLocationInfo Targetlocation = await GetAGVEmptyCacheLocation(item.AreaId, item); if (Targetlocation == null) { return content.Error("起点未定义或终点区域未找到空闲库位"); } var stock = _stockInfoRepository.QueryFirst(x => x.LocationCode == item.LocationCode); var Relocationtask = BaseDal.QueryFirst(x => x.SourceAddress == item.LocationCode); if (Relocationtask != null) { taskDTO.Add(CreateTaskDTO(Relocationtask)); continue; } else { taskNew.Add(new Dt_Task { Grade = item.Column, Roadway = "AGV", TargetAddress = Targetlocation.LocationCode, Dispatchertime = DateTime.Now, MaterialNo = "", NextAddress = Targetlocation.LocationCode, OrderNo = null, PalletCode = stock == null ? "M" + DateTime.Now.ToString("MMddHHmmss") + "-" + new Random().Next(100, 1000) : stock.PalletCode, SourceAddress = item.LocationCode, CurrentAddress = item.LocationCode, TaskState = (int)TaskRelocationStatusEnum.RelocationNewAGV, TaskType = (int)TaskRelocationTypeEnum.Relocation, TaskNum = BaseDal.GetTaskNo().Result, CreateDate = DateTime.Now, TaskId = 0, AGVTaskNum = GenerateUniqueId(), Floor = item.Floor, Remark = item.AreaId.ToString(), }); } } } taskDTO = CreateTaskDTO(taskNew); var result = AddTaskAsync(taskNew); await _unitOfWorkManage.UseTranAsync(async () => { await _locationStatusChangeRecordRepository.AddDataAsync(result.Item2); await _locationRepository.UpdateDataAsync(result.Item1); await BaseDal.AddDataAsync(taskNew); }); return content.OK(data: taskDTO); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 更新起点货位信息 public async Task UpdateStartLocationInfo(Dt_Task task) { WebResponseContent content = new WebResponseContent(); try { if (task == null) return content.OK(); var result = UpdateLocationStatus(task.SourceAddress, LocationEnum.Free, task.TaskNum.Value, task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup ? (int)StatusChangeTypeEnum.AutomaticOutbound : (int)StatusChangeTypeEnum.AutomaticInbound); await _locationStatusChangeRecordRepository.AddDataAsync(result.Item1); await _locationRepository.UpdateDataAsync(result.Item2); return content.OK(); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 获取终点货位信息 public async Task RequestLocation(string palletCode) { WebResponseContent content = new WebResponseContent(); try { var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == palletCode); if (task == null) return content.Error("未找到任务"); var areaInfo = await _areaInfoRepository.QueryFirstAsync(x => x.AreaName == task.TargetAddress); if (areaInfo == null) return content.Error($"未找到终点区域信息{task.TargetAddress}请联系管理员"); var location = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress); DtLocationInfo locationInfo = new DtLocationInfo(); switch (areaInfo.AreaID) { case 1: locationInfo = await GetEmptyLocation("SC1"); break; case 2: case 3: case 4: case 5: case 6: locationInfo = await GetAGVEmptyCacheLocation(areaInfo.AreaID, location); break; default: return content.Error("请选择正确的区域信息"); } if (locationInfo == null) { return content.Error("未找到可分配货位,请查看是否还有空闲可使用货位"); } task.CurrentAddress = task.NextAddress; task.TargetAddress = locationInfo.LocationCode; task.NextAddress = locationInfo.LocationCode; var result = UpdateLocationStatus(locationInfo.LocationCode, LocationEnum.Lock, task.TaskNum.Value, task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup ? StatusChangeTypeEnum.AutomaticOutbound : StatusChangeTypeEnum.AutomaticInbound); await BaseDal.UpdateDataAsync(task); await _locationStatusChangeRecordRepository.AddDataAsync(result.Item1); await _locationRepository.UpdateDataAsync(result.Item2); return content.OK(data: locationInfo.LocationCode); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 获取AGV任务号 private static readonly Random _random = new Random(); public static string GenerateUniqueId() { // 获取当前毫秒级时间戳 long timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // 生成4位随机数(0000-9999) int randomNumber = _random.Next(0, 10000); string randomPart = randomNumber.ToString("D4"); // 补零到4位 return $"{timestamp}{randomPart}"; } #endregion #region 获取任务信息 public WebResponseContent GetTaskInfo() { WebResponseContent content = new WebResponseContent(); try { Expression> expression = x => true; if (!App.User.IsSuperAdmin) { expression = x => x.Creater == App.User.UserName; } var task = BaseDal.Db.Queryable().OrderByDescending(x => x.CreateDate).Take(100).Select(x => new Dt_Task { TaskNum = x.TaskNum, PalletCode = x.PalletCode, TaskType = x.TaskType, SourceAddress = x.SourceAddress, TargetAddress = x.TargetAddress }).ToList(); content = WebResponseContent.Instance.OK(data: task); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } #endregion #endregion 外部接口方法 #region 调用WCS接口 private string GetWCSIPAddress(string baseIp, string name) { var configz = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wcsBasez = configz.Where(x => x.ConfigKey == baseIp).FirstOrDefault()?.ConfigValue; var address = configz.Where(x => x.ConfigKey == name).FirstOrDefault()?.ConfigValue; if (wcsBasez == null || address == null) { throw new InvalidOperationException("WMS IP 未配置"); } return wcsBasez + address; } public async Task SendWCSTask(List taskDTO) { WebResponseContent content = new WebResponseContent(); var AgvSendTaskAddrss = GetWCSIPAddress(SysConfigConst.WCSIPAddress, SysConfigConst.ReceiveTask); // 发送请求并等待响应 var result = await HttpHelper.PostAsync(AgvSendTaskAddrss, taskDTO.ToJsonString()); content = JsonConvert.DeserializeObject(result.ToString()); return content; } #endregion #region ERP接口调用 public string GetERPIPAddress(string baseIp, string name) { var configz = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wcsBasez = configz.Where(x => x.ConfigKey == baseIp).FirstOrDefault()?.ConfigValue; var address = configz.Where(x => x.ConfigKey == name).FirstOrDefault()?.ConfigValue; if (wcsBasez == null || address == null) { throw new InvalidOperationException("WMS IP 未配置"); } return wcsBasez + address; } /// /// 生产领料 /// /// /// public async Task ERPProduction(List orderOutDetails) { WebResponseContent content = new WebResponseContent(); try { MaterialRequisition materialRequisition = new MaterialRequisition { context = new Context { CultureName = "zh-CN", EntCode = "001", OrgCode = "102", UserCode = "MH0551" }, documentTypeCode = "LL20", businessDate = DateTime.Now.ToString("yyyy-MM-dd"), isApproved = true, issueList = orderOutDetails.Select(item => new issueList { PickListID = item.ERPOrderId, //存储地点 WhCode = "205", //领料数量 IssueQty = item.OutboundQuantity, }).ToList() }; var ERPProduction = GetERPIPAddress(SysConfigConst.ERPIPAddress, SysConfigConst.MaterialRequisition); // 发送请求并等待响应 var result = await HttpsClient.PostAsync(ERPProduction, materialRequisition.ToJsonString()); var respone = JsonConvert.DeserializeObject(result.ToString()); if (respone.d.ResultStatus) { return content.OK(); } return content.Error(respone.d.ResultMsg); } catch (Exception ex) { return content.Error(ex.Message); } } /// /// 调拨 /// /// /// /// public async Task ERPAllocate(DtBoxingInfo boxing) { try { if (boxing == null) { throw new Exception("未找到组盘信息"); } Allocate allocate = new Allocate { context = new Context { CultureName = "zh-CN", EntCode = "001", OrgCode = "102", UserCode = "MH0551" }, documentTypeCode = "TransIn002", businessDate = DateTime.Now.ToString("yyyy-MM-dd"), isApproved = true, transferInList = boxing.BoxingInfoDetails.Select(item => new transferInList { //物料编码 ItemCode = item.MaterielCode, //调入仓库地址 TransInWHCode = "107", //调入数量 TransInQty = item.Quantity, // 调出仓库编码 TransOutWHCode = item.WareHouseId, }).ToList() }; var Allocate = GetERPIPAddress(SysConfigConst.ERPIPAddress, SysConfigConst.Allocate); // 发送请求并等待响应 var result = await HttpsClient.PostAsync(Allocate, allocate.ToJsonString()); var respone = JsonConvert.DeserializeObject(result.ToString()); if (!respone.d.ResultStatus) { throw new Exception(respone.d.ResultMsg); } } catch (Exception ex) { throw new Exception(ex.Message); } } public async Task ERPAllocateOut(DtStockInfo stock) { try { if (stock == null) { throw new Exception("未找到库存信息"); } Allocate allocate = new Allocate { context = new Context { CultureName = "zh-CN", EntCode = "001", OrgCode = "102", UserCode = "MH0551" }, documentTypeCode = "TransIn002", businessDate = DateTime.Now.ToString("yyyy-MM-dd"), isApproved = true, transferInList = stock.StockInfoDetails.Select(item => new transferInList { //物料编码 ItemCode = item.MaterielCode, //调入仓库地址 TransInWHCode = "205", //调入数量 TransInQty = item.Quantity, // 调出仓库编码 TransOutWHCode = "107", }).ToList() }; var Allocate = GetERPIPAddress(SysConfigConst.ERPIPAddress, SysConfigConst.Allocate); // 发送请求并等待响应 var result = await HttpsClient.PostAsync(Allocate, allocate.ToJsonString()); var respone = JsonConvert.DeserializeObject(result.ToString()); if (!respone.d.ResultStatus) { throw new Exception(respone.d.ResultMsg); } } catch (Exception ex) { throw new Exception(ex.Message); } } public async Task ERPAllocate(List orderOutDetails) { try { if (orderOutDetails.Count <= 0) { throw new Exception($"未找到调拨出库数据"); } List transferInList=new List(); foreach (var item in orderOutDetails) { if (item.AllocateWarehouseId == "205") { continue; } transferInList.Add(new transferInList { //物料编码 ItemCode = item.MaterielCode, //调入仓库地址 TransInWHCode = item.AllocateWarehouseId, //调入数量 TransInQty = item.OutboundQuantity, // 调出仓库编码 TransOutWHCode = "205", }); } if (transferInList.Count <= 0) { return; } Allocate allocate = new Allocate { context = new Context { CultureName = "zh-CN", EntCode = "001", OrgCode = "102", UserCode = "MH0551" }, documentTypeCode = "TransIn002", businessDate = DateTime.Now.ToString("yyyy-MM-dd"), isApproved = true, transferInList = transferInList, }; var Allocate = GetERPIPAddress(SysConfigConst.ERPIPAddress, SysConfigConst.Allocate); // 发送请求并等待响应 var result = await HttpsClient.PostAsync(Allocate, allocate.ToJsonString()); var respone = JsonConvert.DeserializeObject(result.ToString()); if (!respone.d.ResultStatus) { throw new Exception($"ERP调拨出库{respone.d.ResultMsg}"); } } catch (Exception ex) { throw new Exception(ex.Message); } } /// /// 杂发 /// /// /// public async Task ERPMixedSend(List orderOutDetails) { try { if (orderOutDetails.Count <= 0) { throw new Exception($"未找到调拨出库数据"); } MixedSend send = new MixedSend { context = new Context { CultureName = "zh-CN", EntCode = "001", OrgCode = "102", UserCode = "MH0551" }, documentTypeCode = "MiscShip001", businessDate = DateTime.Now.ToString("yyyy-MM-dd"), isApproved = true, miscShipList = orderOutDetails.Select(item => new miscShipList { //物料编码 ItemCode = item.MaterielCode, //存储地点编号 WhCode = "205", //杂发数量 Qty = item.OutboundQuantity, BenefitDeptCode = "0505", }).ToList() }; var ERPMixedSend = GetERPIPAddress(SysConfigConst.ERPIPAddress, SysConfigConst.MixedSend); // 发送请求并等待响应 var result = await HttpsClient.PostAsync(ERPMixedSend, send.ToJsonString()); var respone = JsonConvert.DeserializeObject(result.ToString()); if (!respone.d.ResultStatus) { throw new Exception($"ERP其他出库{respone.d.ResultMsg}"); } } catch (Exception ex) { throw new Exception(ex.Message); } } /// /// 杂收 /// /// /// public async Task ERPMixedReceive(string palletCode) { WebResponseContent content = new WebResponseContent(); try { DtStockInfo stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == palletCode); MixedReceive allocate = new MixedReceive { context = new Context { CultureName = "zh-CN", EntCode = "001", OrgCode = "102", UserCode = "MH0551" }, documentTypeCode = "TransIn002", businessDate = DateTime.Now.ToString("yyyy-MM-dd"), isApproved = true, miscRcvList = stock.StockInfoDetails.Where(x => x.OutboundQuantity > 0).Select(item => new miscRcvList { ItemCode = item.MaterielCode, WhCode = item.Warehouse, Qty = item.OutboundQuantity, CostPrice = 0, }).ToList() }; return content.OK(data: allocate); } catch (Exception ex) { return content.Error(ex.Message); } } /// /// 退料 /// /// /// public async Task ERPreturnMaterialList(string palletCode) { WebResponseContent content = new WebResponseContent(); try { DtStockInfo stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == palletCode); ReturnMaterials allocate = new ReturnMaterials { context = new Context { CultureName = "zh-CN", EntCode = "001", OrgCode = "102", UserCode = "MH0551" }, documentTypeCode = "TransIn002", businessDate = DateTime.Now.ToString("yyyy-MM-dd"), isApproved = true, returnMaterialList = stock.StockInfoDetails.Select(item => new returnMaterialList { PickListID = item.MaterielCode, WhCode = item.Warehouse, RecedeQty = item.OutboundQuantity, RecedeReason = 1, }).ToList() }; return content.OK(data: allocate); } catch (Exception ex) { return content.Error(ex.Message); } } #endregion #region 内部调用方法 public (List,List) UpdateLocationStatus(DtLocationInfo location, LocationEnum locationStatus, int taskNum, int StatusChangeType) { List locations = GetGroupLocations(location); List Beforelocation = locations.Select(x => new DtLocationInfo { Id = x.Id, LocationCode = x.LocationCode, LocationStatus = x.LocationStatus }).ToList(); foreach (var item in locations) { if (locationStatus == LocationEnum.Lock) { if (item.LocationCode == location.LocationCode) { item.LocationStatus = (int)LocationEnum.Lock; } else if (item.LocationStatus == (int)LocationEnum.Free) { item.LocationStatus = (int)LocationEnum.FreeDisable; } } else if (locationStatus == LocationEnum.InStock) { if (item.LocationCode == location.LocationCode) { item.LocationStatus = (int)LocationEnum.InStock; } else if (item.LocationStatus == (int)LocationEnum.FreeDisable) { item.LocationStatus = (int)LocationEnum.Free; } } else if (locationStatus == LocationEnum.InStockDisable) { if (item.LocationStatus == (int)LocationEnum.InStock) { item.LocationStatus = (int)LocationEnum.InStockDisable; } else if (item.LocationStatus == (int)LocationEnum.Free) { item.LocationStatus = (int)LocationEnum.FreeDisable; } } else if (locationStatus == LocationEnum.Free) { if (item.LocationCode == location.LocationCode) { item.LocationStatus = (int)LocationEnum.Free; } else if (item.LocationStatus == (int)LocationEnum.FreeDisable || item.LocationStatus == (int)LocationEnum.InStockDisable) { item.LocationStatus = (int)LocationEnum.Free; } } } List changeRecordDto = new List(); foreach (var item in Beforelocation) { var loc = locations.Where(x => x.LocationCode == item.LocationCode).FirstOrDefault(); if (loc != null) { DtLocationStatusChangeRecord dtLocationStatusChangeRecord = new DtLocationStatusChangeRecord() { ChangeType = StatusChangeType, LocationCode = item.LocationCode, LocationId = loc.Id, Creater = "System", TaskNum = taskNum, AfterStatus = loc.LocationStatus, BeforeStatus = item.LocationStatus, }; changeRecordDto.Add(dtLocationStatusChangeRecord); } } return (changeRecordDto,locations); } public (List, List) UpdateLocationStatus(string locationCode, LocationEnum locationStatus, int taskNum, int StatusChangeType) { var location = _locationRepository.QueryFirst(x => x.LocationCode == locationCode); List locations = GetGroupLocations(location); List Beforelocation = locations.Select(x => new DtLocationInfo { Id = x.Id, LocationCode = x.LocationCode, LocationStatus = x.LocationStatus }).ToList(); foreach (var item in locations) { if (locationStatus == LocationEnum.Lock) { if (item.LocationCode == location.LocationCode) { item.LocationStatus = (int)LocationEnum.Lock; } } else if (locationStatus == LocationEnum.InStock) { if (item.LocationCode == location.LocationCode) { item.LocationStatus = (int)LocationEnum.InStock; } } else if (locationStatus == LocationEnum.InStockDisable) { if (item.LocationStatus == (int)LocationEnum.InStock) { item.LocationStatus = (int)LocationEnum.InStockDisable; } } else if (locationStatus == LocationEnum.Free) { item.LocationStatus = (int)LocationEnum.Free; } } List changeRecordDto = new List(); foreach (var item in Beforelocation) { var loc = locations.Where(x => x.LocationCode == item.LocationCode).FirstOrDefault(); if (loc != null) { DtLocationStatusChangeRecord dtLocationStatusChangeRecord = new DtLocationStatusChangeRecord() { ChangeType = StatusChangeType, LocationCode = item.LocationCode, LocationId = loc.Id, Creater = "System", TaskNum = taskNum, AfterStatus = loc.LocationStatus, BeforeStatus = item.LocationStatus, }; changeRecordDto.Add(dtLocationStatusChangeRecord); } } return (changeRecordDto, locations); } public (DtLocationStatusChangeRecord, DtLocationInfo) UpdateLocationStatus(string locationCode, LocationEnum locationStatus, int taskNum, StatusChangeTypeEnum StatusChangeType) { var location = _locationRepository.QueryFirst(x => x.LocationCode == locationCode); int Beforelocation = location.LocationStatus; location.LocationStatus = (int)locationStatus; DtLocationStatusChangeRecord dtLocationStatusChangeRecord = new DtLocationStatusChangeRecord() { ChangeType = (int)StatusChangeType, LocationCode = locationCode, LocationId = location.Id, Creater = "System", TaskNum = taskNum, AfterStatus = location.LocationStatus, BeforeStatus = Beforelocation, }; return (dtLocationStatusChangeRecord, location); } public List GetGroupLocations(DtLocationInfo location) { List locationInfos = _locationRepository.QueryData(x => x.AreaId == location.AreaId); List locations = new List() { location }; if (location.AreaId == 1) { if (location.Depth == 2) { DtLocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.Depth == 1 && x.Column == location.Column && x.Layer == location.Layer && x.Row == 1); if (locationInfo != null) { locations.Add(locationInfo); } } } else if (location.AreaId == 2 || location.AreaId == 7) { var locationLateral = _locationRepository.QueryData(x => x.Row == location.Row && x.Column > location.Column && x.Remark == location.Remark); if (locationLateral.Count > 0) { locations.AddRange(locationLateral); } } else if (location.AreaId == 5 || location.AreaId == 6) { var locationLateral = _locationRepository.QueryData(x => x.Row == location.Row && x.Column < location.Column && x.Remark == location.Remark); if (locationLateral.Count > 0) { locations.AddRange(locationLateral); } } return locations; } /// /// 创建任务DTO /// private List CreateListTaskDTO(Dt_Task task) { return new List { new WMSTaskDTO { TaskNum = task.TaskNum.Value, Grade = task.Grade.Value, PalletCode = task.PalletCode, RoadWay = task.Roadway, SourceAddress = task.SourceAddress, TargetAddress = task.TargetAddress, TaskState = task.TaskState, Id = 0, TaskType = task.TaskType, Floor =task.Floor, AGVTaskNum = task.AGVTaskNum, DoubleTray = task.DoubleTray, } }; } private WMSTaskDTO CreateTaskDTO(Dt_Task task) { return new WMSTaskDTO { TaskNum = task.TaskNum.Value, Grade = task.Grade.Value, PalletCode = task.PalletCode, RoadWay = task.Roadway, SourceAddress = task.SourceAddress, TargetAddress = task.TargetAddress, TaskState = task.TaskState, Id = 0, TaskType = task.TaskType, AGVTaskNum = task.AGVTaskNum, Remark = task.Remark, Floor = task.Floor, DoubleTray = task.DoubleTray, }; } private List CreateTaskDTO(List task) { List taskNews = new List(); foreach (var item in task) { taskNews.Add(new WMSTaskDTO { TaskNum = item.TaskNum.Value, Grade = item.Grade.Value, PalletCode = item.PalletCode, RoadWay = item.Roadway, SourceAddress = item.SourceAddress, TargetAddress = item.TargetAddress, TaskState = item.TaskState, Id = 0, TaskType = item.TaskType, AGVTaskNum = item.AGVTaskNum, Remark = item.Remark, Floor = item.Floor, DoubleTray = item.DoubleTray, }); } return taskNews; } private async Task DeleteStockInfoAsync(int stockId) { var isStockUpdated = await _stockInfoRepository.DeleteDataByIdAsync(stockId); if (!isStockUpdated) { throw new Exception("库存信息更新失败"); } } private async Task AddStockInfoHtyAsync(DtStockInfo_Hty dtStock) { var isStockAdd = await SqlSugarHelper.DbWMS.InsertNav(dtStock).IncludesAllFirstLayer().ExecuteCommandAsync(); if (!isStockAdd) { throw new Exception("库存历史信息添加失败"); } } private async Task DeleteBoxingInfoAsync(int boxingId) { var isStockUpdated = await _stockInfoRepository.DeleteDataByIdAsync(boxingId); if (!isStockUpdated) { throw new Exception("库存信息更新失败"); } } private async Task AddBoxingHtyAsync(DtBoxingInfo_Hty boxingInfo) { var isStockAdd = await SqlSugarHelper.DbWMS.InsertNav(boxingInfo).IncludesAllFirstLayer().ExecuteCommandAsync(); if (!isStockAdd) { throw new Exception("组盘历史信息添加失败"); } } private async Task DeleteStockInfoDetailsAsync(IEnumerable details) { var ids = details.Select(x => (object)x.Id).ToArray(); var isStockDetailUpdated = await _stockInfoDetailRepository.DeleteDataByIdsAsync(ids); if (!isStockDetailUpdated) { throw new Exception("库存详情信息更新失败"); } } private async Task DeleteTaskAsync(int taskId) { var isTaskUpdated = await BaseDal.DeleteDataByIdAsync(taskId); if (!isTaskUpdated) { throw new Exception("任务信息更新失败"); } } private async Task AddTaskHtyAsync(Dt_Task_Hty taskHty) { var isTaskAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0; if (!isTaskAdd) { throw new Exception("历史任务信息添加失败"); } } public override WebResponseContent DeleteData(object[] key) { WebResponseContent content = new WebResponseContent(); // 创建历史任务实例模型 try { foreach (var item in key) { Dt_Task task = BaseDal.QueryFirst(x => x.TaskId == Convert.ToInt32(key)); if (task == null) { return content.Error("未找到任务信息!"); } var taskHtyNG = CreateHistoricalTask(task, true); // 添加历史任务 var isTaskHtyAdd = _task_HtyRepository.AddData(taskHtyNG) > 0; // 删除任务数据 var isTaskDelete = BaseDal.Delete(task.TaskId); } return content.OK("删除成功!"); } catch (Exception ex) { return content.Error("删除任务异常:" + ex.Message); } } /// /// 根据任务号获取任务 /// /// /// public async Task GetByTaskNum(int taskNum) { return await BaseDal.QueryFirstAsync(x => x.TaskNum == taskNum); } public async Task GetByTaskAddress(string SourceAddress, string TargetAddress) { return await BaseDal.QueryFirstAsync(x => x.SourceAddress == SourceAddress|| x.TargetAddress== TargetAddress); } #endregion 内部调用方法 #region private 内部方法 /// /// 创建历史任务记录 /// /// /// private Dt_Task_Hty CreateHistoricalTask(Dt_Task task, bool isHand = false) { // 更新任务状态 task.TaskState = task.TaskType > 199 ? (int)TaskInStatusEnum.InFinish : (int)TaskOutStatusEnum.OutFinish; task.CurrentAddress = task.NextAddress; // 创建历史任务 var taskHty = _mapper.Map(task); taskHty.FinishTime = DateTime.Now; taskHty.TaskId = 0; taskHty.OperateType = isHand ? (int)OperateTypeEnum.人工删除 : App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成; taskHty.SourceId = task.TaskId; if (isHand) { taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System"; } return taskHty; } #region 任务请求方法 private static readonly SemaphoreSlim _semaphoreUpdate = new SemaphoreSlim(1, 1); // 更新任务货位 // 修改任务 private async Task UpdateTaskAsync(Dt_Task task, DtLocationInfo location, int beforeStatus) { bool isResult = await BaseDal.UpdateDataAsync(task); LocationChangeRecordDto changeRecordDto = new LocationChangeRecordDto() { AfterStatus = location.LocationStatus, BeforeStatus = beforeStatus, TaskNum = task.TaskNum.Value, LocationId = location.Id, LocationCode = location.LocationCode, ChangeType = (int)StatusChangeTypeEnum.AutomaticInbound, }; bool isUpdateChange = _locationStatusChangeRecordRepository.AddStatusChangeRecord(changeRecordDto); bool isUpdateLo = await _locationRepository.UpdateDataAsync(location); return isResult && isUpdateLo; } private async Task AddTaskAsync(Dt_Task task, DtLocationInfo StartAddress, DtLocationInfo EndAddress) { bool isResult = await BaseDal.AddDataAsync(task) > 0; int SourcebeforeStatus = StartAddress.LocationStatus; int TargetbeforeStatus = EndAddress.LocationStatus; StartAddress.LocationStatus = (int)LocationEnum.InStockDisable; EndAddress.LocationStatus = (int)LocationEnum.Lock; List changeRecordDto = new List() { new LocationChangeRecordDto() { AfterStatus = StartAddress.LocationStatus, BeforeStatus = SourcebeforeStatus, TaskNum = task.TaskNum.Value, LocationId = StartAddress.Id, LocationCode = StartAddress.LocationCode, ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation, }, new LocationChangeRecordDto() { AfterStatus = EndAddress.LocationStatus, BeforeStatus = TargetbeforeStatus, TaskNum = task.TaskNum.Value, LocationId = EndAddress.Id, LocationCode = EndAddress.LocationCode, ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation, }, }; bool isUpdateChange = _locationStatusChangeRecordRepository.AddStatusChangeRecord(changeRecordDto); bool Source = await _locationRepository.UpdateDataAsync(StartAddress); bool Target = await _locationRepository.UpdateDataAsync(EndAddress); return isResult && Source && Target; } private (List,List) AddTaskAsync(List task) { List changeRecordDto = new List(); List locationos = new List(); foreach (var item in task) { var SourceAddress = _locationRepository.QueryFirst(x => x.LocationCode == item.SourceAddress); var TargetAddress = _locationRepository.QueryFirst(x => x.LocationCode == item.TargetAddress); int SourcebeforeStatus = SourceAddress.LocationStatus; int TargetbeforeStatus = TargetAddress.LocationStatus; SourceAddress.LocationStatus = (int)LocationEnum.InStockDisable; TargetAddress.LocationStatus = (int)LocationEnum.Lock; changeRecordDto.Add(new DtLocationStatusChangeRecord() { ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation, LocationCode = TargetAddress.LocationCode, LocationId = TargetAddress.Id, Creater = "System", TaskNum = item.TaskNum, AfterStatus = TargetAddress.LocationStatus, BeforeStatus = TargetbeforeStatus, }); changeRecordDto.Add(new DtLocationStatusChangeRecord { AfterStatus = TargetAddress.LocationStatus, BeforeStatus = TargetbeforeStatus, TaskNum = item.TaskNum.Value, Creater = "System", LocationId = TargetAddress.Id, LocationCode = TargetAddress.LocationCode, ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation, }); locationos.Add(TargetAddress); locationos.Add(SourceAddress); } return (locationos, changeRecordDto); } /// /// 获取货位号 /// /// public async Task GetEmptyLocation(string roadWay) { List locations = await _locationRepository.QueryDataAsync(x => x.RoadwayNo == "SC1" && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == 1); if (locations.Count < 2) { return null; } List locationInfos = new List(); var locationInside = locations.Where(x => x.Row == 3).ToList(); if (locations.Where(x => x.Row == 2).OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault() != null) { return locations.Where(x => x.Row == 2).ToList().OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault(); } else if (locationInside.Count > 0) { foreach (var item in locationInside) { var locationLateral = _locationRepository.QueryFirst(x => x.Row == 1 && x.Layer == item.Layer && x.Column == item.Column); if (locationLateral.LocationStatus == (int)LocationEnum.Free && locationLateral.EnalbeStatus == 1) { locationInfos.Add(item); } } return locationInfos.Distinct().OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault(); } else if (locations.Where(x => x.Row == 1).OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault() != null) { return locations.Where(x => x.Row == 1).OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault(); } else { return null; } } public async Task GetAGVEmptyCacheLocation(int AreaId, DtLocationInfo loc) { if (loc == null) { return null; } switch (AreaId) { case 2: return await FromShallowToDeep(AreaId, loc); case 3: return await AGVLIKU(AreaId); case 5: case 6: return await FromDeepToShallow(AreaId, loc); default: return null; } } /// /// 由深到浅 /// /// /// public async Task FromDeepToShallow(int AreaId, DtLocationInfo loc) { List locations = new List(); if (AreaId == loc.AreaId) { locations = await _locationRepository.QueryDataAsync(x => x.AreaId == AreaId && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == 1 && x.Row != loc.Row); } else { locations = await _locationRepository.QueryDataAsync(x => x.AreaId == AreaId && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == 1); } if (locations.Count == 0) { return null; } List locationInfos = new List(); foreach (var item in locations) { var locationLateral = _locationRepository.QueryData(x => x.Row == item.Row && x.Column < item.Column && x.Remark == item.Remark); if (locationLateral.Count == 0) { locationInfos.Add(item); continue; } bool Isavailable = true; foreach (var lateral in locationLateral) { if (lateral.LocationStatus != (int)LocationEnum.Free && lateral.EnalbeStatus == 1) { Isavailable = false; continue; } } if (Isavailable) locationInfos.Add(item); } return locationInfos.Distinct().OrderByDescending(x => x.Column).ThenBy(x => x.Row).FirstOrDefault(); } /// /// 由浅到深 /// /// /// public async Task FromShallowToDeep(int AreaId, DtLocationInfo loc) { List locations = new List(); if (AreaId == loc.AreaId) { locations = await _locationRepository.QueryDataAsync(x => x.AreaId == AreaId && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == 1 && x.Row != loc.Row); } else { locations = await _locationRepository.QueryDataAsync(x => x.AreaId == AreaId && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == 1); } if (locations.Count == 0) { return null; } List locationInfos = new List(); foreach (var item in locations) { var locationLateral = _locationRepository.QueryData(x => x.Row == item.Row && x.Column > item.Column && x.Remark == item.Remark); if (locationLateral.Count == 0) { locationInfos.Add(item); continue; } bool Isavailable = true; foreach (var lateral in locationLateral) { if (lateral.LocationStatus != (int)LocationEnum.Free && lateral.EnalbeStatus == 1) { Isavailable = false; continue; } } if (Isavailable) locationInfos.Add(item); } return locationInfos.Distinct().OrderBy(x => x.Column).ThenBy(x => x.Row).FirstOrDefault(); } public async Task AGVLIKU(int AreaId) { WebResponseContent content = new WebResponseContent(); List locations = await _locationRepository.QueryDataAsync(x => x.AreaId == AreaId && x.LocationStatus == 0 && x.EnalbeStatus == 1); var location = locations.OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault(); return location; } public bool LocationIsOutBound(DtLocationInfo location) { if (location.AreaId == 1) { if (location.Depth == 2) { var locationLateral = _locationRepository.QueryFirst(x => x.Row == 1 && x.Column == location.Column && x.Layer == location.Layer); if (locationLateral.LocationStatus == (int)LocationEnum.Lock && locationLateral.EnalbeStatus == 1) { return false; } } } else if (location.AreaId == 2 || location.AreaId == 7) { var locationLateral = _locationRepository.QueryData(x => x.Row == location.Row && x.Column > location.Column && x.Remark == location.Remark); foreach (var Lateral in locationLateral) { if (Lateral.LocationStatus == (int)LocationEnum.Lock && Lateral.EnalbeStatus == 1) { return false; } } } else if (location.AreaId == 5 || location.AreaId == 6) { var locationLateral = _locationRepository.QueryData(x => x.Row == location.Row && x.Column < location.Column && x.Remark == location.Remark); foreach (var lateral in locationLateral) { if (lateral.LocationStatus == (int)LocationEnum.Lock && lateral.EnalbeStatus == 1) { return false; } } } return true; } #endregion 任务请求方法 #endregion private 内部方法 }