#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_TaskInfoService * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using AutoMapper; using SqlSugar; using System.Diagnostics.CodeAnalysis; using WIDESEAWCS_BasicInfoService; using WIDESEAWCS_Common; using WIDESEAWCS_Common.LocationEnum; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.BaseRepository; using WIDESEAWCS_Core.BaseServices; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_DTO; using WIDESEAWCS_DTO.AGV.HIKROBOT; using WIDESEAWCS_DTO.RGV.FOURBOT; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_DTO.WMS; using WIDESEAWCS_IBasicInfoService; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob.Models; using WIDESEAWCS_QuartzJob.Service; namespace WIDESEAWCS_TaskInfoService { public partial class TaskService : ServiceBase>, ITaskService { private readonly ITrackloginfoService _trackloginfoService; private readonly IRouterService _routerService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly IHKLocationInfoService _hKLocationInfoService; private readonly IKLSLocationInfoService _kLSLocationInfoService; private readonly IRGVLocationInfoService _rGVLocationInfoService; private readonly IRepository _taskExecuteDetailRepository; private readonly IApiInfoService _apiInfoService; private readonly IStationMangerService _stationMangerService; private readonly IMapper _mapper; private Dictionary _taskOrderBy = new() { {nameof(Dt_Task.Grade),OrderByType.Desc }, {nameof(Dt_Task.CreateDate),OrderByType.Asc}, }; public Dictionary TaskOrderBy { get { return _taskOrderBy; } set { _taskOrderBy = value; } } public List TaskInboundTypes => typeof(TaskInboundTypeEnum).GetEnumIndexList(); public List TaskOutboundTypes => typeof(TaskOutboundTypeEnum).GetEnumIndexList(); /// /// 仓储层(数据库访问) /// public IRepository Repository => BaseDal; public TaskService(IRepository BaseDal, IRouterService routerService, ITaskExecuteDetailService taskExecuteDetailService, IRepository taskExecuteDetailRepository, IMapper mapper, IKLSLocationInfoService kLSLocationInfoService, IRGVLocationInfoService rGVLocationInfoService, IHKLocationInfoService hKLocationInfoService, IApiInfoService apiInfoService, ITrackloginfoService trackloginfoService, IStationMangerService stationMangerService) : base(BaseDal) { _routerService = routerService; _taskExecuteDetailService = taskExecuteDetailService; _taskExecuteDetailRepository = taskExecuteDetailRepository; _mapper = mapper; _kLSLocationInfoService = kLSLocationInfoService; _rGVLocationInfoService = rGVLocationInfoService; _hKLocationInfoService = hKLocationInfoService; _apiInfoService = apiInfoService; _trackloginfoService = trackloginfoService; _stationMangerService=stationMangerService; } public WebResponseContent ReceiveWMSTask([NotNull] List taskDTOs) { WebResponseContent content = new WebResponseContent(); try { foreach (var item in taskDTOs) { foreach (var task in item.tasks) { content = TaskHelpMethods.isOkTaskInfo(task, true, true); if (!content.Status) throw new Exception(content.Message); if (BaseDal.QueryFirst(x => x.WMSTaskNum == task.taskCode || x.PalletCode == task.containerCode) != null) { continue; } switch (item.taskType) { case (int)TaskTypeEnum.MLInbound: CreateKLSNewInTask(task, item.taskType); break; case (int)TaskTypeEnum.MLOutbound: CreateKLSNewOutTask(task, item.taskType); break; case (int)TaskTypeEnum.CPInbound: CreateRGVNewInTask(task, item.taskType); break; case (int)TaskTypeEnum.CPOutbound: CreateRGVNewOutTask(task, item.taskType); break; case (int)TaskTypeEnum.CJInbound: CreateHKNewInTask(task, item.taskType); break; case (int)TaskTypeEnum.CJOutbound: CreateHKNewOutTask(task, item.taskType); break; case (int)TaskTypeEnum.Carry: CarryTask(task, item.taskType); break; case (int)TaskTypeEnum.CJCarry: CJCarryTaske(task, item.taskType); break; default: break; } } } } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 取消任务 /// /// 任务号 /// 料箱条码 /// public WebResponseContent CancelWMSTask(WMSCancelTask wMSCancelTask) { WebResponseContent content = new WebResponseContent(); try { Dt_Task dt_Task = BaseDal.QueryFirst(x => x.WMSTaskNum == wMSCancelTask.TaskCode); if (dt_Task == null) throw new Exception("未查询到任务号相关任务"); // 判断当前任务是否为凯乐士任务 bool isGALAXISTask = dt_Task.TaskType == (int)TaskTypeEnum.MLInbound || dt_Task.TaskType == (int)TaskTypeEnum.MLOutbound; //四向车 bool isAGV = dt_Task.TaskType == (int)TaskTypeEnum.CPInbound || dt_Task.TaskType == (int)TaskTypeEnum.CPOutbound; //海康 bool isHK = dt_Task.TaskType == (int)TaskTypeEnum.Carry || dt_Task.TaskType == (int)TaskTypeEnum.CJInbound || dt_Task.TaskType == (int)TaskTypeEnum.CJInbound || dt_Task.TaskType == (int)TaskTypeEnum.CJOutbound; //这里将状态改变了198取消任务 dt_Task.TaskType = TaskStatusEnum.WMSCancel.ObjToInt(); #region 凯乐士 if (isGALAXISTask) { var KLS = new CancelGALAXISTask { taskId = dt_Task.WMSTaskNum, reportTime = DateTime.Now.ToString() }; Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == nameof(CancelGALAXISTask)); if (apiInfo == null) throw new Exception("未找到凯乐士AGV任务下发接口配置信息!请检查接口配置"); string response = HttpHelper.Post(apiInfo.ApiAddress, KLS.Serialize()); GALAXISReturn agvContent = response.DeserializeObject(); if (agvContent.success == true && agvContent.code == 0) { //直接移入历史 BaseDal.DeleteAndMoveIntoHty(dt_Task, OperateTypeEnum.自动完成); return content.OK("取消任务成功", dt_Task); } else { return content.Error($"任务失败{agvContent.data.returnInfo}"); } } #endregion #region 四向车 if (isAGV) { CancelSXCTake cancelSXCTake = new CancelSXCTake { taskID = dt_Task.RGVTaskId }; Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == nameof(CancelSXCTake)); if (apiInfo == null) throw new Exception("未找到四向车AGV任务下发接口配置信息!请检查接口配置"); string response = HttpHelper.Post(apiInfo.ApiAddress, cancelSXCTake.Serialize()); FOURBOTReturn fOURBOTReturn = response.DeserializeObject(); if (fOURBOTReturn.returnCode == 0 && fOURBOTReturn.returnUserMsg == "成功") { //直接移入历史 BaseDal.DeleteAndMoveIntoHty(dt_Task, OperateTypeEnum.自动完成); return content.OK("取消任务成功", dt_Task); } else { return content.Error($"任务失败{fOURBOTReturn.data}"); } } #endregion #region 海康 if (isHK) { CancelHIKROBOTTask cancelHIKROBOTTask = new CancelHIKROBOTTask { robotTaskCode = dt_Task.WMSTaskNum, cancelType = "CANCEL"//原软取消,DROP人工介入(原硬取消) }; Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == nameof(CancelHIKROBOTTask)); if (apiInfo == null) throw new Exception("未找到四向车AGV任务下发接口配置信息!请检查接口配置"); string response = HttpHelper.Post(apiInfo.ApiAddress, cancelHIKROBOTTask.Serialize()); HIKROBOTReturn hIKROBOTReturn = response.DeserializeObject(); if (hIKROBOTReturn.code == "SUCCESS" && hIKROBOTReturn.message == "成功") { //直接移入历史 BaseDal.DeleteAndMoveIntoHty(dt_Task, OperateTypeEnum.自动完成); return content.OK("取消任务成功", dt_Task); } else { return content.Error($"任务失败{hIKROBOTReturn.data}"); } } #endregion } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 修改任务优先级 /// /// /// public WebResponseContent UpdateWMSTaskPriority(WMSUpdateTaskPriority updateTaskPriority) { WebResponseContent content = new WebResponseContent(); try { Dt_Task dt_Task = BaseDal.QueryFirst(x => x.WMSTaskNum == updateTaskPriority.taskCode); if (dt_Task == null) throw new Exception("未查询到任务号相关任务"); // 判断当前任务是否为凯乐士任务 bool isGALAXISTask = dt_Task.TaskType == (int)TaskTypeEnum.MLInbound || dt_Task.TaskType == (int)TaskTypeEnum.MLOutbound; //四向车 bool isAGV = dt_Task.TaskType == (int)TaskTypeEnum.CPInbound || dt_Task.TaskType == (int)TaskTypeEnum.CPOutbound; //海康 bool isHK = dt_Task.TaskType == (int)TaskTypeEnum.Carry || dt_Task.TaskType == (int)TaskTypeEnum.CJInbound || dt_Task.TaskType == (int)TaskTypeEnum.CJInbound || dt_Task.TaskType == (int)TaskTypeEnum.CJOutbound; //修改原本任务优先级 dt_Task.Grade = updateTaskPriority.taskPriority; #region 凯乐士 if (isGALAXISTask) { var updateGALAXISTaskGrade = new UpdateGALAXISTaskGrade { taskId = dt_Task.WMSTaskNum, reportTime = DateTime.Now.ToString(), district = dt_Task.Roadway,//任务库区 priorityCode = updateTaskPriority.taskPriority, }; Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == nameof(UpdateGALAXISTaskGrade)); if (apiInfo == null) throw new Exception("未找到凯乐士AGV任务下发接口配置信息!请检查接口配置"); string response = HttpHelper.Post(apiInfo.ApiAddress, updateGALAXISTaskGrade.Serialize()); GALAXISReturn agvContent = response.DeserializeObject(); if (agvContent.success == true && agvContent.code == 0) { BaseDal.UpdateData(dt_Task); return content.OK("修改任务优先级成功", dt_Task); } else { return content.Error($"任务失败{agvContent.data.returnInfo}"); } } #endregion #region 四向车 if (isAGV) { var request = new UpdateAgvSXCTake { taskID = dt_Task.RGVTaskId, priority = updateTaskPriority.taskPriority }; Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == nameof(UpdateAgvSXCTake)); if (apiInfo == null) throw new Exception("未找到四向车AGV任务下发接口配置信息!请检查接口配置"); string response = HttpHelper.Post(apiInfo.ApiAddress, request.Serialize()); FOURBOTReturn fOURBOTReturn = response.DeserializeObject(); if (fOURBOTReturn.returnCode == 0 && fOURBOTReturn.returnUserMsg == "成功") { BaseDal.UpdateData(dt_Task); return content.OK("修改任务优先级成功", dt_Task); } else { return content.Error($"任务失败{fOURBOTReturn.data}"); } } #endregion #region 海康 if (isHK) { var request = new HIKROBOTTaskGrade { robotTaskCode = dt_Task.WMSTaskNum,//任务号 initPriority = updateTaskPriority.taskPriority//优先级 }; Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == nameof(HIKROBOTTaskGrade)); if (apiInfo == null) throw new Exception("未找到四向车AGV任务下发接口配置信息!请检查接口配置"); string response = HttpHelper.Post(apiInfo.ApiAddress, request.Serialize()); HIKROBOTReturn hIKROBOTReturn = response.DeserializeObject(); if (hIKROBOTReturn.code == "SUCCESS0" && hIKROBOTReturn.message == "成功") { BaseDal.UpdateData(dt_Task); return content.OK("修改任务优先级成功", dt_Task); } else { return content.Error($"任务失败{hIKROBOTReturn.data}"); } } #endregion } catch (Exception ex) { content.Error(ex.Message); } return content; } /// /// 修改库位分区 /// /// public WebResponseContent ModifyWMSLayoutZone(WMSUpdateLocationArea wMSUpdateLocationArea) { WebResponseContent content = new WebResponseContent(); try { var rgv = new List(); var kls = new List(); var hk = new List(); if (wMSUpdateLocationArea.WarehouseId == 1) { var rgvList = _rGVLocationInfoService.Repository.QueryData(x => wMSUpdateLocationArea.LocationCodes.Contains(x.LocationCode)).ToList(); foreach (var item in rgvList) { item.WarehouseId = wMSUpdateLocationArea.UpdateAreaCode.ObjToInt(); } rgv.AddRange(rgvList); } if (wMSUpdateLocationArea.WarehouseId == 2) { var KLSLocationInfoList = _kLSLocationInfoService.Repository.QueryData(x => wMSUpdateLocationArea.LocationCodes.Contains(x.LocationCode)).ToList(); foreach (var item in KLSLocationInfoList) { item.WarehouseId = wMSUpdateLocationArea.UpdateAreaCode.ObjToInt(); } kls.AddRange(KLSLocationInfoList); } if (wMSUpdateLocationArea.WarehouseId == 3) { var hkList = _hKLocationInfoService.Repository.QueryData(x => wMSUpdateLocationArea.LocationCodes.Contains(x.LocationCode)).ToList(); foreach (var item in hkList) { item.WarehouseId = wMSUpdateLocationArea.UpdateAreaCode.ObjToInt(); } hk.AddRange(hkList); } Db.Ado.BeginTran(); _rGVLocationInfoService.UpdateData(rgv); _kLSLocationInfoService.UpdateData(kls); _hKLocationInfoService.UpdateData(hk); Db.Ado.CommitTran(); content.OK(); } catch (Exception ex) { content.Error(ex.Message); } return content; } private void UpdateLocationCode(object LocationInfo, string updateAreaCode) { } /// /// 接收WMS任务信息 /// /// WMS任务对象集合 /// 返回处理结果 public WebResponseContent ReceiveWMSTask([NotNull] List taskDTOs) { WebResponseContent content = new WebResponseContent(); try { List tasks = new List(); foreach (var item in taskDTOs) { if (BaseDal.QueryFirst(x => x.TaskNum == item.TaskNum || x.PalletCode == item.PalletCode) != null) { continue; } Dt_Task task = _mapper.Map(item); task.Creater = "WMS"; if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { List routers = _routerService.QueryNextRoutes(item.RoadWay, item.TargetAddress); //暂不考虑多路径 if (routers.Count > 0) { task.TaskState = (int)TaskOutStatusEnum.OutNew; task.CurrentAddress = item.SourceAddress; task.NextAddress = routers.FirstOrDefault().ChildPosi; } } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) { List routers = _routerService.QueryNextRoutes(item.SourceAddress, item.TargetAddress); //暂不考虑多路径 if (routers.Count > 0) { task.TaskState = (int)TaskInStatusEnum.InNew; task.CurrentAddress = item.SourceAddress; task.NextAddress = routers.FirstOrDefault().ChildPosi; } } tasks.Add(task); } BaseDal.AddData(tasks); _taskExecuteDetailService.AddTaskExecuteDetail(tasks.Select(x => x.TaskNum).ToList(), "接收WMS任务"); content = WebResponseContent.Instance.OK("成功"); } catch (Exception ex) { content = WebResponseContent.Instance.Error($"任务接收错误,错误信息:{ex.Message}"); } return content; } /// /// 根据托盘号、起始地址向WMS请求任务 /// /// 托盘号 /// 起始地址 /// public WebResponseContent RequestWMSTask(string palletCode, string sourceAddress) { WebResponseContent content = new WebResponseContent(); try { WMSTaskDTO taskDTO = new WMSTaskDTO() { TaskNum = Convert.ToInt32(DateTime.Now.ToString("HHmmss")), Grade = 1, PalletCode = palletCode, RoadWay = "SC01", SourceAddress = sourceAddress, TargetAddress = "SC01", TaskState = (int)TaskInStatusEnum.InNew, Id = 0, TaskType = (int)TaskInboundTypeEnum.Inbound }; content = ReceiveWMSTask(new List { taskDTO }); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 根据设备编号、当前地址查询输送线未执行的任务 /// /// 设备编号 /// 当前地址 /// public Dt_Task QueryConveyorLineTask(string deviceNo, string currentAddress) { return BaseDal.QueryFirst(x => (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.InNew || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.SC_OutFinish) && x.CurrentAddress == currentAddress, TaskOrderBy); } /// /// 根据任务号、下一地址查询输送线执行中的任务 /// /// 任务号 /// 下一地址 /// public Dt_Task QueryExecutingConveyorLineTask(int taskNum, string nextAddress) { return BaseDal.QueryFirst(x => x.TaskNum == taskNum && x.NextAddress == nextAddress && (x.TaskState == (int)TaskInStatusEnum.Line_InExecuting || x.TaskState == (int)TaskOutStatusEnum.Line_OutExecuting), TaskOrderBy); } /// /// 根据任务号、当前地址查询输送线完成的任务 /// /// 任务号 /// 当前地址 /// public Dt_Task QueryCompletedConveyorLineTask(int taskNum, string currentAddress) { return BaseDal.QueryFirst(x => x.TaskNum == taskNum && x.CurrentAddress == currentAddress && (x.TaskState == (int)TaskInStatusEnum.Line_InFinish || x.TaskState == (int)TaskOutStatusEnum.Line_OutFinish), TaskOrderBy); } /// /// 根据设备编号、任务类型分组(可选)按照优先级以及创建时间排序查询任务池新增的任务 /// /// 设备编号 /// 任务类型分组(可选) /// public Dt_Task? QuertStackerCraneTask(string deviceNo, TaskTypeGroup? taskTypeGroup = null) { if (taskTypeGroup == null) return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew), TaskOrderBy); if (taskTypeGroup.Value == TaskTypeGroup.InboundGroup) return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish, TaskOrderBy); if (taskTypeGroup.Value == TaskTypeGroup.OutbondGroup) return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew, TaskOrderBy); return null; } /// /// 根据设备编号、当前地址按照优先级以及创建时间排序查询任务池新增的任务 /// /// 设备编号 /// 当前地址 /// 返回任务实体对象,可能为null public Dt_Task QueryStackerCraneTask(string deviceNo, string currentAddress = "") { if (string.IsNullOrEmpty(currentAddress)) return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew), TaskOrderBy); else return BaseDal.QueryFirst(x => x.Roadway == deviceNo && x.CurrentAddress == currentAddress && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew), TaskOrderBy); } /// /// 根据设备编号、当前地址按照优先级以及创建时间排序查询任务池入库类型的新增的任务 /// /// 设备编号 /// 当前地址 /// 返回任务实体对象,可能为null public Dt_Task QueryStackerCraneInTask(string deviceNo, string currentAddress = "") { if (string.IsNullOrEmpty(currentAddress)) return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish, TaskOrderBy); else return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.Line_InFinish && x.CurrentAddress == currentAddress, TaskOrderBy); } /// /// 根据设备编号、当前地址按照优先级以及创建时间排序查询任务池出库类型的新增的任务 /// /// 设备编号 /// 当前地址 /// 返回任务实体对象,可能为null public Dt_Task QueryStackerCraneOutTask(string deviceNo, string currentAddress = "") { if (string.IsNullOrEmpty(currentAddress)) return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew, TaskOrderBy); else return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew && x.CurrentAddress == currentAddress, TaskOrderBy); } /// /// 根据设备编号、当前地址按照优先级以及创建时间排序查询任务池出库类型的新增的任务 /// /// 设备编号 /// 当前地址 /// 返回任务实体对象集合,可能为null public List QueryStackerCraneOutTasks(string deviceNo, List outStationCodes) { return BaseDal.QueryData(x => x.Roadway == deviceNo && TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew && outStationCodes.Contains(x.CurrentAddress), TaskOrderBy); } /// /// 更新任务异常信息显示 /// /// 任务号 /// 异常信息 public WebResponseContent UpdateTaskExceptionMessage(int taskNum, string message) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { task.TaskState = (int)TaskOutStatusEnum.OutPending; } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) { task.TaskState = (int)TaskInStatusEnum.InPending; } task.ExceptionMessage = message; task.ModifyDate = DateTime.Now; BaseDal.UpdateData(task); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, task.ExceptionMessage); content = WebResponseContent.Instance.OK(); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 更新任务状态信息,并同步至WMS /// /// 任务号 /// 任务状态 public void UpdateTaskStatus(int taskNum, int status) { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return; task.TaskState = status; task.ModifyDate = DateTime.Now; BaseDal.UpdateData(task); } /// /// 将任务状态修改为下一个状态 /// /// 任务号 public WebResponseContent UpdateTaskStatusToNext(int taskNum) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); return UpdateTaskStatusToNext(task); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 将任务状态修改为下一个状态 /// /// 任务实体对象 /// public WebResponseContent UpdateTaskStatusToNext([NotNull] Dt_Task task) { WebResponseContent content = new WebResponseContent(); try { int oldState = task.TaskState; if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { if (task.TaskState >= (int)TaskOutStatusEnum.OutFinish) { return content = WebResponseContent.Instance.Error($"该任务状态不可跳转到下一步,任务号:【{task.TaskNum}】,任务状态:【{task.TaskState}】"); } int nextStatus = task.TaskState.GetNextNotCompletedStatus(); task.TaskState = nextStatus; } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) { if (task.TaskState >= (int)TaskInStatusEnum.InFinish) { return content = WebResponseContent.Instance.Error($"该任务状态不可跳转到下一步,任务号:【{task.TaskNum}】,任务状态:【{task.TaskState}】"); } int nextStatus = task.TaskState.GetNextNotCompletedStatus(); task.TaskState = nextStatus; if (task.TaskState == (int)TaskInStatusEnum.Line_InFinish) { Random random = new Random(); task.CurrentAddress = task.NextAddress; task.NextAddress = $"{random.Next(1, 100).ToString().PadLeft(3, '0')}-{random.Next(1, 100).ToString().PadLeft(3, '0')}-{random.Next(1, 100).ToString().PadLeft(3, '0')}"; task.TargetAddress = task.NextAddress; } } else { throw new Exception($"任务类型错误,未找到该任务类型,任务号:【{task.TaskNum}】,任务类型:【{task.TaskType}】"); } if (task.TaskState <= 0) { return content = WebResponseContent.Instance.Error($"该任务状态不可跳转到下一步,任务号:【{task.TaskNum}】,任务状态:【{task.TaskState}】"); } task.ModifyDate = DateTime.Now; task.Modifier = "System"; BaseDal.UpdateData(task); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, App.User.UserId > 0 ? $"人工手动将任务状态从【{oldState}】跳转到【{task.TaskState}】" : $"系统自动流程,任务状态从【{oldState}】转到【{task.TaskState}】"); content = WebResponseContent.Instance.OK(); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 根据任务号、当前地址更新任务位置信息 /// /// 任务号 /// 当前地址 /// public Dt_Task? UpdatePosition(int taskNum, string currentAddress) { try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum && x.CurrentAddress == currentAddress); if (task == null) throw new Exception($"未找到该任务信息,任务号:【{taskNum}】"); string oldCurrentPos = task.CurrentAddress; string oldNextPos = task.NextAddress; List routers = _routerService.QueryNextRoutes(task.NextAddress, task.TargetAddress); if (!routers.Any()) throw new Exception($"未找到设备路由信息"); task.CurrentAddress = task.NextAddress; task.NextAddress = routers.FirstOrDefault().ChildPosi; task.ModifyDate = DateTime.Now; task.Modifier = "System"; BaseDal.UpdateData(task); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"系统自动流程,更新当前位置【{oldCurrentPos} ----> {task.CurrentAddress}】和下一位置【{oldNextPos} ----> {task.NextAddress}】"); return task; } catch (Exception ex) { } return null; } /// /// 任务完成 /// /// 任务编号 /// 返回处理结果 public WebResponseContent StackCraneTaskCompleted(int taskNum) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup && task.TaskState == (int)TaskOutStatusEnum.SC_OutExecuting) { List routers = _routerService.QueryNextRoutes(task.NextAddress, task.TargetAddress); if (!routers.Any()) return WebResponseContent.Instance.Error($"未找到设备路由信息"); int nextStatus = task.TaskState.GetNextNotCompletedStatus(); task.TaskState = nextStatus; task.CurrentAddress = task.NextAddress; task.NextAddress = routers.FirstOrDefault().ChildPosi; task.ModifyDate = DateTime.Now; task.Modifier = "System"; BaseDal.UpdateData(task); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库完成"); //todo 同步到WMS //暂不考虑多个出库口 } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup && task.TaskState == (int)TaskInStatusEnum.SC_InExecuting) { //todo int nextStatus = task.TaskState.GetNextNotCompletedStatus(); task.TaskState = nextStatus; task.ModifyDate = DateTime.Now; task.Modifier = "System"; BaseDal.UpdateData(task); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机入库完成"); WMSTaskDTO taskDTO = new WMSTaskDTO() { TaskNum = Convert.ToInt32(DateTime.Now.ToString("HHmmss")), Grade = 1, PalletCode = task.PalletCode + "S", RoadWay = "SC01", SourceAddress = task.TargetAddress, TargetAddress = "CLOutAreaA", TaskState = (int)TaskOutStatusEnum.OutNew, Id = 0, TaskType = (int)TaskOutboundTypeEnum.Outbound }; content = ReceiveWMSTask(new List { taskDTO }); } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup) { //todo 调用WMS移库完成 } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OtherGroup) { } else { throw new Exception($"任务类型错误,未找到该任务类型,任务号:【{taskNum}】,任务类型:【{task.TaskType}】"); } content = WebResponseContent.Instance.OK(); } catch (Exception ex) { content = WebResponseContent.Instance.Error($"任务完成异常,任务号:【{taskNum}】"); } return content; } /// /// 恢复挂起任务 /// /// 任务号 /// 返回处理结果 public WebResponseContent TaskStatusRecovery(int taskNum) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); if (task.TaskState != (int)TaskInStatusEnum.InPending && task.TaskState != (int)TaskOutStatusEnum.OutPending) { return content = WebResponseContent.Instance.Error($"该任务状态不可恢复,任务号:【{taskNum}】,任务状态:【{task.TaskState}】"); } Dt_TaskExecuteDetail taskExecuteDetail = _taskExecuteDetailRepository.QueryFirst(x => x.TaskId == task.TaskId && x.IsNormal, new Dictionary { { nameof(Dt_TaskExecuteDetail.TaskDetailId), OrderByType.Desc } }); if (taskExecuteDetail != null) { task.TaskState = taskExecuteDetail.TaskState; } else { if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup) { task.TaskState = (int)TaskOutStatusEnum.OutNew; } else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup) { task.TaskState = (int)TaskInStatusEnum.InNew; } //todo } task.ExceptionMessage = string.Empty; BaseDal.UpdateData(task); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"人工恢复挂起任务,恢复挂起时任务状态【{task.TaskState}】"); content = WebResponseContent.Instance.OK(); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 回滚任务状态 /// /// 任务号 /// 返回处理结果 public WebResponseContent RollbackTaskStatusToLast(int taskNum) { WebResponseContent content = new(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); int oldState = task.TaskState; Dt_TaskExecuteDetail taskExecuteDetail = _taskExecuteDetailRepository.QueryFirst(x => x.TaskId == task.TaskId && x.TaskState < task.TaskState && x.TaskState > 0, new Dictionary { { nameof(Dt_TaskExecuteDetail.TaskDetailId), OrderByType.Desc } }); if (taskExecuteDetail != null) { task.TaskState = taskExecuteDetail.TaskState; task.CurrentAddress = taskExecuteDetail.CurrentAddress; task.NextAddress = taskExecuteDetail.NextAddress; } else { return content = WebResponseContent.Instance.Error($"未找到任务明细信息,该任务状态不可回滚到上一步,任务号:【{taskNum}】,任务状态:【{task.TaskState}】"); } task.ExceptionMessage = string.Empty; BaseDal.UpdateData(task); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"人工将任务状态从【{oldState}】回滚到【{task.TaskState}】"); content = WebResponseContent.Instance.OK(); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } static object lock_taskNum = new object(); public int GetTaskNum(string sequenceName) { lock (lock_taskNum) { return Db.Ado.GetScalar($"SELECT NEXT VALUE FOR {sequenceName}").ObjToInt(); } } /// /// 区域库位信息查询 /// /// /// /// 区域号 public WebResponseContent LocationInquiry(string AreaCode) { if (AreaCode == null) { //查询输送线空托缓存信息时返回空位数量 } return WebResponseContent.Instance.OK(); } /// /// 地图同步 /// /// /// public WebResponseContent MapSynchronize(MapSynchronizationDto mapSynchronizationDto) { return WebResponseContent.Instance; } /// /// 出入库完成 /// /// /// /// public WebResponseContent InandoutCompleted(WMSInOutBoundCompleteFeedback wMSInOutBoundCompleteFeedback) { throw new NotImplementedException(); } /// /// 料箱验证 /// /// 任务号 /// 容器编码 /// public WebResponseContent MaterialBoxInspection(string taskCode, string containerCode) { throw new NotImplementedException(); } /// /// wcs移库数据回传 /// /// public WebResponseContent WcsMovingDataBack(WMSMoveLocationFeedback wMSMoveLocationFeedback) { throw new NotImplementedException(); } /// /// 容器流动请求 /// /// /// /// public WebResponseContent ContainerRequest(WMSContainerFlow wMSContainerFlow) { try { Dt_StationManger stationManger = _stationMangerService.Repository.QueryFirst(x => x.StationCode == wMSContainerFlow.slotCode) ?? throw new Exception($"未找到站台【{wMSContainerFlow.slotCode}】信息"); Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == "releaseStation") ?? throw new Exception("未找到站点容器释放接口配置信息!请检查接口配置"); if (wMSContainerFlow.direction == "200") { stationManger.IsOccupied = LocationStatusEnum.Free.ObjToInt(); FOURBOToccupyStation fOURBOToccupyStation = new FOURBOToccupyStation() { stationCode = wMSContainerFlow.slotCode, }; string response = HttpHelper.Post(apiInfo.ApiAddress, fOURBOToccupyStation.Serialize()); FOURBOTReturn fOURBOTReturn = response.DeserializeObject(); if (fOURBOTReturn.returnCode != 0) throw new Exception(fOURBOTReturn.returnUserMsg); _stationMangerService.UpdateData(stationManger); } return WebResponseContent.Instance.OK(); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } /// /// 质检结果反馈 /// /// /// /// public WebResponseContent IQCResult(IQCResultDTO iQC) { try { Dt_StationManger stationManger = _stationMangerService.Repository.QueryFirst(x => x.StationCode == iQC.StationCode) ?? throw new Exception($"未找到站台【{iQC.StationCode}】信息"); Dt_ApiInfo? apiInfo = _apiInfoService.Repository.QueryFirst(x => x.ApiCode == nameof(FOURBOToccupyStation)) ?? throw new Exception("未找到站点容器上架接口配置信息!请检查接口配置"); FOURBOToccupyStation fOURBOToccupyStation = new FOURBOToccupyStation() { stationCode = iQC.StationCode, podID = iQC.ContainerCode, }; string response = HttpHelper.Post(apiInfo.ApiAddress, fOURBOToccupyStation.Serialize()); FOURBOTReturn fOURBOTReturn = response.DeserializeObject(); if (fOURBOTReturn.returnCode != 0) throw new Exception(fOURBOTReturn.returnUserMsg); return WebResponseContent.Instance.OK(); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } /// /// 批量更新储位状态 /// /// /// /// public WebResponseContent multiSetNodeStatus(FOURBOTStorageStatusNotify fOURBOTStorageStatusNotify) { try { var Agvlocation = _rGVLocationInfoService.Repository.QueryData(x => fOURBOTStorageStatusNotify.storageCode.Contains(x.LocationCode)); foreach (var item in Agvlocation) { item.LocationStatus = (int)(fOURBOTStorageStatusNotify.disable == 0 ? EnableStatusEnum.Normal : EnableStatusEnum.Disable); } _rGVLocationInfoService.UpdateData(Agvlocation); return WebResponseContent.Instance.OK(); } catch (Exception ex) { return WebResponseContent.Instance.Error(ex.Message); } } } }