/* *所有关于Dt_TaskWCSinfo类的业务代码应在此处编写 *可使用repository.调用常用方法,获取EF/Dapper等信息 *如果需要事务请使用repository.DbContextBeginTransaction *也可使用DBServerProvider.手动获取数据库相关信息 *用户信息、权限、角色等使用UserContext.Current操作 *Dt_TaskWCSinfoService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter */ using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using WIDESEA_Common; using WIDESEA_Common.CutomerModel; using WIDESEA_Common.TaskEnum; using WIDESEA_Common.Tools; using WIDESEA_Core.BaseProvider; using WIDESEA_Core.Extensions; using WIDESEA_Core.Extensions.AutofacManager; using WIDESEA_Core.Utilities; using WIDESEA_Entity.DomainModels; using WIDESEA_Services.IRepositories; using WIDESEA_Services.Repositories; namespace WIDESEA_Services.Services { public partial class Dt_TaskWCSinfoService { private readonly IHttpContextAccessor _httpContextAccessor; private readonly IDt_TaskWCSinfoRepository _repository;//访问数据库 [ActivatorUtilitiesConstructor] public Dt_TaskWCSinfoService( IDt_TaskWCSinfoRepository dbRepository, IHttpContextAccessor httpContextAccessor ) : base(dbRepository) { _httpContextAccessor = httpContextAccessor; _repository = dbRepository; //多租户会用到这init代码,其他情况可以不用 //base.Init(dbRepository); } /// /// 根据WMS下发的任务,添加WCS任务 /// /// /// public WebResponseContent AddTaskByWms(List taskInfos) { WebResponseContent content = new WebResponseContent(); try { List wcsTaskList = new List(); List rgvTaskList = new List(); foreach (var taskInfo in taskInfos) { if (repository.Exists(x => x.wcstask_barcode == taskInfo.task_barcode)) return content.Error(taskInfo.task_barcode + "已存在未完成的任务,请先检查。"); if (taskInfo.task_type.Contains("Inbound")) if (repository.Exists(x => x.wcstask_startPoint == "20101" && x.wcstask_state == TaskState.TaskState_Assigned.ToString())) return content.Error("当前存在待执行的入库任务,请等待."); //空托盘入库 if (taskInfo.task_type == TaskType.TaskType_Empty_Pallet_Inbound.ToString()) { Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSEmptyInboundTask(taskInfo, Dt_TaskWCSinfoRepository.Instance); wcsTaskList.Add(wcsInfo); } //空托盘出库 else if (taskInfo.task_type == TaskType.TaskType_Empty_Pallet_Outbound.ToString()) { Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSEmptyOutboundTask(taskInfo); wcsTaskList.Add(wcsInfo); if (taskInfo.task_endstation.Equal("20101")) { Dt_TaskRGVinfo rgvInfo = CommonFunction.AddOutboundTask(taskInfo, wcsInfo); rgvTaskList.Add(rgvInfo); } } //实托入库 else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Inbound.ToString() || taskInfo.task_type == TaskType.TaskType_ErrorCheckBackIn.ToString() || taskInfo.task_type == TaskType.TaskType_CheckBackIn.ToString()) { Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSBoxInboundTask(taskInfo); wcsTaskList.Add(wcsInfo); } //实托出库 else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Outbound.ToString()|| taskInfo.task_type == TaskType.TaskType_CheckOutbound.ToString()) { Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSBoxOutboundTask(taskInfo); wcsTaskList.Add(wcsInfo); //入库区才直接添加AGV任务 if (taskInfo.task_endstation.Equal("20101")) { Dt_TaskRGVinfo rgvInfo = CommonFunction.AddOutboundTask(taskInfo, wcsInfo); rgvTaskList.Add(rgvInfo); } } //轴承测量出库 else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Measure_Out.ToString()) { Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSMeasureOutboundTask(taskInfo); wcsTaskList.Add(wcsInfo); Dt_TaskRGVinfo rgvInfo = CommonFunction.AddOutboundTask(taskInfo, wcsInfo); rgvTaskList.Add(rgvInfo); } //轴承测量完成后回库-----【该类任务不是WMS下发的,而是WCS在测量完成后,自动转变为该类任务的】 else if (taskInfo.task_type == TaskType.TaskType_Box_Pallet_Measure_Back.ToString()) { } else if (taskInfo.task_type == TaskType.TaskType_MoveOutbound.ToString()) { Dt_TaskWCSinfo wcsInfo = CommonFunction.AddWCSMoveOutboundTask(taskInfo); wcsTaskList.Add(wcsInfo); string[] fromLocationArray = wcsInfo.wcstask_startLocation.Split('-'); string[] toLocationArray = wcsInfo.wcstask_endLocation.Split('-'); if (fromLocationArray[0] == toLocationArray[0]) { Dt_TaskRGVinfo moveOutbound = CommonFunction.AddRGVMoveOutboundTask(taskInfo, wcsInfo, RGVTaskType.RgvTaskType_Move); rgvTaskList.Add(moveOutbound); } else { Dt_TaskRGVinfo moveInbound = CommonFunction.AddRGVMoveOutboundTask(taskInfo, wcsInfo, RGVTaskType.RgvTaskType_Outbound); rgvTaskList.Add(moveInbound); } } else throw new Exception("无效任务类型:" + taskInfo.task_type); } if (null != wcsTaskList && wcsTaskList.Count > 0) { content = repository.DbContextBeginTransaction(() => { repository.AddRange(wcsTaskList, true); if (null != rgvTaskList && rgvTaskList.Count > 0) repository.AddRange(rgvTaskList, true); return content.OK(); }); } } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 取消一条未开始执行的任务 /// /// /// public WebResponseContent CancelATask(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { string barcode = saveModel.MainData["barcode"].ToString(); if (barcode == null) throw new Exception("取消任务的托盘号不能为空"); Dt_TaskWCSinfo taskinfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode); if (taskinfo == null) return content.OK($"没有找到托盘号:【{barcode}】对应的任务"); if (taskinfo.wcstask_state != TaskState.TaskState_Assigned.ToString()) throw new Exception($"托盘号:【{barcode}】对应的任务已经开始执行,无法取消"); content = Dt_TaskWCSinfoRepository.Instance.DbContextBeginTransaction(() => { Dt_TaskWCSinfoRepository.Instance.Delete(taskinfo, true); Dt_TaskRGVinfo rgvInfo = Dt_TaskRGVinfoRepository.Instance.FindFirst(x => x.rgvtask_barCode == barcode && x.rgvtask_taskStatus == RGVTaskState.RgvTaskState_Wait_Send.ToString()); if (rgvInfo != null) Dt_TaskRGVinfoRepository.Instance.Delete(rgvInfo, true); return content.OK(); }); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// WMS下发的更改任务状态,给测量设备测量完毕后,更新WCS任务状态 /// /// /// public WebResponseContent UpdateWcsTaskState(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { string barcode = saveModel.MainData["barcode"].ToString(); string state = saveModel.MainData["state"].ToString(); string taskType = saveModel.MainData["tasktype"].ToString(); Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode); if (wcsInfo != null) { //更新任务数据,准备回库,起点终点倒换 string endLoc = wcsInfo.wcstask_endPoint; wcsInfo.wcstask_state = TaskState.TaskState_Measure_Back_Line_Executing.ToString(); wcsInfo.wcstask_endPoint = wcsInfo.wcstask_startPoint; wcsInfo.wcstask_endLocation = wcsInfo.wcstask_startLocation; wcsInfo.wcstask_startLocation = endLoc; wcsInfo.wcstask_startPoint = "10301"; wcsInfo.wcstask_state = state; wcsInfo.wcstask_type = taskType; Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true); } else { content.Error($"没有找到托盘码:【{barcode}】对应的任务!!"); return content; } content.OK(); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 手动更改任务状态 /// /// /// public static WebResponseContent ChangeWcsTaskStatus(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { int taskNumer = int.Parse(saveModel.MainData["taskNumber"].ToString()); string state = saveModel.MainData["state"].ToString(); Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_taskNumber == taskNumer); if (wcsInfo == null) { content.Error($"::Error::没有找到任务号:【{taskNumer}】对应的任务!"); return content; } content = Dt_TaskWCSinfoRepository.Instance.DbContextBeginTransaction(() => { try { content = WMSApi.PostTaskStateToWMS(wcsInfo.wcstask_barcode, state); if (content.Status) { wcsInfo.wcstask_state = state; if (state == TaskState.TaskState_Measure_Back_Line_Executing.ToString()) { //将任务类型改为回库中 wcsInfo.wcstask_type = TaskType.TaskType_Box_Pallet_Measure_Back.ToString(); //将任务起始站台和目的站台对调,准备回库 wcsInfo.wcstask_endPoint = wcsInfo.wcstask_startPoint; wcsInfo.wcstask_startPoint = "10301"; wcsInfo.wcstask_endLocation = wcsInfo.wcstask_startLocation; wcsInfo.wcstask_startLocation = wcsInfo.wcstask_endPoint; wcsInfo.wcstask_state = TaskState.TaskState_Measure_Back_Line_Executing.ToString(); wcsInfo.wcstask_dispatcherTime = DateTime.Now; } Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true); WriteLog.Info("手动更改测量状态").Write($"{DateTime.Now}:测量回库异常,反转货位 任务号{taskNumer},托盘号{wcsInfo.wcstask_barcode},反转后起始站台【10301】" + $"终点货位【{wcsInfo.wcstask_endLocation}】", "手动更改测量状态"); } else { content.Error($"::Error::上报WMS更新任务号:【{taskNumer}】对应的任务出错!原因:{content.Message}"); return content; } content.OK(); } catch (Exception ex) { content.Error(ex.Message); } return content; }); if (content.Status) { Dt_TaskRGVinfoRepository taskRGVinfoRepository = new Dt_TaskRGVinfoRepository(Dt_TaskRGVinfoRepository.Instance.DbContext); //根据任务类型和更改的任务状态,进行接着的逻辑 if (wcsInfo.wcstask_type == TaskType.TaskType_Box_Pallet_Inbound.ToString() || wcsInfo.wcstask_type == TaskType.TaskType_Empty_Pallet_Inbound.ToString()) { //比如手动操作系统将托盘运送至入库口,则需要生成对应的穿梭车任务 if (state == TaskState.TaskState_ConveyorLineFinish.ToString()) { Dt_TaskRGVinfo rgvInfo = new Dt_TaskRGVinfo(); rgvInfo.rgvtask_taskId = GetTaskNumber.GetRgvTaskNumber().ToString(); rgvInfo.rgvtask_taskType = RGVTaskType.RgvTaskType_Inbound.ToString(); rgvInfo.rgvtask_taskStatus = RGVTaskState.RgvTaskState_Wait_Send.ToString(); rgvInfo.rgvtask_priorityCode = wcsInfo.wcstask_grade.ToString(); rgvInfo.rgvtask_startNode = wcsInfo.wcstask_startLocation; rgvInfo.rgvtask_endNode = wcsInfo.wcstask_endLocation; rgvInfo.rgvtask_wcsTaskNumber = wcsInfo.wcstask_taskNumber; rgvInfo.rgvtask_barCode = wcsInfo.wcstask_barcode; rgvInfo.rgvtask_msgTime = DateTime.Now; rgvInfo.rgvtask_areaCode = "InboundArea"; taskRGVinfoRepository.Add(rgvInfo, true); } } else { } } } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// WMS下发更改任务信息,当入库任务与出库测量任务冲突时,WMS调用此接口来更换目的货位 /// /// /// public WebResponseContent UpdateWcsTaskInformation(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { string barcode = saveModel.MainData["barcode"].ToString(); string newLocationId = saveModel.MainData["newLocationId"].ToString(); string newStation = saveModel.MainData["newStation"].ToString(); Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode); if (wcsInfo == null) { Console.WriteLine($"::Error::=> WMS下发新货位是,在WCS任务中没有找到对应托盘【{barcode}】的号的任务"); return content.Error($"::Error::=> WMS下发新货位是,在WCS任务中没有找到对应托盘【{barcode}】的号的任务"); } wcsInfo.wcstask_startLocation = newStation; wcsInfo.wcstask_endPoint = newStation; wcsInfo.wcstask_endLocation = newLocationId; Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true); content.OK(); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 取消测量,直接回库 /// /// /// public WebResponseContent CancelAMeasureTask(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { string barcode = saveModel.MainData["barcode"].ToString(); Dt_TaskWCSinfo wcsInfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_barcode == barcode); if (wcsInfo == null) { Console.WriteLine($"::Error::=> 没有找到【{barcode}】对应的测量任务"); return content.Error($"::Error::=> 没有找到【{barcode}】对应的测量任务"); } //将任务类型改为回库中 wcsInfo.wcstask_type = TaskType.TaskType_Box_Pallet_Measure_Back.ToString(); //将任务起始站台和目的站台对调,准备回库 wcsInfo.wcstask_endPoint = wcsInfo.wcstask_startPoint; wcsInfo.wcstask_startPoint = "10301"; wcsInfo.wcstask_endLocation = wcsInfo.wcstask_startLocation; wcsInfo.wcstask_startLocation = wcsInfo.wcstask_endPoint; wcsInfo.wcstask_state = TaskState.TaskState_Measure_Back_Line_Wait_Executing.ToString(); wcsInfo.wcstask_dispatcherTime = DateTime.Now; Dt_TaskWCSinfoRepository.Instance.Update(wcsInfo, true); content.OK(); } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 手动完成一个WCS任务(目前仅支持手动完成空托盘出库功能,因为空托盘到了缓存位经常有人手动去动) /// /// /// public static WebResponseContent CompleteWcsTaskByMannual(SaveModel saveModel) { WebResponseContent content = new WebResponseContent(); try { int taskNumer = int.Parse(saveModel.MainData["taskNumber"].ToString()); Dt_TaskWCSinfo taskWCSinfo = Dt_TaskWCSinfoRepository.Instance.FindFirst(x => x.wcstask_taskNumber == taskNumer); if (taskWCSinfo == null) throw new Exception($"没有找到任务号:【{taskNumer}】对应的WCS任务"); //在此完成该空托出库任务 content = Dt_TaskWCSinfoRepository.Instance.DbContextBeginTransaction(() => { WebResponseContent transContent = new WebResponseContent(); try { //上报WMS任务完成 transContent = WMSApi.TellWmsTaskFinished(taskWCSinfo.wcstask_barcode,taskWCSinfo.wcstask_backUp_2); if (transContent.Status) { //移动任务到历史表 taskWCSinfo.wcstask_state = TaskState.TaskState_Finished.ToString(); CommonFunction.AddWcsTaskToHistory(taskWCSinfo, Dt_TaskWCSinfoRepository.Instance, Dt_TaskWCSinfo_HtyRepository.Instance); } else { throw new Exception($"上报WMS任务完成出错,原因:【{transContent.Message}】"); } transContent.OK(); } catch (Exception ex) { transContent.Error(ex.Message); } return transContent; }); if (!content.Status) throw new Exception($"::Error::=> 手动完成任务出错,原因:{content.Message}"); } catch (Exception ex) { content.Error(ex.Message); } return content; } } }